#version 330 core
out vec4 FragColor;
in vec3 FragCoord;
in vec3 ourColor;
in vec2 TexCoord;
uniform sampler2DMS screenTexture; // color screen
uniform sampler2D waterDepthTex; // terrain without water
uniform sampler2D sceneDepthTex; // terrain + water
uniform sampler2D sceneStencilTex; // custom 3d text stencils
uniform sampler2D waterHeightTex; // procedural texture for underwater
// (find more water stuff in ..water2.glsl and water_height.glsl)
uniform int viewport_width;
uniform int viewport_height;
uniform int rendMode;
uniform float time;
uniform vec3 data; // hidewater, offset, scale
uniform float daytime; // -1-0-1 night-day-night
uniform int samples;
uniform mat4 invProjection; // Inverse projection matrix
uniform mat4 invView; // Inverse view matrix
uniform vec3 cameraPosition; // Camera's world position
uniform vec3 fogColor; // Underwater fog color, e.g., vec3(0.0, 0.2, 0.3)
// Reconstruct world position from depth
//vec3 getWorldPosition(float depth, vec2 uv) {
// float z = depth * 2.0 - 1.0; // Convert depth from [0,1] to [-1,1]
// vec4 clipSpace = vec4(uv * 2.0 - 1.0, z, 1.0);
// vec4 viewSpace = invProjection * clipSpace;
// viewSpace /= viewSpace.w; // Perspective divide
// vec4 worldSpace = invView * viewSpace;
// return worldSpace.xyz;
//}
// v2
float linearizeDepth(float depth) {
float near=0.1f;
float far=5000.0f;
float z = depth * 2.0 - 1.0; // NDC
return 2.0 * near * far / (far + near - z * (far - near));
}
vec3 getWorldPosition(float depth, vec2 uv, bool linearize) {
float z = linearize ? linearizeDepth(depth) : (depth * 2.0 - 1.0);
vec4 clipSpace = vec4(uv * 2.0 - 1.0, linearize ? depth : z, 1.0);
vec4 viewSpace = invProjection * clipSpace;
viewSpace /= viewSpace.w;
vec4 worldSpace = invView * viewSpace;
return worldSpace.xyz;
}
void main()
{
vec2 uv = gl_FragCoord.xy / vec2(viewport_width,viewport_height);
ivec2 vpCoords = ivec2(gl_FragCoord.x, gl_FragCoord.y);
//////
vec4 sample1 = texelFetch(screenTexture, vpCoords, 0);
vec4 sample2 = texelFetch(screenTexture, vpCoords, 1);
vec4 sample3 = texelFetch(screenTexture, vpCoords, 2);
vec4 sample4 = texelFetch(screenTexture, vpCoords, 3);
vec4 colorSample = (sample1 + sample2 + sample3 + sample4) / 4.0f;
//////// do fancy post processing stuff
vec3 color = vec3(colorSample.r,colorSample.g,colorSample.b);
//vec3 color = vec3(1.0,0.0,0.0); // debug red
float sceneDepth = texture(sceneDepthTex, uv).r;
float waterDepth = texture(waterDepthTex, uv).r;
float stencilDepth = texture(sceneStencilTex, uv).r;
// sceneDepth = terrain with water
// waterDepth = terrain without water
// stencilDepth = text boxes
float depthDiff = (waterDepth - sceneDepth)*1000;
float stencilDiff = sceneDepth - stencilDepth;
float edgeThreshold = .05;
float scale=512.0;
vec2 worldMin = vec2(-scale / 2.0, -scale / 2.0);
vec2 worldMax = vec2(scale / 2.0, scale / 2.0);
float wlev = data.y-1.1;
float heightScale = data.z * 1;
float heightOffset = wlev;
// Sample scene color and depth
//--vec3 color = texture(screenTexture, uv).rgb;
vec3 debug=vec3(0.0,0.0,0.0);
int hiddenWater = int(data.x);
if(hiddenWater==1) {
FragColor = vec4(color,1.0);
} else {
// -- underwater render itself - in water
// Reconstruct world position of the scene point
//vec3 P = getWorldPosition(sceneDepth - depthDiff, uv);
//vec3 P = getWorldPosition(depthDiff, uv);
//vec3 P = getWorldPosition(waterDepth, uv, false);
vec3 P = getWorldPosition(sceneDepth, uv, false);
vec2 waterUV = (P.xz - worldMin) / (worldMax - worldMin);
waterUV = clamp(waterUV, 0.0, 1.0);
//waterUV.x = 1.0-waterUV.x;
//waterUV.y = 1.0-waterUV.y;
//waterUV.xy = waterUV.yx;
//P.y *= depthDiff * 1;
// Sample water height at this (X, Z) position
float waterHeight = texture(waterHeightTex, waterUV).r * (heightScale) + (heightOffset);
//float dhdx = dFdx(waterHeight);
//float dhdy = dFdy(waterHeight);
// Check if the camera is fully underwater (using camera Y vs water height at camera's position)
vec2 camWaterUV = (cameraPosition.xz - worldMin) / (worldMax - worldMin);
camWaterUV = clamp(camWaterUV, 0.0, 1.0);
float camWaterHeight = texture(waterHeightTex, camWaterUV).r * heightScale + heightOffset;
float camDiff = camWaterHeight - cameraPosition.y;
// vec3 tFog = fogColor;
// Initialize output color
float distance = length(P - cameraPosition);
// float fogDistance = 50.0f;
// float fogHeight = 25.0;
// float tFac = clamp(camDiff/fogHeight,1.2,1.8); // min max fac
// float fogFac = clamp(distance / fogDistance, 0.0, 0.5*tFac);
float dt=abs(daytime);
float methodA=dt;
float methodD=(methodA*2);
float methodE=(methodA*2)-1;
// day/night water fog colors blend
vec3 color1 = vec3(0.0,0.1,0.1); // day
vec3 color2 = vec3(0.1,0.26,0.26);
vec3 color3 = vec3(0.1,0.3,0.36); // <<day begin
//
vec3 color4 = vec3(0.02,0.02,0.02); // night
vec3 color5 = vec3(0.02,0.03,0.05);
vec3 color6 = vec3(0.01,0.05,0.07);
vec3 ourColor = vec3(mix(color3,color2,methodD));
ourColor = mix(ourColor,color1,methodE);
vec3 ourColor2 = vec3(mix(color5,color4,methodD));
ourColor2 = mix(ourColor2,color6,methodE);
vec3 fogColor = vec3(mix(ourColor,ourColor2,dt));
vec3 underwaterColor = vec3(0.2, 0.6, 0.8) * (1.15-dt*1.45); // Tint
// //vec3 fogColor = vec3(0.1, 0.3, 0.4);
// //float waterDim=1.0; // surface
// float fogDim=1;
// float hdrBrightness=2.0; // 2.0
// float fogOffset=hdrBrightness-((fogFac*.5)+(fogDim*.5));
bool isCameraUnderwater = camDiff > 1;
//bool isCameraUnderwater = false;
bool isLookingAtWaterSurface = depthDiff > 0.0 && waterDepth < 1.0; // Water in front and not at far plane
float waterSurfaceFac = 0.0f;
float terrainSurfaceFac = 0.0;
if(isCameraUnderwater) { // fully submerged only--
if(isLookingAtWaterSurface) { // surface from below
if(stencilDiff < 0.0) { // stencil front of water
color = mix(color,underwaterColor,1.0-stencilDepth);
debug=vec3(0.5,0.0,0.0); // half red
} else { // water surface
debug=vec3(0.0,0.0,0.5); // half blue
waterSurfaceFac = 1.0;
//color = mix(fogColor, color, clamp(1.0 - (waterSurfaceFac * .3 +(distance*.01)),0.0,1.0)); // surface below
}
} else { // underwater render
debug=vec3(0.0,0.25,0.0); // quart green
terrainSurfaceFac = 1.0;
color = mix(fogColor, color, clamp(1.0 - (terrainSurfaceFac * .4 +(distance*.045)),0.0,1.0)); // underwater fog
}
} else { // not entierly under water/above water
if(stencilDiff < 0.0) { // stencil front of water
color = mix(color,underwaterColor,1.0-stencilDepth);
debug=vec3(1.0,0.0,0.0); // red
} else {
float epsilon = 0.01; // Small threshold for blending
float underwaterFactor = smoothstep(waterHeight - epsilon, waterHeight + epsilon, P.y);
if(underwaterFactor <= 0.0) { // below water pixel
if(!isLookingAtWaterSurface) {
debug=vec3(0.0,0.5,0.0); // half green
terrainSurfaceFac = 1.0;
// the actual underwater fog here
// other lines marked //---- post sshould have press pass
color = mix(fogColor, color, clamp(1.0 - (terrainSurfaceFac * .4 +(distance*.045)),0.0,1.0)); // overwater fog
} else {
debug=vec3(0.0,0.0,0.5); // half blue
waterSurfaceFac = 1.0;
//--color = mix(fogColor, color, clamp(1.0 - (waterSurfaceFac * .3 +(distance*.01)),0.0,1.0));
}
} else { // above water pixel
if(!isLookingAtWaterSurface) {
debug=vec3(0.5,1.0,0.0); // double green
terrainSurfaceFac = .5;
} else {
debug=vec3(0.0,0.0,1.0); // blue
waterSurfaceFac = 1.0;
//--color = mix(fogColor, color, clamp(1.0 - (waterSurfaceFac * .3 +(distance*.01)),0.0,1.0));
}
}
//// Apply depth-based adjustment if needed
//if (depthDiff/100 > 0.0) { // Water is in front
// underwaterFactor = min(underwaterFactor + depthDiff * 10.0, 1.0); // Fine-tune multiplier
//}
}
//underwaterFactor = 1.0f; // clear for debug
}
//vec3 terrainFogDay = vec3(0.3,0.6,0.7);
//vec3 terrainFogNight = vec3(0.001,0.003,0.005);
// day/night terrain fog colors blend
color1 = vec3(0.5,0.3,0.3); // day
color2 = vec3(0.3,0.2,0.3);
color3 = vec3(0.3,0.2,0.2); // <<day begin
//
color4 = vec3(0.3,0.0,0.02); // night
color5 = vec3(0.0,0.05,0.03);
color6 = vec3(0.0,0.0,0.03);
ourColor = vec3(mix(color3,color2,methodD));
ourColor = mix(ourColor,color1,methodE);
ourColor2 = vec3(mix(color5,color4,methodD));
ourColor2 = mix(ourColor2,color6,methodE);
vec3 terrainFogBlend = vec3(mix(ourColor,ourColor2,dt)) * (2.0-dt*4);
float terrainFogDist = 50.0;
float terrainFogFac = distance * terrainFogDist *.001;
terrainFogFac=clamp(terrainFogFac,0.0,0.1);
// consider, fog render and transparent text boxes??
//if(distance<500.0 && stencilDiff > 0.0) { // prevent touching skybox at ~1000
// //----color = mix(underwaterColor, color, 1.0 - (waterSurfaceFac * .4 -.25));
// float epsilon = 120.0; // Small threshold for blending
// float terrainFogEps = smoothstep(distance - epsilon, distance + epsilon, terrainFogFac)*.4+.80; // hdr?
// //----color = mix(terrainFogBlend, color, terrainFogEps);
// //----color = mix(terrainFogBlend, color, terrainFogEps)*tFac*fogOffset;
//} else if(stencilDiff > 0.0) {
// debug=vec3(0.5,0.0,0.5);
//}
//if(stencilDiff < 0.0) { // fog behind text/depth
// color *= .5;
//}
// Output the final color
FragColor = vec4(color, 1.0);
// DEBUG water
////if (camWaterHeight < cameraPosition.y) {
//if (P.y < waterHeight) {
// FragColor = vec4(1.0, 0.0, 0.0, 1.0); // Red for underwater
//} else {
// FragColor = vec4(0.0, 1.0, 0.0, 1.0); // Green for above
//}
//color = vec3(P.x,P.y,P.z);
//FragColor = vec4(color, 1.0);
}
//// Water edge effect
//if (depthDiff < edgeThreshold) {
// vec2 refractUV = uv + vec2(sin(time + uv.y * 10.0) * 0.01, 0.0); // Simple refraction
// ivec2 vpRef = ivec2(refractUV.x, refractUV.y);
// vec4 edgeColor;
// vec4 esample1 = texelFetch(screenTexture, vpCoords, 0);
// edgeColor = esample1;
// FragColor = mix(FragColor, edgeColor, 0.5); // Blend with edge effect
//}
if(rendMode==1) {
float single=(color.r+color.g+color.b)/3 * 2; // B/W
float single2=0.0;
float single3=0.0;
//single2 *= sin(uv.x * 3.14f); // gradient sides
single2 = depthDiff; // waterDepth - sceneDepth = green
FragColor = vec4(single,single2,single3,1.0);
} else if(rendMode==2) {
float single=(color.r+color.g+color.b)/3 * 2;
float single2=0.0;
float single3=0.0;
single = depthDiff; // waterDepth - sceneDepth = red
FragColor = vec4(single,single2,single3,1.0);
} else if(rendMode==3) {
float single=(color.r+color.g+color.b)/3 * 2;
float single2=0.0;
float single3=0.0;
single = 1.0 - stencilDiff; // sceneDepth - stencilDepth = red
FragColor = vec4(single,single2,single3,1.0);
} else if(rendMode==4) { // debug mode
FragColor = vec4(debug, 1.0);
//} else { // 0 using underwater above
//FragColor = vec4(color,1.0);
}
};
Top