From adec05f6f87678fff63c9153d6325cfd92b0a4cf Mon Sep 17 00:00:00 2001 From: Natalia Nowakowska Date: Mon, 22 Jan 2024 12:38:19 +0100 Subject: [PATCH] wip bloom --- grk/cw 6/shaders/shader_FBO.frag | 21 +++ grk/cw 6/shaders/shader_FBO.vert | 12 ++ grk/cw 6/shaders/shader_bloom.frag | 57 ++++++ .../{shader_smap.vert => shader_bloom.vert} | 0 grk/cw 6/shaders/shader_smap.frag | 6 - grk/cw 6/shaders/shader_tex.frag | 9 +- grk/cw 6/shaders/test.frag | 12 -- grk/cw 6/shaders/test.vert | 14 -- grk/cw 6/src/Planet.hpp | 167 ++++++++++-------- 9 files changed, 187 insertions(+), 111 deletions(-) create mode 100644 grk/cw 6/shaders/shader_FBO.frag create mode 100644 grk/cw 6/shaders/shader_FBO.vert create mode 100644 grk/cw 6/shaders/shader_bloom.frag rename grk/cw 6/shaders/{shader_smap.vert => shader_bloom.vert} (100%) delete mode 100644 grk/cw 6/shaders/shader_smap.frag delete mode 100644 grk/cw 6/shaders/test.frag delete mode 100644 grk/cw 6/shaders/test.vert diff --git a/grk/cw 6/shaders/shader_FBO.frag b/grk/cw 6/shaders/shader_FBO.frag new file mode 100644 index 0000000..a5c0dcb --- /dev/null +++ b/grk/cw 6/shaders/shader_FBO.frag @@ -0,0 +1,21 @@ +#version 330 core + +out vec4 FragColor; +in vec2 texCoords; + +uniform sampler2D screenTexture; +uniform sampler2D bloomTexture; +uniform float gamma; + +void main() +{ + vec3 fragment = texture(screenTexture, texCoords).rgb; + vec3 bloom = texture(bloomTexture, texCoords).rgb; + + vec3 color = fragment + bloom; + + float exposure = 0.8f; + vec3 toneMapped = vec3(1.0f) - exp(-color * exposure); + + FragColor.rgb = pow(toneMapped, vec3(1.0f / gamma)); +} \ No newline at end of file diff --git a/grk/cw 6/shaders/shader_FBO.vert b/grk/cw 6/shaders/shader_FBO.vert new file mode 100644 index 0000000..454a01d --- /dev/null +++ b/grk/cw 6/shaders/shader_FBO.vert @@ -0,0 +1,12 @@ +#version 430 core + +layout (location = 0) in vec2 inPos; +layout (location = 1) in vec2 inTexCoords; + +out vec2 texCoords; + +void main() +{ + gl_Position = vec4(inPos.x, inPos.y, 0.0, 1.0); + texCoords = inTexCoords; +} \ No newline at end of file diff --git a/grk/cw 6/shaders/shader_bloom.frag b/grk/cw 6/shaders/shader_bloom.frag new file mode 100644 index 0000000..6cb67d8 --- /dev/null +++ b/grk/cw 6/shaders/shader_bloom.frag @@ -0,0 +1,57 @@ +#version 430 core +out vec4 FragColor; + +in vec2 texCoords; + +uniform sampler2D screenTexture; +uniform bool horizontal; + +// How far from the center to take samples from the fragment you are currently on +const int radius = 6; +// Keep it between 1.0f and 2.0f (the higher this is the further the blur reaches) +float spreadBlur = 2.0f; +float weights[radius]; + +void main() +{ + // Calculate the weights using the Gaussian equation + float x = 0.0f; + for (int i = 0; i < radius; i++) + { + // Decides the distance between each sample on the Gaussian function + if (spreadBlur <= 2.0f) + x += 3.0f / radius; + else + x += 6.0f / radius; + + weights[i] = exp(-0.5f * pow(x / spreadBlur, 2.0f)) / (spreadBlur * sqrt(2 * 3.14159265f)); + } + + + vec2 tex_offset = 1.0f / textureSize(screenTexture, 0); + vec3 result = texture(screenTexture, texCoords).rgb * weights[0]; + + // Calculate horizontal blur + if(horizontal) + { + for(int i = 1; i < radius; i++) + { + // Take into account pixels to the right + result += texture(screenTexture, texCoords + vec2(tex_offset.x * i, 0.0)).rgb * weights[i]; + // Take into account pixels on the left + result += texture(screenTexture, texCoords - vec2(tex_offset.x * i, 0.0)).rgb * weights[i]; + } + } + // Calculate vertical blur + else + { + for(int i = 1; i < radius; i++) + { + // Take into account pixels above + result += texture(screenTexture, texCoords + vec2(0.0, tex_offset.y * i)).rgb * weights[i]; + // Take into account pixels below + result += texture(screenTexture, texCoords - vec2(0.0, tex_offset.y * i)).rgb * weights[i]; + } + } + FragColor = vec4(result, 1.0f); +} \ No newline at end of file diff --git a/grk/cw 6/shaders/shader_smap.vert b/grk/cw 6/shaders/shader_bloom.vert similarity index 100% rename from grk/cw 6/shaders/shader_smap.vert rename to grk/cw 6/shaders/shader_bloom.vert diff --git a/grk/cw 6/shaders/shader_smap.frag b/grk/cw 6/shaders/shader_smap.frag deleted file mode 100644 index c7b231b..0000000 --- a/grk/cw 6/shaders/shader_smap.frag +++ /dev/null @@ -1,6 +0,0 @@ -#version 430 core - -void main() -{ - -} \ No newline at end of file diff --git a/grk/cw 6/shaders/shader_tex.frag b/grk/cw 6/shaders/shader_tex.frag index 22d6d31..0bdf9d5 100644 --- a/grk/cw 6/shaders/shader_tex.frag +++ b/grk/cw 6/shaders/shader_tex.frag @@ -10,7 +10,8 @@ in vec3 vecNormal; in vec3 worldPos; in vec2 vtc; vec4 textureColor; -out vec4 outColor; +layout (location = 0) out vec4 outColor; +layout (location = 1) out vec4 bloomColor; vec3 outputColor; uniform sampler2D colorTexture; @@ -35,4 +36,10 @@ void main() outputColor = toneMapping(outputColor); outColor = vec4(outputColor , 1.0); + + float brightness = dot(outColor.rgb, vec3(0.2126f, 0.7152f, 0.0722f)); + if(brightness > 0.15f) + bloomColor = vec4(outColor.rgb, 1.0f); + else + bloomColor = vec4(0.0f, 0.0f, 0.0f, 1.0f); } \ No newline at end of file diff --git a/grk/cw 6/shaders/test.frag b/grk/cw 6/shaders/test.frag deleted file mode 100644 index 404c2c6..0000000 --- a/grk/cw 6/shaders/test.frag +++ /dev/null @@ -1,12 +0,0 @@ -#version 330 core -out vec4 FragColor; - -in vec2 tc; - -uniform sampler2D depthMap; - -void main() -{ - float depthValue = texture(depthMap, tc).r; - FragColor = vec4(vec3(depthValue+0.5), 1.0); -} \ No newline at end of file diff --git a/grk/cw 6/shaders/test.vert b/grk/cw 6/shaders/test.vert deleted file mode 100644 index f65f59d..0000000 --- a/grk/cw 6/shaders/test.vert +++ /dev/null @@ -1,14 +0,0 @@ -#version 430 core - -layout(location = 0) in vec3 vertexPosition; -layout(location = 1) in vec3 vertexNormal; -layout(location = 2) in vec2 vertexTexCoord; - - -out vec2 tc; - -void main() -{ - tc = vertexTexCoord; - gl_Position = vec4(vertexPosition*0.9, 1.0); -} diff --git a/grk/cw 6/src/Planet.hpp b/grk/cw 6/src/Planet.hpp index a87ba06..a6ef138 100644 --- a/grk/cw 6/src/Planet.hpp +++ b/grk/cw 6/src/Planet.hpp @@ -48,8 +48,9 @@ namespace texture { GLuint program; GLuint programSun; -GLuint programDepth; +GLuint programBlur; GLuint programTex; +GLuint programFramebuffer; Core::Shader_Loader shaderLoader; @@ -65,14 +66,13 @@ GLuint VAO, VBO; float aspectRatio = 1.77f; -unsigned int hdrFBO; +unsigned int hdrFBO, depthMap, depthMapFBO; unsigned int colorBuffers[2]; -unsigned int depthMap; -unsigned int depthMapFBO; +unsigned int blurFBO[2]; +unsigned int blurBuffer[2]; - -int HDR_WIDTH = 1024; -int HDR_HEIGHT = 1024; +float gamma = 2.2f; +int HDR_WIDTH = 1024, HDR_HEIGHT = 1024; glm::vec3 lightColor = glm::vec3(50, 50, 50); @@ -115,7 +115,6 @@ glm::mat4 createCameraMatrix() glm::mat4 createPerspectiveMatrix() { - glm::mat4 perspectiveMatrix; float n = 0.05f; float f = 20.f; @@ -159,24 +158,29 @@ void initHDR() { glBindFramebuffer(GL_FRAMEBUFFER, 0); } -void initDepthMap() { - glGenFramebuffers(1, &depthMapFBO); - glGenTextures(1, &depthMap); - glBindTexture(GL_TEXTURE_2D, depthMap); - glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, - HDR_WIDTH, HDR_HEIGHT, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthMap, 0); - glDrawBuffer(GL_NONE); - glReadBuffer(GL_NONE); +void initBlurFBO() { + + glGenFramebuffers(2, blurFBO); + glGenTextures(2, blurBuffer); + for (unsigned int i = 0; i < 2; i++) + { + glBindFramebuffer(GL_FRAMEBUFFER, blurFBO[i]); + glBindTexture(GL_TEXTURE_2D, blurBuffer[i]); + glTexImage2D( + GL_TEXTURE_2D, 0, GL_RGBA16F, HDR_WIDTH, HDR_HEIGHT, 0, GL_RGBA, GL_FLOAT, NULL + ); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glFramebufferTexture2D( + GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, blurBuffer[i], 0); + } glBindFramebuffer(GL_FRAMEBUFFER, 0); } + void drawObjectTexture(Core::RenderContext& context, glm::mat4 modelMatrix, GLuint texture) { glUseProgram(programTex); Core::SetActiveTexture(texture, "colorTexture", programTex, 0); @@ -186,7 +190,18 @@ void drawObjectTexture(Core::RenderContext& context, glm::mat4 modelMatrix, GLui glUniformMatrix4fv(glGetUniformLocation(programTex, "modelMatrix"), 1, GL_FALSE, (float*)&modelMatrix); glUniform3f(glGetUniformLocation(programTex, "lightPos"), sunPosition.x, sunPosition.y, sunPosition.z); glUniform3f(glGetUniformLocation(programTex, "lightColor"), lightColor.x, lightColor.y, lightColor.z); + + /* glUseProgram(programFramebuffer); + glUniform1i(glGetUniformLocation(programFramebuffer, "screenTexture"), 0); + glUniform1i(glGetUniformLocation(programFramebuffer, "bloomTexture"), 1); + glUniform1f(glGetUniformLocation(programFramebuffer, "gamma"), gamma); + + glUseProgram(programBlur); + glUniform1i(glGetUniformLocation(programBlur, "screenTexture"), 0); + */ + Core::DrawContext(context); + glUseProgram(0); } @@ -201,6 +216,43 @@ void drawSun(Core::RenderContext& context, glm::mat4 modelMatrix, GLuint texture Core::DrawContext(context); glUseProgram(0); } + +void drawObjectBloom(Core::RenderContext& context, glm::mat4 modelMatrix, GLuint texture, int amount, bool horizontal, bool first_iteration) { + glUseProgram(programBlur); + Core::SetActiveTexture(texture, "colorTexture", programTex, 0); + glm::mat4 viewProjectionMatrix = createPerspectiveMatrix() * createCameraMatrix(); + glm::mat4 transformation = viewProjectionMatrix * modelMatrix; + + glUniformMatrix4fv(glGetUniformLocation(programBlur, "transformation"), 1, GL_FALSE, (float*)&transformation); + glUniformMatrix4fv(glGetUniformLocation(programBlur, "modelMatrix"), 1, GL_FALSE, (float*)&modelMatrix); + + for (unsigned int i = 0; i < amount; i++) + { + glBindFramebuffer(GL_FRAMEBUFFER, blurFBO[horizontal]); + glUniform1i(glGetUniformLocation(programBlur, "horizontal"), horizontal); + + // In the first bounc we want to get the data from the bloomTexture + if (first_iteration) + { + glBindTexture(GL_TEXTURE_2D, colorBuffers[1]); + first_iteration = false; + } + // Move the data between the pingPong textures + else + { + glBindTexture(GL_TEXTURE_2D, blurBuffer[!horizontal]); + } + + // Render the image + + Core::DrawContext(context); + + // Switch between vertical and horizontal blurring + horizontal = !horizontal; + } + glUseProgram(0); +} + /* void drawObjectColor(Core::RenderContext& context, glm::mat4 modelMatrix, glm::vec3 color) { glUseProgram(program); @@ -247,62 +299,13 @@ void drawObjectPBR(Core::RenderContext& context, glm::mat4 modelMatrix, glm::vec void renderScene(GLFWwindow* window) { + //glBindFramebuffer(GL_FRAMEBUFFER, hdrFBO); glClearColor(0.0f, 0.0f, 0.15f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glm::mat4 transformation; + glEnable(GL_DEPTH_TEST); float time = glfwGetTime(); - /* - glm::mat4 mercuryScale = glm::scale(glm::vec3(0.24)); - glm::mat4 mercuryRotate = glm::rotate(time * 0.24f, glm::vec3(0, 1, 0)); - glm::mat4 mercuryTranslate = glm::translate(glm::vec3(0, 0, -3)); - - glm::mat4 venusScale = glm::scale(glm::vec3(0.55)); - glm::mat4 venusRotate = glm::rotate(time * 0.61f, glm::vec3(0, 1, 0)); - glm::mat4 venusTranslate = glm::translate(glm::vec3(0, 0, -5)); - - glm::mat4 earthScale = glm::scale(glm::vec3(0.6)); - glm::mat4 earthRotate = glm::rotate(time, glm::vec3(0, 1, 0)); - glm::mat4 earthTranslate = glm::translate(glm::vec3(0, 0, -7)); - - glm::mat4 moonScale = glm::scale(glm::vec3(0.2)); - glm::mat4 moonRotate = glm::rotate(time, glm::vec3(0, 1, 0)); - glm::mat4 moonTranslate = glm::translate(glm::vec3(0, 0, -2)); - - glm::mat4 marsScale = glm::scale(glm::vec3(0.3)); - glm::mat4 marsRotate = glm::rotate(time * 1.8f, glm::vec3(0, 1, 0)); - glm::mat4 marsTranslate = glm::translate(glm::vec3(0, 0, -9)); - - //glm::mat4 shipScale = glm::scale(glm::vec3(0.3)); - //glm::mat4 shipRotate = createShipMatrix(); - //glm::mat4 shipTranslate = glm::translate(shipPos); - - //glUseProgram(program); - //glUniform3f(glGetUniformLocation(program, "lightDir"), 1.0, -1.0, 0.0); - //glUniform3f(glGetUniformLocation(program, "lightColor"), lightColor.x, lightColor.y, lightColor.z); - //glUniform3f(glGetUniformLocation(program, "cameraPos"), cameraPos.x, cameraPos.y, cameraPos.z); - //glUniform3f(glGetUniformLocation(program, "lightPos"), 0.0, 0.0, 0.0); - //glUseProgram(0); - - - drawObjectColor(sphereContext, sunScale, glm::vec3(0.9, 0.9, 0.2)); //sun - - drawObjectTexture(sphereContext, mercuryRotate * mercuryTranslate * mercuryScale, texture::mercury); //mercury - - drawObjectTexture(sphereContext, venusRotate * venusTranslate * venusScale, texture::venus); //venus - - drawObjectTexture(sphereContext, earthRotate * earthTranslate * earthScale, texture::earth); //earth - - drawObjectTexture(sphereContext, earthRotate * earthTranslate * earthScale * moonRotate * moonTranslate * moonScale, texture::moon); //moon - - drawObjectTexture(sphereContext, marsRotate * marsTranslate * marsScale, texture::mars); //mars - - drawObjectTexture(shipContext, shipTranslate * shipRotate * shipScale, texture::ship); //ship - */ - - //glUseProgram(programTex); - //glUniform3f(glGetUniformLocation(programTex, "lightDir"), cameraDir.x, cameraDir.y, cameraDir.z); - //glUseProgram(0); + glUseProgram(programTex); glm::mat4 sunScale = glm::scale(glm::vec3(0.04f)); glm::mat4 sunTranslate = glm::translate(sunPosition); @@ -314,7 +317,13 @@ void renderScene(GLFWwindow* window) glm::mat4 planetTranslate = glm::translate(glm::vec3(0, 0, 0)); // zostaje na domyślnej pozycji drawObjectTexture(sphereContext, planetTranslate * planetRotate * planetScale, texture::earth); - + /* + glBindFramebuffer(hdrFBO, 0); + glUseProgram(programBlur); + drawObjectBloom(sphereContext, planetTranslate * planetRotate * planetScale, texture::earth, 2, true, true); + */ + + glfwSwapBuffers(window); } @@ -343,10 +352,11 @@ void init(GLFWwindow* window) glEnable(GL_DEPTH_TEST); - //initDepthMap(); initHDR(); + initBlurFBO(); - programDepth = shaderLoader.CreateProgram("shaders/shader_smap.vert", "shaders/shader_smap.frag"); + programBlur = shaderLoader.CreateProgram("shaders/shader_FBO.vert", "shaders/shader_bloom.frag"); + programFramebuffer = shaderLoader.CreateProgram("shaders/shader_FBO.vert", "shaders/shader_FBO.frag"); program = shaderLoader.CreateProgram("shaders/shader.vert", "shaders/shader.frag"); programTex = shaderLoader.CreateProgram("shaders/shader_tex.vert", "shaders/shader_tex.frag"); programSun = shaderLoader.CreateProgram("shaders/shader_sun.vert", "shaders/shader_sun.frag"); @@ -411,8 +421,9 @@ void renderLoop(GLFWwindow* window) { while (!glfwWindowShouldClose(window)) { - /*glfwPollEvents(); + glfwPollEvents(); + /* // Start the Dear ImGui frame ImGui_ImplOpenGL3_NewFrame(); ImGui_ImplGlfw_NewFrame();