[shaderx6] 3.7 Robust Order-Independent Transparency via Reverse Depth Peeling in DirectX 10
Upcoming SlideShare
Loading in...5
×
 

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

on

  • 2,503 views

 

Statistics

Views

Total Views
2,503
Views on SlideShare
2,129
Embed Views
374

Actions

Likes
0
Downloads
17
Comments
0

8 Embeds 374

http://ohyecloudy.com 280
http://opnote.tistory.com 81
http://www.hanrss.com 6
http://0.0.0.0 3
http://search.naver.com 1
http://translate.googleusercontent.com 1
http://webcache.googleusercontent.com 1
http://www.linkedin.com 1
More...

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

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

  • ShaderX6
    3.7 Robust Order-Independent Transparency via Reverse Depth Peeling in DirectX 10
    ohyecloudyhttp://ohyecloudy.com
    shader studyhttp://cafe.naver.com/shader.cafe
  • Introduction
    Depth Peeling
    Reverse Depth Peeling
    Overview
    Algorithm
    Emulating Second Depth Buffer
    Optimal # of Layers
    Optimizations
    Conclusion
  • Order-Independent Transparency
    반투명 지오메트리를정렬 없이 편하게 그리자
    왜 고생하고 있나?
    z-buffer는 fragment마다
    entry 하나만 가지도록 설계됐음.
  • back-to-front order
    전통적인 방식
    카메라 공간에서
    먼 지오메트리부터 가까운 지오메트리 순서로
    정렬한다.
    정렬하는 비용
    공짜는 없다.
    보통 CPU에서
    bitonic정렬같은 방법으로 GPU에서 할 수도 있음
  • back-to-front order 문제점
    정렬이 per-object나 per-polygon단위
    per-pixel이 아니라서 visual artfact존재
    정렬한 순서대로 렌더링을 하기 때문에
    모아 찍기가 불가능
    shader switching이 많다.
  • per-object sorting
    reverse depth peeling
  • Introduction
    Depth Peeling
    Reverse Depth Peeling
    Overview
    Algorithm
    Emulating Second Depth Buffer
    Optimal # of Layers
    Optimizations
    Conclusion
  • from google사전
    깊이depth를 귤 껍질 까듯이하나하나 벗겨peelinglayer에 그린다.
  • back-to-front order
    blend
    반투명 폴리곤
    Layer
    반투명 폴리곤
    Layer
    반투명 폴리곤
    Layer
    반투명 폴리곤
    Layer
    반투명 폴리곤
    Layer
    Render
    Target
    Layer
    정렬 안 하고 렌더링
    사용하는 layer 수 만큼
    layer 추출
  • per-pixel반투명 평가 가능
    visual artifact X
    layer가 deferred shading에 있는
    G-buffer와 닮았다.
    layer는 video memory에 저장
    몇 개야! 도대체
    압박
  • Introduction
    Depth Peeling
    Reverse Depth Peeling
    Overview
    Algorithm
    Emulating Second Depth Buffer
    Optimal # of Layers
    Optimizations
    Conclusion
  • depth peeling 메모리 사용량을 줄이자
    layer 하나만 사용
    하나를 계속 업데이트해서 쓴다는 얘기.
    layer가 하나란 개념이 아니다.
    layer 추출하는 순서를 바꿨다.
    depth peeling
    front-to-back order로 layer를 추출
    reverse depth peeling
    back-to-front order로 layer를 추출
  • blend
    반투명 폴리곤
    Layer
    반투명 폴리곤
    반투명 폴리곤
    반투명 폴리곤
    반투명 폴리곤
    Render
    Target
    layer 추출
    정렬 안 하고 렌더링
    사용하는 layer 수 만큼
  • layer = 1
    (furthermost)
    Render Target
  • layer = 2
    Render Target
  • layer = 3
    Render Target
  • layer = 4
    (frontmost)
    Render Target
  • Introduction
    Depth Peeling
    Reverse Depth Peeling
    Overview
    Algorithm
    Emulating Second Depth Buffer
    Optimal # of Layers
    Optimizations
    Conclusion
  • 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]);
    }
  • 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으로 전체를 지운다.
  • 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 비교 값으로 사용하기 위해
  • 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 하기 위한 임시 렌더링
  • 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한다.
  • Introduction
    Depth Peeling
    Reverse Depth Peeling
    Overview
    Algorithm
    Emulating Second Depth Buffer
    Optimal # of Layers
    Optimizations
    Conclusion
  • 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번 인덱스에 바인딩?
    이런 게 있나?
  • 있으면 좋겠지만 그런 거 없다
    단지 Pseudo-code일뿐
    두 번째 테스트
    depth 값을 비교해서 버림
    쓰는 작업이 없기 때문에 구현이 간단
  • 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);
    clip(-f);
    // calculate color and alpha etc
    ...
    }
  • Introduction
    Depth Peeling
    Reverse Depth Peeling
    Overview
    Algorithm
    Emulating Second Depth Buffer
    Optimal # of Layers
    Optimizations
    Conclusion
  • Layer를 몇 개 쓰면 될까?
    간단한 답
    depth complexity로 layer 개수를 정한다.
    DirectX9::GetDepthComplexity()
    현재 장면 깊이 복잡도를 구하는 함수
    이런 게 있으면 얼마나 좋을까?
    있을 리가 없다.
    Layer 개수를 정해서 사용
    어느 정도 visual error 감수
    좀 더 나은 방법이 없을까?
  • Occlusion Queries
    pixel이 depth test를 통과했는지 못했는지
    알 수 있다.
    ID3D10Query::Begin() ~ ID3D10Query::End()
    ID3D10Query::GetData()
    depth 테스트를 통과한 pixel 개수를 알 수 있다.
    Dynamic하게 layer 개수를 조정할 수 있겠다.
  • Occlusion Queries
    픽셀이 안 남을 때까지 peeling
    원칙적으로는 맞다
    성능을 높이려면 threshold를 둬서 그만 둠
    데모에선 threshold 값으로 0.01% 사용
  • Introduction
    Depth Peeling
    Reverse Depth Peeling
    Overview
    Algorithm
    Emulating Second Depth Buffer
    Optimal # of Layers
    Optimizations
    Conclusion
  • Transform
    반투명 지오메트리를layer마다
    stream-out
    Direct3D 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;
    }
  • Introduction
    Depth Peeling
    Reverse Depth Peeling
    Overview
    Algorithm
    Emulating Second Depth Buffer
    Optimal # of Layers
    Optimizations
    Conclusion
  • depth peeling,reverse depth peeling 개념 정리
    DirectX 10은 되야지 쓸만할 것 같다.
    직접 써봐야지 평가할 수 있을 것 같음
    아직까진 가장 현실적인 해결책은
    전통적인 방법으로 sorting
    품질을 좀 양보하면Alpha to coverage