diff options
Diffstat (limited to 'indra/newview/app_settings')
11 files changed, 450 insertions, 220 deletions
| diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 4739728bee..1aec56447d 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -12783,7 +12783,7 @@      <key>UpdaterWillingToTest</key>      <map>        <key>Comment</key> -      <string>Whether or not the updater should offer test candidate upgrades.</string> +      <string>Whether or not the updater should offer Beta upgrades.</string>        <key>Persist</key>        <integer>1</integer>        <key>Type</key> diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredTonemap.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredTonemap.glsl index fc6d4d7727..c4610bffac 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredTonemap.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredTonemap.glsl @@ -28,138 +28,11 @@  out vec4 frag_color;  uniform sampler2D diffuseRect; -uniform sampler2D exposureMap; -uniform vec2 screen_res;  in vec2 vary_fragcoord;  vec3 linear_to_srgb(vec3 cl); - -//=============================================================== -// tone mapping taken from Khronos sample implementation -//=============================================================== - -// sRGB => XYZ => D65_2_D60 => AP1 => RRT_SAT -const mat3 ACESInputMat = mat3 -( -    0.59719, 0.07600, 0.02840, -    0.35458, 0.90834, 0.13383, -    0.04823, 0.01566, 0.83777 -); - - -// ODT_SAT => XYZ => D60_2_D65 => sRGB -const mat3 ACESOutputMat = mat3 -( -    1.60475, -0.10208, -0.00327, -    -0.53108,  1.10813, -0.07276, -    -0.07367, -0.00605,  1.07602 -); - -// ACES tone map (faster approximation) -// see: https://knarkowicz.wordpress.com/2016/01/06/aces-filmic-tone-mapping-curve/ -vec3 toneMapACES_Narkowicz(vec3 color) -{ -    const float A = 2.51; -    const float B = 0.03; -    const float C = 2.43; -    const float D = 0.59; -    const float E = 0.14; -    return clamp((color * (A * color + B)) / (color * (C * color + D) + E), 0.0, 1.0); -} - - -// ACES filmic tone map approximation -// see https://github.com/TheRealMJP/BakingLab/blob/master/BakingLab/ACES.hlsl -vec3 RRTAndODTFit(vec3 color) -{ -    vec3 a = color * (color + 0.0245786) - 0.000090537; -    vec3 b = color * (0.983729 * color + 0.4329510) + 0.238081; -    return a / b; -} - - -// tone mapping -vec3 toneMapACES_Hill(vec3 color) -{ -    color = ACESInputMat * color; - -    // Apply RRT and ODT -    color = RRTAndODTFit(color); - -    color = ACESOutputMat * color; - -    // Clamp to [0, 1] -    color = clamp(color, 0.0, 1.0); - -    return color; -} - -// Khronos Neutral tonemapping -// https://github.com/KhronosGroup/ToneMapping/tree/main -// Input color is non-negative and resides in the Linear Rec. 709 color space. -// Output color is also Linear Rec. 709, but in the [0, 1] range. -vec3 PBRNeutralToneMapping( vec3 color ) -{ -  const float startCompression = 0.8 - 0.04; -  const float desaturation = 0.15; - -  float x = min(color.r, min(color.g, color.b)); -  float offset = x < 0.08 ? x - 6.25 * x * x : 0.04; -  color -= offset; - -  float peak = max(color.r, max(color.g, color.b)); -  if (peak < startCompression) return color; - -  const float d = 1. - startCompression; -  float newPeak = 1. - d * d / (peak + d - startCompression); -  color *= newPeak / peak; - -  float g = 1. - 1. / (desaturation * (peak - newPeak) + 1.); -  return mix(color, newPeak * vec3(1, 1, 1), g); -} - -uniform float exposure; -uniform float tonemap_mix; -uniform int tonemap_type; - -vec3 toneMap(vec3 color) -{ -#ifndef NO_POST -    float exp_scale = texture(exposureMap, vec2(0.5,0.5)).r; - -    color *= exposure * exp_scale; - -    vec3 clamped_color = clamp(color.rgb, vec3(0.0), vec3(1.0)); - -    switch(tonemap_type) -    { -    case 0: -        color = PBRNeutralToneMapping(color); -        break; -    case 1: -        color = toneMapACES_Hill(color); -        break; -    } - -    // mix tonemapped and linear here to provide adjustment -    color = mix(clamped_color, color, tonemap_mix); -#endif - -    return color; -} - -//=============================================================== - -void debugExposure(inout vec3 color) -{ -    float exp_scale = texture(exposureMap, vec2(0.5,0.5)).r; -    exp_scale *= 0.5; -    if (abs(vary_fragcoord.y-exp_scale) < 0.01 && vary_fragcoord.x < 0.1) -    { -        color = vec3(1,0,0); -    } -} +vec3 toneMap(vec3 color);  void main()  { diff --git a/indra/newview/app_settings/shaders/class1/deferred/tonemapUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/tonemapUtilF.glsl new file mode 100644 index 0000000000..a63b8d7c2b --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/tonemapUtilF.glsl @@ -0,0 +1,180 @@ +/** + * @file postDeferredTonemap.glsl + * + * $LicenseInfo:firstyear=2024&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2024, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +/*[EXTRA_CODE_HERE]*/ + +uniform sampler2D exposureMap; +uniform vec2 screen_res; +in vec2 vary_fragcoord; + +//=============================================================== +// tone mapping taken from Khronos sample implementation +//=============================================================== + +// sRGB => XYZ => D65_2_D60 => AP1 => RRT_SAT +const mat3 ACESInputMat = mat3 +( +    0.59719, 0.07600, 0.02840, +    0.35458, 0.90834, 0.13383, +    0.04823, 0.01566, 0.83777 +); + + +// ODT_SAT => XYZ => D60_2_D65 => sRGB +const mat3 ACESOutputMat = mat3 +( +    1.60475, -0.10208, -0.00327, +    -0.53108,  1.10813, -0.07276, +    -0.07367, -0.00605,  1.07602 +); + +// ACES tone map (faster approximation) +// see: https://knarkowicz.wordpress.com/2016/01/06/aces-filmic-tone-mapping-curve/ +vec3 toneMapACES_Narkowicz(vec3 color) +{ +    const float A = 2.51; +    const float B = 0.03; +    const float C = 2.43; +    const float D = 0.59; +    const float E = 0.14; +    return clamp((color * (A * color + B)) / (color * (C * color + D) + E), 0.0, 1.0); +} + + +// ACES filmic tone map approximation +// see https://github.com/TheRealMJP/BakingLab/blob/master/BakingLab/ACES.hlsl +vec3 RRTAndODTFit(vec3 color) +{ +    vec3 a = color * (color + 0.0245786) - 0.000090537; +    vec3 b = color * (0.983729 * color + 0.4329510) + 0.238081; +    return a / b; +} + + +// tone mapping +vec3 toneMapACES_Hill(vec3 color) +{ +    color = ACESInputMat * color; + +    // Apply RRT and ODT +    color = RRTAndODTFit(color); + +    color = ACESOutputMat * color; + +    // Clamp to [0, 1] +    color = clamp(color, 0.0, 1.0); + +    return color; +} + +// Khronos Neutral tonemapping +// https://github.com/KhronosGroup/ToneMapping/tree/main +// Input color is non-negative and resides in the Linear Rec. 709 color space. +// Output color is also Linear Rec. 709, but in the [0, 1] range. +vec3 PBRNeutralToneMapping( vec3 color ) +{ +  const float startCompression = 0.8 - 0.04; +  const float desaturation = 0.15; + +  float x = min(color.r, min(color.g, color.b)); +  float offset = x < 0.08 ? x - 6.25 * x * x : 0.04; +  color -= offset; + +  float peak = max(color.r, max(color.g, color.b)); +  if (peak < startCompression) return color; + +  const float d = 1. - startCompression; +  float newPeak = 1. - d * d / (peak + d - startCompression); +  color *= newPeak / peak; + +  float g = 1. - 1. / (desaturation * (peak - newPeak) + 1.); +  return mix(color, newPeak * vec3(1, 1, 1), g); +} + +uniform float exposure; +uniform float tonemap_mix; +uniform int tonemap_type; + +vec3 toneMap(vec3 color) +{ +#ifndef NO_POST +    float exp_scale = texture(exposureMap, vec2(0.5,0.5)).r; + +    color *= exposure * exp_scale; + +    vec3 clamped_color = clamp(color.rgb, vec3(0.0), vec3(1.0)); + +    switch(tonemap_type) +    { +    case 0: +        color = PBRNeutralToneMapping(color); +        break; +    case 1: +        color = toneMapACES_Hill(color); +        break; +    } + +    // mix tonemapped and linear here to provide adjustment +    color = mix(clamped_color, color, tonemap_mix); +#endif + +    return color; +} + + +vec3 toneMapNoExposure(vec3 color) +{ +#ifndef NO_POST +    vec3 clamped_color = clamp(color.rgb, vec3(0.0), vec3(1.0)); + +    switch(tonemap_type) +    { +    case 0: +        color = PBRNeutralToneMapping(color); +        break; +    case 1: +        color = toneMapACES_Hill(color); +        break; +    } + +    // mix tonemapped and linear here to provide adjustment +    color = mix(clamped_color, color, tonemap_mix); +#endif + +    return color; +} + + +//=============================================================== + +void debugExposure(inout vec3 color) +{ +    float exp_scale = texture(exposureMap, vec2(0.5,0.5)).r; +    exp_scale *= 0.5; +    if (abs(vary_fragcoord.y-exp_scale) < 0.01 && vary_fragcoord.x < 0.1) +    { +        color = vec3(1,0,0); +    } +} diff --git a/indra/newview/app_settings/shaders/class1/environment/srgbF.glsl b/indra/newview/app_settings/shaders/class1/environment/srgbF.glsl index d7f6d20547..bf8737615f 100644 --- a/indra/newview/app_settings/shaders/class1/environment/srgbF.glsl +++ b/indra/newview/app_settings/shaders/class1/environment/srgbF.glsl @@ -41,6 +41,26 @@ vec3 srgb_to_linear(vec3 cs)  } + +vec4 srgb_to_linear4(vec4 cs) +{ +    vec4 low_range = cs / vec4(12.92); +    vec4 high_range = pow((cs+vec4(0.055))/vec4(1.055), vec4(2.4)); +    bvec4 lte = lessThanEqual(cs,vec4(0.04045)); + +#ifdef OLD_SELECT +    vec4 result; +    result.r = lte.r ? low_range.r : high_range.r; +    result.g = lte.g ? low_range.g : high_range.g; +    result.b = lte.b ? low_range.b : high_range.b; +    result.a = lte.a ? low_range.a : high_range.a; +    return result; +#else +    return mix(high_range, low_range, lte); +#endif + +} +  vec3 linear_to_srgb(vec3 cl)  {      cl = clamp(cl, vec3(0), vec3(1)); diff --git a/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl b/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl index 20b61e9302..44a979e565 100644 --- a/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl +++ b/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl @@ -66,11 +66,11 @@ vec4 getWaterFogViewNoClip(vec3 pos)      float t2 = kd + ks * es;      float t3 = pow(F, t2*l) - 1.0; -    float L = min(t1/t2*t3, 1.0); +    float L = pow(min(t1/t2*t3, 1.0), 1.0/1.7);      float D = pow(0.98, l*kd); -    return vec4(srgb_to_linear(kc.rgb*L), D); +    return vec4(srgb_to_linear(kc.rgb)*L, D);  }  vec4 getWaterFogView(vec3 pos) diff --git a/indra/newview/app_settings/shaders/class1/objects/simpleColorF.glsl b/indra/newview/app_settings/shaders/class1/objects/simpleColorF.glsl new file mode 100644 index 0000000000..dea76da5a5 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/objects/simpleColorF.glsl @@ -0,0 +1,57 @@ +/** + * @file simpleColorF.glsl + * + * $LicenseInfo:firstyear=2025&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +out vec4 frag_color; + +in vec4 vertex_color; +in vec4 vertex_position; + +uniform vec4 waterPlane; +uniform float waterSign; + +void waterClip(vec3 pos) +{ +    // TODO: make this less branchy +    if (waterSign > 0) +    { +        if ((dot(pos.xyz, waterPlane.xyz) + waterPlane.w) < 0.0) +        { +            discard; +        } +    } +    else +    { +        if ((dot(pos.xyz, waterPlane.xyz) + waterPlane.w) > 0.0) +        { +            discard; +        } +    } +} + +void main() +{ + +    frag_color = vertex_color; +} diff --git a/indra/newview/app_settings/shaders/class1/objects/simpleNoAtmosV.glsl b/indra/newview/app_settings/shaders/class1/objects/simpleNoAtmosV.glsl new file mode 100644 index 0000000000..4564e56313 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/objects/simpleNoAtmosV.glsl @@ -0,0 +1,43 @@ +/** + * @file simpleNoAtmosV.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +uniform mat4 modelview_matrix; +uniform mat4 modelview_projection_matrix; + +uniform vec4 color; + +in vec3 position; + +out vec4 vertex_color; +out vec4 vertex_position; + +void main() +{ +    //transform vertex +    vec4 pos = (modelview_matrix * vec4(position.xyz, 1.0)); +    vertex_position = modelview_projection_matrix * vec4(position.xyz, 1.0); +    gl_Position = vertex_position; +    vertex_color = color; +} diff --git a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl index 6df0403198..2f577f8459 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl @@ -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) diff --git a/indra/newview/app_settings/shaders/class3/deferred/waterHazeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/waterHazeF.glsl index 2bf785e773..091c25d15e 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/waterHazeF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/waterHazeF.glsl @@ -35,13 +35,25 @@ vec4 getWaterFogView(vec3 pos);  uniform int above_water; +uniform sampler2D exclusionTex; +  void main()  {      vec2  tc           = vary_fragcoord.xy/vary_fragcoord.w*0.5+0.5;      float depth        = getDepth(tc.xy); +    float mask = texture(exclusionTex, tc.xy).r;      if (above_water > 0)      { +        // Just discard if we're in the exclusion mask. +        // The previous invisiprim hack we're replacing would also crank up water fog desntiy. +        // But doing that makes exclusion surfaces very slow as we'd need to render even more into the mask. +        // - Geenz 2025-02-06 +        if (mask < 1) +        { +            discard; +        } +          // we want to depth test when the camera is above water, but some GPUs have a hard time          // with depth testing against render targets that are bound for sampling in the same shader          // so we do it manually here @@ -51,11 +63,13 @@ void main()          {              discard;          } +      }      vec4  pos          = getPositionWithDepth(tc, depth);      vec4 fogged = getWaterFogView(pos.xyz); +    fogged.a = max(pow(fogged.a, 1.7), 0);      frag_color = max(fogged, vec4(0)); //output linear since local lights will be added to this shader's results diff --git a/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl b/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl index 1c02dc764d..fa410e9f11 100644 --- a/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl +++ b/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl @@ -26,6 +26,7 @@  out vec4 frag_color;  uniform sampler2D bumpMap; +uniform sampler2D exclusionTex;  #ifdef TRANSPARENT_WATER  uniform sampler2D screenTex; @@ -59,6 +60,9 @@ void mirrorClip(vec3 position);  void main()  {      mirrorClip(vary_position); +    vec2 screen_tc = (refCoord.xy/refCoord.z) * 0.5 + 0.5; +    float water_mask = texture(exclusionTex, screen_tc).r; +      vec4 color;      //get detail normals @@ -68,8 +72,8 @@ void main()      vec3 wavef = normalize(wave1+wave2+wave3);      //figure out distortion vector (ripply) -    vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5; -    distort = distort+wavef.xy*refScale; +    vec2 distort = screen_tc; +    distort = mix(distort, distort+wavef.xy*refScale, water_mask);  #ifdef TRANSPARENT_WATER      vec4 fb = texture(screenTex, distort); diff --git a/indra/newview/app_settings/shaders/class3/environment/waterF.glsl b/indra/newview/app_settings/shaders/class3/environment/waterF.glsl index 84c287fc50..028813ef23 100644 --- a/indra/newview/app_settings/shaders/class3/environment/waterF.glsl +++ b/indra/newview/app_settings/shaders/class3/environment/waterF.glsl @@ -25,6 +25,8 @@  // class3/environment/waterF.glsl +#define WATER_MINIMAL 1 +  out vec4 frag_color;  #ifdef HAS_SUN_SHADOW @@ -86,23 +88,17 @@ uniform sampler2D screenTex;  uniform sampler2D depthMap;  #endif -uniform sampler2D refTex; +uniform sampler2D exclusionTex; -uniform float sunAngle; -uniform float sunAngle2; +uniform int classic_mode;  uniform vec3 lightDir;  uniform vec3 specular; -uniform float lightExp; +uniform float blurMultiplier;  uniform float refScale;  uniform float kd; -uniform vec2 screenRes;  uniform vec3 normScale;  uniform float fresnelScale;  uniform float fresnelOffset; -uniform float blurMultiplier; -uniform vec4 waterFogColor; -uniform vec3 waterFogColorLinear; -  //bigWave is (refCoord.w, view.w);  in vec4 refCoord; @@ -122,6 +118,10 @@ 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 toneMapNoExposure(vec3 color); +  vec3 vN, vT, vB;  vec3 transform_normal(vec3 vNt) @@ -132,59 +132,107 @@ vec3 transform_normal(vec3 vNt)  void sampleReflectionProbesWater(inout vec3 ambenv, inout vec3 glossenv,          vec2 tc, vec3 pos, vec3 norm, float glossiness, vec3 amblit_linear); +void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv, +        vec2 tc, vec3 pos, vec3 norm, float glossiness, bool transparent, vec3 amblit_linear); + +void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyenv, +        vec2 tc, vec3 pos, vec3 norm, float glossiness, float envIntensity, bool transparent, vec3 amblit); + +  vec3 getPositionWithNDC(vec3 ndc); +void generateWaveNormals(out vec3 wave1, out vec3 wave2, out vec3 wave3) +{ +    // Generate all of our wave normals. +    // We layer these back and forth. + +    vec2 bigwave = vec2(refCoord.w, view.w); + +    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; + +    vec3 wave1_b = texture(bumpMap2, bigwave).xyz * 2.0 - 1.0; +    vec3 wave2_b = texture(bumpMap2, littleWave.xy).xyz * 2.0 - 1.0; +    vec3 wave3_b = texture(bumpMap2, littleWave.zw).xyz * 2.0 - 1.0; + +    wave1 = BlendNormal(wave1_a, wave1_b); +    wave2 = BlendNormal(wave2_a, wave2_b); +    wave3 = BlendNormal(wave3_a, wave3_b); +} + +void calculateFresnelFactors(out vec3 df3, out vec2 df2, vec3 viewVec, vec3 wave1, vec3 wave2, vec3 wave3, vec3 wavef) +{ +    // We calculate the fresnel here. +    // We do this by getting the dot product for each sets of waves, and applying scale and offset. + +    df3 = max(vec3(0), vec3( +        dot(viewVec, wave1), +        dot(viewVec, (wave2 + wave3) * 0.5), +        dot(viewVec, wave3) +    ) * fresnelScale + fresnelOffset); + +    df3 *= df3; + +    df2 = max(vec2(0), vec2( +        df3.x + df3.y + df3.z, +        dot(viewVec, wavef) * fresnelScale + fresnelOffset +    )); +} +  void main()  {      mirrorClip(vary_position); +      vN = vary_normal;      vT = vary_tangent;      vB = cross(vN, vT);      vec3 pos = vary_position.xyz; +    float linear_depth = 1.0 / -pos.z;      float dist = length(pos.xyz);      //normalize view vector      vec3 viewVec = normalize(pos.xyz); -    //get wave normals -    vec2 bigwave = vec2(refCoord.w, view.w); -    vec3 wave1_a = texture(bumpMap, bigwave, -2.0    ).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; +    // Setup our waves. -    vec3 wave1_b = texture(bumpMap2, bigwave      ).xyz*2.0-1.0; -    vec3 wave2_b = texture(bumpMap2, littleWave.xy).xyz*2.0-1.0; -    vec3 wave3_b = texture(bumpMap2, littleWave.zw).xyz*2.0-1.0; +    vec3 wave1 = vec3(0, 0, 1); +    vec3 wave2 = vec3(0, 0, 1); +    vec3 wave3 = vec3(0, 0, 1); -    //wave1_a = wave2_a = wave3_a = wave1_b = wave2_b = wave3_b = vec3(0,0,1); - -    vec3 wave1 = BlendNormal(wave1_a, wave1_b); -    vec3 wave2 = BlendNormal(wave2_a, wave2_b); -    vec3 wave3 = BlendNormal(wave3_a, wave3_b); +    generateWaveNormals(wave1, wave2, wave3); +    float dmod = sqrt(dist);      vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5; -    //wave1 = transform_normal(wave1); -    //wave2 = transform_normal(wave2); -    //wave3 = transform_normal(wave3); -      vec3 wavef = (wave1 + wave2 * 0.4 + wave3 * 0.6) * 0.5; +    vec3 df3 = vec3(0); +    vec2 df2 = vec2(0); + +    vec3 sunlit; +    vec3 amblit; +    vec3 additive; +    vec3 atten; +    calcAtmosphericVarsLinear(pos.xyz, wavef, vary_light_dir, sunlit, amblit, additive, atten); + +    calculateFresnelFactors(df3, df2, normalize(view.xyz), wave1, wave2, wave3, wavef); +      vec3 waver = wavef*3.0;      vec3 up = transform_normal(vec3(0,0,1));      float vdu = -dot(viewVec, up)*2.0; -    vec3 wave_ibl = wavef; +    vec3 wave_ibl = wavef * normScale;      wave_ibl.z *= 2.0;      wave_ibl = transform_normal(normalize(wave_ibl));      vec3 norm = transform_normal(normalize(wavef));      vdu = clamp(vdu, 0.0, 1.0); -    wavef.z *= max(vdu*vdu*vdu, 0.1); +    //wavef.z *= max(vdu*vdu*vdu, 0.1);      wavef = normalize(wavef); @@ -194,62 +242,66 @@ 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); +    vec2 distort2 = distort + waver.xy * refScale / max(dmod, 1.0) * 2.0;      distort2 = clamp(distort2, vec2(0), vec2(0.999)); -    vec3 sunlit; -    vec3 amblit; -    vec3 additive; -    vec3 atten; -      float shadow = 1.0f; +    float water_mask = texture(exclusionTex, distort).r; +  #ifdef HAS_SUN_SHADOW      shadow = sampleDirectionalShadow(pos.xyz, norm.xyz, distort);  #endif -    calcAtmosphericVarsLinear(pos.xyz, wavef, vary_light_dir, sunlit, amblit, additive, atten); -      vec3 sunlit_linear = srgb_to_linear(sunlit); - +    float fade = 0.0;  #ifdef TRANSPARENT_WATER -    vec4 fb = texture(screenTex, distort2); -    float depth = texture(depthMap, distort2).r; -    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)); + +    // Calculate some distance fade in the water to better assist with refraction blending and reducing the refraction texture's "disconnect". +    fade = max(0.0,min(1.0, (pos.z - refPos.z) / 10.0)) * water_mask; +    distort2 = mix(distort, distort2, min(1.0, fade * 10.0)); +    depth = texture(depthMap, distort2).r; + +    refPos = getPositionWithNDC(vec3(distort2 * 2.0 - vec2(1.0), depth * 2.0 - 1.0)); -    if (refPos.z > pos.z-0.05) +    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 -    // fudge sample on other side of water to be a tad darker -    fb.rgb *= 0.75; +    if (water_mask < 1.0) +        discard; +#endif -    float metallic = 0.0; -    float perceptualRoughness = 0.05; +    float metallic = 1.0; +    float perceptualRoughness = blurMultiplier;      float gloss      = 1.0 - perceptualRoughness;      vec3  irradiance = vec3(0);      vec3  radiance  = vec3(0); -    sampleReflectionProbesWater(irradiance, radiance, distort2, pos.xyz, wave_ibl.xyz, gloss, amblit); +    vec3 legacyenv = vec3(0); -    irradiance       = vec3(0); +    // TODO: Make this an option. +#ifdef WATER_MINIMAL +    sampleReflectionProbesWater(irradiance, radiance, distort2, pos.xyz, wave_ibl.xyz, gloss, amblit); +#elif WATER_MINIMAL_PLUS +    sampleReflectionProbes(irradiance, radiance, distort2, pos.xyz, wave_ibl.xyz, gloss, 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); @@ -257,46 +309,36 @@ void main()      float ao = 1.0;      vec3 light_dir = transform_normal(lightDir); -    perceptualRoughness = 0.0; -    metallic = 1.0; -      float NdotV = clamp(abs(dot(norm, v)), 0.001, 1.0); -    float nl = 0; +    float nl = 0.0;      vec3 diffPunc = vec3(0);      vec3 specPunc = vec3(0); -    pbrPunctual(vec3(0), specularColor, 0.1, 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)); - -    vec3 color = punctual * sunlit_linear * 2.75 * shadow; -    vec3 iblDiff; -    vec3 iblSpec; -    pbrIbl(vec3(0), vec3(1), radiance, vec3(0), ao, NdotV, 0.0, iblDiff, iblSpec); - -    color += iblDiff + iblSpec; +    pbrPunctual(diffuseColor, specularColor, perceptualRoughness, metallic, normalize(wavef+up*max(dist, 32.0)/32.0*(1.0-vdu)), v, normalize(light_dir), nl, diffPunc, specPunc); -    float nv = clamp(abs(dot(norm.xyz, v)), 0.001, 1.0); -    vec2 brdf = BRDF(clamp(nv, 0.0, 1.0), 1.0); -    float f = 1.0-brdf.y; //1.0 - (brdf.x+brdf.y); -    f *= 0.9; -    f *= f; +    vec3 punctual = clamp(nl * (diffPunc + specPunc), vec3(0), vec3(10)) * sunlit_linear * shadow; +    radiance *= df2.y; +    //radiance = toneMapNoExposure(radiance); +    vec3 color = vec3(0); +    color = mix(fb.rgb, radiance, min(1.0, df2.x)) + punctual.rgb; -    // incoming scale is [0, 1] with 0.5 being default -    // shift to 0.5 to 1.5 -    f *= (fresnelScale - 0.5)+1.0; +    float water_haze_scale = 4.0; -    // incoming offset is [0, 1] with 0.5 being default -    // shift from -1 to 1 -    f += (fresnelOffset - 0.5) * 2.0; +    if (classic_mode > 0) +        water_haze_scale = 1.0; -    f = clamp(f, 0.0, 1.0); +    // 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 = mix(color, additive * water_haze_scale, (1 - atten)); -    color = ((1.0 - f) * color) + fb.rgb; +    // We shorten the fade here at the shoreline so it doesn't appear too soft from a distance. +    fade *= 60.0; +    fade = min(1.0, fade); +    color = mix(fb.rgb, color, fade); -    float spec = min(max(max(punctual.r, punctual.g), punctual.b), 0.05); +    float spec = min(max(max(punctual.r, punctual.g), punctual.b), 0.0); -    frag_color = max(vec4(color, spec), vec4(0)); +    frag_color = min(vec4(1),max(vec4(color.rgb, spec * water_mask), vec4(0)));  } | 
