#version 450 core layout(quads, fractional_even_spacing, cw) in; layout(binding = 0) uniform sampler2D heightTexture; layout(location = 0) uniform mat4 M; uniform float displacementScale = 0.05; layout(std140, binding = 0) uniform SceneUniforms { mat4 PV; //camera projection * view matrix vec4 eye_w; //world-space eye position }; in TC_OUT { vec3 position; vec2 texCoord; } te_in[]; out TE_OUT { vec3 position; vec2 texCoord; vec3 normal; } te_out; float getHeight(vec2 uv) { return texture(heightTexture, uv).r; } vec3 calculateFaceNormal(vec3 p1, vec3 p2, vec3 p3) { return normalize(cross(p2 - p1, p3 - p1)); } void main() { vec3 barycentricCoords = gl_TessCoord; vec3 p0 = te_in[0].position; vec3 p1 = te_in[1].position; vec3 p2 = te_in[2].position; vec3 displacedPosition = barycentricCoords.x * p0 + barycentricCoords.y * p1 + barycentricCoords.z * p2; float displacement = texture(heightTexture, vec2(displacedPosition.x, displacedPosition.z)).r * displacementScale; //te_out.position = vec4(displacedPosition, 1.0f).xyz; vec3 dp1 = p1 - p0; vec3 dp2 = p2 - p0; dp1.z += texture(heightTexture, vec2(p1.x, p1.y)).r * displacementScale - texture(heightTexture, vec2(p0.x, p0.y)).r * displacementScale; dp2.z += texture(heightTexture, vec2(p2.x, p2.y)).r * displacementScale - texture(heightTexture, vec2(p0.x, p0.y)).r * displacementScale; te_out.normal = normalize(cross(dp1, dp2)); // Interpolate texture coordinates vec2 texCoord = mix( mix(te_in[0].texCoord, te_in[1].texCoord, gl_TessCoord[0]), mix(te_in[3].texCoord, te_in[2].texCoord, gl_TessCoord[0]), gl_TessCoord[1] ); // Interpolate the original position vec3 position = mix( mix(te_in[0].position, te_in[1].position, gl_TessCoord[0]), mix(te_in[3].position, te_in[2].position, gl_TessCoord[0]), gl_TessCoord[1] ); position.z += texture(heightTexture, texCoord).r * displacementScale; // // Calculate normals based on the tessellated triangle's vertices // 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 n_u = p1 - p0; // vec3 v_u = p2 - p0; // vec3 v_normal = normalize(cross(n_u, v_u)); // // Calculate normals for the specific triangle being rendered // vec3 normal = calculateFaceNormal(p0, p1, position); // normal += calculateFaceNormal(p1, p2, position); // normal += calculateFaceNormal(p2, p0, position); // normal = (PV*M*vec4(normalize(normal), 1.0f)).xyz; te_out.position = (PV*M*vec4(position, 1.0f)).xyz; te_out.texCoord = texCoord; //te_out.normal = (PV*M*vec4(v_normal, 1.0f)).xyz; gl_Position = PV*M*vec4(position, 1.0f); }