[shaderx6] 3.7 robust order-independent transparency via reverse depth peeling in directx 10

37
3.7 Robust Order-Independent Transparency via Reverse Depth Peeling in DirectX 10 ohyecloudy http://ohyecloudy.com shader studyhttp://cafe.naver.com/shader.cafe 2010.06.21 ShaderX 6

Upload: -

Post on 27-Jun-2015

1.980 views

Category:

Technology


5 download

TRANSCRIPT

Page 1: [shaderx6] 3.7 Robust Order-Independent Transparency via Reverse Depth Peeling in DirectX 10

3.7 Robust Order-Independent Transparency via Reverse Depth Peeling in DirectX 10

ohyecloudy http://ohyecloudy.com

shader studyhttp://cafe.naver.com/shader.cafe

2010.06.21

ShaderX6

Page 2: [shaderx6] 3.7 Robust Order-Independent Transparency via Reverse Depth Peeling in DirectX 10

Introduction

Depth Peeling

Reverse Depth Peeling

Overview

Algorithm

Emulating Second Depth Buffer

Optimal # of Layers

Optimizations

Conclusion

Page 3: [shaderx6] 3.7 Robust Order-Independent Transparency via Reverse Depth Peeling in DirectX 10

Order-Independent Transparency

반투명 지오메트리를 정렬 없이 편하게 그리자

왜 고생하고 있나?

z-buffer는 fragment마다

entry 하나만 가지도록 설계됐음.

Page 4: [shaderx6] 3.7 Robust Order-Independent Transparency via Reverse Depth Peeling in DirectX 10

back-to-front order

전통적인 방식 카메라 공간에서 먼 지오메트리부터 가까운 지오메트리 순서로 정렬한다. 정렬하는 비용

공짜는 없다.

보통 CPU에서 bitonic 정렬같은 방법으로 GPU에서 할 수도 있음

Page 5: [shaderx6] 3.7 Robust Order-Independent Transparency via Reverse Depth Peeling in DirectX 10

back-to-front order 문제점

정렬이 per-object나 per-polygon 단위

per-pixel이 아니라서 visual artfact 존재

정렬한 순서대로 렌더링을 하기 때문에

모아 찍기가 불가능

shader switching이 많다.

Page 6: [shaderx6] 3.7 Robust Order-Independent Transparency via Reverse Depth Peeling in DirectX 10

per-object sorting

reverse depth peeling

Page 7: [shaderx6] 3.7 Robust Order-Independent Transparency via Reverse Depth Peeling in DirectX 10

Introduction

Depth Peeling

Reverse Depth Peeling

Overview

Algorithm

Emulating Second Depth Buffer

Optimal # of Layers

Optimizations

Conclusion

Page 8: [shaderx6] 3.7 Robust Order-Independent Transparency via Reverse Depth Peeling in DirectX 10

깊이depth를 귤 껍질 까듯이 하나하나 벗겨peeling

layer에 그린다.

from google 사전

Page 9: [shaderx6] 3.7 Robust Order-Independent Transparency via Reverse Depth Peeling in DirectX 10

Layer Layer Layer Layer Layer Layer

반투명 폴리곤 반투명 폴리곤 반투명 폴리곤 반투명 폴리곤 반투명 폴리곤

정렬 안 하고 렌더링

Render Target

back-to-front order blend

사용하는 layer 수 만큼 layer 추출

Page 10: [shaderx6] 3.7 Robust Order-Independent Transparency via Reverse Depth Peeling in DirectX 10

per-pixel 반투명 평가 가능

visual artifact X

layer가 deferred shading에 있는

G-buffer와 닮았다.

layer는 video memory에 저장

몇 개야! 도대체

압박

Page 11: [shaderx6] 3.7 Robust Order-Independent Transparency via Reverse Depth Peeling in DirectX 10

Introduction

Depth Peeling

Reverse Depth Peeling

Overview

Algorithm

Emulating Second Depth Buffer

Optimal # of Layers

Optimizations

Conclusion

Page 12: [shaderx6] 3.7 Robust Order-Independent Transparency via Reverse Depth Peeling in DirectX 10

depth peeling 메모리 사용량을 줄이자

layer 하나만 사용 하나를 계속 업데이트해서 쓴다는 얘기.

layer가 하나란 개념이 아니다.

layer 추출하는 순서를 바꿨다.

depth peeling front-to-back order로 layer를 추출

reverse depth peeling back-to-front order로 layer를 추출

Page 13: [shaderx6] 3.7 Robust Order-Independent Transparency via Reverse Depth Peeling in DirectX 10

반투명 폴리곤 반투명 폴리곤 반투명 폴리곤 반투명 폴리곤 반투명 폴리곤

정렬 안 하고 렌더링

Layer Render Target

blend

layer 추출

사용하는 layer 수 만큼

Page 14: [shaderx6] 3.7 Robust Order-Independent Transparency via Reverse Depth Peeling in DirectX 10

layer = 1 (furthermost)

Render Target

Page 15: [shaderx6] 3.7 Robust Order-Independent Transparency via Reverse Depth Peeling in DirectX 10

layer = 2

Render Target

Page 16: [shaderx6] 3.7 Robust Order-Independent Transparency via Reverse Depth Peeling in DirectX 10

layer = 3

Render Target

Page 17: [shaderx6] 3.7 Robust Order-Independent Transparency via Reverse Depth Peeling in DirectX 10

layer = 4 (frontmost)

Render Target

Page 18: [shaderx6] 3.7 Robust Order-Independent Transparency via Reverse Depth Peeling in DirectX 10

Introduction

Depth Peeling

Reverse Depth Peeling Overview

Algorithm

Emulating Second Depth Buffer

Optimal # of Layers

Optimizations

Conclusion

Page 19: [shaderx6] 3.7 Robust Order-Independent Transparency via Reverse Depth Peeling in DirectX 10

for (nLayer=0; nLayer<nRequiredLayers; ++nLayer)

{

BindDepthBuffer(0, pDepthBuffer[0], EnableWrites, GREATER);

Clear(pDepthBuffer[0], 0.0);

BindDepthBuffer(1, pDepthBuffer[1], DisableWrites, LESS);

SetRenderTarget(pCurrentTransparentLayer);

SetBlendMode(ONE, ZERO);

DrawTransparentGeometry();

SetTexture(pCurrentTransparentLayer);

SetRenderTarget(pMainRenderTarget);

SetBlendMode(SRCALPHA, INVSRCALPHA);

DrawFullscreenQuad();

SWAP(pDepthBuffer[0], pDepthBuffer[1]);

}

Page 20: [shaderx6] 3.7 Robust Order-Independent Transparency via Reverse Depth Peeling in DirectX 10

for (nLayer=0; nLayer<nRequiredLayers; ++nLayer)

{

BindDepthBuffer(0, pDepthBuffer[0], EnableWrites, GREATER);

Clear(pDepthBuffer[0], 0.0);

BindDepthBuffer(1, pDepthBuffer[1], DisableWrites, LESS);

SetRenderTarget(pCurrentTransparentLayer);

SetBlendMode(ONE, ZERO);

DrawTransparentGeometry();

SetTexture(pCurrentTransparentLayer);

SetRenderTarget(pMainRenderTarget);

SetBlendMode(SRCALPHA, INVSRCALPHA);

DrawFullscreenQuad();

SWAP(pDepthBuffer[0], pDepthBuffer[1]);

}

가장 멀리 있는 반투명 fragment를 판단하기 위한 depth buffer Z 값을 write. GREATER 비교 GREATER로 비교하기 때문에 0.0으로 전체를 지운다.

Page 21: [shaderx6] 3.7 Robust Order-Independent Transparency via Reverse Depth Peeling in DirectX 10

for (nLayer=0; nLayer<nRequiredLayers; ++nLayer)

{

BindDepthBuffer(0, pDepthBuffer[0], EnableWrites, GREATER);

Clear(pDepthBuffer[0], 0.0);

BindDepthBuffer(1, pDepthBuffer[1], DisableWrites, LESS);

SetRenderTarget(pCurrentTransparentLayer);

SetBlendMode(ONE, ZERO);

DrawTransparentGeometry();

SetTexture(pCurrentTransparentLayer);

SetRenderTarget(pMainRenderTarget);

SetBlendMode(SRCALPHA, INVSRCALPHA);

DrawFullscreenQuad();

SWAP(pDepthBuffer[0], pDepthBuffer[1]);

}

이전 layer에서 벗겨낸 지오메트리를 또 다시 안 벗겨내기 위해서 back – to – front 순서로 벗겨내고 있는 것을 명심 LESS 비교 제외시키기 위한 용도이므로 z값을 write하지 않는다.

이번에 기록한 가장 먼 depth를 다음 루프에서 LESS 비교 값으로 사용하기 위해

Page 22: [shaderx6] 3.7 Robust Order-Independent Transparency via Reverse Depth Peeling in DirectX 10

for (nLayer=0; nLayer<nRequiredLayers; ++nLayer)

{

BindDepthBuffer(0, pDepthBuffer[0], EnableWrites, GREATER);

Clear(pDepthBuffer[0], 0.0);

BindDepthBuffer(1, pDepthBuffer[1], DisableWrites, LESS);

SetRenderTarget(pCurrentTransparentLayer);

SetBlendMode(ONE, ZERO);

DrawTransparentGeometry();

SetTexture(pCurrentTransparentLayer);

SetRenderTarget(pMainRenderTarget);

SetBlendMode(SRCALPHA, INVSRCALPHA);

DrawFullscreenQuad();

SWAP(pDepthBuffer[0], pDepthBuffer[1]);

}

Layer에 반투명 지오메트리를 렌더링한다. 렌더 타겟에 blend 하기 위한 임시 렌더링

Page 23: [shaderx6] 3.7 Robust Order-Independent Transparency via Reverse Depth Peeling in DirectX 10

for (nLayer=0; nLayer<nRequiredLayers; ++nLayer)

{

BindDepthBuffer(0, pDepthBuffer[0], EnableWrites, GREATER);

Clear(pDepthBuffer[0], 0.0);

BindDepthBuffer(1, pDepthBuffer[1], DisableWrites, LESS);

SetRenderTarget(pCurrentTransparentLayer);

SetBlendMode(ONE, ZERO);

DrawTransparentGeometry();

SetTexture(pCurrentTransparentLayer);

SetRenderTarget(pMainRenderTarget);

SetBlendMode(SRCALPHA, INVSRCALPHA);

DrawFullscreenQuad();

SWAP(pDepthBuffer[0], pDepthBuffer[1]);

}

메인 렌더 타겟에 blend한다.

Page 24: [shaderx6] 3.7 Robust Order-Independent Transparency via Reverse Depth Peeling in DirectX 10

Introduction

Depth Peeling

Reverse Depth Peeling Overview

Algorithm

Emulating Second Depth Buffer

Optimal # of Layers

Optimizations

Conclusion

Page 25: [shaderx6] 3.7 Robust Order-Independent Transparency via Reverse Depth Peeling in DirectX 10

for (nLayer=0; nLayer<nRequiredLayers; ++nLayer)

{

BindDepthBuffer(0, pDepthBuffer[0], EnableWrites, GREATER);

Clear(pDepthBuffer[0], 0.0);

BindDepthBuffer(1, pDepthBuffer[1], DisableWrites, LESS);

...

}

잠깐! DepthBuffer 0,1번 인덱스에 바인딩? 이런 게 있나?

Page 26: [shaderx6] 3.7 Robust Order-Independent Transparency via Reverse Depth Peeling in DirectX 10

있으면 좋겠지만 그런 거 없다

단지 Pseudo-code일뿐

두 번째 테스트

depth 값을 비교해서 버림

쓰는 작업이 없기 때문에 구현이 간단

Page 27: [shaderx6] 3.7 Robust Order-Independent Transparency via Reverse Depth Peeling in DirectX 10

struct PS_INPUT

{

float4 vPosition : SV_POSITION;

float2 vTex : TEXCOORD0;

};

Texture2D txInputDepth;

float4 PSRenderObjects(PS_INPUT intput) : SV_TARGET

{

// Fetch depth value from 2nd depth buffer

float fDepth =

txInputDepth.Load(int3(input.vPosition.xy, 0));

// Discard fragment if LESS depth test failes

float f = (fDepth <= input.vPosition.z);

flip(-f);

// calculate color and alpha etc

...

}

Page 28: [shaderx6] 3.7 Robust Order-Independent Transparency via Reverse Depth Peeling in DirectX 10

Introduction

Depth Peeling

Reverse Depth Peeling Overview

Algorithm

Emulating Second Depth Buffer

Optimal # of Layers

Optimizations

Conclusion

Page 29: [shaderx6] 3.7 Robust Order-Independent Transparency via Reverse Depth Peeling in DirectX 10

Layer를 몇 개 쓰면 될까?

간단한 답 depth complexity로 layer 개수를 정한다.

DirectX9::GetDepthComplexity() 현재 장면 깊이 복잡도를 구하는 함수

이런 게 있으면 얼마나 좋을까?

있을 리가 없다.

Layer 개수를 정해서 사용 어느 정도 visual error 감수

좀 더 나은 방법이 없을까?

Page 30: [shaderx6] 3.7 Robust Order-Independent Transparency via Reverse Depth Peeling in DirectX 10

Occlusion Queries

pixel이 depth test를 통과했는지 못했는지

알 수 있다.

ID3D10Query::Begin() ~ ID3D10Query::End()

ID3D10Query::GetData()

• depth 테스트를 통과한 pixel 개수를 알 수 있다.

Dynamic하게 layer 개수를 조정할 수 있겠다.

Page 31: [shaderx6] 3.7 Robust Order-Independent Transparency via Reverse Depth Peeling in DirectX 10

Occlusion Queries

픽셀이 안 남을 때까지 peeling

원칙적으로는 맞다

성능을 높이려면 threshold를 둬서 그만 둠

데모에선 threshold 값으로 0.01% 사용

Page 32: [shaderx6] 3.7 Robust Order-Independent Transparency via Reverse Depth Peeling in DirectX 10

Introduction

Depth Peeling

Reverse Depth Peeling Overview

Algorithm

Emulating Second Depth Buffer

Optimal # of Layers

Optimizations

Conclusion

Page 33: [shaderx6] 3.7 Robust Order-Independent Transparency via Reverse Depth Peeling in DirectX 10

Transform

반투명 지오메트리를 layer마다

stream-out

Direct3D 10

트랜스폼된 지오메트리를 버퍼에 저장

다시 사용할 수 있다

결국 트랜스폼은 한 번만 해서 여러번 사용

Page 34: [shaderx6] 3.7 Robust Order-Independent Transparency via Reverse Depth Peeling in DirectX 10

Fill-Rate

dynamic branch를 사용

float fDepth = txInputDepth.Load(int3(input.vPosition.xy, 0));

if (input.vPosition.z < fDepth)

{

// Depth test passes

// calculate color and alpha etc..

}

else

{

// Emulated depth test fails. kill fragment

discard;

}

Page 35: [shaderx6] 3.7 Robust Order-Independent Transparency via Reverse Depth Peeling in DirectX 10

Introduction

Depth Peeling

Reverse Depth Peeling

Overview

Algorithm

Emulating Second Depth Buffer

Optimal # of Layers

Optimizations

Conclusion

Page 36: [shaderx6] 3.7 Robust Order-Independent Transparency via Reverse Depth Peeling in DirectX 10

depth peeling, reverse depth peeling 개념 정리

DirectX 10은 되야지 쓸만할 것 같다.

직접 써봐야지 평가할 수 있을 것 같음

아직까짂 가장 현실적인 해결책은

전통적인 방법으로 sorting

품질을 좀 양보하면 Alpha to coverage

Page 37: [shaderx6] 3.7 Robust Order-Independent Transparency via Reverse Depth Peeling in DirectX 10