To create a shader program that will generate a Bezier curve from a patch of four control points, use the following steps:
- Use the following code for the vertex shader. Note that we send the vertex position along to the TCS unmodified:
layout (location = 0 ) in vec2 VertexPosition; void main() { gl_Position = vec4(VertexPosition, 0.0, 1.0); }
- Use the following code as the tessellation control shader:
layout( vertices=4 ) out; uniform int NumSegments; uniform int NumStrips; void main() { // Pass along the vertex position unmodified gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position; // Define the tessellation levels gl_TessLevelOuter[0] = float(NumStrips); gl_TessLevelOuter[1] = float(NumSegments); }
- Use the following code as the tessellation evaluation shader:
layout( isolines ) in; uniform mat4 MVP; // projection * view * model void main() { // The tessellation u coordinate float u = gl_TessCoord.x; // The patch vertices (control points) vec3 p0 = gl_in[0].gl_Position.xyz; vec3 p1 = gl_in[1].gl_Position.xyz; vec3 p2 = gl_in[2].gl_Position.xyz; vec3 p3 = gl_in[3].gl_Position.xyz; float u1 = (1.0 - u); float u2 = u * u; // Bernstein polynomials evaluated at u float b3 = u2 * u; float b2 = 3.0 * u2 * u1; float b1 = 3.0 * u * u1 * u1; float b0 = u1 * u1 * u1; // Cubic Bezier interpolation vec3 p = p0 * b0 + p1 * b1 + p2 * b2 + p3 * b3; gl_Position = MVP * vec4(p, 1.0); }
- Use the following code for the fragment shader:
uniform vec4 LineColor; layout ( location = 0 ) out vec4 FragColor; void main() { FragColor = LineColor; }
- It is important to define the number of vertices per patch within the OpenGL application. You can do so using the glPatchParameter function:
glPatchParameteri( GL_PATCH_VERTICES, 4);
- Render the four control points as a patch primitive within the OpenGL application's render function:
glDrawArrays(GL_PATCHES, 0, 4);