#version 400 core layout( isolines, fractional_even_spacing, ccw ) in; out Vertex { vec3 color; } te_out; uniform mat4 modelViewMatrix; uniform mat3 normalMatrix; uniform mat4 projectionMatrix; uniform mat4 mvp; // Calculate RGB triplet from HSV vec3 hsvToRGB( float h, float s, float v ) { if ( s <= 0.0 ) return vec3( v ); h = h * 6.0; float c = v * s; float x = ( 1.0 - abs( ( mod( h, 2 ) - 1 ) ) ) * c; float m = v - c; float r = 0.0; float g = 0.0; float b = 0.0; if ( h < 1.0 ) { r = c; g = x; b = 0.0;} else if ( h < 2.0 ) { r = x; g = c; b = 0.0; } else if ( h < 3.0 ) { r = 0.0; g = c; b = x; } else if ( h < 4.0 ) { r = 0.0; g = x; b = c; } else if ( h < 5.0 ) { r = x; g = 0.0; b = c; } else { r = c; g = 0.0; b = x; } return vec3( r + m, g + m, b + m ); } void main() { float u = gl_TessCoord.x; float v = gl_TessCoord.y; vec4 a = gl_in[0].gl_Position; vec4 b = gl_in[1].gl_Position; vec4 c = gl_in[2].gl_Position; vec4 d = gl_in[3].gl_Position; // Use the (u,v) parametric coords to calculate the vertex. // u is the position along an isoline // v is isoline number // Let's make a sinusoidal curve as a function of u that varies // in the v direction which we will define as orthogonal to u // Interpolate in u along top and bottom edges of the patch vec4 q0 = mix( a, b, u ); vec4 q1 = mix( d, c, u ); // Interpolate in v between the above positions. This gives the // nominal position for our vertex vec4 p = mix( q0, q1, v ); // Find "vertical" direction vec4 vBasis = normalize( q1 - q0 ); // Offset vertex in this direction using sinusoid vec4 pos = p + 0.2 * vBasis * sin( 20.0 * u ); // Use a hue value based on v te_out.color = hsvToRGB( v, 1.0, 1.0 ); // Transform to clip-space gl_Position = mvp * pos; }