You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
<strong>Edge</strong>-Aware <strong>Shaders</strong><br />
Peter-Pike Sloan and Peter Shirley<br />
NVIDIA
Motivation
Conventional shaders unaware of edges<br />
P
Conventional shaders unaware of edges<br />
P<br />
a
Inspiration PLACEHOLDER - PERMISSIONS<br />
Z N RGB<br />
[Deering88]<br />
[Reshetov09]<br />
[FXAA10]<br />
[Nehab07]
Alternative approaches?<br />
Explicitly model geometry/texture?<br />
— Increases authoring time and storage<br />
— Concave edges implicitly defined<br />
Completely in CUDA/DXCompute?<br />
— Rasterization turns out to be useful<br />
Forward rendering?<br />
— Implicit features<br />
— Conceptually clean in deferred<br />
[Kavan11]
Why not use CUDA or DirectCompute?<br />
Rasterization<br />
— Splatting convex edges, splatting corners<br />
Setup Draw Call parameters from GPU<br />
— Also in DirectCompute<br />
A (tiny) bit easier to integrate with graphics app<br />
RWStructuredBuffer WSCornerBuffer;<br />
uint uPos = WSCornerBuffer.IncrementCounter();<br />
WSCornerBufferRead[uPos].Color = float3(1,0,0);<br />
pd3dDeviceContext->CopyStructureCount(pCountBuffer,4,m_WSCornerBufferUAV);<br />
pd3dDeviceContext->DrawIndexedInstancedIndirect(pCountBuffer,0);
Algorithm<br />
Splat convex edges<br />
Search GBuffer for edges<br />
Flood Fill (jump flooding)<br />
Splat existing corners<br />
Search for new corners<br />
Update GBuffer<br />
Shade image
<strong>Edge</strong> Features
Line Information + Feature Buffer<br />
Direction vector in eye space<br />
Point on edge [*]<br />
Feature buffer<br />
— asfloat(distance)<br />
— 2x12bits for location<br />
— 1 bit concave/convex<br />
— 2 bits for which neighbor<br />
2x32 bits uint<br />
2x16 bits SNORM [Meyer10]<br />
4x32 bits float
Silhouette <strong>Edge</strong>s<br />
struct AuxFace {<br />
unsigned int uFlags; // 3 bits edge info, 24 bits are material ID's<br />
float3 OppNormals[3]; // opposite normals<br />
};<br />
StructuredBuffer SilAuxFaceBuffer;
Silhouette <strong>Edge</strong>s<br />
// now fixup these distances<br />
[branch]<br />
if (fDist.x < g_DistanceThreshold) {<br />
float fCheck = dot(P-verts[0],edgeVectors[0]);<br />
if (fCheck < 0) {<br />
fDist.x = length(P-verts[0]);<br />
} else if (fCheck > dot(edgeVectors[0],edgeVectors[0])) {<br />
fDist.x = length(P-verts[1]);<br />
}<br />
}
Line Textures (sparse)
Flood Fill<br />
Jump Flooding<br />
[Rong06]
Flood Fill
Corners
Corner Search<br />
First Pass<br />
— Volume of neighboring normals:<br />
— Store distance, set candidate bit, encode neighbor<br />
Second Pass<br />
(abs(dot(N,cross(NR,ND))) > 0.2f)<br />
— Suppress corner if any 8-connected neighbor is closer<br />
struct WSCornerStruct {<br />
float3 CornerPos; // origin<br />
float3 CornerNorm; // average normal at corner<br />
float3 LineDirs[3]; // direction for each edge<br />
float3 LineNorms[3]; // needed for shading – average of faces<br />
uint LineInfo[3]; // has convex/concave bit, material pair 17 bits only...<br />
};<br />
RWStructuredBuffer WSCornerBufferWrite; // IncrementCounter() to add<br />
StructuredBuffer WSCornerBufferRead;
Corner Splat<br />
Occurs before search<br />
Copy the number of corners into CountBuffer (GPU)<br />
Transform corners into eye space (CountBuffer+PS)<br />
Draw a cube for each corner, # Instances from CountBuffer<br />
pd3dDeviceContext->CopyStructureCount(pCountBuffer,4,m_WSCornerBufferUAV);<br />
// Bunch of other code…<br />
pd3dDeviceContext->DrawIndexedInstancedIndirect(pCountBuffer,0);<br />
Bit in Feature Buffer set indicating corner<br />
— Screen coordinates replaced with corner ID, neighbor replaced<br />
with edge index in corner buffer
Corner Fixup
Results
Original
Modify G-Buffer<br />
Round edges – interpolate to average normal at edge<br />
Paint slop – use material ID on either side + noise<br />
Grout/Caulk – material ID on either side
Performance Quadro 5000<br />
Task ms %<br />
Compute G Buffer 882 8.78<br />
Line Buffers (splat + search) 1360 13.53<br />
Jump Flooding 6670 66.36<br />
Corner splat + search 508 5.05<br />
Shade 631 6.28
Future Work<br />
Performance<br />
— Faster Jump Flooding [Rong2007]<br />
— Compress Buffers<br />
— Move stages to compute/CUDA?<br />
Quality<br />
— Interaction with FXAA? AA in general?<br />
— LOD<br />
Workflow/artist in the loop?
References<br />
[Deering88] The Triangle Processor and Normal Vector Shader: a VLSI System<br />
for High Performance Graphics, SIGGRAPH 1998<br />
[Reshetov09] Morphological Antialiasing, HPG 2009<br />
[FXAA10]<br />
http://developer.download.nvidia.com/assets/gamedev/files/sdk/11/FXAA_<br />
WhitePaper.pdf<br />
[Nehab07] Accelerating Real-Time Shading with Reverse Reprojection<br />
Caching, Graphics Hardware 2007<br />
[Kavan11] Least Squares Vertex Baking, EGSR 2011<br />
[Meyer10] On floating-point normal vectors, EGSR 2010<br />
[Rong06] Jump Flooding in GPU with Applications to Voronoi Diagram and<br />
Distance Transform, I3D 2006<br />
[Rong07] Variants of Jump Flooding Algorithm for Computing Discrete Voronoi<br />
Diagrams, 4 th Symposium on Voronoi Diagrams in Science and Engineering
Backup slides after this…
Line Features
Line textures (sparse set of points)
Flood Fill
Flood Fill