diff --git a/shaders/final_combine.frag b/shaders/final_combine.frag index 0bf72657801b64b736df7c59f2f4b32dc224a770..4fd4e2b32fd3f3f11dcb22fc9dcdc0995ea9b4c8 100644 --- a/shaders/final_combine.frag +++ b/shaders/final_combine.frag @@ -3,115 +3,105 @@ in vec2 TexCoords; out vec4 FragColor; -// Samplers for the required textures -uniform sampler2D uNormalsTex; // from depthNormalsProgram -uniform sampler2D uLightAttenTex;// from thicknessAttenProgram (R=attenuation) -uniform sampler2D uDepthTex; // from depthFilterProgram (R=linearDepth) - -// Camera parameters -uniform mat4 invProjectionMatrix; // For reconstructing position -uniform vec3 viewPos; // Camera/Eye position in *eye space* - -// Lighting parameters -uniform vec3 lightPos; // Light pos in eye space -uniform vec3 lightColor; -uniform vec3 fluidColor; -uniform float shininess; - -// Fresnel parameters +// Samplers +uniform sampler2D uNormalsTex; +uniform sampler2D uLightAttenTex;// not used in the example +uniform sampler2D uDepthTex; + +// Camera/eye parameters +uniform mat4 invProjectionMatrix; +uniform float zNear; +uniform float zFar; + +// If your camera is at the origin in eye space, +// then viewPos = (0,0,0). +// If for some reason it's not, you can pass that in. +uniform vec3 viewPos; + +// Light in eye space +uniform vec3 lightPos; +uniform vec3 lightColor; + +// Material +uniform vec3 fluidColor; +uniform float shininess; + +// Fresnel uniform float fresnelPower; uniform float fresnelScale; uniform float fresnelBias; -void main() +/////////////////////////////////////////// +// Helper: Reconstruct eye position +/////////////////////////////////////////// +vec3 reconstructEyePos(vec2 uv, float depthLin) { - //--------------------------------------------------------- - // 1) Grab the attenuation from the Red channel - //--------------------------------------------------------- - float attenuation = texture(uLightAttenTex, TexCoords).r; - - // Quick check: If attenuation is near 1.0 => likely background => paint white - if (attenuation > 0.9999) { - FragColor = vec4(1.0, 1.0, 1.0, 1.0); // White background - return; - } + float dEye = depthLin * (zFar - zNear) + zNear; - //--------------------------------------------------------- - // 2) Reconstruct normal - // If background is not written in the normal pass, - // we should skip or clamp if normal=0. - //--------------------------------------------------------- - vec3 normal = texture(uNormalsTex, TexCoords).rgb; - // If no fluid was there, normal might be (0,0,0). - // Let's skip if length(normal) < small threshold: - if (length(normal) < 0.001) { - // Also background => white - FragColor = vec4(1.0); - return; - } + vec2 ndc = uv * 2.0 - 1.0; + vec4 clip = vec4(ndc, -1.0, 1.0); + vec4 eye4 = invProjectionMatrix * clip; + vec3 dir = eye4.xyz / eye4.w; + dir = normalize(dir); - // Expand [0..1] -> [-1..1], then normalize - //normal = normalize(normal * 2.0 - 1.0); + return dEye * dir; +} - //--------------------------------------------------------- - // 3) Reconstruct eye-space position from depth - //--------------------------------------------------------- +void main() +{ + //--------------------------------------- + // 1) Depth => Position + //--------------------------------------- float depthLin = texture(uDepthTex, TexCoords).r; - // If your background is ~1.0 in depth as well, skip it: if (depthLin >= 0.9999) { + // probably background FragColor = vec4(1.0); return; } + vec3 position = reconstructEyePos(TexCoords, depthLin); + + //--------------------------------------- + // 2) Normal + //--------------------------------------- + vec3 packedNormal = texture(uNormalsTex, TexCoords).rgb; + if (length(packedNormal) < 0.001) { + // background => skip + FragColor = vec4(1.0); + return; + } + // Unpack from [0..1] => [-1..1] + vec3 normal = normalize(packedNormal * 2.0 - 1.0); - // Convert [0..1] -> clipZ in [-1..1] - vec4 clipSpacePos = vec4(TexCoords * 2.0 - 1.0, depthLin * 2.0 - 1.0, 1.0); - vec4 eyeSpacePos = invProjectionMatrix * clipSpacePos; - eyeSpacePos /= eyeSpacePos.w; - vec3 position = eyeSpacePos.xyz; - - //--------------------------------------------------------- - // 4) Lighting vectors - //--------------------------------------------------------- + //--------------------------------------- + // 3) Basic Blinn-Phong + //--------------------------------------- + // Eye space camera position might be (0,0,0) vec3 viewDir = normalize(viewPos - position); vec3 lightDir = normalize(lightPos - position); vec3 halfDir = normalize(lightDir + viewDir); - //--------------------------------------------------------- - // 5) Blinn-Phong shading - //--------------------------------------------------------- + // ambient + diffuse + spec vec3 ambient = 0.1 * lightColor; - float ndl = max(dot(normal, lightDir), 0.0); vec3 diffuse = ndl * lightColor; - float ndh = max(dot(normal, halfDir), 0.0); float spec = pow(ndh, shininess); vec3 specular = spec * lightColor; - // Combine them (still ignoring fluid color): vec3 lighting = ambient + diffuse + specular; - //--------------------------------------------------------- - // 6) Multiply by attenuation - //--------------------------------------------------------- - //lighting *= attenuation; - float alpha = 1 - attenuation; - //--------------------------------------------------------- - // 7) Fresnel effect - //--------------------------------------------------------- + //--------------------------------------- + // 4) Fresnel (optional) + //--------------------------------------- float cosTheta = max(dot(viewDir, normal), 0.0); float fresnel = fresnelBias + fresnelScale * pow((1.0 - cosTheta), fresnelPower); - - //--------------------------------------------------------- - // 8) Combine fluid color, lighting, Fresnel - //--------------------------------------------------------- - // Common approach: fluid color tints the base lighting: + + // fluid color tinted by fresnel vec3 finalColor = fluidColor * lighting; - // Optionally add a Fresnel highlight tinted by fluidColor or lightColor: - // e.g. finalColor += lightColor * fresnel; // white-ish Fresnel - finalColor += fluidColor * fresnel; // tinted Fresnel + finalColor += fluidColor * fresnel; - // Done - //FragColor = vec4(finalColor, 0.5); - FragColor = vec4(normal, 1.0); //vec4(finalColor, 0.5); + //--------------------------------------- + // 5) Output + //--------------------------------------- + FragColor = vec4(finalColor, 1.0); } diff --git a/src/FluidRenderer.cpp b/src/FluidRenderer.cpp index 5ad8d3932963652b702600c15e270a41601455b8..0427c37663bc8660ddccb026cdd6a34faeb03e70 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_depthRenderProgram.fboTexture); // temporary to se normals for spheres + glBindTexture(GL_TEXTURE_2D, m_depthFilterProgram.fboTexture); // temporary to se normals for spheres glUniform1i(glGetUniformLocation(m_depthNormalsProgram.programID, "uDepthTex"), 0); // 4) Set uniforms: zNear, zFar, uTexelSize, maxDepth, etc.