From 8d130ee906fd585ef7eee631440ca7428d400a7b Mon Sep 17 00:00:00 2001 From: Faerbit Date: Thu, 5 Mar 2015 16:21:30 +0100 Subject: [PATCH] Made first attempt at blurring shadows with gaussian blur. Doesn't seem to work right now. Not that important right now. --- data/shader/gauss_blur.fsh | 41 +++++++++++++++++++++++++++++++++++ data/shader/gauss_blur.vsh | 11 ++++++++++ graphics.cc | 44 ++++++++++++++++++++++++++++++++------ graphics.hh | 5 ++++- 4 files changed, 93 insertions(+), 8 deletions(-) create mode 100644 data/shader/gauss_blur.fsh create mode 100644 data/shader/gauss_blur.vsh diff --git a/data/shader/gauss_blur.fsh b/data/shader/gauss_blur.fsh new file mode 100644 index 0000000..7d5d5e6 --- /dev/null +++ b/data/shader/gauss_blur.fsh @@ -0,0 +1,41 @@ +#version 150 + +in vec2 vTexCoord; + +uniform sampler2D screen; +uniform int windowSizeX; +uniform int windowSizeY; +uniform bool verticalPass; + +out float oColor; + +const float stretching = 2.0; + +void main() { + vec4 sum = vec4(0.0); + if (verticalPass){ + float blurSize = 1.0/(float(windowSizeY)/(stretching)); + sum += texture(screen, vec2(vTexCoord.x - 4.0*blurSize, vTexCoord.y)) * 0.05; + sum += texture(screen, vec2(vTexCoord.x - 3.0*blurSize, vTexCoord.y)) * 0.09; + sum += texture(screen, vec2(vTexCoord.x - 2.0*blurSize, vTexCoord.y)) * 0.12; + sum += texture(screen, vec2(vTexCoord.x - blurSize, vTexCoord.y)) * 0.15; + sum += texture(screen, vec2(vTexCoord.x, vTexCoord.y)) * 0.16; + sum += texture(screen, vec2(vTexCoord.x + blurSize, vTexCoord.y)) * 0.15; + sum += texture(screen, vec2(vTexCoord.x + 2.0*blurSize, vTexCoord.y)) * 0.12; + sum += texture(screen, vec2(vTexCoord.x + 3.0*blurSize, vTexCoord.y)) * 0.09; + sum += texture(screen, vec2(vTexCoord.x + 4.0*blurSize, vTexCoord.y)) * 0.05; + } + else { + float blurSize = 1.0/(float(windowSizeX)/stretching); + sum += texture(screen, vec2(vTexCoord.x, vTexCoord.y - 4.0*blurSize)) * 0.05; + sum += texture(screen, vec2(vTexCoord.x, vTexCoord.y - 3.0*blurSize)) * 0.09; + sum += texture(screen, vec2(vTexCoord.x, vTexCoord.y - 2.0*blurSize)) * 0.12; + sum += texture(screen, vec2(vTexCoord.x, vTexCoord.y - blurSize)) * 0.15; + sum += texture(screen, vec2(vTexCoord.x, vTexCoord.y)) * 0.16; + sum += texture(screen, vec2(vTexCoord.x, vTexCoord.y + blurSize)) * 0.15; + sum += texture(screen, vec2(vTexCoord.x, vTexCoord.y + 2.0*blurSize)) * 0.12; + sum += texture(screen, vec2(vTexCoord.x, vTexCoord.y + 3.0*blurSize)) * 0.09; + sum += texture(screen, vec2(vTexCoord.x, vTexCoord.y + 4.0*blurSize)) * 0.05; + } + oColor = sum; +} diff --git a/data/shader/gauss_blur.vsh b/data/shader/gauss_blur.vsh new file mode 100644 index 0000000..f3e6540 --- /dev/null +++ b/data/shader/gauss_blur.vsh @@ -0,0 +1,11 @@ +#version 150 + +in vec2 aPosition; +in vec2 aTexCoord; + +out vec2 vTexCoord; + +void main() { + vTexCoord = aTexCoord; + gl_Position = vec4(aPosition, 0.0, 1.0); +} diff --git a/graphics.cc b/graphics.cc index 65dcead..38c6fac 100644 --- a/graphics.cc +++ b/graphics.cc @@ -92,11 +92,14 @@ void Graphics::init(Level* level) { flamePostShader = ShaderProgramCreator("flame_post") .attributeLocations(fullscreen_quad->getAttributeLocations()).create(); + gaussShader = ShaderProgramCreator("gauss_blur") + .attributeLocations(fullscreen_quad->getAttributeLocations()).create(); + glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &number_of_texture_units); printf("Your graphics card supports %d texture units.\n", number_of_texture_units); // Exit if we need more texture units - if (number_of_texture_units < 16) { - printf("You need at least 16 texture units to run this application. Exiting\n"); + if (number_of_texture_units < 17) { + printf("You need at least 17 texture units to run this application. Exiting\n"); exit(-1); } @@ -136,7 +139,7 @@ void Graphics::init(Level* level) { depth_cubeMaps.at(i)->setCompareMode(GL_COMPARE_REF_TO_TEXTURE); } - framebuffer_cube = SharedFrameBufferObject(new FrameBufferObject()); + framebuffer_cube_blurred = SharedFrameBufferObject(new FrameBufferObject()); if (level->getLights()->size() > 0) { for(unsigned int i = 0; isetUniform("windowSizeX", int(windowSize.x)); flamePostShader->setUniform("windowSizeY", int(windowSize.y)); + skydomeShader->use(); skydomeShader->setTexture("nightTexture", level->getSkydome()->getNightTexture()->getReference(), 15); + framebuffer_cube_texture = SharedTexture2D(new Texture2D(glm::vec2(cube_size, cube_size), GL_RGBA8)); + framebuffer_cube_texture->setMinFilter(GL_NEAREST); + framebuffer_cube_texture->setMagFilter(GL_NEAREST); + framebuffer_cube_texture->setWrapS(GL_CLAMP_TO_BORDER); + framebuffer_cube_texture->setWrapT(GL_CLAMP_TO_BORDER); + + framebuffer_cube = SharedFrameBufferObject(new FrameBufferObject()); + framebuffer_cube->attachColorTexture("gl_FragDepth", framebuffer_cube_texture); + framebuffer_cube->validate(); + + gaussShader->use(); + gaussShader->setTexture("screen", framebuffer_cube_texture, 16); + gaussShader->setUniform("windowSizeX", cube_size); + gaussShader->setUniform("windowSizeY", cube_size); + updateClosestLights(); } @@ -190,21 +209,32 @@ void Graphics::render(double time) glm::vec3(0.0f, 0.0f, -1.0f),glm::vec3(0.0f, -1.0f, 0.0f),glm::vec3(0.0f, -1.0f, 0.0f)}; - framebuffer_cube->bind(); for (unsigned int i_pointlight = 0; i_pointlightgetObjectName(), 0); + framebuffer_cube->bind(); + depthCubeShader->use(); glClear(GL_DEPTH_BUFFER_BIT); glm::mat4 viewMatrix = glm::lookAt(closestLights.at(i_pointlight).getPosition(), closestLights.at(i_pointlight).getPosition() + looking_directions[i_face], upvectors[i_face]); glm::mat4 depthViewProjectionMatrix_face = depthProjectionMatrix_pointlights * viewMatrix; - std::vector viewMatrixVector = std::vector(); - viewMatrixVector.push_back(viewMatrix); + std::vector viewMatrixVector = std::vector(1); + viewMatrixVector.at(0) = viewMatrix; level->render(depthCubeShader, false, &depthViewProjectionMatrix_face, &viewMatrixVector); if (!framebuffer_cube->isFrameBufferObjectComplete()) { printf("Framebuffer incomplete, unknown error occured during shadow generation!\n"); } + framebuffer_cube_blurred->bind(); + gaussShader->use(); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i_face, depth_cubeMaps.at(i_pointlight)->getObjectName(), 0); + glClear(GL_DEPTH_BUFFER_BIT); + gaussShader->setUniform("verticalPass", true); + fullscreen_quad->render(); + gaussShader->setUniform("verticalPass", false); + fullscreen_quad->render(); + if (!framebuffer_cube_blurred->isFrameBufferObjectComplete()) { + printf("Framebuffer incomplete, unknown error occured during shadow generation!\n"); + } } } diff --git a/graphics.hh b/graphics.hh index 3e5358a..9fd3826 100644 --- a/graphics.hh +++ b/graphics.hh @@ -33,16 +33,19 @@ class Graphics { SharedShaderProgram lightingShader; SharedShaderProgram skydomeShader; SharedShaderProgram depthCubeShader; + SharedShaderProgram gaussShader; SharedShaderProgram depthShader; SharedShaderProgram flameShader; SharedShaderProgram flamePostShader; std::vector depth_directionalMaps; std::vector framebuffer_directional; std::vector depth_cubeMaps; - SharedFrameBufferObject framebuffer_cube; + SharedFrameBufferObject framebuffer_cube_blurred; SharedFrameBufferObject framebuffer_light; SharedTexture2D light_fbo_color_texture; SharedTexture2D light_fbo_depth_texture; + SharedFrameBufferObject framebuffer_cube; + SharedTexture2D framebuffer_cube_texture; SharedVertexArrayObject flame_positions; SharedArrayBuffer flame_positions_ab; SharedVertexArrayObject fullscreen_quad;