2024-08-15 13:53:52 -04:00
|
|
|
#version 450 core
|
2024-08-14 18:04:06 -04:00
|
|
|
|
2024-08-15 13:53:52 -04:00
|
|
|
layout(quads, fractional_even_spacing, cw) in;
|
|
|
|
|
2024-08-16 00:15:26 -04:00
|
|
|
layout(binding = 0) uniform sampler2D heightTexture;
|
2024-08-14 19:14:43 -04:00
|
|
|
|
2024-08-25 23:32:58 -04:00
|
|
|
layout(std140, binding = 4) uniform GeoUniforms
|
2024-08-14 19:14:43 -04:00
|
|
|
{
|
2024-08-25 23:32:58 -04:00
|
|
|
mat4 PV;
|
|
|
|
mat4 M;
|
|
|
|
|
|
|
|
float minTessellation;
|
|
|
|
float maxTessellation;
|
|
|
|
float displacementScale;
|
|
|
|
int gridDensity;
|
2024-08-14 19:14:43 -04:00
|
|
|
};
|
|
|
|
|
2024-08-16 00:15:26 -04:00
|
|
|
in TC_OUT {
|
|
|
|
vec3 position;
|
|
|
|
vec2 texCoord;
|
2024-08-28 23:12:18 -04:00
|
|
|
float tessLevel;
|
2024-08-16 00:15:26 -04:00
|
|
|
} te_in[];
|
2024-08-15 00:56:29 -04:00
|
|
|
|
2024-08-16 00:15:26 -04:00
|
|
|
out TE_OUT {
|
|
|
|
vec3 position;
|
|
|
|
vec2 texCoord;
|
|
|
|
vec3 normal;
|
|
|
|
} te_out;
|
|
|
|
|
|
|
|
float getHeight(vec2 uv) {
|
2024-08-17 19:10:45 -04:00
|
|
|
return texture(heightTexture, uv).r * displacementScale;
|
2024-08-16 00:15:26 -04:00
|
|
|
}
|
|
|
|
|
2024-08-28 23:12:18 -04:00
|
|
|
float getNeighbor(float tessFactor) {
|
|
|
|
return (float(gridDensity) * tessFactor + 1.0f);
|
|
|
|
}
|
|
|
|
|
2024-08-17 19:10:45 -04:00
|
|
|
vec3 calculateSmoothNormal(vec3 pos, vec2 coord) {
|
2024-08-25 23:32:58 -04:00
|
|
|
// Currently hardcoded to match patch density
|
2024-08-28 23:12:18 -04:00
|
|
|
//float step = 1.0f / (float(gridDensity) * tessLevel + 1.0f);
|
|
|
|
float stepU = 1.0f / (float(gridDensity) * gl_TessLevelInner[0]);
|
|
|
|
float stepV = 1.0f / (float(gridDensity) * gl_TessLevelInner[1]);
|
2024-08-16 00:15:26 -04:00
|
|
|
|
2024-08-25 23:32:58 -04:00
|
|
|
// Find surrounding heights
|
2024-08-28 23:12:18 -04:00
|
|
|
float hLeft = getHeight(coord + vec2(-stepU, 0.0f));
|
|
|
|
float hRight = getHeight(coord + vec2(stepU, 0.0f));
|
|
|
|
float hUp = getHeight(coord + vec2(0.0f, stepV));
|
|
|
|
float hDown = getHeight(coord + vec2(0.0f, -stepV));
|
2024-08-17 19:10:45 -04:00
|
|
|
|
2024-08-25 23:32:58 -04:00
|
|
|
// Calculate tangents
|
2024-08-28 23:12:18 -04:00
|
|
|
vec3 tangentX = normalize(vec3(stepU, hRight - hLeft, 0.0));
|
|
|
|
vec3 tangentY = normalize(vec3(0.0, hUp - hDown, stepV));
|
2024-08-16 00:15:26 -04:00
|
|
|
|
2024-08-17 19:10:45 -04:00
|
|
|
return normalize(cross(tangentY, tangentX));
|
|
|
|
}
|
2024-08-16 00:15:26 -04:00
|
|
|
|
2024-08-17 19:10:45 -04:00
|
|
|
void main() {
|
2024-08-15 13:53:52 -04:00
|
|
|
// 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]
|
|
|
|
);
|
2024-08-15 00:56:29 -04:00
|
|
|
|
2024-08-15 13:53:52 -04:00
|
|
|
// 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]
|
|
|
|
);
|
|
|
|
|
2024-08-16 00:15:26 -04:00
|
|
|
position.z += texture(heightTexture, texCoord).r * displacementScale;
|
2024-08-15 13:53:52 -04:00
|
|
|
|
2024-08-17 19:10:45 -04:00
|
|
|
te_out.position = (M*vec4(position, 1.0f)).xyz; // Position in world-space
|
2024-08-16 00:15:26 -04:00
|
|
|
te_out.texCoord = texCoord;
|
2024-08-17 19:10:45 -04:00
|
|
|
te_out.normal = calculateSmoothNormal(position, texCoord);
|
|
|
|
gl_Position = PV*M*vec4(position, 1.0f); // Position in screen-space
|
2024-08-16 00:15:26 -04:00
|
|
|
}
|