From 2f4de89791ec23a1857bb83c67fd78cb3314aa2b Mon Sep 17 00:00:00 2001 From: Jack Christensen Date: Sat, 17 Aug 2024 19:08:11 -0400 Subject: [PATCH] Add position output for deferred rendering --- include/fbo.h | 2 + shaders/fragment.glsl | 95 ++++++-------------------------------- shaders/quad_fragment.glsl | 7 ++- source/fbo.cpp | 16 ++++++- source/scene.cpp | 8 +++- 5 files changed, 42 insertions(+), 86 deletions(-) diff --git a/include/fbo.h b/include/fbo.h index e7927d4..c17c90d 100644 --- a/include/fbo.h +++ b/include/fbo.h @@ -10,6 +10,7 @@ class FBO { GLuint fbo_id_; GLuint color_texture_id_; + GLuint position_texture_id_; GLuint depth_rbo_id_; void Init(int width, int height); @@ -17,6 +18,7 @@ class FBO { void Unbind(); void Cleanup(); GLuint GetColorTexture() const; + GLuint GetPositionTexture() const; }; #endif // FBO_H_ \ No newline at end of file diff --git a/shaders/fragment.glsl b/shaders/fragment.glsl index d85431a..1085b9f 100644 --- a/shaders/fragment.glsl +++ b/shaders/fragment.glsl @@ -14,18 +14,19 @@ layout(std140, binding = 0) uniform SceneUniforms vec4 eye_w; //world-space eye position }; -out vec4 FragColor; +layout(location = 0) out vec4 FragColor; +layout(location = 1) out vec4 FragPosition; float getHeight(vec2 uv) { - return texture(heightTexture, uv).r * 0.05f; + return texture(heightTexture, uv).r * 0.025f; } -vec3 calculateNormals() { +vec3 calculateNormalsFromHeightTexture() { // 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 eps = 1.0f / textureSize(heightTexture, 0).x; 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)); @@ -52,7 +53,6 @@ vec3 calculateNormals() { void main() { //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); @@ -61,10 +61,11 @@ void main() { 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); + //vec3 norm = normalize(normal); + vec3 norm = calculateNormalsFromHeightTexture(); + vec3 lightDir = normalize(vec3(1.0f, 1.0f, -1.0f) - fs_in.position); float diff = max(dot(norm, lightDir), 0.0); - vec3 diffuse = diff * objectColor; + vec3 diffuse = diff * vec3(texture(heightTexture, fs_in.texCoord).r); // Specular (Phong) vec3 viewDir = normalize(eye_w.xyz - fs_in.position); @@ -74,77 +75,9 @@ void main() { // Combine results vec3 result = ambient + diffuse; - FragColor = vec4(result, 1.0); - + FragColor = vec4(fs_in.normal, 1.0); + FragPosition = vec4(fs_in.position, 1.0); + + //FragColor = vec4(vec3(texture(heightTexture, fs_in.texCoord).r), 1.0); //FragColor = vec4((fs_in.position * 0.5 + 0.5), 1.0); -} - - - - - -// layout(binding = 0) uniform sampler2D heightTexture; -// layout(location = 1) uniform float time; - -// layout(std140, binding = 0) uniform SceneUniforms -// { -// mat4 PV; //camera projection * view matrix -// vec4 eye_w; //world-space eye position -// }; - -// layout(std140, binding = 1) uniform LightUniforms -// { -// vec4 La; //ambient light color -// vec4 Ld; //diffuse light color -// vec4 Ls; //specular light color -// vec4 light_w; //world-space light position -// }; - -// layout(std140, binding = 2) uniform MaterialUniforms -// { -// vec4 ka; //ambient material color -// vec4 kd; //diffuse material color -// vec4 ks; //specular material color -// float shininess; //specular exponent -// }; - -// in vec3 frag_position; - -// in VertexData { -// vec2 tex_coord; -// } inData; - -// out vec4 frag_color; //the output color for this fragment - -// void main(void) -// { -// //Compute per-fragment Phong lighting -// // vec4 ktex = vec4(vec3(texture(heightTexture, inData.tex_coord).r, 1.0); - -// // vec4 ambient_term = ka*ktex*La; - -// // const float eps = 1e-8; //small value to avoid division by 0 -// // float d = distance(light_w.xyz, inData.pw.xyz); -// // float atten = 1.0/(d*d+eps); //d-squared attenuation - -// // vec3 nw = normalize(inData.nw); //world-space unit normal vector -// // vec3 lw = normalize(light_w.xyz - inData.pw.xyz); //world-space unit light vector -// // vec4 diffuse_term = atten*kd*ktex*Ld*max(0.0, dot(nw, lw)); - -// // vec3 vw = normalize(eye_w.xyz - inData.pw.xyz); //world-space unit view vector -// // vec3 rw = reflect(-lw, nw); //world-space unit reflection vector - -// // vec4 specular_term = atten*ks*Ls*pow(max(0.0, dot(rw, vw)), shininess); - -// // frag_color = ambient_term + diffuse_term + specular_term; - - -// float height = texture(heightTexture, inData.tex_coord).r; - -// //frag_color = vec4(inData.tex_coord, 0.0f, 1.0f); - -// // if (height > 0.8) frag_color = vec4(vec3(1.0f-height), 1.0f); -// // else frag_color = vec4(vec3(height), 1.0f); -// frag_color = vec4(height, height, height, 1.0); -// } - +} \ No newline at end of file diff --git a/shaders/quad_fragment.glsl b/shaders/quad_fragment.glsl index 58d6f30..efa02cc 100644 --- a/shaders/quad_fragment.glsl +++ b/shaders/quad_fragment.glsl @@ -5,13 +5,16 @@ out vec4 frag_color; in vec2 tex_coords; -uniform sampler2D screen_texture; +uniform sampler2D colorTexture; +uniform sampler2D positionTexture; void main() { - vec3 hdr_color = texture(screen_texture, tex_coords).rgb; + vec3 hdr_color = texture(colorTexture, tex_coords).rgb; vec3 tone_mapped_color = hdr_color / (hdr_color + vec3(1.0)); tone_mapped_color = pow(tone_mapped_color, vec3(1.0/2.2)); + vec3 position = texture(positionTexture, tex_coords).rgb; + frag_color = vec4(tone_mapped_color, 1.0); } diff --git a/source/fbo.cpp b/source/fbo.cpp index 6062b67..311f9ed 100644 --- a/source/fbo.cpp +++ b/source/fbo.cpp @@ -4,7 +4,7 @@ #include "fbo.h" -FBO::FBO() : fbo_id_(-1), color_texture_id_(-1), depth_rbo_id_(-1) {} +FBO::FBO() : fbo_id_(-1), color_texture_id_(-1), position_texture_id_(-1), depth_rbo_id_(-1) {} FBO::~FBO() { Cleanup(); @@ -25,6 +25,20 @@ void FBO::Init(int width, int height) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color_texture_id_, 0); + // Generate the position texture + glGenTextures(1, &position_texture_id_); + glBindTexture(GL_TEXTURE_2D, position_texture_id_); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, width, height, 0, GL_RGBA, GL_FLOAT, nullptr); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, position_texture_id_, 0); + + GLenum drawBuffers[2] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1}; + glDrawBuffers(2, drawBuffers); + + // RBO was causing issues. Not using for now // Generate the Depth renderbuffer glGenRenderbuffers(1, &depth_rbo_id_); glBindRenderbuffer(GL_RENDERBUFFER, depth_rbo_id_); diff --git a/source/scene.cpp b/source/scene.cpp index 93ce056..6d88149 100644 --- a/source/scene.cpp +++ b/source/scene.cpp @@ -242,9 +242,13 @@ void Scene::Display(GLFWwindow* window) { glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, fbo_.GetColorTexture()); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, fbo_.GetPositionTexture()); - GLint screenTextureLoc = glGetUniformLocation(quad_shader_program_, "screenTexture"); - glUniform1i(screenTextureLoc, 0); // Texture unit 0 + GLint colorTextureLoc = glGetUniformLocation(quad_shader_program_, "colorTexture"); + glUniform1i(colorTextureLoc, 0); // Texture unit 0 + GLint positionTextureLoc = glGetUniformLocation(quad_shader_program_, "positionTexture"); + glUniform1i(positionTextureLoc, 1); // Render the full-screen quad glBindVertexArray(quad_vao_);