wip bloom

This commit is contained in:
Natalia Nowakowska 2024-01-22 12:38:19 +01:00
parent 5050374c1f
commit adec05f6f8
9 changed files with 187 additions and 111 deletions

View File

@ -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));
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -1,6 +0,0 @@
#version 430 core
void main()
{
}

View File

@ -10,7 +10,8 @@ in vec3 vecNormal;
in vec3 worldPos; in vec3 worldPos;
in vec2 vtc; in vec2 vtc;
vec4 textureColor; vec4 textureColor;
out vec4 outColor; layout (location = 0) out vec4 outColor;
layout (location = 1) out vec4 bloomColor;
vec3 outputColor; vec3 outputColor;
uniform sampler2D colorTexture; uniform sampler2D colorTexture;
@ -35,4 +36,10 @@ void main()
outputColor = toneMapping(outputColor); outputColor = toneMapping(outputColor);
outColor = vec4(outputColor , 1.0); 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);
} }

View File

@ -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);
}

View File

@ -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);
}

View File

@ -48,8 +48,9 @@ namespace texture {
GLuint program; GLuint program;
GLuint programSun; GLuint programSun;
GLuint programDepth; GLuint programBlur;
GLuint programTex; GLuint programTex;
GLuint programFramebuffer;
Core::Shader_Loader shaderLoader; Core::Shader_Loader shaderLoader;
@ -65,14 +66,13 @@ GLuint VAO, VBO;
float aspectRatio = 1.77f; float aspectRatio = 1.77f;
unsigned int hdrFBO; unsigned int hdrFBO, depthMap, depthMapFBO;
unsigned int colorBuffers[2]; unsigned int colorBuffers[2];
unsigned int depthMap; unsigned int blurFBO[2];
unsigned int depthMapFBO; unsigned int blurBuffer[2];
float gamma = 2.2f;
int HDR_WIDTH = 1024; int HDR_WIDTH = 1024, HDR_HEIGHT = 1024;
int HDR_HEIGHT = 1024;
glm::vec3 lightColor = glm::vec3(50, 50, 50); glm::vec3 lightColor = glm::vec3(50, 50, 50);
@ -115,7 +115,6 @@ glm::mat4 createCameraMatrix()
glm::mat4 createPerspectiveMatrix() glm::mat4 createPerspectiveMatrix()
{ {
glm::mat4 perspectiveMatrix; glm::mat4 perspectiveMatrix;
float n = 0.05f; float n = 0.05f;
float f = 20.f; float f = 20.f;
@ -159,24 +158,29 @@ void initHDR() {
glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindFramebuffer(GL_FRAMEBUFFER, 0);
} }
void initDepthMap() { void initBlurFBO() {
glGenFramebuffers(1, &depthMapFBO);
glGenTextures(1, &depthMap); glGenFramebuffers(2, blurFBO);
glBindTexture(GL_TEXTURE_2D, depthMap); glGenTextures(2, blurBuffer);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, for (unsigned int i = 0; i < 2; i++)
HDR_WIDTH, HDR_HEIGHT, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL); {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glBindFramebuffer(GL_FRAMEBUFFER, blurFBO[i]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glBindTexture(GL_TEXTURE_2D, blurBuffer[i]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexImage2D(
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); GL_TEXTURE_2D, 0, GL_RGBA16F, HDR_WIDTH, HDR_HEIGHT, 0, GL_RGBA, GL_FLOAT, NULL
glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO); );
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthMap, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glDrawBuffer(GL_NONE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glReadBuffer(GL_NONE); 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); glBindFramebuffer(GL_FRAMEBUFFER, 0);
} }
void drawObjectTexture(Core::RenderContext& context, glm::mat4 modelMatrix, GLuint texture) { void drawObjectTexture(Core::RenderContext& context, glm::mat4 modelMatrix, GLuint texture) {
glUseProgram(programTex); glUseProgram(programTex);
Core::SetActiveTexture(texture, "colorTexture", programTex, 0); 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); glUniformMatrix4fv(glGetUniformLocation(programTex, "modelMatrix"), 1, GL_FALSE, (float*)&modelMatrix);
glUniform3f(glGetUniformLocation(programTex, "lightPos"), sunPosition.x, sunPosition.y, sunPosition.z); glUniform3f(glGetUniformLocation(programTex, "lightPos"), sunPosition.x, sunPosition.y, sunPosition.z);
glUniform3f(glGetUniformLocation(programTex, "lightColor"), lightColor.x, lightColor.y, lightColor.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); Core::DrawContext(context);
glUseProgram(0); glUseProgram(0);
} }
@ -201,6 +216,43 @@ void drawSun(Core::RenderContext& context, glm::mat4 modelMatrix, GLuint texture
Core::DrawContext(context); Core::DrawContext(context);
glUseProgram(0); 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) { void drawObjectColor(Core::RenderContext& context, glm::mat4 modelMatrix, glm::vec3 color) {
glUseProgram(program); glUseProgram(program);
@ -247,62 +299,13 @@ void drawObjectPBR(Core::RenderContext& context, glm::mat4 modelMatrix, glm::vec
void renderScene(GLFWwindow* window) void renderScene(GLFWwindow* window)
{ {
//glBindFramebuffer(GL_FRAMEBUFFER, hdrFBO);
glClearColor(0.0f, 0.0f, 0.15f, 1.0f); glClearColor(0.0f, 0.0f, 0.15f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glm::mat4 transformation; glEnable(GL_DEPTH_TEST);
float time = glfwGetTime(); float time = glfwGetTime();
/* glUseProgram(programTex);
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);
glm::mat4 sunScale = glm::scale(glm::vec3(0.04f)); glm::mat4 sunScale = glm::scale(glm::vec3(0.04f));
glm::mat4 sunTranslate = glm::translate(sunPosition); 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 glm::mat4 planetTranslate = glm::translate(glm::vec3(0, 0, 0)); // zostaje na domyślnej pozycji
drawObjectTexture(sphereContext, planetTranslate * planetRotate * planetScale, texture::earth); drawObjectTexture(sphereContext, planetTranslate * planetRotate * planetScale, texture::earth);
/*
glBindFramebuffer(hdrFBO, 0);
glUseProgram(programBlur);
drawObjectBloom(sphereContext, planetTranslate * planetRotate * planetScale, texture::earth, 2, true, true);
*/
glfwSwapBuffers(window); glfwSwapBuffers(window);
} }
@ -343,10 +352,11 @@ void init(GLFWwindow* window)
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
//initDepthMap();
initHDR(); 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"); program = shaderLoader.CreateProgram("shaders/shader.vert", "shaders/shader.frag");
programTex = shaderLoader.CreateProgram("shaders/shader_tex.vert", "shaders/shader_tex.frag"); programTex = shaderLoader.CreateProgram("shaders/shader_tex.vert", "shaders/shader_tex.frag");
programSun = shaderLoader.CreateProgram("shaders/shader_sun.vert", "shaders/shader_sun.frag"); programSun = shaderLoader.CreateProgram("shaders/shader_sun.vert", "shaders/shader_sun.frag");
@ -411,8 +421,9 @@ void renderLoop(GLFWwindow* window) {
while (!glfwWindowShouldClose(window)) while (!glfwWindowShouldClose(window))
{ {
/*glfwPollEvents(); glfwPollEvents();
/*
// Start the Dear ImGui frame // Start the Dear ImGui frame
ImGui_ImplOpenGL3_NewFrame(); ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplGlfw_NewFrame(); ImGui_ImplGlfw_NewFrame();