paris master class 2011 - 03 order independent transparency
TRANSCRIPT
Order-Independent Transparency
Wolfgang EngelConfetti Special Effects Inc., Carlsbad
Paris Master Class
Agenda
• Order-Independent Transparency– Depth Peeling– Reverse Depth Peeling– Per-Pixel Linked Lists
Depth Peeling
• Usually the depth buffer holds the nearest fragment• Depth Peeling & Deferred Lighting– One depth buffer holds nearest fragment– Second depth buffer holds second nearest fragment– Third depth buffer holds third nearest fragment– Etc.
Depth Peeling• Layer 1 shows the
inside of the teapot• Layer 2 shows some of
the insideof the teapot but mostly theground plane
• Layer 3 shows what is behind the knob and lots of ground plane
Depth Peeling
• View from left
Depth Peeling
• Drawback: whole G-Buffer needs to be layered-> if three depth layers are necessary, three full-screen G-Buffers need to be stored in memory
Depth Peeling
• Shader code to create depth layers; first layer:struct VsIn {
float4 position : Position;
};
struct PsIn {
float4 position : SV_Position;
};
[Vertex shader]
float4x4 viewProj;
PsIn main(VsIn In){
PsIn Out;
Out.position = mul(viewProj, In.position);
return Out;
}
Depth Peeling• Shader code to create depth layers; second layer:[Vertex shader]
float4x4 viewProj;
PsIn main(VsIn In){PsIn Out;
Out.position = mul(viewProj, In.position);
return Out;}
[Fragment shader]Texture2DArray Depth;SamplerState filter;float2 invSize;
void main(PsIn In){
float3 screenCoord = float3(In.position.xy * invSize, 0.0);float depth = Depth.Sample(filter, screenCoord).x;
// Peel away pixels from previous layers. Use a small bias to avoid precision issues.clip(In.position.z - depth - 0.0000001);
}
Depth Peeling
• Code to do lightingfloat blend = 1.0;
[unroll]
// nearest first
for (int i = 0; i < LAYERS; i++)
{
[branch]
if (blend > 0.0)
{
// do lighting
// Blend in this layer
// base.a 0.0 is transparent 1.0 solid
Out.colorData.xyz += (blend * base.a) * lighting;
}
// Update blend factor
// base.a comes from the textures alpha channel
blend *= 1.0 - base.a;
}
Reverse Depth Peeling
• Depth Peeling extracts layers front-to-back and stores each layer in a render target
• Reverse Depth Peeling extracts layers back-to-front and blends them immediately [Thibieroz]-> less memory -> console platforms like this
• The order of operations is:1. Determine furthest layer2. Fill-up depth buffer texture3. Fill-up normal and color buffer4. Do lighting & shadowing5. Blend in backbuffer6. Go to 1 for the next layer
Per-Pixel Linked Lists• Linked list [Gruen] – each element holds
– a layer of depth– + link
• List represents one pixel in the viewport• Stored in read/write structured buffer == buffer of elements
of equal size -> DX11 feature• This buffer can be called the fragment and link bufferstruct FragmentAndLinkBuffer_STRUCT {
FramentData_STRUCT FragmentData; uint uNext;
}RWStructuredBuffer<FragmentAndLinkBuffer_STRUCT>FLBuffer;
Per-Pixel Linked Lists
• A “Start Offset Buffer” (SOB) holds offsets into the “Fragment and Link Buffer” (FLB)
• Example: FLB holds a color value and the link
Per-Pixel Linked Lists
Per-Pixel Linked Lists
• Traversing: – viewport / SOB same size– Look at the pixel in the SOB– then follow the uNext entry in FLB until it is -1
• Implement Order-Independent Transparency – by storing the list entries in back-to-front order– blend those in a pixel shader; blend mode can be
unique per pixel
References• [Everitt] Cass Everitt, “Interactive Order-Independent Transparency.”,
http://developer.nvidia.com/object/Interactive_Order_Transparency.html• [Gruen] Holger Gruen, Nicolas Thibieroz, “OIT and Indirect Illumination using DX11 Linked
Lists”, GDC 2010, http://developer.amd.com/gpu_assets/OIT%20and%20Indirect%20Illumination%20using%20DX11%20Linked%20Lists_forweb.ppsx
• [Thibieroz] Nicolas Thibieroz, “Robust Order-Independent Transparency via Reverse Depth Peeling in DirectX 10”, ShaderX6