71 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			GLSL
		
	
	
	
			
		
		
	
	
			71 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			GLSL
		
	
	
	
#version 450 core
 | 
						|
 | 
						|
layout(quads, fractional_even_spacing, cw) in;
 | 
						|
 | 
						|
layout(binding = 0) uniform sampler2D heightTexture;
 | 
						|
 | 
						|
layout(std140, binding = 4) uniform GeoUniforms
 | 
						|
{
 | 
						|
    mat4 PV;
 | 
						|
    mat4 M;
 | 
						|
    
 | 
						|
    float minTessellation;
 | 
						|
    float maxTessellation;
 | 
						|
    float displacementScale;
 | 
						|
    int gridDensity;
 | 
						|
};
 | 
						|
 | 
						|
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 * displacementScale;
 | 
						|
}
 | 
						|
 | 
						|
vec3 calculateSmoothNormal(vec3 pos, vec2 coord) {
 | 
						|
    // Currently hardcoded to match patch density
 | 
						|
    float step = 1.0f / (float(gridDensity) * maxTessellation + 1.0f);
 | 
						|
 | 
						|
    // Find surrounding heights
 | 
						|
    float hLeft = getHeight(coord + vec2(-step, 0.0f));
 | 
						|
    float hRight = getHeight(coord + vec2(step, 0.0f));
 | 
						|
    float hUp = getHeight(coord + vec2(0.0f, step));
 | 
						|
    float hDown = getHeight(coord + vec2(0.0f, -step));
 | 
						|
    
 | 
						|
    // Calculate tangents
 | 
						|
    vec3 tangentX = normalize(vec3(step, hRight - hLeft, 0.0));
 | 
						|
    vec3 tangentY = normalize(vec3(0.0, hUp - hDown, step));
 | 
						|
 | 
						|
    return normalize(cross(tangentY, tangentX));
 | 
						|
}
 | 
						|
 | 
						|
void main() {
 | 
						|
    // 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;
 | 
						|
 | 
						|
    te_out.position = (M*vec4(position, 1.0f)).xyz; // Position in world-space
 | 
						|
    te_out.texCoord = texCoord;
 | 
						|
    te_out.normal   = calculateSmoothNormal(position, texCoord);  
 | 
						|
    gl_Position = PV*M*vec4(position, 1.0f);        // Position in screen-space
 | 
						|
} |