From 7e3c2c4897138f4f3fd043c2f8ce4b9bb0631a34 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sat, 15 Nov 2014 20:37:47 +0100 Subject: [PATCH 1/5] Add a shader to blur shadow --- data/shaders/blurshadowH.comp | 0 data/shaders/blurshadowV.comp | 0 src/graphics/shaders.cpp | 20 ++++++++++++++++++++ src/graphics/shaders.hpp | 14 ++++++++++++++ 4 files changed, 34 insertions(+) create mode 100644 data/shaders/blurshadowH.comp create mode 100644 data/shaders/blurshadowV.comp diff --git a/data/shaders/blurshadowH.comp b/data/shaders/blurshadowH.comp new file mode 100644 index 000000000..e69de29bb diff --git a/data/shaders/blurshadowV.comp b/data/shaders/blurshadowV.comp new file mode 100644 index 000000000..e69de29bb diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp index b953b776f..4319ea4cd 100644 --- a/src/graphics/shaders.cpp +++ b/src/graphics/shaders.cpp @@ -1752,6 +1752,16 @@ namespace FullScreenShader AssignTextureUnit(Program, TexUnit(TU_dest, "dest")); } + ComputeShadowBlurHShader::ComputeShadowBlurHShader() + { + Program = LoadProgram(OBJECT, + GL_COMPUTE_SHADER, file_manager->getAsset("shaders/blurshadowH.comp").c_str()); + TU_dest = 1; + AssignUniforms("pixel", "sigma"); + AssignSamplerNames(Program, 0, "source"); + AssignTextureUnit(Program, TexUnit(TU_dest, "dest")); + } + Gaussian6HBlurShader::Gaussian6HBlurShader() { Program = LoadProgram(OBJECT, @@ -1812,6 +1822,16 @@ namespace FullScreenShader AssignTextureUnit(Program, TexUnit(TU_dest, "dest")); } + ComputeShadowBlurVShader::ComputeShadowBlurVShader() + { + Program = LoadProgram(OBJECT, + GL_COMPUTE_SHADER, file_manager->getAsset("shaders/blurshadowV.comp").c_str()); + TU_dest = 1; + AssignUniforms("pixel", "sigma"); + AssignSamplerNames(Program, 0, "source"); + AssignTextureUnit(Program, TexUnit(TU_dest, "dest")); + } + Gaussian6VBlurShader::Gaussian6VBlurShader() { Program = LoadProgram(OBJECT, diff --git a/src/graphics/shaders.hpp b/src/graphics/shaders.hpp index 8e7b1d53a..2f1eb1b00 100644 --- a/src/graphics/shaders.hpp +++ b/src/graphics/shaders.hpp @@ -471,6 +471,13 @@ public: ComputeGaussian6HBlurShader(); }; +class ComputeShadowBlurHShader : public ShaderHelperSingleton, public TextureRead +{ +public: + GLuint TU_dest; + ComputeShadowBlurHShader(); +}; + class Gaussian6HBlurShader : public ShaderHelperSingleton, public TextureRead { public: @@ -510,6 +517,13 @@ public: ComputeGaussian6VBlurShader(); }; +class ComputeShadowBlurVShader : public ShaderHelperSingleton, public TextureRead +{ +public: + GLuint TU_dest; + ComputeShadowBlurVShader(); +}; + class Gaussian6VBlurShader : public ShaderHelperSingleton, public TextureRead { public: From a7b8ba13cdb740a3c908b98a7de6c2d5069283a8 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sat, 15 Nov 2014 20:43:44 +0100 Subject: [PATCH 2/5] Add shader content --- data/shaders/blurshadowH.comp | 41 +++++++++++++++++++++++++++++++++++ data/shaders/blurshadowV.comp | 41 +++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) diff --git a/data/shaders/blurshadowH.comp b/data/shaders/blurshadowH.comp index e69de29bb..e03ae6d77 100644 --- a/data/shaders/blurshadowH.comp +++ b/data/shaders/blurshadowH.comp @@ -0,0 +1,41 @@ +uniform sampler2D source; +uniform layout(rgba16f) restrict writeonly image2D dest; +uniform vec2 pixel; +uniform float sigma; + +// Gaussian separated blur with radius 6. + +layout (local_size_x = 8, local_size_y = 8) in; + +shared float local_src[8 + 2 * 6][8]; + +void main() +{ + int x = int(gl_LocalInvocationID.x), y = int(gl_LocalInvocationID.y); + ivec2 iuv = ivec2(gl_GlobalInvocationID.x, gl_GlobalInvocationID.y); + vec2 uv_m = (iuv - ivec2(6, 0)) * pixel; + vec2 uv = iuv * pixel; + vec2 uv_p = (iuv + ivec2(6, 0)) * pixel; + + local_src[x][y] = texture(source, uv_m).x; + local_src[x + 6][y] = texture(source, uv).x; + local_src[x + 12][y] = texture(source, uv_p).x; + + barrier(); + + float g0, g1, g2; + g0 = 1.0 / (sqrt(2.0 * 3.14) * sigma); + g1 = exp(-0.5 / (sigma * sigma)); + g2 = g1 * g1; + float sum = local_src[x + 6][y] * g0; + g0 *= g1; + g1 *= g2; + for (int i = 1; i < 6; i++) { + sum += local_src[6 + x - i][y] * g0; + sum += local_src[6 + x + i][y] * g0; + g0 *= g1; + g1 *= g2; + } + + imageStore(dest, iuv, vec4(sum)); +} diff --git a/data/shaders/blurshadowV.comp b/data/shaders/blurshadowV.comp index e69de29bb..cbcc567c9 100644 --- a/data/shaders/blurshadowV.comp +++ b/data/shaders/blurshadowV.comp @@ -0,0 +1,41 @@ +uniform sampler2D source; +uniform layout(rgba16f) restrict writeonly image2D dest; +uniform vec2 pixel; +uniform float sigma; + +// Gaussian separated blur with radius 6. + +layout (local_size_x = 8, local_size_y = 8) in; + +shared float local_src[8][8 + 2 * 6]; + +void main() +{ + int x = int(gl_LocalInvocationID.x), y = int(gl_LocalInvocationID.y); + ivec2 iuv = ivec2(gl_GlobalInvocationID.x, gl_GlobalInvocationID.y); + vec2 uv_m = (iuv - ivec2(0, 6)) * pixel; + vec2 uv = iuv * pixel; + vec2 uv_p = (iuv + ivec2(0, 6)) * pixel; + + local_src[x][y] = texture(source, uv_m).x; + local_src[x][y + 6] = texture(source, uv).x; + local_src[x][y + 12] = texture(source, uv_p).x; + + barrier(); + + float g0, g1, g2; + g0 = 1.0 / (sqrt(2.0 * 3.14) * sigma); + g1 = exp(-0.5 / (sigma * sigma)); + g2 = g1 * g1; + floar sum = local_src[x][y + 6] * g0; + g0 *= g1; + g1 *= g2; + for (int i = 1; i < 6; i++) { + sum += local_src[x][6 + y - i] * g0; + sum += local_src[x][6 + y + i] * g0; + g0 *= g1; + g1 *= g2; + } + + imageStore(dest, iuv, vec4(sum)); +} From 448f254a2b62aefc9effe4069a0041bbf32d71e8 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sat, 15 Nov 2014 21:02:24 +0100 Subject: [PATCH 3/5] Fixes --- data/shaders/blurshadowH.comp | 2 +- data/shaders/blurshadowV.comp | 4 ++-- src/graphics/irr_driver.hpp | 2 ++ src/graphics/post_processing.cpp | 36 +++++++++++++++++++++++++------- src/graphics/rtts.cpp | 4 ++++ 5 files changed, 38 insertions(+), 10 deletions(-) diff --git a/data/shaders/blurshadowH.comp b/data/shaders/blurshadowH.comp index e03ae6d77..21b176cbe 100644 --- a/data/shaders/blurshadowH.comp +++ b/data/shaders/blurshadowH.comp @@ -1,5 +1,5 @@ uniform sampler2D source; -uniform layout(rgba16f) restrict writeonly image2D dest; +uniform layout(r32f) restrict writeonly image2D dest; uniform vec2 pixel; uniform float sigma; diff --git a/data/shaders/blurshadowV.comp b/data/shaders/blurshadowV.comp index cbcc567c9..a6b439ce3 100644 --- a/data/shaders/blurshadowV.comp +++ b/data/shaders/blurshadowV.comp @@ -1,5 +1,5 @@ uniform sampler2D source; -uniform layout(rgba16f) restrict writeonly image2D dest; +uniform layout(r32f) restrict writeonly image2D dest; uniform vec2 pixel; uniform float sigma; @@ -27,7 +27,7 @@ void main() g0 = 1.0 / (sqrt(2.0 * 3.14) * sigma); g1 = exp(-0.5 / (sigma * sigma)); g2 = g1 * g1; - floar sum = local_src[x][y + 6] * g0; + float sum = local_src[x][y + 6] * g0; g0 *= g1; g1 *= g2; for (int i = 1; i < 6; i++) { diff --git a/src/graphics/irr_driver.hpp b/src/graphics/irr_driver.hpp index 9bffa86cc..e5358012b 100644 --- a/src/graphics/irr_driver.hpp +++ b/src/graphics/irr_driver.hpp @@ -99,6 +99,7 @@ enum TypeFBO FBO_EIGHTH2, FBO_DISPLACE, FBO_BLOOM_1024, + FBO_SCALAR_1024, FBO_BLOOM_512, FBO_TMP_512, FBO_LENS_512, @@ -160,6 +161,7 @@ enum TypeRTT RTT_MLAA_TMP, RTT_BLOOM_1024, + RTT_SCALAR_1024, RTT_BLOOM_512, RTT_TMP_512, RTT_LENS_512, diff --git a/src/graphics/post_processing.cpp b/src/graphics/post_processing.cpp index 1488ba56c..2f557ecc6 100644 --- a/src/graphics/post_processing.cpp +++ b/src/graphics/post_processing.cpp @@ -321,16 +321,38 @@ void PostProcessing::renderGaussian6BlurLayer(FrameBuffer &in_fbo) for (unsigned i = 0; i < 4; i++) { - // Used as temp - irr_driver->getFBO(FBO_BLOOM_1024).Bind(); GLuint LayerTex; glGenTextures(1, &LayerTex); glTextureView(LayerTex, GL_TEXTURE_2D, in_fbo.getRTT()[0], GL_R32F, 0, 1, i, 1); - FullScreenShader::Gaussian6VBlurShader::getInstance()->SetTextureUnits(LayerTex); - DrawFullScreenEffect(core::vector2df(1.f / 1024.f, 1.f / 1024.f), 1.f); - in_fbo.BindLayer(i); - FullScreenShader::Gaussian6HBlurShader::getInstance()->SetTextureUnits(irr_driver->getFBO(FBO_BLOOM_1024).getRTT()[0]); - DrawFullScreenEffect(core::vector2df(1.f / 1024.f, 1.f / 1024.f), 1.f); + if (!irr_driver->hasARBComputeShaders()) + { + // Used as temp + irr_driver->getFBO(FBO_SCALAR_1024).Bind(); + FullScreenShader::Gaussian6VBlurShader::getInstance()->SetTextureUnits(LayerTex); + DrawFullScreenEffect(core::vector2df(1.f / 1024.f, 1.f / 1024.f), 1.f); + in_fbo.BindLayer(i); + FullScreenShader::Gaussian6HBlurShader::getInstance()->SetTextureUnits(irr_driver->getFBO(FBO_SCALAR_1024).getRTT()[0]); + DrawFullScreenEffect(core::vector2df(1.f / 1024.f, 1.f / 1024.f), 1.f); + } + else + { + glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT); + glUseProgram(FullScreenShader::ComputeShadowBlurVShader::getInstance()->Program); + FullScreenShader::ComputeShadowBlurVShader::getInstance()->SetTextureUnits(LayerTex); + glBindSampler(FullScreenShader::ComputeShadowBlurVShader::getInstance()->TU_dest, 0); + glBindImageTexture(FullScreenShader::ComputeShadowBlurVShader::getInstance()->TU_dest, irr_driver->getFBO(FBO_SCALAR_1024).getRTT()[0], 0, false, 0, GL_WRITE_ONLY, GL_R32F); + FullScreenShader::ComputeShadowBlurVShader::getInstance()->setUniforms(core::vector2df(1.f / 1024.f, 1.f / 1024.f), 1.f); + glDispatchCompute((int)1024 / 8 + 1, (int)1024 / 8 + 1, 1); + + glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT | GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); + glUseProgram(FullScreenShader::ComputeShadowBlurHShader::getInstance()->Program); + FullScreenShader::ComputeShadowBlurHShader::getInstance()->SetTextureUnits(irr_driver->getFBO(FBO_SCALAR_1024).getRTT()[0]); + glBindSampler(FullScreenShader::ComputeShadowBlurHShader::getInstance()->TU_dest, 0); + glBindImageTexture(FullScreenShader::ComputeShadowBlurHShader::getInstance()->TU_dest, LayerTex, 0, false, 0, GL_WRITE_ONLY, GL_R32F); + FullScreenShader::ComputeShadowBlurHShader::getInstance()->setUniforms(core::vector2df(1.f / 1024.f, 1.f / 1024.f), 1.f); + glDispatchCompute((int)1024 / 8 + 1, (int)1024 / 8 + 1, 1); + glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); + } glDeleteTextures(1, &LayerTex); } } diff --git a/src/graphics/rtts.cpp b/src/graphics/rtts.cpp index 5dad9df4f..723dfdd80 100644 --- a/src/graphics/rtts.cpp +++ b/src/graphics/rtts.cpp @@ -123,6 +123,7 @@ RTT::RTT(size_t width, size_t height) RenderTargetTextures[RTT_HALF2_R] = generateRTT(half, GL_R16F, GL_RED, GL_FLOAT); RenderTargetTextures[RTT_BLOOM_1024] = generateRTT(shadowsize0, GL_RGBA16F, GL_BGR, GL_FLOAT); + RenderTargetTextures[RTT_SCALAR_1024] = generateRTT(shadowsize0, GL_R32F, GL_RED, GL_FLOAT); RenderTargetTextures[RTT_BLOOM_512] = generateRTT(shadowsize1, GL_RGBA16F, GL_BGR, GL_FLOAT); RenderTargetTextures[RTT_TMP_512] = generateRTT(shadowsize1, GL_RGBA16F, GL_BGR, GL_FLOAT); RenderTargetTextures[RTT_LENS_512] = generateRTT(shadowsize1, GL_RGBA16F, GL_BGR, GL_FLOAT); @@ -208,6 +209,9 @@ RTT::RTT(size_t width, size_t height) somevector.push_back(RenderTargetTextures[RTT_BLOOM_1024]); FrameBuffers.push_back(new FrameBuffer(somevector, 1024, 1024)); somevector.clear(); + somevector.push_back(RenderTargetTextures[RTT_SCALAR_1024]); + FrameBuffers.push_back(new FrameBuffer(somevector, 1024, 1024)); + somevector.clear(); somevector.push_back(RenderTargetTextures[RTT_BLOOM_512]); FrameBuffers.push_back(new FrameBuffer(somevector, 512, 512)); somevector.clear(); From 239a32b1d85311abaece93d1289bb4e48d73a492 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sat, 15 Nov 2014 21:19:17 +0100 Subject: [PATCH 4/5] Add mipmap level for shadow --- src/graphics/rtts.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/graphics/rtts.cpp b/src/graphics/rtts.cpp index 723dfdd80..6fb3ba12c 100644 --- a/src/graphics/rtts.cpp +++ b/src/graphics/rtts.cpp @@ -245,7 +245,7 @@ RTT::RTT(size_t width, size_t height) if (UserConfigParams::m_shadows && !irr_driver->needUBOWorkaround()) { - shadowColorTex = generateRTT3D(GL_TEXTURE_2D_ARRAY, 1024, 1024, 4, GL_R32F, GL_RED, GL_FLOAT, 1); + shadowColorTex = generateRTT3D(GL_TEXTURE_2D_ARRAY, 1024, 1024, 4, GL_R32F, GL_RED, GL_FLOAT, 10); shadowDepthTex = generateRTT3D(GL_TEXTURE_2D_ARRAY, 1024, 1024, 4, GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 1); somevector.clear(); From c2859d24ce4bd7628b0284ee909f109c5dbc9477 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sat, 15 Nov 2014 21:27:15 +0100 Subject: [PATCH 5/5] Improved shadow stability --- data/shaders/sunlightshadow.frag | 2 +- src/graphics/post_processing.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/data/shaders/sunlightshadow.frag b/data/shaders/sunlightshadow.frag index 7ad3e08a0..f242a309c 100644 --- a/data/shaders/sunlightshadow.frag +++ b/data/shaders/sunlightshadow.frag @@ -34,7 +34,7 @@ float getShadowFactor(vec3 pos, float bias, int index) float z = texture(shadowtex, vec3(shadowtexcoord, float(index))).x; float d = shadowcoord.z; - return min(pow(exp(-8. * d) * z, 256.), 1.); + return min(pow(exp(-8. * d) * z, 32.), 1.); } void main() { diff --git a/src/graphics/post_processing.cpp b/src/graphics/post_processing.cpp index 2f557ecc6..cf6b58e5e 100644 --- a/src/graphics/post_processing.cpp +++ b/src/graphics/post_processing.cpp @@ -341,7 +341,7 @@ void PostProcessing::renderGaussian6BlurLayer(FrameBuffer &in_fbo) FullScreenShader::ComputeShadowBlurVShader::getInstance()->SetTextureUnits(LayerTex); glBindSampler(FullScreenShader::ComputeShadowBlurVShader::getInstance()->TU_dest, 0); glBindImageTexture(FullScreenShader::ComputeShadowBlurVShader::getInstance()->TU_dest, irr_driver->getFBO(FBO_SCALAR_1024).getRTT()[0], 0, false, 0, GL_WRITE_ONLY, GL_R32F); - FullScreenShader::ComputeShadowBlurVShader::getInstance()->setUniforms(core::vector2df(1.f / 1024.f, 1.f / 1024.f), 1.f); + FullScreenShader::ComputeShadowBlurVShader::getInstance()->setUniforms(core::vector2df(1.f / 1024.f, 1.f / 1024.f), 1.5f); glDispatchCompute((int)1024 / 8 + 1, (int)1024 / 8 + 1, 1); glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT | GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); @@ -349,7 +349,7 @@ void PostProcessing::renderGaussian6BlurLayer(FrameBuffer &in_fbo) FullScreenShader::ComputeShadowBlurHShader::getInstance()->SetTextureUnits(irr_driver->getFBO(FBO_SCALAR_1024).getRTT()[0]); glBindSampler(FullScreenShader::ComputeShadowBlurHShader::getInstance()->TU_dest, 0); glBindImageTexture(FullScreenShader::ComputeShadowBlurHShader::getInstance()->TU_dest, LayerTex, 0, false, 0, GL_WRITE_ONLY, GL_R32F); - FullScreenShader::ComputeShadowBlurHShader::getInstance()->setUniforms(core::vector2df(1.f / 1024.f, 1.f / 1024.f), 1.f); + FullScreenShader::ComputeShadowBlurHShader::getInstance()->setUniforms(core::vector2df(1.f / 1024.f, 1.f / 1024.f), 1.5f); glDispatchCompute((int)1024 / 8 + 1, (int)1024 / 8 + 1, 1); glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); }