HW-Tessellation Basics Peter Houska Institute of Computer Graphics and Algorithms Vienna University of Technology
Tessellation Video [UnHe] Institute of Computer Graphics and Algorithms 1
What is Tessellation? Refers to subdivision of geometry Geometry shader could do that already OpenCL etc. could be used for subdiv, too Nowadays prefer tessellation shader(s) better performance! subdivision itself is taken care of automatically just supply subdivision factors Institute of Computer Graphics and Algorithms 2
Why Tessellation? Ever increasing polygon counts Application needs to: store data transmit data between RAM & VRAM Possible bottleneck! better to refine mesh entirely on GPU Example: Skinned animation transmit & animate coarse mesh only refine mesh entirely on the GPU Institute of Computer Graphics and Algorithms 3
Typical Usage of Tessellation (True) Displacement mapping not just modification of lighting ( bump mapping, etc.) changes objects silhouette Institute of Computer Graphics and Algorithms 4
Example: Displacement Mapping [UnHe] Institute of Computer Graphics and Algorithms 5
Typical Usage of Tessellation cont'd Dynamic & Continuous Level Of Detail e.g. subdivide based on screen space error Algebraic Surfaces only send control points to GPU, evaluate surface on the fly [OglDev] Institute of Computer Graphics and Algorithms 6
New Shader Stages in the Pipeline Input Assembler Vertex Shader Tessellation Control Shader Primitive Generator Tessellation Evaluation Shader Geometry Shader Rasterizer Fragment Shader Output Merger Input Assembler Vertex Shader Hull Shader Tessellator Domain Shader Geometry Shader Rasterizer Pixel Shader Output Merger Institute of Computer Graphics and Algorithms 7
Tessellation Dataflow input patch = group of CPs may add/delete CPs Tessellation Control Shader TLs barycentric coordinates + connectivity Primitive Generator (PG) output patch 1:1 (no add/delete) Tessellation Evaluation Shader vertex for each barycentric coord from PG CPs... control points (=collection of vertices with attributes) TLs... tessellation levels Institute of Computer Graphics and Algorithms 8
Tessellation Dataflow - TCS input patch = group of CPs may add/delete CPs Tessellation Control Shader TLs barycentric coordinates + connectivity Primitive Generator (PG) output patch 1:1 (no add/delete) Tessellation Evaluation Shader vertex for each barycentric coord from PG CPs... control points (=collection of vertices with attributes) TLs... tessellation levels Institute of Computer Graphics and Algorithms 9
Tessellation Control Shader (TCS) Reads an input patch consists of "any" number of vertices Emits an output patch is run once for each vertex in output patch computes attributes of that vertex Most important per-patch outputs are tessellation levels (TLs) TLs control the number of subdivisions performed by the primitive generator Institute of Computer Graphics and Algorithms 10
Tessellation Control Shader (TCS) Per-vertex output variables are declared as arrays indexed by vertex number May write only to outputs corresponding to its output patch vertex given by special variable gl_invocationid Institute of Computer Graphics and Algorithms 11
Tessellation Control Shader (TCS) May declare per-patch output variables use qualifier patch out Per-patch outputs do not correspond to any specific vertex in the patch are not indexed by vertex number. User-defined per-patch outputs are not used by the primitive generator but may be read by tessellation evaluation shaders. Institute of Computer Graphics and Algorithms 12
Tessellation Dataflow - PG input patch = group of CPs may add/delete CPs Tessellation Control Shader TLs barycentric coordinates + connectivity Primitive Generator (PG) output patch 1:1 (no add/delete) Tessellation Evaluation Shader vertex for each barycentric coord from PG CPs... control points (=collection of vertices with attributes) TLs... tessellation levels Institute of Computer Graphics and Algorithms 13
Primitive Generator (PG) Subdivides triangle or quad primitive based on tessellation levels of the patch the set of layout declarations specified in tessellation evaluation shader yields collection of points, lines, or triangles Institute of Computer Graphics and Algorithms 14
Primitive Generator (PG) The type of subdivision performed is specified by an input layout declaration in the tessellation evaluation shader Possible domain parameterizations triangles quads isolines Strictly speaking only subdivides domain, not the input primitive Institute of Computer Graphics and Algorithms 15
Primitive Generator (PG) Domain parameterization for tessellation generator primitive modes IL 0-1 inner tessellation levels OL 0-3 outer tessellation levels [OglSpec] Institute of Computer Graphics and Algorithms 16
Primitive Generator (PG) Generated vertices have associated (u,v,w) or (u,v) position in a normalized parameter space Parameter values in the range [0; 1] For triangles: vertex position is barycentric coordinate (u,v,w) (u + v + w) = 1 Institute of Computer Graphics and Algorithms 17
Primitive Generator (PG) Input layout declaration in the tessellation evaluation shader controls number and spacing of segments equal_spacing fractional_even_spacing fractional_odd_spacing Institute of Computer Graphics and Algorithms 18
Tessellation Factors [LGGh] Institute of Computer Graphics and Algorithms 19
Subdivision Step-by-Step (1/6) Start with equilateral triangle 3 outer TLs, 1 inner TL given Ignore the 3 outer TLs for now Temporarily subdivide outer edges by inner TL n we get n segments and (n+1) vertices on each edge inner TL=4 inner TL=5 Institute of Computer Graphics and Algorithms 20
Subdivision Step-by-Step (2/6) Form the corner points of inner triangle Intersect lines which are perpendicular to edge and contain nearest subdivision points on edge Intersection points are new corner points for inner triangle inner TL=4 inner TL=5 Institute of Computer Graphics and Algorithms 21
Subdivision Step-by-Step (3/6) Intersect inner triangle edge with perpendicular lines through remaining ((n+1)-4) points on outer edge inner TL=4 inner TL=5 Institute of Computer Graphics and Algorithms 22
Subdivision Step-by-Step (4/6) Note: inner TL=4 outer triangle has n segments inner triangle has (n-2) segments outer triangle has n+1 vertices inner triangle has n-1 vertices inner TL=5 Institute of Computer Graphics and Algorithms 23
Subdivision Step-by-Step (5/6) Newly created inner triangle is treated as the outer triangle in the next step recursively create new triangles @ inner TL= 4: Note that the innermost triangle is degenerate (a point) inner TL=4 inner TL=5 Institute of Computer Graphics and Algorithms 24
Subdivision Step-by-Step (6/6) Outermost edges are finally subdivided by given outer TLs Completely fill area between concentric triangles with triangles Each vertex is assigned its corresponding barycentric coordinate Institute of Computer Graphics and Algorithms 25
Tessellation Dataflow - TES input patch = group of CPs may add/delete CPs Tessellation Control Shader TLs barycentric coordinates + connectivity Primitive Generator (PG) output patch 1:1 (no add/delete) Tessellation Evaluation Shader vertex for each barycentric coord from PG CPs... control points (=collection of vertices with attributes) TLs... tessellation levels Institute of Computer Graphics and Algorithms 26
Tessellation Evaluation Shader (TES) Is run on each vertex generated by PG Has access to relative location of vertex in subdivided output primitive (u,v) or (u,v,w) coordinate all vertex attributes in input patch position, texture coordinates,... Calculates and writes final vertex position other attributes of each vertex Institute of Computer Graphics and Algorithms 27
Important Code in the Application Configure number of vertices in patch glpatchparameteri(gl_patch_vertices, n); Query for the maximum allowable number n GLint MaxPatchVertices; glgetintegerv(gl_max_patch_vertices, &MaxPatchVertices); Use new primitive mode GL_PATCHES for rendering, e.g.: gldrawarrays(gl_patches, first_vert, vert_cnt); gldrawelements(gl_patches, idx_buffer_len, GL_UNSIGNED_INT, 0); Just as passing 3 vertices+attributes when rendering triangles, pass n vertices for each patch Institute of Computer Graphics and Algorithms 28
Creating Tessellation Shaders Basically the same procedure as for VS/GS/FS, just replace constants:... glcreateshader(gl_tess_control_shader);... glcreateshader(gl_tess_evaluation_shader);... Institute of Computer Graphics and Algorithms 29
Example: Simple Displacement Mapping Application Render patches, each made up of 3 vertices so each patch is basically a triangle vertex attributes: position & texture coordinate VS simply passes data down to TCS TCS calculates the tessellation levels passes vertex attributes down to TES TES performs texture fetch at received texture coordinate and uses value as displacement factor FS fetches color from texture at same texture coordinate Institute of Computer Graphics and Algorithms 30
Vertex Shader #version 410 core // matrix that transforms from object space to world space (WS) uniform mat4 model_mat; in vec4 in_vertex; in vec2 in_tc0; // attribute 0: object space vertex position // attribute 1: texture coordinate // variables to pass down information from VS to TCS out vec2 tc0_v2tc; out vec4 WS_pos_v2tc; void main(void) { tc0_v2tc = in_tc0; WS_pos_v2tc = model_mat * in_vertex; // transform vertex to WS } Institute of Computer Graphics and Algorithms 31
Tessellation Control Shader (1/2) #version 410 core // define the number of CPs in the output patch layout (vertices = 3) out; uniform vec4 cam_pos_ws; // camera position in WS // attributes of the input CPs in vec2 tc0_v2tc[]; in vec4 WS_pos_v2tc[]; // attributes of the output CPs out vec2 tc0_tc2te[]; out vec4 WS_pos_tc2te[]; Institute of Computer Graphics and Algorithms 32
Tessellation Control Shader (2/2) void main(void) { // Set the control points of the output patch tc0_tc2te[gl_invocationid] = tc0_v2tc[gl_invocationid]; WS_pos_tc2te[gl_InvocationID] = WS_pos_v2tc[gl_InvocationID]; // the next snippet just sketches the calculations... // based on the vertex distances to the camera, we choose the TLs } // Calculate the tessellation levels see next slide for indices // actually we only need to write these once per patch, // not once per vertex [hint: check for gl_invocationid ] gl_tesslevelouter[0] = calc_tl(ws_pos_v2tc[1], WS_pos_v2tc[2]); gl_tesslevelouter[1] = calc_tl(ws_pos_v2tc[2], WS_pos_v2tc[0]); gl_tesslevelouter[2] = calc_tl(ws_pos_v2tc[0], WS_pos_v2tc[1]); gl_tesslevelinner[0] = calc_inner_tl(... ); Institute of Computer Graphics and Algorithms 33
Tessellation Control Shader - Indices V (vertex 1) [OglSpec] W (vertex 2) edge 1 U (vertex 0) Institute of Computer Graphics and Algorithms 34
Tessellation Evaluation Shader (1/2) #version 410 core // tell PG to emit triangles in counter-clockwise order // with equal spacing (try fractional_even_spacing and // fractional_odd_spacing, too!) layout(triangles, equal_spacing, ccw) in; uniform mat4 proj_mat; uniform mat4 view_mat; uniform sampler2d disp_tex; // texture for displacement values uniform float displacement_factor; // these vertex attributes are passed down from the TCS in vec2 tc0_tc2te[]; in vec4 WS_pos_tc2te[]; out vec2 tc0; // the only attribute we'll need later in the FS Institute of Computer Graphics and Algorithms 35
Tessellation Evaluation Shader (2/2) // Interpolate values v0-v2 based on the barycentric coordinates // of the current vertex within the triangle vec2 ipol2d(vec2 v0, vec2 v1, vec2 v2) { return vec2(gl_tesscoord.x) * v0 + vec2(gl_tesscoord.y) * v1 + vec2(gl_tesscoord.z) * v2; } void main(void) { // Interpolate attribs of output vertex using its barycentric coords vec2 tc0_tess = ipol2d(tc0_tc2te[0], tc0_tc2te[1], tc0_tc2te[2]); } vec4 WS_pos_tess = vec4( ipol3d( Institute of Computer Graphics and Algorithms 36 WS_pos_tc2te[0].xyz, WS_pos_tc2te[1].xyz, WS_pos_tc2te[2].xyz ), 1.0); tc0 = tc0_tess; // pass texture coordinate to FS // Displace the vertex along the WS z-axis float displacement = texture(disp_tex, tc0_tess).x; WS_pos_tess.z += displacement * displacement_factor; // transform to NDC gl_position = proj_mat * view_mat * WS_vertex_pos_tess;
Fragment Shader #version 410 core uniform sampler2d c_tex; // color texture in vec2 tc0; // passed down from the TES out vec4 out_color0; // the final fragment color void main(void) { out_color0 = texture(c_tex, tc0); } Institute of Computer Graphics and Algorithms 37
References [OglSpec] www.opengl.org http://www.opengl.org/registry/specs/arb/tessellation_shader.txt [UnHe] Unigine "Heaven" benchmark http://www.youtube.com/watch?v=bkkty2g3fbu Some tutorials: [LGGh] prideout.net/blog/?p=48 [OglDev] ogldev.atspace.co.uk/www/tutorial30/tutorial30.html http://www.geeks3d.com/20100730/test-first-contact-with-opengl-4-0-gpu-tessellation/ Institute of Computer Graphics and Algorithms 38