diff --git a/shaders/depth_normals.frag b/shaders/depth_normals.frag
index 5a59e0860fbec2a1077d5d5cd8621b0cd9e8adc7..d550e44760e2ae51adddbed9162f306633f36c7f 100644
--- a/shaders/depth_normals.frag
+++ b/shaders/depth_normals.frag
@@ -3,104 +3,97 @@
 in vec2 TexCoords;
 out vec4 FragColor;
 
-// The linear depth texture (0..1 -> zNear..zFar)
 uniform sampler2D uDepthTex;
 
-// The inverse of the projection matrix (pass from CPU)
+// We need these to convert linear [0..1] to actual distance
+uniform float zNear;
+uniform float zFar;
+
+// The inverse of the same projection matrix used when rendering depth
 uniform mat4 invProjectionMatrix;
 
-// Optional max depth clamp
-uniform float maxDepth; // e.g., 1.0 if 1 means zFar
+// We can discard if depth is bigger than some clamp
+uniform float maxDepth;
 
-// Offset in texture coordinates for neighbor sampling
-// Usually (1.0 / screenWidth, 1.0 / screenHeight)
+// Pixel-size step for neighbor sampling
 uniform vec2 uTexelSize;
 
+//////////////////////////////////////////////////////////
+// Helper: Reconstruct eye-space position from linear depth
+//////////////////////////////////////////////////////////
+vec3 reconstructEyePos(vec2 uv, float depthLin)
+{
+    // 1) Convert [0..1] -> actual eye-space distance
+    float dEye = depthLin * (zFar - zNear) + zNear;
+
+    // 2) Compute direction from camera through this UV.
+    //    We'll treat the clip-space z = -1 (the near plane),
+    //    so that we get a direction vector after inverse-projection.
+    float xNDC = uv.x * 2.0 - 1.0;
+    float yNDC = uv.y * 2.0 - 1.0;
+
+    vec4 clipPos  = vec4(xNDC, yNDC, -1.0, 1.0);
+    vec4 eyePos4  = invProjectionMatrix * clipPos;
+    // perspective divide
+    vec3 dir = eyePos4.xyz / eyePos4.w;
+    dir = normalize(dir);
+
+    // 3) Actual position = direction * distance
+    return dir * dEye;
+}
+
 void main()
 {
+    //////////////////////////////////
     // 1) Sample center depth
+    //////////////////////////////////
     float depthLin = texture(uDepthTex, TexCoords).r;
-    // Validate
-    if (depthLin < 0.0 || depthLin > 1.0 || depthLin > maxDepth)
-    {
+    if (depthLin < 0.0 || depthLin > 1.0 || depthLin > maxDepth) {
         discard;
     }
 
-    // 2) Convert to clip space
-    // OpenGL clip space: X, Y in [-1,1], Z in [-1,1].
-    // Our linear depth is [0..1], we map it to clip Z by (depthLin * 2 - 1).
-    vec4 clipPos = vec4(
-        TexCoords.x * 2.0 - 1.0,
-        TexCoords.y * 2.0 - 1.0,
-        depthLin      * 2.0 - 1.0,
-        1.0
-    );
-
-    // 3) Inverse-project to eye space
-    vec4 eyePos4 = invProjectionMatrix * clipPos;
-    // perspective divide
-    eyePos4.xyz /= eyePos4.w;
-    vec3 centerEye = eyePos4.xyz; // The actual eye-space position
+    // Reconstruct center pixel in eye space
+    vec3 centerEye = reconstructEyePos(TexCoords, depthLin);
 
-    // 4) Sample neighbors and reconstruct their eye-space positions
-    // We'll do left-right in x direction
+    //////////////////////////////////
+    // 2) Sample neighbors (x direction)
+    //////////////////////////////////
     vec2 uvLeft  = TexCoords + vec2(-uTexelSize.x, 0.0);
     vec2 uvRight = TexCoords + vec2( uTexelSize.x, 0.0);
 
     float depthL = texture(uDepthTex, uvLeft).r;
     float depthR = texture(uDepthTex, uvRight).r;
 
-    vec3 leftEye  = vec3(0.0);
-    vec3 rightEye = vec3(0.0);
-
-    if (depthL >= 0.0 && depthL <= maxDepth) {
-        vec4 clipL = vec4(uvLeft.x * 2.0 - 1.0, uvLeft.y * 2.0 - 1.0, depthL * 2.0 - 1.0, 1.0);
-        vec4 epL   = invProjectionMatrix * clipL;
-        leftEye    = epL.xyz / epL.w;
-    } else {
-        discard; // or skip partial if invalid
-    }
+    // If invalid neighbors, optionally discard
+    if (depthL < 0.0 || depthL > 1.0 || depthL > maxDepth) discard;
+    if (depthR < 0.0 || depthR > 1.0 || depthR > maxDepth) discard;
 
-    if (depthR >= 0.0 && depthR <= maxDepth) {
-        vec4 clipR = vec4(uvRight.x * 2.0 - 1.0, uvRight.y * 2.0 - 1.0, depthR * 2.0 - 1.0, 1.0);
-        vec4 epR   = invProjectionMatrix * clipR;
-        rightEye   = epR.xyz / epR.w;
-    } else {
-        discard;
-    }
+    vec3 leftEye  = reconstructEyePos(uvLeft,  depthL);
+    vec3 rightEye = reconstructEyePos(uvRight, depthR);
 
     // partial derivative in x
     vec3 ddx  = rightEye - centerEye;
     vec3 ddx2 = centerEye - leftEye;
+
+    // Optionally pick whichever has smaller Z difference
     if (abs(ddx2.z) < abs(ddx.z)) {
         ddx = ddx2;
     }
 
-    // 5) same approach for up-down
+    //////////////////////////////////
+    // 3) Sample neighbors (y direction)
+    //////////////////////////////////
     vec2 uvUp = TexCoords + vec2(0.0,  uTexelSize.y);
     vec2 uvDn = TexCoords + vec2(0.0, -uTexelSize.y);
 
     float depthU = texture(uDepthTex, uvUp).r;
     float depthD = texture(uDepthTex, uvDn).r;
 
-    vec3 upEye  = vec3(0.0);
-    vec3 dnEye  = vec3(0.0);
-
-    if (depthU >= 0.0 && depthU <= maxDepth) {
-        vec4 clipU = vec4(uvUp.x * 2.0 - 1.0, uvUp.y * 2.0 - 1.0, depthU * 2.0 - 1.0, 1.0);
-        vec4 epU   = invProjectionMatrix * clipU;
-        upEye      = epU.xyz / epU.w;
-    } else {
-        discard;
-    }
+    if (depthU < 0.0 || depthU > 1.0 || depthU > maxDepth) discard;
+    if (depthD < 0.0 || depthD > 1.0 || depthD > maxDepth) discard;
 
-    if (depthD >= 0.0 && depthD <= maxDepth) {
-        vec4 clipD = vec4(uvDn.x * 2.0 - 1.0, uvDn.y * 2.0 - 1.0, depthD * 2.0 - 1.0, 1.0);
-        vec4 epD   = invProjectionMatrix * clipD;
-        dnEye      = epD.xyz / epD.w;
-    } else {
-        discard;
-    }
+    vec3 upEye = reconstructEyePos(uvUp, depthU);
+    vec3 dnEye = reconstructEyePos(uvDn, depthD);
 
     vec3 ddy  = upEye - centerEye;
     vec3 ddy2 = centerEye - dnEye;
@@ -108,15 +101,17 @@ void main()
         ddy = ddy2;
     }
 
-    // 6) Cross partial derivatives to get normal
+    //////////////////////////////////
+    // 4) Cross partials => normal
+    //////////////////////////////////
     vec3 N = normalize(cross(ddx, ddy));
 
-    // Optionally flip if needed
-    if (N.z > 0.0) {
-        N = -N;
-    }
+    // Some folks invert if N.z > 0
+    //if (N.z > 0.0) {
+    //    N = -N;
+    //}
 
-    // Shift from [-1..1] to [0..1]
+    // Map [-1..1] -> [0..1] for display
     vec3 normalColor = 0.5 * (N + vec3(1.0));
     FragColor = vec4(normalColor, 1.0);
 }
diff --git a/shaders/final_combine.frag b/shaders/final_combine.frag
index 28f4880a32bd4af84356e5411461bc9a242d3ec3..0bf72657801b64b736df7c59f2f4b32dc224a770 100644
--- a/shaders/final_combine.frag
+++ b/shaders/final_combine.frag
@@ -51,7 +51,7 @@ void main()
     }
 
     // Expand [0..1] -> [-1..1], then normalize
-    normal = normalize(normal * 2.0 - 1.0);
+    //normal = normalize(normal * 2.0 - 1.0);
 
     //---------------------------------------------------------
     // 3) Reconstruct eye-space position from depth
@@ -94,8 +94,8 @@ void main()
     //---------------------------------------------------------
     // 6) Multiply by attenuation
     //---------------------------------------------------------
-    lighting *= attenuation;
-
+    //lighting *= attenuation;
+    float alpha = 1 - attenuation;
     //---------------------------------------------------------
     // 7) Fresnel effect
     //---------------------------------------------------------
@@ -112,5 +112,6 @@ void main()
     finalColor     += fluidColor * fresnel;     // tinted Fresnel
 
     // Done
-    FragColor = vec4(finalColor, 1.0);
+    //FragColor = vec4(finalColor, 0.5);
+    FragColor = vec4(normal, 1.0); //vec4(finalColor, 0.5);
 }
diff --git a/shaders/thickness.frag b/shaders/thickness.frag
index d4e13cf0fb6b0514a806a38cbb30913425193093..c97ea00327df46a75fbef7b877c438a98fb5dab7 100644
--- a/shaders/thickness.frag
+++ b/shaders/thickness.frag
@@ -19,7 +19,7 @@ void main()
         discard;
 
     // For thickness: each particle in this pixel adds some amount.
-    float thicknessIncrement = 0.01;
+    float thicknessIncrement = 0.04;
 
     // Output that in the red channel. Using GL32F only reed chanele sotred  
     FragColor = vec4(thicknessIncrement, 0.0, 0.0, 1.0);
diff --git a/src/FluidRenderer.cpp b/src/FluidRenderer.cpp
index edc478bac7c549b43df6523a0defd89b67ed4e16..5ad8d3932963652b702600c15e270a41601455b8 100644
--- a/src/FluidRenderer.cpp
+++ b/src/FluidRenderer.cpp
@@ -816,7 +816,7 @@ void FluidRenderer::renderDepthNormalsFrame()
 
     // 3) Bind the *filtered depth* texture as input
     glActiveTexture(GL_TEXTURE0);
-    glBindTexture(GL_TEXTURE_2D, m_depthFilterProgram.fboTexture);
+    glBindTexture(GL_TEXTURE_2D, m_depthRenderProgram.fboTexture); // temporary to se normals for spheres
     glUniform1i(glGetUniformLocation(m_depthNormalsProgram.programID, "uDepthTex"), 0);
 
     // 4) Set uniforms: zNear, zFar, uTexelSize, maxDepth, etc.
@@ -898,7 +898,7 @@ void FluidRenderer::renderThicknessFrame(size_t particleCount, size_t boundaryCo
 
 void FluidRenderer::renderThicknessFilterFrame()
 {
-    int radius = 5; // or something
+    int radius = 24; // or something
     std::vector<float> weights;
     computeGaussianWeights(radius, weights);
 
@@ -989,7 +989,7 @@ void FluidRenderer::renderThicknessAttenFrame()
     glUniform1i(glGetUniformLocation(m_thicknessAttenProgram.programID, "uThicknessTex"), 0);
 
     // 3) Set uniform: absorption, fluidColor, etc.
-    float absorption = 0.2f; // tweak to taste
+    float absorption = 0.8f; // tweak to taste
     GLuint absorpLoc = glGetUniformLocation(m_thicknessAttenProgram.programID, "absorption");
     glUniform1f(absorpLoc, absorption);
 
@@ -1016,11 +1016,14 @@ void FluidRenderer::renderFinalCombineFrame()
     glBindFramebuffer(GL_FRAMEBUFFER, m_finalCombineProgram.fbo); // Or 0 for screen
     
     glViewport(0, 0, m_fbWidth, m_fbHeight);
-    glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Clear to black
+    glClearColor(1.0f, 1.0f, 1.0f, 1.0f); // Clear to black
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     
     glDisable(GL_DEPTH_TEST); // Disable depth testing for fullscreen quad
     
+    glEnable(GL_BLEND);
+    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);  
+    
     glUseProgram(m_finalCombineProgram.programID);
     
     // Bind the required textures
diff --git a/src/include/FluidSimulationApp.h b/src/include/FluidSimulationApp.h
index e9614d36f3c6dc793dfda4f43a82c5728f1d446f..0211cbf52d1ab6a9ac385e83103359a4679bc041 100644
--- a/src/include/FluidSimulationApp.h
+++ b/src/include/FluidSimulationApp.h
@@ -23,7 +23,7 @@ namespace FluidSimulation
         FluidSimulation* m_fluidSimulation;
          
         bool m_updatePhysics;
-        RenderStage selectedStage = RenderStage::ParticleView;
+        RenderStage selectedStage = RenderStage::ScreenSpacedRender;
     
         void RenderControlPannel();
         void RenderFluidView();