tessellation - katie.cs.mtech.edu

35
1 TESSELLATION

Upload: others

Post on 14-May-2022

6 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: TESSELLATION - katie.cs.mtech.edu

1

TESSELLATION

Page 2: TESSELLATION - katie.cs.mtech.edu

OUTLINE

2

• Tessellation in OpenGL

• Tessellation of Bezier Surfaces

• Tessellation for Terrain/Height Maps

• Level of Detail

Page 3: TESSELLATION - katie.cs.mtech.edu

THE EXAMPLE

Page 4: TESSELLATION - katie.cs.mtech.edu

TESSELLATION SHADING

• Instead of specifying vertices, you specify a “patch”

• Just an ordered set of vertices

• Tessellation control shader determines how much geometry is generated from patch

• Other primitives are processed by vertex, fragment and geometry shaders and bypass tessellation

• You specify the total number of vertices in the patch (with primitives, OpenGL already knows how many vertices to expect)

glPatchParameteri(GLenum pname, Glint value);

• pname is set to GL_PATCH_VERTICES

• value is number of vertices

glPatchParameteri(GL_PATCH_VERTICES, 4);

glDrawArrays(GL_PATCHES, 0, 8);

Page 5: TESSELLATION - katie.cs.mtech.edu

VERTEX SHADER

#version 430

uniform mat4 mvp;

void main(void)

{

}

Page 6: TESSELLATION - katie.cs.mtech.edu

TESSELLATION CONTROL SHADER

#version 430

uniform mat4 mvp;

layout (vertices = 1) out;

void main(void)

{

gl_TessLevelOuter[0] = 6;

gl_TessLevelOuter[2] = 6;

gl_TessLevelOuter[1] = 6;

gl_TessLevelOuter[3] = 6;

gl_TessLevelInner[0] = 12;

gl_TessLevelInner[1] = 12;

}

Specifies the number of output-patch

vertices and specifies how many times

the TCS will execute – once for each

output vertex.

Page 7: TESSELLATION - katie.cs.mtech.edu

TESSELLATION LEVELS

Page 8: TESSELLATION - katie.cs.mtech.edu

QUAD TESSELLATION

Page 9: TESSELLATION - katie.cs.mtech.edu

TRIANGLE TESSELLATION

Page 10: TESSELLATION - katie.cs.mtech.edu

TESSELLATION EVALUATION SHADER

• Executed once for each tessellation coordinate that the tessellator generates

• Determines the position of the vertex derived from the coordinate

• Looks similar to vertex shader

• Transforming vertices into screen positions

• (Unless we will use a geometry shader – but that’s at least one

lecture away)

Page 11: TESSELLATION - katie.cs.mtech.edu

TESSELLATION EVALUATION SHADER

#version 430

layout (quads, equal_spacing, ccw) in;

uniform mat4 mvp;

void main (void)

{

float u = gl_TessCoord.x;

float v = gl_TessCoord.y;

gl_Position = mvp * vec4(u,0,v,1);

}

Primitive type can be quads,

triangles or isolines

cw or ccw for winding order

equal_spacing, fractional_even_spacing or

fractional_odd_spacing

Page 12: TESSELLATION - katie.cs.mtech.edu

SPACING

• equal_spacing is the default

• It subdivides the perimeter into the number of segments you specified

• Looks best here, but has the disadvantage that it rounds up to the nearest integer so

if your object changes size you can get visible differences

• fractional_even…and fractional_odd round down – but you are left with a fractional

triangle somewhere

Page 13: TESSELLATION - katie.cs.mtech.edu

FRAGMENT SHADER

#version 430

out vec4 color;

uniform mat4 mvp;

void main(void)

{

color = vec4(1.0, 1.0, 0.0, 1.0);

}

Page 14: TESSELLATION - katie.cs.mtech.edu

TESSELLATION FOR BEZIER SURFACES

Page 15: TESSELLATION - katie.cs.mtech.edu

VERTEX SHADER #version 430

out vec2 tc;

uniform mat4 mvp;

layout (binding = 0) uniform sampler2D tex_color;

void main(void)

{

const vec4 vertices[] =

vec4[] (vec4(-1.0, 0.5, -1.0, 1.0),

vec4(-0.5, 0.5, -1.0, 1.0),

vec4( 0.5, 0.5, -1.0, 1.0),

vec4( 1.0, 0.5, -1.0, 1.0),

vec4(-1.0, 0.0, -0.5, 1.0),

vec4(-0.5, 0.0, -0.5, 1.0),

vec4( 0.5, 0.0, -0.5, 1.0),

vec4( 1.0, 0.0, -0.5, 1.0),

vec4(-1.0, 0.0, 0.5, 1.0),

vec4(-0.5, 0.0, 0.5, 1.0),

vec4( 0.5, 0.0, 0.5, 1.0),

vec4( 1.0, 0.0, 0.5, 1.0),

vec4(-1.0,-0.5, 1.0, 1.0),

vec4(-0.5, 0.3, 1.0, 1.0),

vec4( 0.5, 0.3, 1.0, 1.0),

vec4( 1.0, 0.3, 1.0, 1.0));

tc = vec2((vertices[gl_VertexID].x + 1.0)/2.0, (vertices[gl_VertexID].z + 1.0)/2.0);

gl_Position = vertices[gl_VertexID];

}

Page 16: TESSELLATION - katie.cs.mtech.edu

TESSELLATION CONTROL SHADER

#version 430

in vec2 tc[];

out vec2 tcs_out[];

uniform mat4 mvp;

layout (binding=0) uniform sampler2D tex_color;

layout (vertices = 16) out;

void main(void)

{ int TL = 32; // tessellation levels

if (gl_InvocationID ==0)

{ gl_TessLevelOuter[0] = TL;

gl_TessLevelOuter[2] = TL;

gl_TessLevelOuter[1] = TL;

gl_TessLevelOuter[3] = TL;

gl_TessLevelInner[0] = TL;

gl_TessLevelInner[1] = TL;

}

tcs_out[gl_InvocationID] = tc[gl_InvocationID];

gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;

}

16 control points per patch

Page 17: TESSELLATION - katie.cs.mtech.edu

TESSELLATION EVALUATION SHADER

#version 430

layout (quads, equal_spacing,ccw) in;

uniform mat4 mvp;

layout (binding = 0) uniform sampler2D tex_color;

in vec2 tcs_out[];

out vec2 tes_out;

Page 18: TESSELLATION - katie.cs.mtech.edu

TESSELLATION EVALUATION SHADER

void main (void)

{ vec3 p00 = (gl_in[0].gl_Position).xyz;

vec3 p10 = (gl_in[1].gl_Position).xyz;

vec3 p20 = (gl_in[2].gl_Position).xyz;

vec3 p30 = (gl_in[3].gl_Position).xyz;

vec3 p01 = (gl_in[4].gl_Position).xyz;

vec3 p11 = (gl_in[5].gl_Position).xyz;

vec3 p21 = (gl_in[6].gl_Position).xyz;

vec3 p31 = (gl_in[7].gl_Position).xyz;

vec3 p02 = (gl_in[8].gl_Position).xyz;

vec3 p12 = (gl_in[9].gl_Position).xyz;

vec3 p22 = (gl_in[10].gl_Position).xyz;

vec3 p32 = (gl_in[11].gl_Position).xyz;

vec3 p03 = (gl_in[12].gl_Position).xyz;

vec3 p13 = (gl_in[13].gl_Position).xyz;

vec3 p23 = (gl_in[14].gl_Position).xyz;

vec3 p33 = (gl_in[15].gl_Position).xyz;

Page 19: TESSELLATION - katie.cs.mtech.edu

TESSELLATION EVALUATION SHADER

float u = gl_TessCoord.x;

float v = gl_TessCoord.y;

// cubic Bezier basis functions

float bu0 = (1.0-u) * (1.0-u) * (1.0-u); //(1-u)^3

float bu1 = 3.0 * u * (1.0-u) * (1.0-u); //3u(1-u)^2

float bu2 = 3. * u * u * (1.0-u); //3u^2(1-u)

float bu3 = u * u * u; //u^3

float bv0 = (1.0-v) * (1.0-v) * (1.0-v); //(1-v)^3

float bv1 = 3.0 * v * (1.0-v) * (1.0-v); //3v(1-v)^2

float bv2 = 3. * v * v * (1.0-v); //3v^2(1-v)

float bv3 = v * v * v; //v^3

Page 20: TESSELLATION - katie.cs.mtech.edu

TESSELLATION EVALUATION SHADER

// output the position of this vertex in the tessellated patch

vec3 outputPosition =

bu0 * ( bv0*p00 + bv1*p01 + bv2*p02 + bv3*p03 )

+ bu1 * ( bv0*p10 + bv1*p11 + bv2*p12 + bv3*p13 )

+ bu2 * ( bv0*p20 + bv1*p21 + bv2*p22 + bv3*p23 )

+ bu3 * ( bv0*p30 + bv1*p31 + bv2*p32 + bv3*p33 );

gl_Position = mvp * vec4(outputPosition,1.0f); // shows bezier curve

// gl_Position = mvp * vec4(u,0,v,1); // shows original grid (pick one)

// output the interpolated texture coordinates

vec2 tc1 = mix(tcs_out[0], tcs_out[3], gl_TessCoord.x);

vec2 tc2 = mix(tcs_out[12], tcs_out[15], gl_TessCoord.x);

vec2 tc = mix(tc2, tc1, gl_TessCoord.y);

tes_out = tc;

}

Page 21: TESSELLATION - katie.cs.mtech.edu

FRAGMENT SHADER

#version 430

in vec2 tes_out;

out vec4 color;

uniform mat4 mvp;

layout (binding=0) uniform sampler2D tex_color;

void main(void)

{

color = texture(tex_color, tes_out);

}

Page 22: TESSELLATION - katie.cs.mtech.edu

TESSELLATION FOR TERRAIN / HEIGHT MAPS

• Height mapping from the vertex shader can lose detail

• Tesselation shaders introduce additional vertices

• Can use this to flesh out the detail

• Matches object geometry better

• Improves silhouette / edge detail

• Strategy:

• Place a tesselated grid in the x-z plane

• Use height map to set y coordinates

• Doesn’t require any patches

• Use grey scale image for both texture and height map

• Initial result?

Page 23: TESSELLATION - katie.cs.mtech.edu

TESSELLATION FOR TERRAIN / HEIGHT MAPS

• White areas should be higher and black areas lower

• Does not correspond on the result

• Even by adding vertices with tessellation, the resolution is too low to capture details

Page 24: TESSELLATION - katie.cs.mtech.edu

TESSELLATION FOR TERRAIN / HEIGHT MAPS

• The solution:

• Use instancing

• Remember instancing from way early on?

• Rendering multiple Java objects with a single Java call

• Build a patch in the vertex shader

• Instance the picture with 64x64 patches - results in over 4 million vertices

Page 25: TESSELLATION - katie.cs.mtech.edu

VERTEX SHADER

#version 430 out vec2 tc; uniform mat4 mvp; layout (binding = 0) uniform sampler2D tex_color; void main(void) { vec2 patchTexCoords[] = vec2[] (vec2(0,0), vec2(1,0), vec2(0,1), vec2(1,1)); // compute an offset for coordinates based on which instance this is int x = gl_InstanceID % 64; int y = gl_InstanceID / 64; // texture coordinates are distributed across 64 patches tc = vec2( (x+patchTexCoords[gl_VertexID].x)/64.0, (y+patchTexCoords[gl_VertexID].y)/64.0 ); // vertex locations range from -0.5 to +0.5 gl_Position = vec4(tc.x-0.5, 0.0, (1.0-tc.y)-0.5, 1.0); }

Page 26: TESSELLATION - katie.cs.mtech.edu

TESSELLATION CONTROL SHADER

#version 430

layout (vertices = 4) out;

in vec2 tc[];

out vec2 tcs_out[];

uniform mat4 mvp;

layout (binding=0) uniform sampler2D tex_color;

void main(void)

{ int TL = 32;

if (gl_InvocationID == 0)

{ gl_TessLevelOuter[0] = TL;

gl_TessLevelOuter[2] = TL;

gl_TessLevelOuter[1] = TL;

gl_TessLevelOuter[3] = TL;

gl_TessLevelInner[0] = TL;

gl_TessLevelInner[1] = TL;

}

tcs_out[gl_InvocationID] = tc[gl_InvocationID];

gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;

}

Page 27: TESSELLATION - katie.cs.mtech.edu

TESSELLATION EVALUATION SHADER

#version 430 layout (quads, equal_spacing,ccw) in; uniform mat4 mvp; layout (binding = 0) uniform sampler2D tex_color; in vec2 tcs_out[]; out vec2 tes_out; void main (void) { // map the texture coordinates onto the sub-grid specified by the incoming control points vec2 tc = vec2(tcs_out[0].x+(gl_TessCoord.x)/64.0, tcs_out[0].y+(1.0-gl_TessCoord.y)/64.0); // map the tessellated grid onto the sub-grid specified by the incoming control points vec4 tessellatedPoint = vec4(gl_in[0].gl_Position.x + gl_TessCoord.x / 64.0, 0.0, gl_in[0].gl_Position.z + gl_TessCoord.y / 64.0, 1.0); // add the height from the height map to the vertex: tessellatedPoint.y += (texture(tex_color, tc).r) / 40.0; gl_Position = mvp * tessellatedPoint; tes_out = tc; }

Page 28: TESSELLATION - katie.cs.mtech.edu

FRAGMENT SHADER

#version 430

in vec2 tes_out;

out vec4 color;

uniform mat4 mvp;

layout (binding=0) uniform sampler2D tex_color;

void main(void)

{

color = texture(tex_color, tes_out);

}

And the result? …

Page 29: TESSELLATION - katie.cs.mtech.edu

OVERLY JAGGED

Page 30: TESSELLATION - katie.cs.mtech.edu

ANOTHER ATTEMPT

• Height mapping detail is somewhat correct, but areas not quite right

• One problem is using a greyscale texture image for height doesn’t quite work

• Not all variations in greyscale images are due to height- some are just color

• Another problem – we don’t have normals so we can do the lighting

• Solution – use a true height map and a normal map

• Bonus – the image now responds to lighting

Page 31: TESSELLATION - katie.cs.mtech.edu

HEIGHT MAP AND NORMAL MAP

Page 32: TESSELLATION - katie.cs.mtech.edu

WITH NORMAL MAP AND LIGHTING

Page 33: TESSELLATION - katie.cs.mtech.edu

SO …WHAT’S THE DRAWBACK?

• Imagery is great, but we have over 4 million vertices just to draw the moon surface

• Any additional graphic objects are going to start taxing the system

• Solution – Only use high resolution in the areas that matter

• Those that are closer to the viewer

• Level of Detail:

• Changing the number of vertices based on the distance from the camera

• One catch… changing detail level, as the object/camera moves can make parts

of the image “pop” or wiggle

• The fix? Use fractional_even_spacing instead of equal_spacing

Page 34: TESSELLATION - katie.cs.mtech.edu

LEVEL OF DETAIL

Page 35: TESSELLATION - katie.cs.mtech.edu

SUMMARY

35

• Tessellation in OpenGL

• Tessellation of Bezier Surfaces

• Tessellation for Terrain/Height Maps

• Level of Detail