#version 120 #extension GL_EXT_gpu_shader4: enable #extension GL_EXT_geometry_shader4: enable uniform int Detail; uniform float Droop; uniform int Length; uniform float Step; varying in vec3 Tnorm[3]; varying in vec4 Color[3]; varying out vec4 FragColor; int ILength; vec3 Norm[3]; vec3 N0, N01, N02; vec4 V0, V01, V02; void ProduceVertices( float s, float t ) { vec4 v = V0 + s*V01 + t*V02; vec3 n = normalize( N0 + s*N01 + t*N02 ); for( int i = 0; i <= Length; i++ ) { gl_Position = gl_ProjectionMatrix * v; FragColor = Color[0]; EmitVertex(); v.xyz += Step * n; v.y -= Droop * float(i*i); } EndPrimitive(); } void main() { V0 = gl_PositionIn[0]; V01 = ( gl_PositionIn[1] - gl_PositionIn[0] ); V02 = ( gl_PositionIn[2] - gl_PositionIn[0] ); Norm[0] = Tnorm[0]; Norm[1] = Tnorm[1]; Norm[2] = Tnorm[2]; if( dot( Norm[0], Norm[1] ) < 0. ) Norm[1] = -Norm[1]; if( dot( Norm[0], Norm[2] ) < 0. ) Norm[2] = -Norm[2]; N0 = normalize( Norm[0] ); N01 = normalize( Norm[1] - Norm[0] ); N02 = normalize( Norm[2] - Norm[0] ); int numLayers = 1 << Detail; float dt = 1. / float( numLayers ); float t = 1.; for( int it = 0; it <= numLayers; it++ ) { float smax = 1. - t; int nums = it + 1; float ds = smax / float( nums - 1 ); float s = 0.; for( int is = 0; is < nums; is++ ) { ProduceVertices( s, t ); s += ds; } t -= dt; } }