Correctly calculate normals with dynamic tessellation

This commit is contained in:
Jack 2024-08-28 23:07:40 -04:00
parent 85533814e1
commit b3aac984a7
2 changed files with 19 additions and 9 deletions

View File

@ -24,6 +24,7 @@ in VS_OUT {
out TC_OUT { out TC_OUT {
vec3 position; vec3 position;
vec2 texCoord; vec2 texCoord;
float tessLevel;
} tc_out[]; } tc_out[];
float getHeight(vec2 uv) { float getHeight(vec2 uv) {
@ -39,8 +40,8 @@ float calculateSlope() {
float hUp = getHeight(tc_in[gl_InvocationID].texCoord + vec2(0.0f, step)); float hUp = getHeight(tc_in[gl_InvocationID].texCoord + vec2(0.0f, step));
float hDown = getHeight(tc_in[gl_InvocationID].texCoord + vec2(0.0f, -step)); float hDown = getHeight(tc_in[gl_InvocationID].texCoord + vec2(0.0f, -step));
float slopeX = abs(hLeft - hRight); float slopeX = abs(hLeft - hRight) * displacementScale;
float slopeY = abs(hUp - hDown); float slopeY = abs(hUp - hDown) * displacementScale;
float maxSlope = max(slopeX, slopeY); float maxSlope = max(slopeX, slopeY);
@ -54,6 +55,8 @@ void main() {
float slope = calculateSlope(); float slope = calculateSlope();
float tessLevel = tessellationFactor * (1.0f + slope * 10.0f); float tessLevel = tessellationFactor * (1.0f + slope * 10.0f);
tessLevel = max(tessLevel, maxTessellation);
tc_out[gl_InvocationID].tessLevel = tessLevel;
// Set tessellation levels // Set tessellation levels
if (gl_InvocationID == 0) { if (gl_InvocationID == 0) {

View File

@ -18,6 +18,7 @@ layout(std140, binding = 4) uniform GeoUniforms
in TC_OUT { in TC_OUT {
vec3 position; vec3 position;
vec2 texCoord; vec2 texCoord;
float tessLevel;
} te_in[]; } te_in[];
out TE_OUT { out TE_OUT {
@ -30,19 +31,25 @@ float getHeight(vec2 uv) {
return texture(heightTexture, uv).r * displacementScale; return texture(heightTexture, uv).r * displacementScale;
} }
float getNeighbor(float tessFactor) {
return (float(gridDensity) * tessFactor + 1.0f);
}
vec3 calculateSmoothNormal(vec3 pos, vec2 coord) { vec3 calculateSmoothNormal(vec3 pos, vec2 coord) {
// Currently hardcoded to match patch density // Currently hardcoded to match patch density
float step = 1.0f / (float(gridDensity) * maxTessellation + 1.0f); //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]);
// Find surrounding heights // Find surrounding heights
float hLeft = getHeight(coord + vec2(-step, 0.0f)); float hLeft = getHeight(coord + vec2(-stepU, 0.0f));
float hRight = getHeight(coord + vec2(step, 0.0f)); float hRight = getHeight(coord + vec2(stepU, 0.0f));
float hUp = getHeight(coord + vec2(0.0f, step)); float hUp = getHeight(coord + vec2(0.0f, stepV));
float hDown = getHeight(coord + vec2(0.0f, -step)); float hDown = getHeight(coord + vec2(0.0f, -stepV));
// Calculate tangents // Calculate tangents
vec3 tangentX = normalize(vec3(step, hRight - hLeft, 0.0)); vec3 tangentX = normalize(vec3(stepU, hRight - hLeft, 0.0));
vec3 tangentY = normalize(vec3(0.0, hUp - hDown, step)); vec3 tangentY = normalize(vec3(0.0, hUp - hDown, stepV));
return normalize(cross(tangentY, tangentX)); return normalize(cross(tangentY, tangentX));
} }