EveryDay.DevUp

[TACampus] 7주차 과제 - 알파 소팅, 알파테스트, 알파블렌딩 본문

TA/TACampus-Com2us

[TACampus] 7주차 과제 - 알파 소팅, 알파테스트, 알파블렌딩

EveryDay.DevUp 2025. 7. 13. 20:49

알파를 처리하는 방법에 대해 이야기 하기전에, 그래픽스를 처리할 때 불투명, 반투명 오브젝트를 어떻게 처리하는지 먼저 이해할 필요가 있습니다.

1. 불투명 오브젝트와 투명 오브젝트

1) 불투명 오브젝트

- 빛을 완전히 차단하여 뒤쪽 객체를 전혀 볼 수 없게 만드는 3D 객체

- 알파값이 1.0(완전 불투명)이거나, 투명도 정보가 없는 객체를 의미

2) 반투명 오브젝트

- 빛을 부분적으로 투과시켜 뒤쪽 객체를 어느 정도 볼 수 있게 만드는 3D 객체

- 알파값이 0.0과 1.0 사이의 값을 가지며, 앞뒤 객체의 색상이 혼합되어 렌더링됩니다.

불투명 오브젝트 (Opaque)
 
 
 
 
 
알파값: 1.0 (완전 불투명)
뒤쪽 객체: 완전히 가려짐
예시: 벽, 나무, 돌
반투명 오브젝트 (Translucent)
 
 
 
 
 
 
알파값: 0.0 ~ 1.0 (부분 투명)
뒤쪽 객체: 부분적으로 투과
예시: 유리, 물, 연기, 안개

2. 불투명 오브젝트와 반투명 오브젝트의 렌더링 차이

1) 불투명 오브젝트의 렌더링 순서

불투명 오브젝트는 뒤에 있는 오브젝트를 완전히 가려서 보이지 않게 만드는 특성 때문에 가장 앞에 있는 픽셀만 화면에 그리면 올바른 결과를 얻을 수 있습니다.

이런 특성 때문에 앞에서 뒤로 (카메라에 가까운 오브젝트부터 먼 오브젝트 순서) 렌더링을 하게 되면, 가려지는 뒤쪽 오브젝트에 대한 불필요한 계산을 생략할 수 있습니다.

불투명 오브젝트의 렌더링을 위해 Z-Buffer (깊이 버퍼)을 사용하게 되는데, 각 픽셀의 깊이값을 저장하는 별도의 메모리 공간으로, 실시간 깊이 비교를 통해 효율적인 가시성 판단을 수행합니다.

이때 깊이값 (Depth Value)은 카메라로브터 각 오브젝트의 픽셀까지의 거리로 기록합니다.

3D 공간 (측면도)
A
B
C
큐브 A: Z = 0.8
큐브 B: Z = 0.5
큐브 C: Z = 0.2

초기 상태

3개의 불투명 큐브가 서로 다른 깊이(Z값)에 위치하고 있습니다. 카메라에서 가장 가까운 것부터 차례로 렌더링됩니다.

2) 반투명 오브젝트의 렌더링 순서

반투명 오브젝트는 불투명 오브젝트와 달리 뒤에서 부터 앞으로 렌덩링을 해야합니다.

불투명 오브젝트는 뒤에 있는 모든 것을 완전히 가리기 때문에, 앞에서부터 그려도 뒤쪽은 어차피 보이지 않기 때문에 문제가 없었습니다.

하지만 반투명 오브젝트는 자신을 통해 뒤쪽 오브젝트가 부분적으로 보입니다. 이때 최종 색상은 앞쪽과 뒤쪽 오브젝트의 색상이 혼합되어 결정됩니다.

문제는 이 알파 블렌딩이 렌더링 순서에 따라 결과가 달라진다는 점입니다.

만약 앞에 있는 반투명 오브젝트를 먼저 그리면, 뒤에 있는 오브젝트를 나중에 그릴 때 이미 화면에 그려진 앞 오브젝트와 올바르게 혼합되지 않습니다.

참고 자료 https://rito15.github.io/posts/unity-transparent-stencil/ 반투명 오브젝트가 겹칠 때 앞에서 뒤로 그리게 될 경우

이를 해결하기 위한 방법으로 알파 소팅 (반대로 뒤에 있는 오브젝트를 먼저 그리고 앞 오브젝트를 나중에 그림)을 사용하면, 뒤 오브젝트의 색상이 이미 화면에 있는 상태에서 앞 오브젝트와 자연스럽게 혼합됩니다. 

알파 소팅은 카메라에서 각 오브젝트의 피벗까지의 거리값을 기반으로 하기 때문에, 카메라 시점이 회전함에 따라 뒤에 있던 오브젝트의 피벗이 가깝다고 판정되면 불쑥 앞으로 튀어나와 앞에 있는 오브젝트를 가리게 되는 이슈가 있습니다.

3) 불투명 오브젝트와 반투명 오브젝트가 서로 겹칠 경우

참고 자료 https://rito15.github.io/posts/unity-transparent-stencil/ 불투명 오브젝트는 반투명 오브젝트와 겹친 부분에서 자신의 픽셀을 그리지 않아야 한다고 판단

불투명 오브젝트와 반투명 오브젝트가 겹치는 영역에 존재하는 경우, 깊이와 렌더링 순서에 따라서 위와 같이 의도하지 않은 최종 결과가 나타날 수 있습니다. 이런 문제를 해결하기 위해서 불투명 오브젝트를 모두 그리고 난 후, 반투명 오브젝트를 그리게 됩니다. 

3. 알파 테스트

알파테스트는 텍스처의 알파값을 기준으로 픽셀을 완전히 투명하거나 완전히 불투명하게만 처리하는 렌더링 기법입니다.

알파테스트는 중간 투명도 없이 이진 처리 방식으로 작동합니다. 이 방식은 알파값을 0 또는 1로만 사용하며, 중간값은 허용하지 않는 특징을 가집니다. 렌더링 과정에서는 임계값 비교를 통해 알파값 > Cutoff 조건을 만족하는 픽셀만 화면에 그리게 됩니다. 이 조건을 만족하지 않는 픽셀들은 클리핑 과정을 거쳐 완전히 제거되며, 최종적으로 그려지는 모든 부분은 불투명 렌더링으로 처리되어 완전한 불투명 상태로 화면에 표시됩니다.

알파테스트는 주로 환경 표현에 활용되는데, 특히 풀, 나뭇잎, 철망, 체인링크 펜스와 같은 복잡한 형태의 오브젝트들을 효율적으로 렌더링할 때 사용됩니다. 이 기법에서 알파 채널은 일반적인 투명도 정보가 아닌 마스킹 정보로 활용됩니다. 다시 말해, 어떤 부분을 그릴지 그리지 않을지를 구분하는 영역 정보로 사용되는 것입니다. 깊이 처리 측면에서는 불투명 오브젝트와 동일하게 깊이 테스트를 적용할 수 있어 안정적인 렌더링이 가능합니다.

알파테스트의 주요 장점으로는 가벼운 처리 방식으로 알파 블렌딩보다 연산량이 적어 빠른 성능을 제공한다는 점입니다. 또한 깊이 테스트를 정확하게 수행할 수 있어 Z-buffer를 통한 효율적인 렌더링이 가능하며, 가려진 부분 제거 기능을 통해 뒤에 있는 오브젝트의 불필요한 렌더링을 생략할 수 있습니다. 불투명 처리 특성상 알파 소팅이 불필요하여 렌더링 순서 문제가 발생하지 않으며, 복잡한 블렌딩 없이 예측 가능한 결과를 얻을 수 있어 일관된 시각적 결과를 보장합니다.

반면 알파테스트의 단점으로는 이진 처리 방식으로 인해 거친 외곽선이 나타나며, 경계면이 자글자글하고 거칠어 보인다는 점이 있습니다. 반투명 표현이 불가능하여 부드러운 투명도 효과를 구현할 수 없으며, 제한된 표현력으로 인해 세밀한 투명도 효과나 그라디언트 같은 복잡한 시각적 표현에 한계가 있습니다. 이러한 특성으로 인해 알파테스트는 성능과 시각적 품질의 균형이 중요한 상황에서 실용적인 해결책을 제공하는 렌더링 기법이라고 할 수 있습니다.

원본 텍스처
알파테스트 결과
0.5
0.8

모바일 기기에서의 알파테스트 성능의 과거와 현재

알파 테스팅은 게임 개발에서 흥미로운 변화를 겪은 기술 중 하나입니다. 과거에는 PC에서 알파 블렌딩보다 빠르고 좋은 기능으로 여겨졌지만, 모바일 환경에서는 완전히 다른 평가를 받았습니다.

과거 모바일에서 알파 테스팅이 비추천되었던 주된 이유는 두 가지였습니다. 첫 번째는 픽셀 셰이더에서 픽셀을 날려버리는 discard 방식을 사용해야 했는데, 이 과정에서 복사된 캐시 뎁스를 사용할 수 없어 직접 램에서 데이터를 읽어와야 했기 때문입니다. 두 번째이자 더 중요한 이유는 TBDR(Tile-Based Deferred Rendering) 기술과의 충돌이었습니다.

TBDR은 많은 사람들이 혼동하는 용어인데, 라이팅 연산에서 사용하는 디퍼드 렌더링과는 완전히 다른 개념입니다. TBDR의 디퍼드는 단순히 '지연'이라는 의미로, 버텍스 단계에서 모든 것을 그린 후 보이지 않는 부분을 제거하고 나서 픽셀 처리를 진행하는 방식입니다. 이 기술은 완전히 불투명한 오브젝트를 전제로 만들어졌기 때문에, 알파 테스팅이 사용되면 TBDR의 고속 처리 능력이 완전히 무력화됩니다.

PowerVR 칩셋을 사용하는 모바일 기기들이 이 TBDR 기술을 활용했기 때문에, 알파 테스팅은 모바일에서 성능 저하의 주범으로 여겨졌습니다. 이로 인해 "알파 테스팅이 블렌딩보다 더 무겁다"는 소문이 퍼졌고, 많은 교육 자료와 메뉴얼에서 모바일에서는 알파 테스팅보다 알파 블렌딩을 사용하라고 권장하게 되었습니다. 

하지만  URP(Universal Render Pipeline)의 등장과 하드웨어의 발전으로 알파 테스팅의 문제점들이 대부분 해결되었습니다. 가장 큰 변화는 TBDR 문제의 해결입니다. PowerVR 칩을 사용하는 주력 스마트폰이 아이폰 7을 마지막으로 사라지면서, TBDR을 사용하는 하드웨어가 거의 없어졌습니다. 완전히 사라진 것은 아니므로 여전히 신경 써야 하지만, 미래에는 점점 더 걱정할 필요가 없어질 것입니다.

두 번째 문제였던 뎁스 처리 방식의 기술적 문제도 Depth Prepass 기능으로 해결되었습니다. Depth Prepass는 깊이 패스만 먼저 그려놓고 프래그먼트 처리를 진행하는 기법으로, 픽셀 처리 시 미리 처리된 뎁스를 사용하기만 하면 되므로 알파 테스팅의 캐시 무결성 문제를 해결합니다. 이 기능은 소프트 파티클이나 물결의 Depth Fade 기능을 위한 'Depth Texture' 옵션이 활성화되면 자동으로 실행됩니다.

흥미로운 점은 저사양을 위해 소프트 파티클 기능을 끄면서 Depth Texture를 비활성화하면, 오히려 알파 테스팅 부하가 급격히 증가할 수 있다는 것입니다. 성능 최적화를 위해 옵션을 껐는데 오히려 무거워지는 역설적인 상황이 발생할 수 있습니다. Unity 2021.2부터는 이런 문제를 해결하기 위해 Depth Priming Mode라는 이름으로 렌더러에서 강제로 Depth Prepass를 실행할 수 있게 되었습니다.

결론적으로 최신 기술 환경에서는 모바일에서 알파 테스팅이 느려지는 문제가 거의 해결되어 큰 걱정 없이 사용할 수 있게 되었습니다. 하지만 여전히 오래된 기기나 특수한 하드웨어를 만날 수 있기 때문에 완전히 마음을 놓을 수는 없는 상태입니다.

알파테스팅 최적화

알파 테스팅의 최적화 방법은 여러 가지가 있습니다. 가장 좋은 방법은 가능하다면 알파 테스팅조차 사용하지 않는 것입니다. 현대 모바일 그래픽 카드는 몇 년 전 PC 그래픽 카드와 맞먹을 정도로 발전했기 때문에, 폴리곤이 너무 적은 것보다는 어느 정도 적당한 폴리곤을 지속적으로 제공하는 것이 더 효율적입니다. 따라서 가능하면 실제 메시 모델링으로 해결하는 것이 최선입니다.

하지만 작은 디테일이 필요한 경우에는 알파 테스팅을 사용하는 것이 좋습니다. 과도한 디테일을 모델링하여 너무 작은 삼각형 폴리곤을 만드는 것은 오히려 성능에 해롭기 때문입니다. 사용할 때는 가급적 큰 알파 테스팅은 피해야 합니다. 최신 기기에서는 문제가 없지만, 구형 기기에서는 여전히 문제가 될 수 있기 때문입니다.

알파 영역의 빈자리를 최대한 줄이는 것도 중요한 최적화 방법입니다. 이는 알파 블렌딩과 같은 개념으로, 조금이라도 타일의 면적을 줄이면 타일 방식 렌더링에 도움이 됩니다. 빈 면적을 줄이기 위해 약간의 폴리곤을 더 사용하는 것이 여러모로 유리합니다.

⚠️ 과거 방식 (비효율)

알파 테스팅
체인링크 펜스
문제점:
  • 복잡한 패턴을 알파 테스팅으로 처리
  • TBDR 성능 저하 발생
  • 구형 모바일에서 심각한 부하
구형 모바일: 12 FPS | TBDR: 비활성화

✅ 현재 권장 방식

 
 
 
 
 
실제 메시 모델링
개선점:
  • 실제 메시로 디테일 구현
  • 알파 테스팅 완전 제거
  • 모든 디바이스에서 안정적
모든 디바이스: 58 FPS | 안정성: 100%

🔧 메시 모델링 활용 최적화

핵심 원리: 현대 모바일 GPU는 몇 년 전 PC 수준의 성능을 가지므로, 적당한 폴리곤을 지속적으로 제공하는 것이 알파 테스팅보다 효율적입니다.
⚡ 성능 팁: "폴리곤이 너무 적은 것보다 어느 정도 적당한 폴리곤을 계속 먹이로 던져주는게 빠릅니다" - 현대 GPU의 특성을 활용하세요.
권장 구현 방법:
// 실제 메시 활용
// 알파 테스팅 대신 폴리곤으로 해결
Mesh fenceMesh = GenerateRealFence(segments);
// 작은 디테일만 알파 테스팅 사용
if (detailSize < threshold) useAlphaTesting();
과거 방식:
• 복잡한 패턴 알파 테스팅
• TBDR 성능 저하
• 구형 디바이스 문제
현재 권장:
• 실제 메시 모델링
• 안정적인 성능
• 모든 디바이스 호환

4. 알파 블렌딩

알파 블렌딩은 컴퓨터 그래픽스에서 투명도를 가진 오브젝트들을 자연스럽게 합성하는 핵심 기술입니다. 게임이나 3D 애플리케이션에서 유리창, 물, 연기, 파티클 효과 등을 표현할 때 필수적으로 사용되는 렌더링 방식으로, 반투명 쉐이더의 기본이 되는 개념입니다.

알파 블렌딩의 핵심은 알파 값(Alpha Value)에 있습니다. 이 값은 0.0에서 1.0 사이의 범위를 가지며, 0.0은 완전 투명, 1.0은 완전 불투명을 의미합니다. 예를 들어 0.5의 알파 값을 가진 오브젝트는 50% 투명하여 앞뒤 색상이 반반 섞인 결과를 보여줍니다.

실시간 블렌딩 효과

💧
 
💧 물 파티클 (배경)
 
⚡ 마법 오라 (전경)
물 파티클과 마법 오라가 겹치는 영역에서 블렌딩 효과를 확인할 수 있습니다

Normal (일반 블렌딩)

수학적 공식:
Result = Source * Alpha + Destination * (1 - Alpha)

가장 기본적인 알파 블렌딩 방식입니다. 전경과 배경의 색상을 알파 값에 따라 선형적으로 혼합합니다. Unity에서 가장 자주 사용되는 블렌딩 모드입니다.

🎮 게임 활용 예시:
  • UI 요소 (메뉴, 인벤토리, HUD)
  • 캐릭터 페이드 인/아웃 효과
  • 반투명 창문, 물 표면
  • 파티클 시스템 (연기, 안개)
  • 반투명 쉐이더 오브젝트
Blend SrcAlpha OneMinusSrcAlpha

빠른 블렌딩 모드 비교

 
 
Normal
 
 
Additive
 
 
Multiply
 
 
Screen
 
 
Overlay
 
 
Soft Light
 
 
Hard Light
 
 
Difference

알파 블렌딩은 알파 테스팅과 비교했을 때 명확한 차이점이 있습니다. 알파 테스팅은 완전 투명하거나 완전 불투명한 두 가지 상태만을 지원하여 처리 속도가 빠르고 메모리 사용량이 적지만, 날카로운 경계를 가진 단순한 표현만 가능합니다. 반면 알파 블렌딩은 부분 투명을 지원하여 자연스러운 투명 효과와 부드러운 경계를 만들 수 있어 시각적 품질이 우수하지만, 그만큼 처리 속도가 느리고 메모리 사용량이 많습니다.

실제 게임 개발에서 알파 블렌딩은 다양하게 활용됩니다. UI 요소에서는 반투명 메뉴나 체력바 배경 등을 구현할 때 사용되며, 환경 효과로는 안개, 연기, 불꽃 파티클 등을 표현할 때 필수적입니다. 또한 유리창, 물 표면, 홀로그램 같은 특수한 재질을 구현할 때도 중요한 역할을 합니다.

하지만 알파 블렌딩은 성능상의 단점도 가지고 있습니다. 하나의 픽셀에 대해 여러 번의 렌더링이 실행될 수 있어 처리 부하가 크고, 올바른 렌더링 순서를 유지하기 위한 정렬 과정이 필요하며, 추가적인 버퍼로 인한 메모리 사용량 증가가 발생합니다. 

알파 블렌딩의 최적화

알파 블렌딩 최적화는 게임 개발에서 성능을 좌우하는 핵심 요소 중 하나입니다. 많은 개발자들이 폴리곤 수를 줄이는 데 집중하지만, 실제로는 알파 블렌딩에서 픽셀 단위 처리가 성능에 훨씬 큰 영향을 미칩니다.

알파 블렌딩의 성능 비용은 화면에 보이는 픽셀 수와 직접적인 상관관계가 있습니다. 작은 파티클이라도 카메라가 가까이 가서 화면을 가득 채우게 되면 심각한 성능 저하를 일으킬 수 있습니다. 이는 알파 블렌딩이 픽셀별로 처리되기 때문인데, 화면에 얼마나 크게 보이느냐가 성능의 핵심 요소가 됩니다. 예를 들어 화면 가득히 먼지 효과가 펼쳐진다면, 기껏 준비한 TBR(Tile-Based Rendering) 같은 최적화 기능도 쓸모없어집니다.

가장 중요한 최적화 전략 중 하나는 알파 영역의 빈자리를 최대한 줄이는 것입니다. 폴리곤을 아끼기 위해 커다란 쿼드에 작은 이펙트를 그려서 빈자리를 많이 남기는 것은 오히려 비효율적입니다. 현대 GPU의 특성을 고려하면, 폴리곤을 조금 더 사용하더라도 알파 픽셀을 줄이는 것이 훨씬 효율적입니다. 이는 마치 큰 공장에서 이쑤시개 하나 만드는 격으로, 현대 하드웨어에서는 적당한 폴리곤 증가보다 대용량 알파 블렌딩이 훨씬 큰 부담이 됩니다.

폴리곤을 좀 더 사용하더라도 알파 픽셀을 줄이면 타일 처리도 줄일 수 있고, 픽셀 블렌딩 연산도 줄일 수 있습니다. 현대 GPU는 폴리곤 처리에 최적화되어 있어서 수십 개의 폴리곤 증가는 문제가 되지 않지만, 큰 면적의 알파 블렌딩은 여전히 큰 부담입니다. 따라서 이펙트 메시를 만들 때는 실제 이펙트 모양에 맞게 폴리곤을 구성하여 불필요한 투명 영역을 최소화해야 합니다.

오버드로우 최소화도 중요한 최적화 전략입니다. 한 자리에 그리고 그리고 또 그리면 빠를 리가 없습니다. 이것이야말로 기껏 빠르다고 광고한 알파 블렌딩을 의미없게 만드는 주범입니다. 특히 이펙트에서 오버드로우는 어느 정도 필연적이지만, 조금씩이라도 덜 쓰고 비슷한 느낌을 내려고 노력한다면 가랑비에 옷 젖듯 성능을 향상시킬 수 있습니다.

거리 기반 최적화 시스템도 필수적입니다. 카메라와의 거리에 따라 파티클의 밀도나 크기를 조절하고, 일정 거리 이하에서는 자연스럽게 페이드 아웃 처리를 해야 합니다. 또한 화면 비율 대비 최대 크기를 제한하여 예상치 못한 성능 저하를 방지할 수 있습니다.

❌ 최적화 전 (비효율)

거대한
파티클
문제점:
  • 화면 가득 채우는 대형 파티클
  • 카메라 접근 시 극심한 성능 저하
  • 불필요한 픽셀 처리 과다
성능: 15 FPS | 픽셀 수: ~32,000개

✅ 최적화 후 (효율적)

최적
크기
LOD
개선점:
  • 거리별 크기 제한 적용
  • LOD 시스템으로 자동 조절
  • 안정적인 성능 유지
성능: 55 FPS | 픽셀 수: ~3,600개

🎯 화면 크기 제한 최적화

핵심 원리: 알파 블렌딩 비용은 화면에 보이는 픽셀 수에 비례합니다. 작은 파티클도 카메라가 가까이 가면 성능 킬러가 됩니다.
⚠️ 주의사항: "가까이 보지 말아 주세요 부끄러우니까" - 유저가 이펙트에 너무 가까이 가지 않도록 거리 제한이나 페이드아웃 처리가 필요합니다.
구현 방법:
// 거리 기반 크기 제한
float distance = length(cameraPos - particlePos);
float sizeLimit = min(1.0, distance / minDistance);
finalSize *= sizeLimit;
비효율적:
• 거리 무관 고정 크기
• 화면 가득 채우는 파티클
• TBR 최적화 무효화
효율적:
• 거리별 동적 크기 조절
• 화면 비율 대비 제한
• 성능 안정성 확보

 

참고자료

https://rito15.github.io/posts/unity-transparent-stencil/

 

유니티 반투명, 스텐실 개념 익히기

목차

rito15.github.io

https://chogyujin-study.tistory.com/30

 

그래픽스 알파 테스트, 알파 블렌딩, 알파 소팅

알파 테스트, 알파 블렌딩, 알파 소팅에 대해 공부하도록 하겠습니다. 알파 테스트와 알파 블렌딩은 그래픽스 공부에서 매우 중요한 편입니다. 텍스쳐에는 알파채널값이 있는데, 보통 256단계 입

chogyujin-study.tistory.com

https://chulin28ho.tistory.com/660#google_vignette

 

모바일에서의 알파 블렌딩과 테스팅

먼저 본 내용에 많은 도움을 주신 유니티 스팟라이트 팀의 고정석 팀장님께 인사박고 시작합니다. 회사에서 썼던 글을 수정해서 외부 공개 가능용으로 만들어 보았습니다. 자아.. 모바일에서의

chulin28ho.tistory.com