Displacement working with normals
This commit is contained in:
parent
05ecd9b4be
commit
5212d5aa19
|
@ -1,10 +1,82 @@
|
||||||
#version 450 core
|
#version 450 core
|
||||||
|
|
||||||
in vec3 fragPosition;
|
layout(binding = 0) uniform sampler2D heightTexture;
|
||||||
|
|
||||||
|
in TE_OUT {
|
||||||
|
vec3 position;
|
||||||
|
vec2 texCoord;
|
||||||
|
vec3 normal;
|
||||||
|
} fs_in;
|
||||||
|
|
||||||
|
layout(std140, binding = 0) uniform SceneUniforms
|
||||||
|
{
|
||||||
|
mat4 PV; //camera projection * view matrix
|
||||||
|
vec4 eye_w; //world-space eye position
|
||||||
|
};
|
||||||
|
|
||||||
out vec4 FragColor;
|
out vec4 FragColor;
|
||||||
|
|
||||||
|
float getHeight(vec2 uv) {
|
||||||
|
return texture(heightTexture, uv).r * 0.05f;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 calculateNormals() {
|
||||||
|
// Calculate height at base_uv
|
||||||
|
float height = getHeight(fs_in.texCoord);
|
||||||
|
|
||||||
|
// Calculate normals using height differences around the fragment
|
||||||
|
float eps = 64.0f / 3601.0f;
|
||||||
|
float hRight = getHeight(fs_in.texCoord + vec2(eps, 0.0));
|
||||||
|
float hLeft = getHeight(fs_in.texCoord - vec2(eps, 0.0));
|
||||||
|
float hUp = getHeight(fs_in.texCoord + vec2(0.0, eps));
|
||||||
|
float hDown = getHeight(fs_in.texCoord - vec2(0.0, eps));
|
||||||
|
|
||||||
|
float heightTL = getHeight(fs_in.texCoord + vec2(-eps, eps));
|
||||||
|
float heightT = getHeight(fs_in.texCoord + vec2( 0.0, eps));
|
||||||
|
float heightTR = getHeight(fs_in.texCoord + vec2( eps, eps));
|
||||||
|
float heightL = getHeight(fs_in.texCoord + vec2(-eps, 0.0));
|
||||||
|
float heightR = getHeight(fs_in.texCoord + vec2( eps, 0.0));
|
||||||
|
float heightBL = getHeight(fs_in.texCoord + vec2(-eps, -eps));
|
||||||
|
float heightB = getHeight(fs_in.texCoord + vec2( 0.0, -eps));
|
||||||
|
float heightBR = getHeight(fs_in.texCoord + vec2( eps, -eps));
|
||||||
|
|
||||||
|
float sobelX = (heightTL + 2.0 * heightL + heightBL) - (heightTR + 2.0 * heightR + heightBR);
|
||||||
|
float sobelZ = (heightTL + 2.0 * heightT + heightTR) - (heightBL + 2.0 * heightB + heightBR);
|
||||||
|
|
||||||
|
vec3 tangentX = normalize(vec3(eps, 0.0, sobelX));
|
||||||
|
vec3 tangentZ = normalize(vec3(0.0, sobelZ, eps));
|
||||||
|
|
||||||
|
// Final normal for the fragment
|
||||||
|
return normalize(cross(tangentZ, tangentX));
|
||||||
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
FragColor = vec4(fragPosition * 0.5f + 0.5f, 1.0f);
|
//FragColor = vec4(fragNormal, 1.0f);
|
||||||
|
vec3 normal = calculateNormals();
|
||||||
|
float shininess = 1.0f;
|
||||||
|
vec3 lightColor = vec3(0.5f);
|
||||||
|
vec3 objectColor = vec3(texture(heightTexture, fs_in.texCoord).r);
|
||||||
|
|
||||||
|
// Ambient
|
||||||
|
vec3 ambient = vec3(0.15f) * vec3(0.15f);
|
||||||
|
|
||||||
|
// Diffuse
|
||||||
|
vec3 norm = normalize(normal);
|
||||||
|
vec3 lightDir = normalize(vec3(1.0f, 1.0f, 0.0f) - fs_in.position);
|
||||||
|
float diff = max(dot(norm, lightDir), 0.0);
|
||||||
|
vec3 diffuse = diff * objectColor;
|
||||||
|
|
||||||
|
// Specular (Phong)
|
||||||
|
vec3 viewDir = normalize(eye_w.xyz - fs_in.position);
|
||||||
|
vec3 reflectDir = reflect(-lightDir, norm);
|
||||||
|
float spec = pow(max(dot(viewDir, reflectDir), 0.0), shininess);
|
||||||
|
vec3 specular = spec * lightColor;
|
||||||
|
|
||||||
|
// Combine results
|
||||||
|
vec3 result = ambient + diffuse;
|
||||||
|
FragColor = vec4(result, 1.0);
|
||||||
|
|
||||||
|
//FragColor = vec4((fs_in.position * 0.5 + 0.5), 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ out TC_OUT {
|
||||||
vec2 texCoord;
|
vec2 texCoord;
|
||||||
} tc_out[];
|
} tc_out[];
|
||||||
|
|
||||||
uniform float tessellationFactor = 8.0f;
|
uniform float tessellationFactor = 64.0f;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
// Pass through position and texture coordinates to the tessellation evaluation shader
|
// Pass through position and texture coordinates to the tessellation evaluation shader
|
||||||
|
|
|
@ -2,25 +2,56 @@
|
||||||
|
|
||||||
layout(quads, fractional_even_spacing, cw) in;
|
layout(quads, fractional_even_spacing, cw) in;
|
||||||
|
|
||||||
in TC_OUT {
|
layout(binding = 0) uniform sampler2D heightTexture;
|
||||||
vec3 position;
|
|
||||||
vec2 texCoord;
|
|
||||||
} te_in[];
|
|
||||||
|
|
||||||
layout(location = 0) uniform mat4 M;
|
layout(location = 0) uniform mat4 M;
|
||||||
|
|
||||||
|
uniform float displacementScale = 0.05;
|
||||||
|
|
||||||
layout(std140, binding = 0) uniform SceneUniforms
|
layout(std140, binding = 0) uniform SceneUniforms
|
||||||
{
|
{
|
||||||
mat4 PV; //camera projection * view matrix
|
mat4 PV; //camera projection * view matrix
|
||||||
vec4 eye_w; //world-space eye position
|
vec4 eye_w; //world-space eye position
|
||||||
};
|
};
|
||||||
|
|
||||||
out vec3 fragPosition;
|
in TC_OUT {
|
||||||
|
vec3 position;
|
||||||
|
vec2 texCoord;
|
||||||
|
} te_in[];
|
||||||
|
|
||||||
layout(binding = 0) uniform sampler2D heightTexture;
|
out TE_OUT {
|
||||||
uniform float displacementScale = 0.1;
|
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() {
|
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
|
// Interpolate texture coordinates
|
||||||
vec2 texCoord = mix(
|
vec2 texCoord = mix(
|
||||||
mix(te_in[0].texCoord, te_in[1].texCoord, gl_TessCoord[0]),
|
mix(te_in[0].texCoord, te_in[1].texCoord, gl_TessCoord[0]),
|
||||||
|
@ -35,102 +66,26 @@ void main() {
|
||||||
gl_TessCoord[1]
|
gl_TessCoord[1]
|
||||||
);
|
);
|
||||||
|
|
||||||
fragPosition = (PV*M*vec4(position, 1.0)).xyz;
|
position.z += texture(heightTexture, texCoord).r * displacementScale;
|
||||||
gl_Position = PV*M*vec4(position, 1.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// // 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;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// layout(quads, equal_spacing, ccw) in; // Define the type of patch (e.g., quads)
|
|
||||||
// in vec2 tcs_uv[];
|
|
||||||
|
|
||||||
// layout(binding = 0) uniform sampler2D heightTexture;
|
|
||||||
|
|
||||||
// layout(location = 0) uniform mat4 M;
|
|
||||||
|
|
||||||
// layout(std140, binding = 0) uniform SceneUniforms
|
|
||||||
// {
|
|
||||||
// mat4 PV; //camera projection * view matrix
|
|
||||||
// vec4 eye_w; //world-space eye position
|
|
||||||
// };
|
|
||||||
|
|
||||||
// in VertexData {
|
|
||||||
// vec2 tex_coord;
|
|
||||||
// } inData[];
|
|
||||||
|
|
||||||
// out vec3 frag_position; // Ensure this matches the input in fragment.glsl
|
|
||||||
|
|
||||||
// out VertexData {
|
|
||||||
// vec2 tex_coord;
|
|
||||||
// } outData;
|
|
||||||
|
|
||||||
// float getHeight(vec2 uv) {
|
|
||||||
// return texture(heightTexture, uv).r;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// void main()
|
|
||||||
// {
|
|
||||||
// const float u = gl_TessCoord[0];
|
|
||||||
// const float v = gl_TessCoord[1];
|
|
||||||
|
|
||||||
// vec2 tess_coord = gl_TessCoord.xy;
|
|
||||||
// vec2 base_uv = mix(tcs_uv[0], tcs_uv[1], tess_coord.x);
|
|
||||||
// base_uv = mix(base_uv, mix(tcs_uv[3], tcs_uv[2], tess_coord.x), tess_coord.y);
|
|
||||||
// vec4 htex = texture(heightTexture, base_uv);
|
|
||||||
|
|
||||||
// const vec4 p0 = PV*M*gl_in[0].gl_Position;
|
|
||||||
// const vec4 p1 = PV*M*gl_in[1].gl_Position;
|
|
||||||
// const vec4 p2 = PV*M*gl_in[2].gl_Position;
|
|
||||||
// const vec4 p3 = PV*M*gl_in[3].gl_Position;
|
|
||||||
|
|
||||||
// vec4 a = mix(p0, p1, u);
|
|
||||||
// vec4 b = mix(p3, p2, u);
|
|
||||||
// vec4 c = mix(a, b, v);
|
|
||||||
|
|
||||||
// c.y = htex.r * 0.5f;
|
|
||||||
|
|
||||||
// float eps = 0.0002;
|
|
||||||
// float hCenter = getHeight(base_uv);
|
|
||||||
// float hRight = getHeight(base_uv + vec2(eps, 0.0));
|
|
||||||
// float hLeft = getHeight(base_uv - vec2(eps, 0.0));
|
|
||||||
// float hUp = getHeight(base_uv + vec2(0.0, eps));
|
|
||||||
// float hDown = getHeight(base_uv - vec2(0.0, eps));
|
|
||||||
|
|
||||||
// vec3 tangentX = normalize(vec3(0.002, hRight - hLeft, 0.0));
|
|
||||||
// vec3 tangentZ = normalize(vec3(0.0, hUp - hDown, 0.002));
|
|
||||||
|
|
||||||
// vec3 d0 = gl_in[0].gl_Position.xyz;
|
|
||||||
// vec3 d1 = gl_in[1].gl_Position.xyz;
|
|
||||||
// vec3 d2 = gl_in[2].gl_Position.xyz;
|
|
||||||
|
|
||||||
// vec3 n_u = d1 - d0;
|
|
||||||
// vec3 v_u = d2 - d0;
|
|
||||||
// vec3 v_normal = normalize(cross(n_u, v_u));
|
// vec3 v_normal = normalize(cross(n_u, v_u));
|
||||||
|
|
||||||
// vec3 normal = cross(tangentZ, tangentX);
|
// // Calculate normals for the specific triangle being rendered
|
||||||
|
// vec3 normal = calculateFaceNormal(p0, p1, position);
|
||||||
|
// normal += calculateFaceNormal(p1, p2, position);
|
||||||
|
// normal += calculateFaceNormal(p2, p0, position);
|
||||||
|
|
||||||
// gl_Position = c;
|
// normal = (PV*M*vec4(normalize(normal), 1.0f)).xyz;
|
||||||
// outData.tex_coord = base_uv;
|
|
||||||
// // outData.pw = vec3(c);
|
|
||||||
// // outData.nw = normal;
|
|
||||||
|
|
||||||
// // Interpolate the position using the barycentric coordinates from tessellation
|
te_out.position = (PV*M*vec4(position, 1.0f)).xyz;
|
||||||
// // vec3 pos = mix(mix(gl_in[0].gl_Position.xyz, gl_in[1].gl_Position.xyz, gl_TessCoord.x),
|
te_out.texCoord = texCoord;
|
||||||
// // mix(gl_in[3].gl_Position.xyz, gl_in[2].gl_Position.xyz, gl_TessCoord.x),
|
//te_out.normal = (PV*M*vec4(v_normal, 1.0f)).xyz;
|
||||||
// // gl_TessCoord.y);
|
gl_Position = PV*M*vec4(position, 1.0f);
|
||||||
|
}
|
||||||
// // frag_position = pos;
|
|
||||||
|
|
||||||
// // outData.tex_coord = mix(mix(inData[0].tex_coord, inData[1].tex_coord, gl_TessCoord.x),
|
|
||||||
// // mix(inData[3].tex_coord, inData[2].tex_coord, gl_TessCoord.x),
|
|
||||||
// // gl_TessCoord.y);
|
|
||||||
|
|
||||||
// // gl_Position = PV*M*vec4(pos, 1.0);
|
|
||||||
// }
|
|
|
@ -53,7 +53,7 @@ Scene::Scene(int width, int height)
|
||||||
aspect_(static_cast<float>(width) / static_cast<float>(height)),
|
aspect_(static_cast<float>(width) / static_cast<float>(height)),
|
||||||
near_z_(0.01f),
|
near_z_(0.01f),
|
||||||
far_z_(100.0f),
|
far_z_(100.0f),
|
||||||
fov_(glm::pi<float>() / 4.0f)
|
fov_(glm::pi<float>() / 6.0f)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
Scene::~Scene() {
|
Scene::~Scene() {
|
||||||
|
@ -99,12 +99,6 @@ void Scene::InitBuffers() {
|
||||||
-0.5f, 0.5f, 0.0f, 0.0f, 1.0f // Top-left
|
-0.5f, 0.5f, 0.0f, 0.0f, 1.0f // Top-left
|
||||||
};
|
};
|
||||||
|
|
||||||
float vertices[] = {
|
|
||||||
-0.5f, -0.5f, 0.0f,
|
|
||||||
0.5f, -0.5f, 0.0f,
|
|
||||||
0.0f, 0.5f, 0.0f
|
|
||||||
};
|
|
||||||
|
|
||||||
glGenVertexArrays(1, &vao_);
|
glGenVertexArrays(1, &vao_);
|
||||||
glGenBuffers(1, &patch_vbo);
|
glGenBuffers(1, &patch_vbo);
|
||||||
glBindVertexArray(vao_);
|
glBindVertexArray(vao_);
|
||||||
|
|
Loading…
Reference in New Issue