Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add some haze to the distance on water. #3508

Merged
merged 12 commits into from
Feb 6, 2025
Original file line number Diff line number Diff line change
Expand Up @@ -789,9 +789,6 @@ void sampleReflectionProbesWater(inout vec3 ambenv, inout vec3 glossenv,
probeIndex[probeInfluences++] = 0;

doProbeSample(ambenv, glossenv, tc, pos, norm, glossiness, false, amblit);

// fudge factor to get PBR water at a similar luminance ot legacy water
glossenv *= 0.4;
}

void debugTapRefMap(vec3 pos, vec3 dir, float depth, int i, inout vec4 col)
Expand Down
63 changes: 43 additions & 20 deletions indra/newview/app_settings/shaders/class3/environment/waterF.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@

// class3/environment/waterF.glsl

#define WATER_MINIMAL 1

out vec4 frag_color;

#ifdef HAS_SUN_SHADOW
Expand Down Expand Up @@ -122,6 +124,9 @@ vec3 BlendNormal(vec3 bump1, vec3 bump2)
vec3 srgb_to_linear(vec3 col);
vec3 linear_to_srgb(vec3 col);

vec3 atmosLighting(vec3 light);
vec3 scaleSoftClip(vec3 light);

vec3 vN, vT, vB;

vec3 transform_normal(vec3 vNt)
Expand All @@ -148,7 +153,7 @@ void generateWaveNormals(out vec3 wave1, out vec3 wave2, out vec3 wave3)

vec2 bigwave = vec2(refCoord.w, view.w);

vec3 wave1_a = texture(bumpMap, bigwave, -2).xyz * 2.0 - 1.0;
vec3 wave1_a = texture(bumpMap, bigwave).xyz * 2.0 - 1.0;
vec3 wave2_a = texture(bumpMap, littleWave.xy).xyz * 2.0 - 1.0;
vec3 wave3_a = texture(bumpMap, littleWave.zw).xyz * 2.0 - 1.0;

Expand Down Expand Up @@ -183,6 +188,7 @@ void calculateFresnelFactors(out vec3 df3, out vec2 df2, vec3 viewVec, vec3 wave
void main()
{
mirrorClip(vary_position);

vN = vary_normal;
vT = vary_tangent;
vB = cross(vN, vT);
Expand All @@ -202,6 +208,7 @@ void main()

generateWaveNormals(wave1, wave2, wave3);

float dmod = sqrt(dist);
vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5;

vec3 wavef = (wave1 + wave2 * 0.4 + wave3 * 0.6) * 0.5;
Expand All @@ -216,7 +223,7 @@ void main()
vec3 up = transform_normal(vec3(0,0,1));
float vdu = -dot(viewVec, up)*2;

vec3 wave_ibl = wavef;
vec3 wave_ibl = wavef * normScale;
wave_ibl.z *= 2.0;
wave_ibl = transform_normal(normalize(wave_ibl));

Expand All @@ -233,8 +240,6 @@ void main()
float dist2 = dist;
dist = max(dist, 5.0);

float dmod = sqrt(dist);

//figure out distortion vector (ripply)
vec2 distort2 = distort + waver.xy * refScale / max(dmod, 1.0) * 2;

Expand All @@ -254,21 +259,27 @@ void main()
calcAtmosphericVarsLinear(pos.xyz, wavef, vary_light_dir, sunlit, amblit, additive, atten);

vec3 sunlit_linear = srgb_to_linear(sunlit);

float fade = 0;
#ifdef TRANSPARENT_WATER
float depth = texture(depthMap, distort2).r;
vec4 fb = texture(screenTex, distort2);
vec3 refPos = getPositionWithNDC(vec3(distort2*2.0-vec2(1.0), depth*2.0-1.0));
float depth = texture(depthMap, distort).r;

vec3 refPos = getPositionWithNDC(vec3(distort*2.0-vec2(1.0), depth*2.0-1.0));

if (refPos.z > pos.z-0.05)
// Calculate some distance fade in the water to better assist with refraction blending and reducing the refraction texture's "disconnect".
fade = max(0,min(1, (pos.z - refPos.z) / 10));
distort2 = mix(distort, distort2, min(1, fade * 10));

depth = texture(depthMap, distort2).r;

refPos = getPositionWithNDC(vec3(distort2 * 2.0 - vec2(1.0), depth * 2.0 - 1.0));

if (pos.z < refPos.z - 0.05)
{
//we sampled an above water sample, don't distort
distort2 = distort;
fb = texture(screenTex, distort2);
depth = texture(depthMap, distort2).r;
refPos = getPositionWithNDC(vec3(distort2 * 2.0 - vec2(1.0), depth * 2.0 - 1.0));
}

vec4 fb = texture(screenTex, distort2);

#else
vec4 fb = applyWaterFogViewLinear(viewVec*2048.0, vec4(1.0));
#endif
Expand All @@ -280,13 +291,18 @@ void main()
vec3 irradiance = vec3(0);
vec3 radiance = vec3(0);
vec3 legacyenv = vec3(0);

// TODO: Make this an option.
#ifdef WATER_MINIMAL
sampleReflectionProbesWater(irradiance, radiance, distort2, pos.xyz, wave_ibl.xyz, gloss, amblit);
//sampleReflectionProbes(irradiance, radiance, distort2, pos.xyz, wave_ibl.xyz, 1, true, amblit);
//sampleReflectionProbesLegacy(irradiance, radiance, legacyenv, distort2, pos.xyz, wave_ibl.xyz, gloss, 1, false, amblit);
#elif WATER_MINIMAL_PLUS
sampleReflectionProbes(irradiance, radiance, distort2, pos.xyz, wave_ibl.xyz, 1, false, amblit);
#endif

vec3 diffuseColor = vec3(0);
vec3 specularColor = vec3(0);
calcDiffuseSpecular(vec3(1), metallic, diffuseColor, specularColor);
vec3 specular_linear = srgb_to_linear(specular);
calcDiffuseSpecular(specular_linear, metallic, diffuseColor, specularColor);

vec3 v = -normalize(pos.xyz);

Expand All @@ -302,14 +318,21 @@ void main()

pbrPunctual(diffuseColor, specularColor, perceptualRoughness, metallic, normalize(wavef+up*max(dist, 32.0)/32.0*(1.0-vdu)), v, normalize(light_dir), nl, diffPunc, specPunc);

vec3 punctual = clamp(nl * (diffPunc + specPunc), vec3(0), vec3(10)) * sunlit_linear * 2.75 * shadow;
vec3 punctual = clamp(nl * (diffPunc + specPunc), vec3(0), vec3(10)) * sunlit_linear * shadow;

vec3 color = vec3(0);
color = mix(fb.rgb, radiance * df2.y, df2.x * 0.99999) + punctual.rgb;

color = mix(fb.rgb, radiance * df2.x, df2.x * 0.99999) + punctual.rgb;
// This looks super janky, but we do this to restore water haze in the distance.
// These values were finagled in to try and bring back some of the distant brightening on legacy water. Also works reasonably well on PBR skies such as PBR midday.
color += color * min(vec3(4),pow(1 - atten, vec3(1.35)) * 16 * fade);

float spec = min(max(max(punctual.r, punctual.g), punctual.b), 0.05);
// We shorten the fade here at the shoreline so it doesn't appear too soft from a distance.
fade *= 60;
fade = min(1, fade);
color = mix(fb.rgb, color, fade);

frag_color = max(vec4(color.rgb, spec), vec4(0));
float spec = min(max(max(punctual.r, punctual.g), punctual.b), 0.05);
frag_color = min(vec4(1),max(vec4(color.rgb, spec), vec4(0)));
}