diff --git a/data/shaders/Lightspaceboundingbox.comp b/data/shaders/Lightspaceboundingbox.comp
index 933517e71..e55e69c68 100644
--- a/data/shaders/Lightspaceboundingbox.comp
+++ b/data/shaders/Lightspaceboundingbox.comp
@@ -49,7 +49,7 @@ void main()
     ivec3 lmax3 = ivec3(-1000);
     ivec3 lmin3 = ivec3(1000);
 
-    vec2 start_xy = gl_LocalInvocationID.xy + gl_WorkGroupID.xy * gl_WorkGroupSize.xy * 8 + vec2(0.5);
+    vec2 start_xy = gl_LocalInvocationID.xy + gl_WorkGroupID.xy * gl_WorkGroupSize.xy * 8;
     for (int i = 0; i < 8; i++) {
         for (int j = 0; j < 8; j++) {
 
diff --git a/data/shaders/bilateralH.comp b/data/shaders/bilateralH.comp
index 76da31d9d..5ecad97c9 100644
--- a/data/shaders/bilateralH.comp
+++ b/data/shaders/bilateralH.comp
@@ -15,10 +15,9 @@ void main()
 {
     int x = int(gl_LocalInvocationID.x), y = int(gl_LocalInvocationID.y);
     ivec2 iuv = ivec2(gl_GlobalInvocationID.x, gl_GlobalInvocationID.y);
-    vec2 guv = gl_GlobalInvocationID.xy + vec2(0.5);
-    vec2 uv_m = (guv - vec2(8, 0)) * pixel;
-    vec2 uv = guv * pixel;
-    vec2 uv_p = (guv + vec2(8, 0)) * pixel;
+    vec2 uv_m = (iuv - ivec2(8, 0)) * pixel;
+    vec2 uv = iuv * pixel;
+    vec2 uv_p = (iuv + ivec2(8, 0)) * pixel;
 
     local_src[x][y] = texture(source, uv_m).x;
     local_depth[x][y] = texture(depth, uv_m).x;
diff --git a/data/shaders/bilateralV.comp b/data/shaders/bilateralV.comp
index af2d7c3db..720566821 100644
--- a/data/shaders/bilateralV.comp
+++ b/data/shaders/bilateralV.comp
@@ -15,10 +15,9 @@ void main()
 {
     int x = int(gl_LocalInvocationID.x), y = int(gl_LocalInvocationID.y);
     ivec2 iuv = ivec2(gl_GlobalInvocationID.x, gl_GlobalInvocationID.y);
-    vec2 guv = gl_GlobalInvocationID.xy + vec2(0.5);
-    vec2 uv_m = (guv - vec2(0, 8)) * pixel;
-    vec2 uv = guv * pixel;
-    vec2 uv_p = (guv + vec2(0, 8)) * pixel;
+    vec2 uv_m = (iuv - ivec2(0, 8)) * pixel;
+    vec2 uv = iuv * pixel;
+    vec2 uv_p = (iuv + ivec2(0, 8)) * pixel;
 
     local_src[x][y] = texture(source, uv_m).x;
     local_depth[x][y] = texture(depth, uv_m).x;
diff --git a/data/shaders/bloom.frag b/data/shaders/bloom.frag
index 90fc1eac4..099922bab 100644
--- a/data/shaders/bloom.frag
+++ b/data/shaders/bloom.frag
@@ -7,7 +7,7 @@ vec3 getRGBFromCIEXxy(vec3 YxyColor);
 
 void main()
 {
-    vec2 uv = gl_FragCoord.xy / 1024;
+    vec2 uv = gl_FragCoord.xy / 512;
     vec3 col = texture(tex, uv).xyz;
     vec3 Yxy = getCIEYxy(col);
     vec3 WhiteYxy = getCIEYxy(vec3(1.));
diff --git a/data/shaders/bloomblend.frag b/data/shaders/bloomblend.frag
new file mode 100644
index 000000000..503c9dcb9
--- /dev/null
+++ b/data/shaders/bloomblend.frag
@@ -0,0 +1,14 @@
+uniform sampler2D tex_128;
+uniform sampler2D tex_256;
+uniform sampler2D tex_512;
+
+out vec4 FragColor;
+
+void main()
+{
+    vec2 uv = gl_FragCoord.xy / screen;
+    vec4 col = .125 * texture(tex_128, uv);
+    col += .25 * texture(tex_256, uv);
+    col += .5 * texture(tex_512, uv);
+    FragColor = vec4(col.xyz, 1.);
+}
diff --git a/data/shaders/gaussian6h.comp b/data/shaders/gaussian6h.comp
index 62f54f821..f2df38fe0 100644
--- a/data/shaders/gaussian6h.comp
+++ b/data/shaders/gaussian6h.comp
@@ -13,10 +13,9 @@ void main()
 {
     int x = int(gl_LocalInvocationID.x), y = int(gl_LocalInvocationID.y);
     ivec2 iuv = ivec2(gl_GlobalInvocationID.x, gl_GlobalInvocationID.y);
-    vec2 guv = gl_GlobalInvocationID.xy + vec2(0.5);
-    vec2 uv_m = (guv - vec2(6, 0)) * pixel;
-    vec2 uv = guv * pixel;
-    vec2 uv_p = (guv + vec2(6, 0)) * pixel;
+    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);
     local_src[x + 6][y] = texture(source, uv);
diff --git a/data/shaders/gaussian6v.comp b/data/shaders/gaussian6v.comp
index 0878e0822..7c3a0979a 100644
--- a/data/shaders/gaussian6v.comp
+++ b/data/shaders/gaussian6v.comp
@@ -13,10 +13,9 @@ void main()
 {
     int x = int(gl_LocalInvocationID.x), y = int(gl_LocalInvocationID.y);
     ivec2 iuv = ivec2(gl_GlobalInvocationID.x, gl_GlobalInvocationID.y);
-    vec2 guv = gl_GlobalInvocationID.xy + vec2(0.5);
-    vec2 uv_m = (guv - vec2(0, 6)) * pixel;
-    vec2 uv = guv * pixel;
-    vec2 uv_p = (guv + vec2(0, 6)) * pixel;
+    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);
     local_src[x][y + 6] = texture(source, uv);
diff --git a/src/graphics/irr_driver.hpp b/src/graphics/irr_driver.hpp
index 5b8245773..b04b380bc 100644
--- a/src/graphics/irr_driver.hpp
+++ b/src/graphics/irr_driver.hpp
@@ -100,7 +100,6 @@ enum TypeFBO
     FBO_DISPLACE,
     FBO_BLOOM_1024,
     FBO_SCALAR_1024,
-    FBO_TMP_1024,
     FBO_BLOOM_512,
     FBO_TMP_512,
     FBO_LENS_512,
@@ -163,7 +162,6 @@ enum TypeRTT
 
     RTT_BLOOM_1024,
     RTT_SCALAR_1024,
-    RTT_TMP_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 80266a818..11c9ab0f9 100644
--- a/src/graphics/post_processing.cpp
+++ b/src/graphics/post_processing.cpp
@@ -722,13 +722,12 @@ FrameBuffer *PostProcessing::render(scene::ICameraSceneNode * const camnode, boo
             glClear(GL_STENCIL_BUFFER_BIT);
             glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
 
-            FrameBuffer::Blit(*in_fbo, irr_driver->getFBO(FBO_TMP_1024), GL_COLOR_BUFFER_BIT, GL_LINEAR);
+            FrameBuffer::Blit(*in_fbo, irr_driver->getFBO(FBO_BLOOM_1024), GL_COLOR_BUFFER_BIT, GL_LINEAR);
 
-            irr_driver->getFBO(FBO_BLOOM_1024).Bind();
-            renderBloom(irr_driver->getRenderTargetTexture(RTT_TMP_1024));
+            irr_driver->getFBO(FBO_BLOOM_512).Bind();
+            renderBloom(irr_driver->getRenderTargetTexture(RTT_BLOOM_1024));
 
             // Downsample
-            FrameBuffer::Blit(irr_driver->getFBO(FBO_BLOOM_1024), irr_driver->getFBO(FBO_BLOOM_512), GL_COLOR_BUFFER_BIT, GL_LINEAR);
             FrameBuffer::Blit(irr_driver->getFBO(FBO_BLOOM_512), irr_driver->getFBO(FBO_BLOOM_256), GL_COLOR_BUFFER_BIT, GL_LINEAR);
             FrameBuffer::Blit(irr_driver->getFBO(FBO_BLOOM_256), irr_driver->getFBO(FBO_BLOOM_128), GL_COLOR_BUFFER_BIT, GL_LINEAR);
 			
@@ -739,44 +738,18 @@ FrameBuffer *PostProcessing::render(scene::ICameraSceneNode * const camnode, boo
 			
 
             // Blur
+            renderGaussian6Blur(irr_driver->getFBO(FBO_BLOOM_512), irr_driver->getFBO(FBO_TMP_512), 1., 1.);
+            renderGaussian6Blur(irr_driver->getFBO(FBO_BLOOM_256), irr_driver->getFBO(FBO_TMP_256), 1., 1.);
+            renderGaussian6Blur(irr_driver->getFBO(FBO_BLOOM_128), irr_driver->getFBO(FBO_TMP_128), 1., 1.);
 
-            // The fbo sum chain is from https://software.intel.com/en-us/articles/compute-shader-hdr-and-bloom
-            glBlendFunc(GL_ONE, GL_ONE);
-            glBlendEquation(GL_FUNC_ADD);
-			
-			renderHorizontalBlur(irr_driver->getFBO(FBO_LENS_512), irr_driver->getFBO(FBO_TMP_512));
-            renderHorizontalBlur(irr_driver->getFBO(FBO_LENS_256), irr_driver->getFBO(FBO_TMP_256));
-            renderHorizontalBlur(irr_driver->getFBO(FBO_LENS_128), irr_driver->getFBO(FBO_TMP_128));
-
-            renderGaussian6Blur(irr_driver->getFBO(FBO_BLOOM_128), irr_driver->getFBO(FBO_TMP_128), 2., 2.);
-            glEnable(GL_BLEND);
-            irr_driver->getFBO(FBO_BLOOM_256).Bind();
-            renderPassThrough(irr_driver->getFBO(FBO_BLOOM_128).getRTT()[0], 256, 256);
-            glDisable(GL_BLEND);
-            renderGaussian6Blur(irr_driver->getFBO(FBO_BLOOM_256), irr_driver->getFBO(FBO_TMP_256), 2., 2.);
-            glEnable(GL_BLEND);
-            irr_driver->getFBO(FBO_BLOOM_512).Bind();
-            renderPassThrough(irr_driver->getFBO(FBO_BLOOM_256).getRTT()[0], 512, 512);
-            glDisable(GL_BLEND);
-            renderGaussian6Blur(irr_driver->getFBO(FBO_BLOOM_512), irr_driver->getFBO(FBO_TMP_512), 2., 2.);
-            glEnable(GL_BLEND);
-            irr_driver->getFBO(FBO_BLOOM_1024).Bind();
-            renderPassThrough(irr_driver->getFBO(FBO_BLOOM_512).getRTT()[0], 1024, 1024);
-            glDisable(GL_BLEND);
-            renderGaussian6Blur(irr_driver->getFBO(FBO_BLOOM_1024), irr_driver->getFBO(FBO_TMP_1024), 2., 2.);
-
-            // Additively blend
+            // Additively blend on top of tmp1
             in_fbo->Bind();
             glEnable(GL_BLEND);
             glBlendFunc(GL_ONE, GL_ONE);
             glBlendEquation(GL_FUNC_ADD);
-            renderPassThrough(irr_driver->getRenderTargetTexture(RTT_BLOOM_1024), in_fbo->getWidth(), in_fbo->getHeight());
-
-
-			FullScreenShader::LensBlendShader::getInstance()->SetTextureUnits(
-                irr_driver->getRenderTargetTexture(RTT_LENS_128), irr_driver->getRenderTargetTexture(RTT_LENS_256), irr_driver->getRenderTargetTexture(RTT_LENS_512));
-            DrawFullScreenEffect<FullScreenShader::LensBlendShader>();
-
+            FullScreenShader::BloomBlendShader::getInstance()->SetTextureUnits(
+                irr_driver->getRenderTargetTexture(RTT_BLOOM_128), irr_driver->getRenderTargetTexture(RTT_BLOOM_256), irr_driver->getRenderTargetTexture(RTT_BLOOM_512));
+            DrawFullScreenEffect<FullScreenShader::BloomBlendShader>();
             glDisable(GL_BLEND);
             glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
         } // end if bloom
diff --git a/src/graphics/rtts.cpp b/src/graphics/rtts.cpp
index 25e237b40..4af6d1d3c 100644
--- a/src/graphics/rtts.cpp
+++ b/src/graphics/rtts.cpp
@@ -105,7 +105,6 @@ RTT::RTT(size_t width, size_t height)
     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_1024] = generateRTT(shadowsize0, 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);
 	
@@ -193,9 +192,6 @@ RTT::RTT(size_t width, size_t height)
     somevector.push_back(RenderTargetTextures[RTT_SCALAR_1024]);
     FrameBuffers.push_back(new FrameBuffer(somevector, 1024, 1024));
     somevector.clear();
-    somevector.push_back(RenderTargetTextures[RTT_TMP_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();
diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp
index 532708a67..c3e50ef32 100644
--- a/src/graphics/shaders.cpp
+++ b/src/graphics/shaders.cpp
@@ -1570,6 +1570,16 @@ namespace FullScreenShader
 
         AssignSamplerNames(Program, 0, "tex");
     }
+
+    BloomBlendShader::BloomBlendShader()
+    {
+        Program = LoadProgram(OBJECT,
+            GL_VERTEX_SHADER, file_manager->getAsset("shaders/screenquad.vert").c_str(),
+            GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/bloomblend.frag").c_str());
+        AssignUniforms();
+
+        AssignSamplerNames(Program, 0, "tex_128", 1, "tex_256", 2, "tex_512");
+    }
 	
 	LensBlendShader::LensBlendShader()
     {
diff --git a/src/graphics/shaders.hpp b/src/graphics/shaders.hpp
index 50a48a759..9661278b1 100644
--- a/src/graphics/shaders.hpp
+++ b/src/graphics/shaders.hpp
@@ -388,6 +388,12 @@ public:
     BloomShader();
 };
 
+class BloomBlendShader : public ShaderHelperSingleton<BloomBlendShader>, public TextureRead<Bilinear_Filtered, Bilinear_Filtered, Bilinear_Filtered>
+{
+public:
+    BloomBlendShader();
+};
+
 class LensBlendShader : public ShaderHelperSingleton<LensBlendShader>, public TextureRead<Bilinear_Filtered, Bilinear_Filtered, Bilinear_Filtered>
 {
 public: