TECHARTNOMAD | TECHARTFLOWIO.COM

TECH.ART.FLOW.IO

[번역] 모바일 플랫폼을 위한 알파 테스트 효율성 재고하기

jplee 2024. 5. 20. 13:54

역자의 말.
최근 신입사원들의 입사도 있고 겸사 해서 아트팀의 파트 주임급 이상 분들은 한번 읽어보게 하고 싶은 토픽들이 있었는데요... 하나 하나 공유 해 보도록 하겠습니다. 가장 처음으로는 알파테스트가 모바일 하드웨어에서 왜 느린지... 폴리지 제작할 때 왜 알파 디스카드 영역을 극최소화 해야 하는지 알려주고 싶었거든요. 이게 알고 하는거랑 하라고 하니까 하는거랑 남이 하니까 하는건 엄연히 다르니 말이죠.


저자

이것은 오래된 질문인데, 어젯밤에 몇 명의 수도사들과 이 문제를 다시 논의하면서 약간 새로운 아이디어가 떠올랐기 때문에 이 자리에서 말씀드리려고 합니다:
어느 쪽이 더 빠르냐는 질문에 대해서는 AlphaTest와 AlphaBlend 중 어느 쪽이 더 빠를까요?

정말 모르겠습니다.

그리고 이 문제에 대해 100% 확실한 결론을 내릴 수 있는 사람이 있는지 모르겠습니다.
이러한 하드웨어 구현의 세부 사항은 기밀로 간주할 수는 없지만 알고 싶다고 해서 알 수 있는 것은 아닙니다. 누구나 알 수 있는 정보의 출처도 다양한 채널에서 일부 정보를 공개하고 있지만 실제로 자세히 알려주지는 않습니다.

따라서 지금까지 어떤 거물급 인사도 이 스레드를 끝낼 수 있는 표준 답변을 내놓지 못했습니다.
하지만 이를 모른다고 해서 개발 작업 자체를 할 수 없는 것은 아니며, 효율성 문제일 뿐이고 효율성 문제는 테스트 중심으로 해결될 수 있기 때문입니다.
실제로 저를 포함한 많은 사람들이 AlphaTest와 AlphaBlend가 비슷하게 효율적이거나 때로는 조금 더 빠르다는 테스트 결과를 내놓았습니다. 물론 테스트 사례는 모두 다르며, 우리 프로젝트가 이런 식으로 작동한다고 해서 모든 프로젝트가 그렇게 작동한다는 의미는 아니므로 안전을 위해 자체 테스트 결과를 사용하여 계획을 결정해야 합니다. 하지만 이런 수고를 하고 싶지 않다면 ......
알파테스트와 알파블렌드가 똑같이 효율적이라고 가정하는 것이 상대적으로 더 안전하며 케이스별로 자유롭게 선택해야 합니다.
 
해결 방법은 어느 정도 해결되었지만, Apple의 공식적인 말이나 파이프라인에 대해 공개된 정보로 판단할 때 AlphaTest가 AlphaBlend보다 빠르거나 비슷할 가능성은 없습니다.
-- 하지만 이는 실제 테스트 결과와 상반됩니다.
따라서 이 글에서는 두 가지 주제에 대해 설명합니다:

  • 알파테스트가 알파블렌드보다 느린 이유는 무엇인가요?
  • 어떻게 알파테스트가 알파블렌드보다 느리지 않을 수 있나요?

 

알파테스트가 알파블렌드보다 느린 이유는 무엇인가요?

알파테스트는 실제로 렌더링할 때 불투명 오브젝트와 비슷하며, '투명한 오브젝트'라기보다는 '구멍을 뚫을 수 있는 불투명 오브젝트'에 가깝습니다. Unity에서는 AlphaTest와 불투명을 혼합하여 사용할 수도 있습니다. 알파테스트 오브젝트는 조명, 허용 또는 허용되지 않는 투영, 렌더링 파이프라인에서의 위치 측면에서 불투명 오브젝트와 똑같이 취급됩니다.
알파테스트는 사실 특별한 종류의 불투명이며, 픽셀 단계에서 픽셀을 폐기하여 특정 픽셀이 화면에 그려지지 않도록 할 뿐이며, 이러한 관점에서 보면 불투명보다 성능 효율이 더 높아야 합니다.
반면에 AlphaBlend는 완전히 투명합니다. 일반적으로 투명한 오브젝트일수록 효율성이 떨어진다는 '경험 법칙'도 있는데, 이는 AlphaBlend가 블렌드 시 화면 버퍼를 읽고 픽셀당 여러 레이어를 다시 계산해야 하며 오버드로가 높으면 채우기 속도가 매우 빨라질 수 있기 때문입니다.
그렇다면 왜 모바일 플랫폼에서 AlphaTest가 AlphaBlend보다 느리다고 말하는 사람이 있을까요?
모바일 플랫폼에서 early-DT(사전 깊이 테스트)가 널리 사용되기 때문입니다.
 
모바일 전용 플랫폼에서는 오브젝트를 먼저 그리고 특정 영역에 깊이를 쓴 다음 나중에 그보다 낮은 깊이의 오브젝트를 그리면 가려져서 그려지지 않는다고 오해하는 경우가 있습니다 .......

하지만 사실 이전 GPU는 이렇게 '스마트'하지 않았습니다.
이 기술 자체는 Early-DT이며, 애플만 과대포장하고 있지만 실제로는 모든 모바일 플랫폼의 모든 GPU에서 사용됩니다. 이 기술을 사용하는 GPU만이 방금 언급한 '드로잉 최적화'를 달성할 수 있습니다.

DepthTest를 프래그 셰이더 앞에 배치해야만 나중에 프래그 셰이더를 중단하여 퍼포먼스 향상을 얻을 수 있습니다!
다른 GPU에는 이 기술이 없기 때문에 DepthTest 단계가 프래그 셰이더(일명 later-DT) 뒤에 오므로 화면 내 오브젝트에 대한 오클루전 컬링이 없습니다.
이러한 이유로 동일한 픽셀에서 반복되는 계산량을 줄이는 디퍼드 셰이딩이 PC 콘솔 플랫폼의 표준이 되었습니다. 모바일 플랫폼에는 디퍼드 셰이딩과 부분적으로 겹치는 early-DT가 있기 때문에 디퍼드 기술의 추가 비용보다 이점이 적을 수 있으므로 모바일 플랫폼에는 디퍼드 셰이딩을 권장하지 않습니다.
(댓글 섹션에서 알려드렸듯이, PC 플랫폼의 GPU에도 동일한 early -DT 기술이 존재합니다. 사실 이 기술은 다른 사람들이 저에게 알려줬던 기술이고, 저도 처음에는 잘 몰랐습니다. 따라서 PC 플랫폼에서는 Z를 기준으로 엄격하게 정렬할 수 없기 때문에 발생하는 마지막 이중 그리기를 제거하기 위해 디퍼드 셰이딩을 사용합니다).
 
early  DT와 later DT에 대해 이해했다면, 한 가지 더 이야기할 것이 있습니다:

병렬화 및 직렬화

하드웨어는 연산을 수행할 때 픽셀 단위로 수행하는 것이 아니라 여러 픽셀을 동시에 수행하는데, 이를 병렬화라고 합니다.

하지만 여러 스레드를 병렬화할 때 항상 동기화 상태를 유지하는 것은 아니며, 프래그 단계에서는 여러 가지 이유로 끝나는 지점에 항상 불일치가 발생하고 먼저 그려진 픽셀이 나중에 그려질 수 있습니다.

모든 픽셀이 순서대로 그려질 필요는 없지만, 픽셀이 그려지는 순서를 강제로 지정하면 GPU가 이를 따라야 하므로 그렇게 해야 합니다:

물론 GPU가 프레임 버퍼를 조작할 필요가 없는 다른 작업을 찾을 수 있다면 이 대기 단계 동안 유휴 상태가 되지 않습니다. 하지만 수행할 '작업'을 찾지 못하면 유휴 상태가 됩니다.
이 때 직렬화가 발생하여 성능 저하가 발생한다고 주장합니다.
 
하지만 GPU는 그렇게 멍청하지 않습니다.
분명한 최적화는 프레임 버퍼에 그리는 순서만 같으면 되기 때문에 프래그 셰이더의 결과를 쌓아서 대기열에 넣고 대기열의 순서가 같은지 확인하면 내 앞에 있는 프래그 셰이더가 언제 끝나든 상관없고 역순이더라도 상관없지 않습니까?
later-DT에서는 그랬죠:

이 뎁스 테스트 프로세스는 실제로 읽기+쓰기 프로세스라는 점을 간과하기 쉬운데, 불투명 오브젝트는 뎁스를 읽은 직후 자신의 뎁스를 다시 써야 다음 픽셀이 읽기 전에 이전 픽셀이 뎁스를 쓸 수 있으므로 뎁스 테스트의 순서도 정확해야 합니다.
따라서 early-DT로 전환한 후 ......

프레임 깊이 버퍼와 프레임 색상 버퍼 작업의 타이밍이 엇갈리지만, 개별 작업의 순서는 여전히 동일하므로 문제가 없습니다.
 
 

자, 이제 드디어 주인공의 차례입니다.

AlphaTest는 later-DT 또는 early-DT를 사용하나요?
later-DT에서는 문제가 없지만, early- DT에서는 알파테스트가 일반적으로 뎁스를 읽을 수 있지만 텍스처를 읽어야만 뎁스를 쓸 수 있다는 것을 알기 때문에 뎁스 쓰기가 작동하지 않습니다.

    •  
    • 불투명 오브젝트는 알파 테스트를 통과하는 한 쓰기 깊이 작업을 수행해야 하며, early depth write에 대한 early 단계는 문제가 되지 않습니다.
    • 투명 오브젝트는 어떤 경우에도 Depth write 연산을 수행하지 않으므로 early 단계에도 영향을 미치지 않습니다.
    • 그리고 알파테스트의 Depth write 연산은 어떤 경우에도 프래그 단계 이후에만 수행할 수 있습니다.


즉, 알파 테스트의 경우 early-DT와 later-DT 렌더링 파이프라인을 혼합해야 했는데, 이는 사소한 작업이 아니며 제가 말하는 '비공식적으로 지정된 세부 사항'과 정확히 일치합니다.
 

정확히 어떤 것인지는 모르겠지만 몇 가지 가능성을 나열해도 괜찮습니다:

1. AlphaTest는 early-DT 단계에서 읽기 작업을 수행한 다음 마지막에 쓰기 작업을 위해 DT를 다시 수행합니다.
이것은 합리적으로 보이지만 가장 사이비적인 접근 방식입니다:

이것이 직렬화의 궁극이며, 만약 그렇다면 AlphaTest는 삭제하고 다른 로직을 추가하여 대기하는 것이 더 나을 것이며, 이 수준의 직렬화에서는 "다른 작업"을 많이 할 필요가 없습니다.
 
2. 알파테스트는 early-DT에서 바로 건너뛰고 기본값은 통과로 설정한 다음 마지막에 전체 DT 읽기+쓰기를 한 번 더 수행합니다.
이것은 나중에 DT와 완전히 동일하며 직렬화 문제가 없습니다. 그러나 나중에 일반 early-DT를 실행해야 하는 불투명/알파 블렌드를 그려야 하는 경우, 여전히 기다려야 하지만 한 번만 기다려야 합니다.

알파테스트와 오파크를 반복적으로 전환하지 않는 한 직렬화는 심각한 문제가 되지 않습니다. 이것이 바로 공식적으로 OpaTest를 Opaque 이후에 그리는 것이 권장되는 이유이기도 한데, Opaque가 두 개 이상으로 분할되어 직렬화 대기가 발생하는 것을 피하기 위해서입니다(한 번만 AlphaBlend로 백업해도 여전히 방지되지 않음).
하지만 결함도 심각합니다. 즉, 알파 테스트는 순수한 later-DT이며 상호 오클루전으로 필터링할 수 없고, 파편 단계가 모두 완전히 실행되어야 합니다. 오디언스가 알파 테스트를 불투명 단계 뒤에 배치하면 알파 테스트는 잔디를 가리는 지형도 제대로 처리하지 못하고 불투명 콘텐츠를 추가로 그리게 됩니다.
따라서 이것이 사실이라면 개인적으로 공식적인 조언을 무시하고 불투명 사이에(또는 그 전에) AlphaTest를 적절히 삽입하는 것이 좋지만 너무 자주 삽입하지 마세요. 직렬화는 성능을 저하시키지만 오버드로는 성능을 더욱 저하시키는 경향이 있습니다.
알파 테스트가 일부 불투명 오브젝트보다 먼저 그리면 위의 이유로 인해 자체 그리기가 낭비되더라도 "오프 픽셀"로 인해 결국 표면의 그리기 시간이 단축됩니다. 알파 테스트는 주로 잔디와 일부 캐릭터 효과에 사용되며 그 자체로 가려질 가능성이 적고 알파 블렌드는 대부분 불투명 오브젝트에 의해 가려지지 않는다는 점을 고려할 때, later-DT로 인해 발생하는 간격은 크지 않습니다.
이러한 여러 요인의 조합으로 인해 "이론적으로는 AlphaTest가 AlphaBlend보다 성능이 떨어지지만, 오버드로가 더 낮다는 이유로 일반 프로젝트에서는 더 효율적일 수 있다"와 같은 현상이 발생할 수 있습니다.
이것이 설계된 것인지는 모르겠지만, 만약 그렇다면 적어도 "왜 알파테스트가 더 효율적인지"에 대한 결과를 어느 정도 설명할 수 있습니다.
 
3.그 외에도 다른 가능성이 있습니다. early-DT에서 읽기 작업을 먼저 수행하여 전달한 다음 마지막에 전체 later-DT를 다시 실행하는 것입니다.

마지막 작업과 큰 차이는 없습니다. 즉, 그 앞에 깊이 읽기 작업이 추가됩니다. 사실 우리가 요구하는 순서는 단지 쓰기 순서일 뿐이며, 잘못된 순서로 읽으면 부정확한 데이터로 이어질 뿐입니다. 판독 결과가 합격인 경우 DepthTest가 통과하지 못해 픽셀이 버려질 수 있지만 판독 결과가 불합격인 경우 실제로 그릴 필요가 없으므로 바로 중단할 수 있습니다.
이렇게 하면 알파테스트가 앞에 있는 불투명한 오브젝트에 가려질 때 알파블렌드와 동일한 오버드로우 효과가 감소하며(발생 확률은 낮지만), 이 경우 알파테스트가 알파블렌드보다 느려질 가능성은 훨씬 적습니다.
 

결론:

  •  
  • 위에 언급된 테스트 결과는 IOS/안드로이드 모두에 대한 것으로, 현재로서는 IOS와 안드로이드 간에 뚜렷한 차이가 없습니다.
  • 현재 PowerVR과 다른 GPU의 주요 차이점은 TBR의 DT 단계에서 최상위 삼각형을 찾기 위한 추가 연산이 있다는 점이지만(다른 GPU의 경우 TBR, TBDR), 그 차이는 제가 말하는 부분에 영향을 미치지 않을 것입니다. 즉, early-DT로 인한 알파테스트의 비효율성 문제는 모든 모바일 플랫폼에 공통적으로 발생하는 문제일 가능성이 높으며, 단지 다른 플랫폼에서는 불만의 목소리가 나오지 않을 뿐입니다. 결국, 테스트의 이 시점에서 안드로이드 계열의 휴대폰은 애플 휴대폰과 다른 결과를 얻지 못합니다.
  • 위에서 언급한 내용은 기껏해야 추측에 불과합니다. 저는 모든 가능성을 열어두고 왜 AlphaTest가 AlphaBlend보다 더 빠른 것으로 밝혀졌는지 설명하려고 노력했습니다. Apple 고유의 TBDR 정렬 문제는 AlphaTest가 AlphaBlend보다 효율성이 떨어지는 결과를 초래할 뿐이므로 언급하지 않았습니다. 이미 글이 충분히 길어졌으니 계속 내용을 추가하지 마세요.
  • 저는 병렬화에 대해 잘 이해하지 못하며 다른 사람들이 말한 것을 의역한 것에 가깝습니다. GPU 멀티코어는 실제로 하나의 명령어가 여러 마이크로 코어에서 동시에 다른 데이터를 실행하는 것을 의미하므로 한 번에 하나의 스레드 번들만 실행할 수 있다면 계산 능력이 낭비되지 않아야 합니다(WARP). 하지만 병렬 멀티스레딩이 없다면 왜 누군가가 알파테스트가 느리다고 말하는지 설명하기가 더 어려워집니다(단지 DT 자체가 느려서 그런 것일까요?). <아니면 스레드 번들 자체가 병렬 실행을 허용할까요? 워프에 포함된 마이크로스레드 수는 규칙에 의해 정해져 있고, 결국 그 이상의 마이크로코어가 작업을 수행해야 하므로 여러 개의 워프가 동시에 실행되도록 허용해야 합니다. 아마도 이것이 사실일 것입니다.
  • 알파테스트가 알파블렌드보다 빠르거나 비슷하게 효율적이라는 것이 아니라, 제 테스트 결과가 그렇다는 뜻입니다. 동일한 테스트 결과를 얻은 사람들이 많이 있습니다. 테스트 결과와 이론의 차이 때문에 이 글을 쓰게 되었습니다. 하지만 테스트 결과가 모두 틀릴 수도 있다는 것은 사실이며 샘플이 정말 적습니다.
  • 저는 신이 아니므로 이 성가시고 사실 매우 중요한 주제를 끝낼 수 있는 충분한 정보를 가지고 계신 분이 있다면 언제든지 의견을 남겨 주세요.

댓글 섹션에 표현된 견해를 바탕으로 몇 가지 결론을 내릴 수 있습니다:

  1.  
  2. 모든 모바일 플랫폼에서 AlphaTest는 later-DT로만 진행되기 때문에 스스로를 "오클루드"할 수 없으며(AlphaBlend는 가능), 이것이 AlphaBlend보다 효율이 떨어지는 주된 이유입니다. 따라서 알파테스트가 덜 가려진다면 이러한 단점은 존재하지 않으며, 대신 알파테스트가 다른 오브젝트를 "오클루드"할 수 있으므로 더 효율적입니다(단, 알파테스트가 불투명한 오브젝트보다 먼저 그려야 함).
  3. 모든 모바일 플랫폼에서 AlphaTest는 후면 AlphaBlend/Opaque를 차단하여 약간의 성능 저하를 일으키므로 이러한 상황이 더 자주 발생하지 않도록 AlphaTest의 오브젝트 정렬을 중앙 집중식으로 만들어야 합니다. 가장 쉬운 방법은 모든 불투명 오브젝트보다 먼저 AlphaTest를 그리도록 하는 것입니다.
  4. PowerVR(IOS) 플랫폼에서 알파테스트가 발생하면 위에서 언급한 문제 외에도 현재 타일의 HSR(깊이별 하드웨어 정렬)이 전체적으로 실패하여 나머지 일반 GPU와 일관성이 떨어지게 됩니다. 불투명한 오브젝트가 앞뒤로 정렬되지 않는 영역에서 알파테스트를 사용하는 경우 성능을 저하시키는 추가 오버드로가 발생합니다. 하지만 성능 손실은 없습니다.
    (Unity에서 모든 불투명 오브젝트를 불투명하게 만든 후에 AlphaTest를 그리도록 하면 HSR이 활성화되는지 확실하지 않음)
  5. "AlphaTest 오브젝트는 대부분 가려지지 않고 다른 오브젝트를 가리기 때문"과 "다른 플랫폼의 효율성을 위해 불투명 오브젝트는 대부분 앞뒤로 렌더링하기 때문"이기 때문에 대부분의 경우 AlphaTest의 성능이 AlphaBlend보다 낮지 않을 것입니다. 그러나 이러한 전제를 충족하지 않는 경우 AlphaTest의 효율이 AlphaBlend보다 낮을 수 있으므로 이를 수정하는 것은 사용자의 몫입니다.

앞쪽부터 순서대로 그리기(由前至后绘制),안쪽부터 순서대로 그리기(由后至前绘制),그리기 순서는 고려하지 않음(不必考虑绘制顺序),펀치스루(AlphaTest)
http://research.tri-ace.com/Data/AndroidABC2014_Final.pptx
이것은 약간 오래되었지만 Mail 400MP를 제외하고는 이전 공제와 일치합니다. 여기서 첫 번째 열은 Mail 400MP이며 "Mail T604"가 포함되어 있지 않으므로 이 시점에서 첫 번째 열은 기본적으로 불필요합니다. 차세대 GPU인 "Mail T604, Tegra4"는 이 차트에 포함되지 않으며, 나머지 PPT에 따르면 "알파테스트(앞뒤) - 불투명(앞뒤) - 반투명(뒷면)"이 전략이 되어야 합니다.

모두 알파테스트로 구성된 개체를 정렬한 후 효율성 테스트. 첫 번째 항목: 비교 그룹, 두 번째 항목: 앞쪽에서 뒤쪽, 세 번째 항목: 뒤쪽에서 앞쪽
여기서 알 수 있듯이 Mail T604, Tegra 4 및 이러한 차세대 GPU를 사용하면 알파 테스트 개체를 앞뒤로 정렬하여 성능을 향상시킬 수 있습니다. 즉, 모든 알파 테스트가 반드시 later-DT가 아닌 잔디와 같은 투명한 개체가 서로 더 많이 겹치는 시나리오에서는 알파 테스트가 더 큰 이점을 얻을 수 있습니다.

불투명 및 알파 테스트 개체가 겹치고 산재되어 있는 경우, 첫째: 뒤에서 앞으로, 둘째: 앞뒤로 재배열된 불투명, 셋째: 앞뒤로 재배열된 알파 테스트.
이 사용 사례에서 PowerVR은 매우 미묘하며(그리고 기본적으로 메일 T604 및 테그라 4와 동일), HSR 저하를 일반 TBR로 떨어뜨린 후 PowerVR의 전략은 알파테스트의 Early-DT. 및 하이브리드 렌더링을 여전히 지원하는 테그라 4와 동일하다고 가정할 수 있으며, 이는 실제 게임에서 발생하는 것과 더 일치할 가능성이 가장 높습니다.
 
즉, 앞서 언급했던 "AlphaTest가 Later-DT를 거치면서 발생하는 성능 저하"는 오늘날의 메인스트림 모델에는 존재하지 않을 가능성이 매우 높습니다. AlphaTest의 가장 일반적인 애플리케이션 환경인 '잔디/잎/2D 스프라이트'에서 AlphaTest는 AlphaBlend보다 느리지 않을 뿐만 아니라 성능에서도 큰 이점을 가지고 있습니다.
스워드 앤 홈이 알파 컷아웃(알파 테스트로 한 번 그린 다음 두 번째 반투명 패스로 반투명 가장자리를 보완하는 방식)을 사용하여 IOS에서 2D 스프라이트의 성능을 최적화하는 이유를 알 수 있습니다.
이보다 더 좋은 일은 없겠죠?


이전 정보가 너무 오래되어서 이걸 망칠 수 없다는 것을 알았습니다. 사실 HSR은 PowerVR만의 고유한 기능도 아닙니다!
 
Adreno 3xx:FlexRender | Qualcomm
HSR에 대한 자세한 내용은 없지만, 디퍼드 렌더링은 PowerVR의 '전환 가능한' 버전인 TBDR과 유사하다고 주장합니다.
 
Mail T62x:Killing Pixels - A New Optimization for Shading on ARM Mali GPUs

 
알파테스트로 무엇을 하고 있는지 알기가 훨씬 더 어렵습니다.
따라서 유일한 보험은 실제 테스트 결과뿐입니다.


원문.
https://zhuanlan.zhihu.com/p/33127345

再议移动平台的AlphaTest效率问题

这问题也算一个老问题了,昨天晚上和蒙哥几位又讨论了下这个事儿,稍微有了一些新的想法,就拿来讲讲: 至于AlphaTest和AlphaBlend到底哪个更快这件事—— 我是真的不知道。而能够对这件事拿

zhuanlan.zhihu.com