| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | ||||
| 4 | 5 | 6 | 7 | 8 | 9 | 10 |
| 11 | 12 | 13 | 14 | 15 | 16 | 17 |
| 18 | 19 | 20 | 21 | 22 | 23 | 24 |
| 25 | 26 | 27 | 28 | 29 | 30 | 31 |
- UE5
- SGPR
- rendering
- SIMD
- DX12
- VGPR
- wave
- hzb
- Wavefront
- Study
- ShadowMap
- DirectX12
- vulkan
- 번역
- GPU Driven Rendering
- atmospheric
- unrealengine
- optimization
- GPU
- Shadow
- ue4
- deferred
- scattering
- forward
- RayTracing
- Nanite
- scalar
- texture
- shader
- Graphics
- Today
- Total
RenderLog
[번역] To z-prepass or not to z-prepass – Interplay of Light 본문
개인 공부용으로 번역한 거라 잘못 번역된 내용이 있을 수 있습니다.
또한 원작자의 동의 없이 올려서 언제든 글이 내려갈 수 있습니다.
출처 : interplayoflight.wordpress.com/2020/12/21/to-z-prepass-or-not-to-z-prepass/amp/?__twitter_impression=true
To z-prepass or not to z-prepass – Interplay of Light
December 21, 2020 | Kostas Anagnostou
트위터의 흥미로운 토론과 그것의 게임에서의 활용에 영감을 받아서, z-prepass와 그것의 렌더링 파이프라인에서의 사용에 대한 생각을 모아봤습니다.
먼저, z-prepass가 무엇인가(zed-prepass, UK에서는 이렇게 부름): 가장 기본적인 형태는 Depth buffer(다른 말로 z-buffer)를 채우기 위해서 장면에서 픽셀 쉐이더나 렌더링 타겟 바운딩 없이 버택스 쉐이더만 사용하여 크고 불투명한 메시 (부분 z-prepass) 혹은 모두 불투명 메시 (전체 z-prepass)를 렌더링 패스에서 렌더링 하는 것입니다.
(전체) z-prepass의 큰 장점은 Depth buffer가 카메라와 가장 가까운 불투명한 표면의 깊이를 갖고 있는 것입니다, 이것은 이후에 그려질 모든 지오메트리들의 드로우콜의 오버드로우가 없도록 보장할 것입니다, 그렇게 하여 (잠재적으로 비싼) 픽셀 쉐이더의 실행을 픽셀당 한 번만 실행하도록 합니다. 심지어 부분 z-prepass의 경우도 많은 이점을 얻을 수 있습니다, 예를 들어 빌딩의 벽을 z-prepass에서만 그리면 빌딩 내의 것들이 픽셀 쉐이더를 GPU에서 실행하는 것을 방지할 수 있습니다.
z-prepass 렌더링 파이프라인에 넣기 위해서 잠재적으로 장면내에 모든 메시를 한번 더 그리는 것은 이상하게 들리며 별도의 추가 GPU 작업을 위해서 늘어난 드로우콜 수 때문에 CPU 부담이 됩니다. 하지만 z-prepass의 단순한 특성 때문에(z-buffer의 깊이만 기록), 단순화하고 비용을 줄일 기회가 있습니다. 예를 들어:
- 메모리 대역폭을 줄이기 위해서 버택스 버퍼의 Position 정보만 바운딩할 수 있습니다.
- 우리가 Position만 필요하고 Normal과 UVs 등등 이 필요하지 않기 때문에 같은 렌더스테이트와 같은 버택스 쉐이더를 사용합니다. 이렇게 하여 드로우콜의 일괄(Batching)을 증가시키고 드로우콜당 오버헤드를 줄일 수 있습니다.
- 몇몇 경우, 만약 장면에서 당신의 LOD의 더 낮은 LOD가 z-fighting 문제를 피하기 위해서 더 높은 폴리곤 수를 가진 것을 완전히 포함한다면, 더 적은 폴리곤 수의 메시 LOD를 사용할 수 있을 것입니다. 당신은 특히 부분 z-prepass의 경우에 특별히 제작된 프록시를 만들 수 있습니다, 빌딩을 위해 간략화된 메시 같은 것(다시 한번 z-fighting에 주의하세요)
쉐도우맵 패스 또한 같은 설정을 사용할 수 있으며 이미 엔진이 그것을 지원하고 있을 수 있습니다.
만약 포워드 렌더링 아키텍쳐를 사용 중에, 당신의 불투명 메시를 앞에서 뒤로 거리 기반 정렬을 적절하게 하지 않는다면, z-prepass는 오버드로우를 줄이기 위해서 대부분의 경우 필요합니다. (즉, 각 픽셀이 이 패스에서 여러번 쉐이딩 되는 것을 피하는 것). 포워드 패스 쉐이더는 많은 라이트 타입에 대한 라이팅과 쉐도잉, 환경맵 라이팅 그리고 표면을 위한 최종 쉐이딩을 사용하여 보통은 아주 비쌉니다. 그래서 오버드로우에 아주 민감합니다. z-prepass는 거리기반 소트를 쉽게 할 수 없는 밀도가 높은(역주 : 메시 내의 버택스들을 소팅할 수 없기 때문에 오버드로우 관리를 소팅으로 해결 못함) 나뭇잎 같은 지오메트리의 경우 특히 오버드로우를 줄이는데 도움을 줍니다.
디퍼드 쉐이딩 아키텍쳐는 픽셀당 오버헤드를 줄이도록 디자인되었습니다, 전용 g-prepass에서 여러 렌더타겟을 머터리얼 정보로 채워서 라이팅과 쉐이딩으로부터 지오메트리의 복잡도 분리합니다. 이론적으로, g-prepass는 비싼 라이팅과 쉐이딩 계산을 화면 공간 패스로 지연시켜서 상대적으로 비용이 저렴해야 됩니다. 머터리얼이 계속해서 복잡해지고 게임 월드의 지오메트리의 복잡도가 증가하여서, z-prepass는 디퍼드 쉐이딩 아키텍쳐에서 역시 여전히 유용할 수 있습니다, 그리고 이 렌더링 아키텍쳐를 사용하는 많은 게임은 무엇보다도 g-prepass 동안 오버드로우를 줄이는데 사용합니다.
렌더링 파이프라인의 초기에 Depth buffer가 있는 것은, 오버드로우 개선 외에, 많은 기술의 최적화를 위한 길을 열어줍니다. 예를 들면:
- Depth equal을 사용한 알파 테스팅: 알파 테스트된 지오메트리(특히 나뭇잎) 렌더링 속도를 높이는데 유용합니다. z-prepass 동안 알파 테스팅을 수행하고 이후의 패스에서 z-equal depth 테스트를 사용하여 메시를 렌더링 합니다. 비싼 쉐이더를 사용하는 곳에서 early-z 최적화가 가능하게 해 줍니다. 이것은 uv 버택스 스트림을 버택스 쉐이더에 바인딩해야 하고 z-prepass의 픽셀 쉐이더에서 텍스쳐를 읽어 클리핑(역주 : 알파테스트의 clip or discard를 호출한다는 의미)을 구현합니다.
- SSAO: Screen Space Ambient Occlusion 계산을 일찍 시작할 수 있습니다. 작은 메시의 기여도를 캡쳐하려면 전체 z-prepass가 필요하고 몇몇 알고리즘에서는, 노멀이 없기 때문에, Depth로부터 Normal을 복원합니다. 이 Normal은 정밀하지 않을 수 있습니다. (Face Normal과 일치)
- SSR: Depth buffer를 Raymarching 하면 화면 공간 반사에 대한 충돌을 결정할 수 있습니다. 이것은 Depth로 부터 Normal을 복원하는 것에 의존합니다. 우리는 메인 렌더타겟이나 이전 프레임의 렌더타겟을 샘플링하여 반사 색상을 결정하기 위해서 충돌 위치를 저장할 것입니다. 이것 또한 전체 z-prepass가 요구될 것입니다.
- 화면 공간 그림자: 유사한 방식으로 화면공간 그림자의 경우, 더 높은 해상도의 화면 공간에서의 그림자 판정을 위해 우리는 depth buffer를 라이트를 방향으로 Raymarch 할 수 있습니다. 위와 같이, 작은 메시에서 그림자를 캡쳐하기 위해서 전체 z-prepass가 요구됩니다.
- Deferred shadows: 특히 포워드 렌더링 파이프라인에서, depth buffer는 월드 위치의 복원과 화면 공간 그림자 계산에 사용하여, 포워드 패스 쉐이더의 복잡도를 줄일 수 있습니다. 위의 2가지 쉐도잉 방법에서, 보통 "face가 light 방향 반대(NdotL < 0)이면, 계산을 건너뜀"을 하는 최적화는 Depth에서 복원된 Normal에 의존해야 합니다.
- Occlusion culling: 프레임의 초기에 depth buffer를 갖는 것은 Hierarchical-z occlusion culling 기술을 가능하게 해 줍니다. 이 기술은 후속 패스(g-prepass or 포워드 패스)에서 가려진 메시를 컬링 하도록 해줍니다. 심지어 Hierarchical-z 오클루젼 컬링이 구현되지 않았더라도, 몇몇 오클루젼은 hardware occlusion queries나 depth buffer를 사용한 predication queries를 통해 얻어질 수 있습니다. 메인 오클루더(occluders)의 깊이를 사용한, 부분 z-prepass는 이것에 적합니다.
- Light binning: 장면의 depth에 접근하는 것은 tiled 혹은 clustered 쉐이딩 라이팅 아키텍쳐의 경우 light binning을 향상시키는 데 사용할 수 있습니다.
- Tighter shadow cascade fitting: 비슷하게, 장면 depth 범위는 쉐도우맵의 활용성 높이기 위해서 케스케이드 쉐도우 매핑에서 케스케이드를 장면에 더 잘 맞추는 데 사용할 수 있습니다. 이 경우 주의점은 쉐도우맵이 z-prepass 이후에 렌더링되야만 한다는 것입니다, 그러나 이것은 쉐도우맵 렌더링과 화면 공간 작업 (즉, SSAO)를 함께 작업할 수 있기 때문에 좋을 수 있습니다.
- 디퍼드 데칼: 초기에 장면 Depth에 접근하여 이득을 얻을 수 있는 또 다른 기술은 디퍼드 데칼 입니다. 디퍼드 데칼은 Depth buffer에 프로젝션 될 수 있으며 데칼 머터리얼은 이후에 g-prepass나 포워드 패스에서 블랜딩 하기 위해서 데칼 "g-buffer"에 저장됩니다.
- 레이 트레이싱: 비싼 포워드 패스로부터 분리된, 어쩌면 더 낮은 해상도에서, 레이트레이싱 쉐도우와 반사를 위해서 Depth buffer는 월드의 원점(그리고 face normals)을 복원에 사용할 수 있습니다.
- 스텐실 마스크: z-prepass와 직접적인 연관은 없으나 스텐실 버퍼를 나중에 쓰일 어떤 값으로 채우기 위해서 사용할 수 있습니다. 이 값은 특정 후속 렌더링 패스에서 특정 메시를 제외하는 데 사용합니다.
이 리스트가 전부는 아닙니다. 기술 중 몇몇은 디퍼드 보다 포워드 렌더링 파이프라인에서 더 도움이 될 수 있습니다. 왜냐하면 포워드 패스 전에 화면 공간에서 장면의 depth(또는 그런 문제에 대한 화면공간 기술을 위한 다른 데이터)에 접근할 기회가 많지 않기 때문입니다. 심지어 디퍼드 쉐이딩 파이프라인 경우에, 이것은 g-prepass의 오버드로우를 줄여주고 더 나은 스케쥴링과 동시 작업을 가능하게 해 줍니다. 동시 작업의 예는 SSAO 패스와 g-prepass는 동시에 진행 가능합니다.
트위터 스레드의 시작 단락에서 내가 지적한 것처럼, z-prepass 기술은 큰 YMMV(역주 : Your Mileage May Vary, 한 사람의 경험이 다른 사람과 다를 수 있음) 배너와 함께 제공됩니다. 줄 수 있는 실제 이득은 컨텐츠와 렌더링 파이프라인에 따라 달라집니다. 그리고 그것을 결정하기 위해서 프로파일링이 필요할 것입니다, 그러나 큰 지오메트릭 복잡도를 가진, 수많은 나뭇잎과 같은, 좋은 오클루젼 컬링 접근을 사용할 수 없고, 알파테스트된 지오메트리를 쓴, 경우 디퍼드 렌더링을 사용하는 편이 낫습니다. 드로우콜을 2번 하기 때문에, CPU 오버헤드가 가 증가하는 점을 고려하여, 엔진에서 일괄(Batching) 방식을 향상시킬 수 있는지 확인해야 할 것입니다. 이 문맥에서 부분 vs 전체 z-prepass 가 결정되어야 합니다.
프레임의 초기에 몇몇 오클루젼 컬링을 활성화하는 것은 확실히 유용하며 CPU 로드(특히 GPU driven submission 이 사용되는 경우) 그리고 후속 패스를 위한 버택스 로드(이것은 z-prepass의 오버헤드를 상쇄함)에 유용합니다. 디퍼드 쉐이딩 아키텍쳐의 경우 화면 공간 작업(예를들어 SSAO)과 지오메트리 렌더링를 동시에 할 수 있는 기회는 g-prepass의 병목에 의존합니다. 이것은 두 패스 모두 보통 대역폭 제한이 있기 때문입니다. z-prepass를 먼저 수행하고나서 쉐도우맵 렌더링을 수행하도록 렌더링 파이프라인을 재정렬하는 것은 compute와 graphics 파이프라인의 동시작업을 가능하게 합니다(즉, 쉐도우맵을 렌더링하는 동안 SSAO 계산이나 화면공간 쉐도우 계산하는 것). SSR, SSAO 등등과 같은 화면공간 효과로부터 포워드 패스 해상도를 분리하는 것은 성능 측면에서 좋으며, 저해상도에서 그들을 계산하는 것을 가능하게 합니다.
고려해야 할 또 다른 주의점이 있습니다, 포워드나 g-buffer 패스 동안 z-prepass로 부터 생성된 depth buffer를 화면 공간(SSAO, SSR 등등) 텍스쳐로 바인딩하는 것은 일부 GPU 아키텍쳐에서 압축해제 될 것입니다. 그래서 이후의 z-testing 이 덜 효율적일 것입니다. 이 경우 z-prepass 과정에서 픽셀 쉐이더를 바인딩하여 분리된 렌더타겟에 depth를 출력하고 이것을 입력으로 사용하는 것을 고려할만합니다.
'Graphics > 참고자료' 카테고리의 다른 글
| [번역] Screen Space Reflections : Implementation and optimization – Part 1 (0) | 2021.01.28 |
|---|---|
| [번역] Lecture 13: Radiosity - Principles (0) | 2020.12.30 |
| [번역] Global Illumination Using Progressive Refinement Radiosity (0) | 2020.12.19 |
| [번역+설명추가] Spherical Mapping (0) | 2020.11.29 |
| [번역]Real-Time Computation of Dynamic Irradiance Environment Maps (0) | 2020.11.26 |