Presentation is loading. Please wait.

Presentation is loading. Please wait.

Tessellation in a Low Poly World Nicolas Thibieroz AMD Graphics Products Group Original materials from Bill Bilodeau 1 15/01/2014.

Similar presentations

Presentation on theme: "Tessellation in a Low Poly World Nicolas Thibieroz AMD Graphics Products Group Original materials from Bill Bilodeau 1 15/01/2014."— Presentation transcript:

1 Tessellation in a Low Poly World Nicolas Thibieroz AMD Graphics Products Group Original materials from Bill Bilodeau 1 15/01/2014 GDC Paris 2008

2 Medium What is Tessellation? Tessellation is the process of adding new primitives into an existing model Triangle counts can be dialed in by adjusting the tessellation level Low High

3 AMD Hardware Tessellator Output Merger Rasterizer Pixel Shader Memory / Resources Vertex Shader Memory / Resources Input Assembler Tessellator

4 Hardware tessellation allows you to render more polygons for better silhouettes Initial concept artwork from Bay Raitt, Valve

5 Surface control cages are easier to work with than individual triangles Artists prefer to create models this way Animations are simpler on a control cage Control cage can be animated on the GPU, then tessellated in a second pass Animated Control Cage Vertex Shader Pixel Shader R2VB Vertex Shader Pixel Shader Tessellator

6 Hardware tessellation is a form of compression Smaller footprint – you only need to store the control cage and possibly a displacement map Improved bandwidth – less data to transfer from memory to GPU

7 Three types of primitives, or superprims, are supported Triangles Quads Lines

8 There are two tessellation modes - Continuous - Adaptive

9 Continuous Tessellation Specify floating point tessellation level per-draw call –Tessellation levels range from 1.0 to Eliminates popping as vertices are added through tessellation Level 1.0 Level 2.0

10 Level = 1.0 Level = 1.1 Level = 1.3 Level = 1.7 Level = 2.0 Continuous Tessellation Level 1.0 Level 2.0 Specify floating point tessellation level per-draw call –Tessellation levels range from 1.0 to Eliminates popping as vertices are added through tessellation

11 Adaptive allows different levels of tessellation within the same mesh Edge tessellation factor = 5.x Edge tessellation factor = 3.x Edge tessellation factor = 5.x Edge tessellation factor = 7.x Edge tessellation factor = 3.x

12 Adaptive tessellation can be done in real-time using multiple passes Transformed Superprim Mesh Superprim Mesh Vertex Shader Pixel Shader Superprim Mesh Vertex Shader Pixel Shader Sampler Stream 0 Vertex Shader Pixel Shader Superprim Mesh Stream 1 Tessellator Tessellation Factors R2VB

13 Code Example: Continuous Tessellation // Enable tessellation: TSSetTessellationMode( pd3dDevice, TSMD_ENABLE_CONTINUOUS ); // Set tessellation level: TSSetMaxTessellationLevel( pd3dDevice, sg_fMaxTessellationLevel ); // Select appropriate technique to render our tessellated objects: sg_pEffect->SetTechnique( "RenderTessellatedDisplacedScene" ); // Render all passes with tessellation V( sg_pEffect->Begin( &cPasses, 0 ) ); for ( iPass = 0; iPass < cPasses; iPass++ ) { V( sg_pEffect->BeginPass( iPass ) ); V( TSDrawMeshSubset( sg_pMesh, 0 ) ); V( sg_pEffect->EndPass() ); } V( sg_pEffect->End() ); // Disable tessellation: TSSetTessellationMode( pd3dDevice, TSMD_DISABLE );

14 Displacement Map The vertex shader is used as an evaluation shader Tessellator Super-prim Mesh Tessellated and Displaced Mesh Tessellated Mesh Vertex Shader (Evaluation Shader) Sampler

15 Example Code: Evaluation Vertex Shader struct VsInputTessellated { // Barycentric weights for this vertex float3 vBarycentric: BLENDWEIGHT0; // Data from superprim vertex 0: float4 vPositionVert0 : POSITION0; float2 vTexCoordVert0 : TEXCOORD0; float3 vNormalVert0 : NORMAL0; // Data from superprim vertex 1: float4 vPositionVert1 : POSITION4; float2 vTexCoordVert1 : TEXCOORD4; float3 vNormalVert1 : NORMAL4; // Data from superprim vertex 2: float4 vPositionVert2 : POSITION8; float2 vTexCoordVert2 : TEXCOORD8; float3 vNormalVert2 : NORMAL8; };

16 Example Code: Evaluation Vertex Shader VsOutputTessellated VSRenderTessellatedDisplaced( VsInputTessellated i ) { VsOutputTessellated o; // Compute new position based on the barycentric coordinates: float3 vPosTessOS = * i.vBarycentric.x + i.vBarycentric.y + * i.vBarycentric.z; // Output world-space position: o.vPositionWS = vPosTessOS; // Compute new normal vector for the tessellated vertex: o.vNormalWS = * i.vBarycentric.x + * i.vBarycentric.y + * i.vBarycentric.z; // Compute new texture coordinates based on the barycentric coordinates: o.vTexCoord = i.vTexCoordVert0.xy * i.vBarycentric.x + i.vTexCoordVert1.xy * i.vBarycentric.y + i.vTexCoordVert2.xy * i.vBarycentric.z; // Displace the tessellated vertex (sample the displacement map) o.vPositionWS = DisplaceVertex( vPosTessOS, o.vTexCoord, o.vNormalWS ); // Transform position to screen-space: o.vPosCS = mul( float4( o.vPositionWS, 1.0 ), g_mWorldViewProjection ); return o; } // End of VsOutputTessellated VSRenderTessellatedDisplaced(..)

17 What if you want to do more? DirectX 9 has a limit of 15 float4 vertex input components – High order surfaces need more inputs TSToggleIndicesRetrieval() allows you to fetch the super-prim data from a vertex texture Bezier Control Points Vertex Shader Sampler Tessellator (u,v) P 0,0, P 0,1 … P 3,3

18 Other Tessellation Library Functions TSDrawIndexed(…) –Analogous to DrawIndexedPrimitive(…) TSDrawNonIndexed(…) –Needed for adaptive tessellation, since every edge needs its own tessellation level TSSetMinTessellationLevel(…) –Sets the minimum tessellation level for adaptive tessellation TSComputeNumTessellatedPrimitives(…) –Calculates the number of tessellated primitives that will be generated by the tessellator

19 Displacement mapping alters tangent space To do normal mapping we need to rotate tangent space Alternatively, use model space normal maps Doesnt work with animation or tiling

20 Displacement map lighting Use the displacement map to calculate the per-pixel normal Central differencing with neighboring displacements can approximate the derivative Light with the computed normal No need to use a normal map

21 Terrain Rendering: Performance Results Both use the same displacement map (2K x 2K) and identical pixel shaders Low Resolution with Tessellation High Resolution, No Tessellation On-disk model polygon count (pre-tessellation) 840 triangles1,280,038 triangles Original model rendering cost 1210 fps (0.83 ms) Actual rendered model polygon count 1,008,038 triangles1,280,038 triangles VRAM Vertex buffer size70 KB31 MB VRAM Index buffer size23 KB14 MB Rendering time fps (1.22 ms)301 fps (3.32 ms) Rendering with tessellation is > 6X faster and provides memory savings over 44MB! Subtracting the cost of shading

22 Terrain Tessellation Sample

23 AMD GPU MeshMapper New tool for generate normal, displacement, and ambient occlusion maps from hi-res and low-res mesh pairs

24 Advantages of the Tessellator Saves memory bandwidth and reduces memory footprint Flexible support for displacement mapping and many kinds of high order surfaces Easier content creation – artists and animators only need to work with low resolution geometry Continuous LOD avoids unnecessary triangles The tessellator is available now on the Xbox 360 and the latest ATI Radeon and FireGL graphics cards Public availability of tessellation SDK very soon

25 Harnessing the Power of Multiple GPUs Nicolas Thibieroz AMD Graphics Products Group Original materials from Jon Story & Holger Grün 25 15/01/2014 GDC Paris 2008

26 Why MGPU? MGPUs can be used to dramatically increase performance and visual quality –At higher screen resolutions –Especially with increased use of MSAA Many applications become GPU limited at higher screen resolutions –High resolution monitors => mainstream affordability Achieve next generation performance on todays HW –Prototype your next engine Provides an upgrade path for mainstream parts 26 15/01/2014

27 Multiple Boards An increasing number of motherboards can accept 2 or more discrete video cards Connected by high speed crossover cables Now possible to fit 4 Radeon HD3850 boards to a single motherboard CrossFireX technology allows you to harness that performance 27 15/01/2014 4x 2x

28 Multiple GPUs per Board The Radeon HD3870 X2 is a single-board multi-GPU architecture –AFR is on by default Heavy peer to peer communication –Bi-directional 16x lane pipe connecting the 2 GPUs CrossFireX supports 2 HD3870 X2 boards for Quad GPU performance 28 15/01/2014 4x 2x

29 Hybrid Crossfire Combination of integrated and discrete graphics 3D graphics performance boost –Laptops –Mainstream desktop PCs Use less power during non- taxing graphical tasks 29 15/01/2014

30 CrossFire Rendering Modes Split Frame Rendering / Scissor –Screen is divided into number of GPUs –Dynamic load balancing Alternate Frame Rendering –GPUs take alternate frames –Vertex processing not duplicated –Highest performing mode 30 15/01/2014

31 How does AFR Work? 31 15/01/2014 CPU GPU0 (Frame N) GPU1 (Frame N+1) Command

32 Hardware Considerations Current MGPU setups are not shared memory architectures –Resources placed in local video memory are duplicated for each GPU Driver initiates peer to peer (P2P) copies to keep resources in sync –On some chipsets this may involve the CPU –Synchronizes all GPUs –Very heavy impact on performance that can even result in negative scaling 32 15/01/2014

33 Driver Modes Compatible AFR Mode –Default mode –Driver checks for AFR unfriendly behaviour –Will P2P copy stale resources Full AFR Mode (Application Profile) –Driver recognises EXE name –Use a unique name and dont change it –Behaviour fully guided by profile –Best performance – no checking –Rename EXE to AFR-FriendlyD3D.exe –Use AFR-FriendlyOGL.exe for OpenGL –No checking : Speed & compatibility test 33 15/01/2014

34 Detecting the Number of GPUs Visit – Download project called CrossFire Detect Statically link to: –atimgpud_s_x86.lib 32 bit version –atimgpud_s_x64.lib 64 bit version Include header file: –atimgpud.h Call this function: –INT count = AtiMultiGPUAdapters(); 34 15/01/2014

35 Common Pitfalls & Solutions 35 15/01/2014

36 Pitfall: Dependencies Between Frames 36 15/01/2014 Update resource A Present (N) Draw using A Update resource A Present (N+1) GPU1 (Frame N+1) GPU0 (Frame N) resource A Present (N-1) Draw using A P2P copy from GPU0 to GPU1

37 Solution: Resources that Change Every Frame 37 15/01/2014 Draw using A Present (N) Update resource A Draw using A Present (N+1) GPU1 (Frame N+1) GPU0 (Frame N) resource A Present (N-1) Update resource A There are no P2P copies if one always modifies the resource before using it within a frame !

38 Solution: Resources that Change Every Few Frames 38 15/01/2014 Draw using A Present (N) Update resource A Draw using A Present (N+1) GPU1 (Frame N+1) GPU0 (Frame N) resource A Present (N-1) Update resource A Draw using A Present (N+2) Draw using A Present (N+4) Draw using A Present (N+3) Repeat the modification for N GPU frames to ensure that each GPU has the same data! No P2P copies will happen!

39 Pitfalls: In DX10 there are Other Ways to Update Resources... Drawing to vertex/index buffers Stream Out CopyResource() calls CopySubresourceRegion() calls GenerateMips() calls ResolveSubresource() calls 39 15/01/2014

40 Pitfall: Waiting on Queries 40 15/01/2014 CPU GPU0 (Frame N) GPU1 (Frame N+1) Command Waiting for Query Result!!! Waiting starves GPU queues Waiting limits parallelismWaiting => CPU limitation

41 Solution: Queries Avoid using queries whenever possible - For occlusion queries consider a CPU-based approach Avoid waiting on query results - Pick up the result of a query at least N-GPU frames after it was issued For queries issued every frame - Create additional query objects for each GPU - Cycle through them

42 Pitfall: CPU Access to a Renderable Resource When the CPU locks a renderable resource it must wait for all GPUs to finish using the resource before acquiring the pointer All GPUs now have to wait until the CPU unlocks the resource pointer After the unlock the driver has to update the resource on each GPU via P2P copies Just dont do this – it destroys performance even on a single GPU setup, and is catastrophic for MGPUs 42 15/01/2014

43 Solutions: Locks / Maps In DX10 stream to and copy from STAGING textures In DX9 StretchRect() is always better than Lock() At resource creation time use the appropriate flags from: –D3D10_USAGE –D3D10_CPU_ACCESS_FLAG In DX9 never lock static Vertex/Index Buffers because it will cause P2P copies 43 15/01/2014

44 Concluding Pitfalls & Solutions Drivers take a conservative approach –Performs checks on resource synchronization –P2P copy if necessary You know the application best –Determine if a P2P copy is necessary –Talk to us about a profile 44 15/01/2014

45 AFR-Friendly SDK Sample Part of the ATI developer SDK – Detects the number of GPUs Correctly deals with textures used as render targets Provides a solution for dealing with mouse cursor lag Go and take a look!! 45 15/01/2014

46 Call to Action MGPUs provide demonstrable performance gains MGPUs boost visual quality Plan from day one to make your rendering scale Detect the number of GPUs Regularly check for AFR unfriendly behavior Talk to us /01/2014


Download ppt "Tessellation in a Low Poly World Nicolas Thibieroz AMD Graphics Products Group Original materials from Bill Bilodeau 1 15/01/2014."

Similar presentations

Ads by Google