Bezier Surfaces - Tessellation Shaders supplement to Ch 8 in display(): gl.glPatchParameteri(GL_PATCH_VERTICES, 16); gl.glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); // FILL or LINE gl.glDrawArrays(GL_PATCHES, 0, 16); Vertex shader: #version 430 core out vec2 tc; uniform mat4 mvp; // out vertex attributes are scalars void main(void) { // cubic bezier patch is 16 control points 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)); Tessellation Evaluation shader: #version 430 layout (quads, equal_spacing, ccw) in; uniform mat4 mvp; in vec2 tcs_out[]; // in vertex attributes are arrays out vec2 tes_out; // out vertex attributes are scalars void main (void) { vec3 p00 = (gl_in[0].gl_Position).xyz; // control points, from TCS 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; // grid coordinates from tessellator processed one at a time float u = gl_TessCoord.x ; float v = gl_TessCoord.y ; // build terrain coordinates by moving to range [0,1] tc = vec2((vertices[gl_VertexID].x + 1.0)/2.0, (vertices[gl_VertexID].z + 1.0)/2.0); // cubic Bezier weighting functions float bu0 = (1.0-u) * (1.0-u) * (1.0-u); float bu1 = 3.0 * u * (1.0-u) * (1.0-u); float bu2 = 3. * u * u * (1.0-u); float bu3 = u * u * u; float bv0 = (1.0-v) * (1.0-v) * (1.0-v); float bv1 = 3.0 * v * (1.0-v) * (1.0-v); float bv2 = 3. * v * v * (1.0-v); float bv3 = v * v * v; // send control points to the TCS gl_Position = vertices[gl_VertexID]; } Tessellation Control Shader: #version 430 core in vec2 tc[]; out vec2 tcs_out[]; uniform float uOuter02; uniform float uOuter13; uniform float uInner0; uniform float uInner1; // vertex attributes are now arrays 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); // patch tesselation levels // (get from application) // also 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; layout (vertices = 16) out; void main(void) { // tessellation levels sent to the tessellator gl_TessLevelOuter[0] = uOuter02; gl_TessLevelOuter[2] = uOuter02; gl_TessLevelOuter[1] = uOuter13; gl_TessLevelOuter[3] = uOuter13; gl_TessLevelInner[0] = uInner0; gl_TessLevelInner[1] = uInner1; // forward the position for this control point to the TES gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position; // also forward the texture coordinates tcs_out[gl_InvocationID] = tc[gl_InvocationID]; } // (1-u)^3 // 3u(1-u)^2 // 3u^2(1-u) // u^3 // (1-v)^3 // 3v(1-v)^2 // 3v^2(1-v) // v^3 } Fragment Shader: #version 430 core in vec2 tes_out; out vec4 color; layout (binding = 0) uniform sampler2D tex_color; void main(void) { color = texture2D(tex_color, tes_out); }
© Copyright 2024 ExpyDoc