nuclear@0: #version 410 compatibility nuclear@0: nuclear@1: layout(quads, ccw) in; nuclear@0: nuclear@0: out vec3 normal; nuclear@0: out vec3 vpos; nuclear@2: out vec2 uv; nuclear@0: nuclear@1: uniform vec3 norm_scale; nuclear@1: nuclear@0: vec3 bezier_patch(float u, float v); nuclear@0: vec3 bezier_patch_norm(float u, float v); nuclear@0: float bernstein(int i, float x); nuclear@0: nuclear@0: void main() nuclear@0: { nuclear@0: vec3 pos = bezier_patch(gl_TessCoord.x, gl_TessCoord.y); nuclear@0: normal = gl_NormalMatrix * bezier_patch_norm(gl_TessCoord.x, gl_TessCoord.y); nuclear@0: nuclear@2: uv = gl_TessCoord.xy; nuclear@2: nuclear@0: gl_Position = gl_ModelViewProjectionMatrix * vec4(pos, 1.0); nuclear@0: vpos = (gl_ModelViewMatrix * vec4(pos, 1.0)).xyz; nuclear@0: } nuclear@0: nuclear@0: vec3 bezier_patch(float u, float v) nuclear@0: { nuclear@0: int i, j; nuclear@0: vec3 res = vec3(0.0, 0.0, 0.0); nuclear@0: nuclear@0: for(j=0; j<4; j++) { nuclear@0: for(i=0; i<4; i++) { nuclear@0: float bu = bernstein(i, u); nuclear@0: float bv = bernstein(j, v); nuclear@0: nuclear@0: res += gl_in[j * 4 + i].gl_Position.xyz * bu * bv; nuclear@0: } nuclear@0: } nuclear@0: return res; nuclear@0: } nuclear@0: nuclear@0: #define DT 0.0001 nuclear@0: vec3 bezier_patch_norm(float u, float v) nuclear@0: { nuclear@0: vec3 tang = bezier_patch(u + DT, v) - bezier_patch(u - DT, v); nuclear@0: vec3 bitan = bezier_patch(u, v + DT) - bezier_patch(u, v - DT); nuclear@1: return cross(tang, bitan) * norm_scale; nuclear@0: } nuclear@0: nuclear@0: float bernstein(int i, float x) nuclear@0: { nuclear@0: float invx = 1.0 - x; nuclear@0: nuclear@0: if(i == 0) { nuclear@0: return invx * invx * invx; nuclear@0: } nuclear@0: if(i == 1) { nuclear@0: return 3 * x * invx * invx; nuclear@0: } nuclear@0: if(i == 2) { nuclear@0: return 3 * x * x * invx; nuclear@0: } nuclear@0: return x * x * x; nuclear@0: }