diff options
Diffstat (limited to 'indra/newview/app_settings/shaders')
57 files changed, 1643 insertions, 194 deletions
| diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarEyesV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarEyesV.glsl index 83b0ba096c..43863dd37a 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarEyesV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarEyesV.glsl @@ -26,6 +26,7 @@  uniform mat3 normal_matrix;  uniform mat4 texture_matrix0;  uniform mat4 modelview_projection_matrix; +uniform mat4 modelview_matrix;  in vec3 position;  in vec3 normal; @@ -35,10 +36,12 @@ in vec2 texcoord0;  out vec3 vary_normal;  out vec4 vertex_color;  out vec2 vary_texcoord0; +out vec3 vary_position;  void main()  {  	//transform vertex +	vary_position = (modelview_matrix * vec4(position.xyz, 1.0)).xyz;  	gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);   	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl index 6ebe4ce251..db7597dd74 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl @@ -25,7 +25,7 @@  /*[EXTRA_CODE_HERE]*/ -out vec4 frag_data[3]; +out vec4 frag_data[4];  uniform sampler2D diffuseMap; @@ -33,11 +33,14 @@ uniform float minimum_alpha;  in vec3 vary_normal;  in vec2 vary_texcoord0; +in vec3 vary_position; -vec2 encode_normal(vec3 n); +void mirrorClip(vec3 pos);  void main()   { +    mirrorClip(vary_position); +  	vec4 diff = texture(diffuseMap, vary_texcoord0.xy);  	if (diff.a < minimum_alpha) @@ -48,6 +51,7 @@ void main()  	frag_data[0] = vec4(diff.rgb, 0.0);  	frag_data[1] = vec4(0,0,0,0);  	vec3 nvn = normalize(vary_normal); -	frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, GBUFFER_FLAG_HAS_ATMOS); +	frag_data[2] = vec4(nvn.xyz, GBUFFER_FLAG_HAS_ATMOS); +    frag_data[3] = vec4(0);  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl index bc0c11ec46..5cc2846156 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl @@ -35,6 +35,7 @@ in vec4 weight;  out vec3 vary_normal;  out vec2 vary_texcoord0; +out vec3 vary_position;  void main()  { @@ -57,6 +58,7 @@ void main()  	vary_normal = norm; +    vary_position = pos.xyz;  	gl_Position = projection_matrix * pos;  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl index 08baf98686..8627ab1852 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl @@ -40,12 +40,12 @@ uniform float kern_scale;  in vec2 vary_fragcoord;  vec4 getPosition(vec2 pos_screen); -vec3 getNorm(vec2 pos_screen); +vec4 getNorm(vec2 pos_screen);  void main()   {      vec2 tc = vary_fragcoord.xy; -    vec3 norm = getNorm(tc); +    vec4 norm = getNorm(tc);      vec3 pos = getPosition(tc).xyz;      vec4 ccol = texture(lightMap, tc).rgba; diff --git a/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl b/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl index 35f483f633..8483f257fa 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl @@ -37,11 +37,13 @@ in vec3 vary_mat2;  in vec4 vertex_color;  in vec2 vary_texcoord0; +in vec3 vary_position; -vec2 encode_normal(vec3 n); - +void mirrorClip(vec3 pos);  void main()   { +    mirrorClip(vary_position); +  	vec4 col = texture(diffuseMap, vary_texcoord0.xy);  	if(col.a < minimum_alpha) @@ -60,6 +62,6 @@ void main()  		frag_data[1] = vertex_color.aaaa; // spec  		//frag_data[1] = vec4(vec3(vertex_color.a), vertex_color.a+(1.0-vertex_color.a)*vertex_color.a); // spec - from former class3 - maybe better, but not so well tested  		vec3 nvn = normalize(tnorm); -		frag_data[2] = vec4(encode_normal(nvn), vertex_color.a, GBUFFER_FLAG_HAS_ATMOS); -        frag_data[3] = vec4(0); +		frag_data[2] = vec4(nvn, GBUFFER_FLAG_HAS_ATMOS); +        frag_data[3] = vec4(vertex_color.a, 0, 0, 0);  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl b/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl index 3af2eab1e4..74319349f6 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl @@ -23,6 +23,7 @@   * $/LicenseInfo$   */ +uniform mat4 modelview_matrix;  uniform mat3 normal_matrix;  uniform mat4 texture_matrix0;  uniform mat4 modelview_projection_matrix; @@ -38,11 +39,11 @@ out vec3 vary_mat1;  out vec3 vary_mat2;  out vec4 vertex_color;  out vec2 vary_texcoord0; +out vec3 vary_position;  #ifdef HAS_SKIN  mat4 getObjectSkinnedTransform();  uniform mat4 projection_matrix; -uniform mat4 modelview_matrix;  #endif  void main() @@ -52,11 +53,13 @@ void main()      mat4 mat = getObjectSkinnedTransform();  	mat = modelview_matrix * mat;  	vec3 pos = (mat*vec4(position.xyz, 1.0)).xyz; +    vary_position = pos;  	gl_Position = projection_matrix*vec4(pos, 1.0);  	vec3 n = normalize((mat * vec4(normal.xyz+position.xyz, 1.0)).xyz-pos.xyz);  	vec3 t = normalize((mat * vec4(tangent.xyz+position.xyz, 1.0)).xyz-pos.xyz);  #else +    vary_position = (modelview_matrix*vec4(position.xyz, 1.0)).xyz;  	gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);   	vec3 n = normalize(normal_matrix * normal);  	vec3 t = normalize(normal_matrix * tangent.xyz); diff --git a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl index f9ebf33b4a..f6696e270c 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl @@ -50,6 +50,7 @@ SOFTWARE.  uniform sampler2D   normalMap;  uniform sampler2D   depthMap; +uniform sampler2D emissiveRect;  uniform sampler2D projectionMap; // rgba  uniform sampler2D brdfLut; @@ -140,40 +141,20 @@ vec2 getScreenCoordinate(vec2 screenpos)      return sc - vec2(1.0, 1.0);  } -// See: https://aras-p.info/texts/CompactNormalStorage.html -//      Method #4: Spheremap Transform, Lambert Azimuthal Equal-Area projection -vec3 getNorm(vec2 screenpos) +vec4 getNorm(vec2 screenpos)  { -   vec2 enc = texture(normalMap, screenpos.xy).xy; -   vec2 fenc = enc*4-2; -   float f = dot(fenc,fenc); -   float g = sqrt(1-f/4); -   vec3 n; -   n.xy = fenc*g; -   n.z = 1-f/2; -   return n; -} - -vec3 getNormalFromPacked(vec4 packedNormalEnvIntensityFlags) -{ -   vec2 enc = packedNormalEnvIntensityFlags.xy; -   vec2 fenc = enc*4-2; -   float f = dot(fenc,fenc); -   float g = sqrt(1-f/4); -   vec3 n; -   n.xy = fenc*g; -   n.z = 1-f/2; -   return normalize(n); // TODO: Is this normalize redundant? +    return texture(normalMap, screenpos.xy);  }  // return packedNormalEnvIntensityFlags since GBUFFER_FLAG_HAS_PBR needs .w  // See: C++: addDeferredAttachments(), GLSL: softenLightF  vec4 getNormalEnvIntensityFlags(vec2 screenpos, out vec3 n, out float envIntensity)  { -    vec4 packedNormalEnvIntensityFlags = texture(normalMap, screenpos.xy); -    n = getNormalFromPacked( packedNormalEnvIntensityFlags ); -    envIntensity = packedNormalEnvIntensityFlags.z; -    return packedNormalEnvIntensityFlags; +    vec4 norm = texture(normalMap, screenpos.xy); +    n = norm.xyz; +    envIntensity = texture(emissiveRect, screenpos.xy).r; + +    return norm;  }  // get linear depth value given a depth buffer sample d and znear and zfar values diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl index 6f3b94f734..82d5d363d2 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl @@ -31,14 +31,18 @@ uniform float minimum_alpha;  uniform sampler2D diffuseMap; +in vec3 vary_position; +  in vec3 vary_normal;  in vec4 vertex_color;  in vec2 vary_texcoord0; -vec2 encode_normal(vec3 n); +void mirrorClip(vec3 pos);  void main()   { +    mirrorClip(vary_position); +  	vec4 col = texture(diffuseMap, vary_texcoord0.xy) * vertex_color;  	if (col.a < minimum_alpha) @@ -49,7 +53,7 @@ void main()  	frag_data[0] = vec4(col.rgb, 0.0);  	frag_data[1] = vec4(0,0,0,0); // spec  	vec3 nvn = normalize(vary_normal); -	frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, GBUFFER_FLAG_HAS_ATMOS); +	frag_data[2] = vec4(nvn.xyz, GBUFFER_FLAG_HAS_ATMOS);      frag_data[3] = vec4(0);  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl index e5f2af2c53..788ea633fc 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl @@ -28,16 +28,19 @@  out vec4 frag_data[4];  in vec3 vary_normal; +in vec3 vary_position;  uniform float minimum_alpha;  in vec4 vertex_color;  in vec2 vary_texcoord0; -vec2 encode_normal(vec3 n); +void mirrorClip(vec3 pos);  void main()   { +    mirrorClip(vary_position); +  	vec4 col = diffuseLookup(vary_texcoord0.xy) * vertex_color;  	if (col.a < minimum_alpha) @@ -48,6 +51,6 @@ void main()  	frag_data[0] = vec4(col.rgb, 0.0);  	frag_data[1] = vec4(0,0,0,0);  	vec3 nvn = normalize(vary_normal); -	frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, GBUFFER_FLAG_HAS_ATMOS); +	frag_data[2] = vec4(nvn.xyz, GBUFFER_FLAG_HAS_ATMOS);      frag_data[3] = vec4(0);  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl index 234f096ed5..22e6d60419 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl @@ -34,8 +34,6 @@ uniform sampler2D diffuseMap;  in vec3 vary_normal;  in vec2 vary_texcoord0; -vec2 encode_normal(vec3 n); -  void main()   {  	vec4 col = texture(diffuseMap, vary_texcoord0.xy); @@ -48,7 +46,7 @@ void main()  	frag_data[0] = vec4(col.rgb, 0.0);  	frag_data[1] = vec4(0,0,0,0); // spec  	vec3 nvn = normalize(vary_normal); -	frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, GBUFFER_FLAG_HAS_ATMOS); +	frag_data[2] = vec4(nvn.xyz, GBUFFER_FLAG_HAS_ATMOS);      frag_data[3] = vec4(0);  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl index 68fb8bf499..799fc62a42 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl @@ -32,17 +32,19 @@ uniform sampler2D diffuseMap;  in vec3 vary_normal;  in vec4 vertex_color;  in vec2 vary_texcoord0; +in vec3 vary_position; -vec2 encode_normal(vec3 n); +void mirrorClip(vec3 pos);  void main()   { +    mirrorClip(vary_position);  	vec3 col = vertex_color.rgb * texture(diffuseMap, vary_texcoord0.xy).rgb;  	frag_data[0] = vec4(col, 0.0);  	frag_data[1] = vertex_color.aaaa; // spec  	//frag_data[1] = vec4(vec3(vertex_color.a), vertex_color.a+(1.0-vertex_color.a)*vertex_color.a); // spec - from former class3 - maybe better, but not so well tested  	vec3 nvn = normalize(vary_normal); -	frag_data[2] = vec4(encode_normal(nvn.xyz), vertex_color.a, GBUFFER_FLAG_HAS_ATMOS); -    frag_data[3] = vec4(0); +	frag_data[2] = vec4(nvn.xyz, GBUFFER_FLAG_HAS_ATMOS); +    frag_data[3] = vec4(vertex_color.a, 0, 0, 0);  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl index 93d561504e..3362a180c6 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl @@ -30,12 +30,14 @@ out vec4 frag_data[4];  in vec3 vary_normal;  in vec4 vertex_color;  in vec2 vary_texcoord0; +in vec3 vary_position; -vec2 encode_normal(vec3 n); +void mirrorClip(vec3 pos);  vec3 linear_to_srgb(vec3 c);  void main()   { +    mirrorClip(vary_position);  	vec3 col = vertex_color.rgb * diffuseLookup(vary_texcoord0.xy).rgb;  	vec3 spec; @@ -44,6 +46,6 @@ void main()  	frag_data[0] = vec4(col, 0.0);  	frag_data[1] = vec4(spec, vertex_color.a); // spec  	vec3 nvn = normalize(vary_normal); -	frag_data[2] = vec4(encode_normal(nvn.xyz), vertex_color.a, GBUFFER_FLAG_HAS_ATMOS); -    frag_data[3] = vec4(0); +	frag_data[2] = vec4(nvn.xyz, GBUFFER_FLAG_HAS_ATMOS); +    frag_data[3] = vec4(vertex_color.a, 0, 0, 0);  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl index 2402cc3b70..64230dc680 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl @@ -36,13 +36,16 @@ out vec3 vary_normal;  out vec4 vertex_color;  out vec2 vary_texcoord0; +out vec3 vary_position;  void passTextureIndex(); +uniform mat4 modelview_matrix; +  #ifdef HAS_SKIN  mat4 getObjectSkinnedTransform();  uniform mat4 projection_matrix; -uniform mat4 modelview_matrix; +  #endif  void main() @@ -51,9 +54,11 @@ void main()      mat4 mat = getObjectSkinnedTransform();      mat = modelview_matrix * mat;      vec4 pos = mat * vec4(position.xyz, 1.0); +    vary_position = pos.xyz;      gl_Position = projection_matrix * pos;      vary_normal = normalize((mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz);  #else +    vary_position = (modelview_matrix * vec4(position.xyz, 1.0)).xyz;  	gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);       vary_normal = normalize(normal_matrix * normal);  #endif diff --git a/indra/newview/app_settings/shaders/class1/deferred/exposureF.glsl b/indra/newview/app_settings/shaders/class1/deferred/exposureF.glsl index 9ac4ceb37e..eff7221ae7 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/exposureF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/exposureF.glsl @@ -28,7 +28,9 @@  out vec4 frag_color;  uniform sampler2D emissiveRect; +#ifdef USE_LAST_EXPOSURE  uniform sampler2D exposureMap; +#endif  uniform float dt;  uniform vec2 noiseVec; @@ -51,10 +53,12 @@ void main()      L /= max_L;      L = pow(L, 2.0);      float s = mix(dynamic_exposure_params.z, dynamic_exposure_params.y, L); - +     +#ifdef USE_LAST_EXPOSURE      float prev = texture(exposureMap, vec2(0.5,0.5)).r;      s = mix(prev, s, min(dt*2.0*abs(prev-s), 0.04)); +#endif      frag_color = max(vec4(s, s, s, dt), vec4(0.0));  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl index a6fab10791..52dfed06ae 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl @@ -50,9 +50,11 @@ void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, ou  vec4 applySkyAndWaterFog(vec3 pos, vec3 additive, vec3 atten, vec4 color);  #endif +void mirrorClip(vec3 pos); +  void main()   { - +    mirrorClip(vary_position);  #ifdef IS_ALPHA      waterClip(vary_position.xyz);  #endif diff --git a/indra/newview/app_settings/shaders/class1/deferred/globalF.glsl b/indra/newview/app_settings/shaders/class1/deferred/globalF.glsl new file mode 100644 index 0000000000..7e3e7d9271 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/globalF.glsl @@ -0,0 +1,45 @@ +/**  + * @file class1/deferred/globalF.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$ + */ + + + // Global helper functions included in every fragment shader + // DO NOT declare sampler uniforms here as OS X doesn't compile + // them out + +uniform float mirror_flag; +uniform vec4 clipPlane; +uniform float clipSign; + +void mirrorClip(vec3 pos) +{ +    if (mirror_flag > 0) +    { +        if ((dot(pos.xyz, clipPlane.xyz) + clipPlane.w) < 0.0) +        { +                discard; +        } +    } +} + diff --git a/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl b/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl index aae595f619..c64f65e32c 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl @@ -37,7 +37,6 @@ uniform sampler2D specularMap;  in vec2 vary_texcoord0;  vec3 linear_to_srgb(vec3 c); -vec2 encode_normal (vec3 n);  void main()   { @@ -53,6 +52,6 @@ void main()  	frag_data[0] = vec4(col.rgb, 0.0);  	frag_data[1] = spec; -	frag_data[2] = vec4(encode_normal(norm.xyz),0,GBUFFER_FLAG_HAS_ATMOS); +	frag_data[2] = vec4(norm.xyz, GBUFFER_FLAG_HAS_ATMOS);      frag_data[3] = vec4(0);  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl b/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl index c8afacf9bb..95b2f80e06 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl @@ -34,6 +34,8 @@ in vec2 vary_fragcoord;  uniform sampler2D diffuseRect;  uniform sampler2D emissiveRect; +uniform sampler2D normalMap; +uniform float diffuse_luminance_scale;  float lum(vec3 col)  { @@ -45,7 +47,21 @@ void main()  {      vec2 tc = vary_fragcoord*0.6+0.2;      tc.y -= 0.1; // HACK - nudge exposure sample down a little bit to favor ground over sky -    vec3 c = texture(diffuseRect, tc).rgb + texture(emissiveRect, tc).rgb; +    vec3 c = texture(diffuseRect, tc).rgb; +     +    vec4  norm         = texture(normalMap, tc); + +    if (!GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_HDRI) && +        !GET_GBUFFER_FLAG(GBUFFER_FLAG_SKIP_ATMOS)) +    { +        // Apply the diffuse luminance scale to objects but not the sky +        // Prevents underexposing when looking at bright environments +        // while still allowing for realistically bright skies. +        c *= diffuse_luminance_scale; +    } + +    c += texture(emissiveRect, tc).rgb; +      float L = lum(c);      frag_color = vec4(max(L, 0.0));  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl index 7cdddfe8db..ddf878ae60 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl @@ -28,25 +28,18 @@  #define DIFFUSE_ALPHA_MODE_MASK 2  #define DIFFUSE_ALPHA_MODE_EMISSIVE 3 -#ifdef HAS_SKIN  uniform mat4 modelview_matrix;  uniform mat4 projection_matrix; +uniform mat4 modelview_projection_matrix; + +#ifdef HAS_SKIN  mat4 getObjectSkinnedTransform();  #else  uniform mat3 normal_matrix; -uniform mat4 modelview_projection_matrix; -#endif - -#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND) - -#if !defined(HAS_SKIN) -uniform mat4 modelview_matrix;  #endif  out vec3 vary_position; -#endif -  uniform mat4 texture_matrix0;  in vec3 position; @@ -85,9 +78,7 @@ void main()  	vec3 pos = (mat*vec4(position.xyz,1.0)).xyz; -#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)  	vary_position = pos; -#endif  	gl_Position = projection_matrix*vec4(pos,1.0); @@ -133,10 +124,8 @@ void main()  	vertex_color = diffuse_color; -#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)  #if !defined(HAS_SKIN)  	vary_position = (modelview_matrix*vec4(position.xyz, 1.0)).xyz;  #endif -#endif  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/moonF.glsl b/indra/newview/app_settings/shaders/class1/deferred/moonF.glsl index 183354b9bd..6ef556d7e8 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/moonF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/moonF.glsl @@ -55,7 +55,7 @@ void main()      frag_data[0] = vec4(0);      frag_data[1] = vec4(0.0); -    frag_data[2] = vec4(0.0, 0.0, 0.0, GBUFFER_FLAG_HAS_ATMOS); +    frag_data[2] = vec4(0.0, 0.0, 0.0, GBUFFER_FLAG_SKIP_ATMOS);      frag_data[3] = vec4(c.rgb, c.a);      // Added and commented out for a ground truth.  Do not uncomment - Geenz diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrShadowAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrShadowAlphaMaskF.glsl index 1d1545be7e..35b7602569 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrShadowAlphaMaskF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrShadowAlphaMaskF.glsl @@ -35,7 +35,7 @@ uniform float minimum_alpha;  void main()   { -    float alpha = texture(diffuseMap,vary_texcoord0.xy).a; +    float alpha = texture(diffuseMap,vary_texcoord0.xy).a * vertex_color.a;      if (alpha < minimum_alpha)      { diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl index faa273b834..380d493636 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl @@ -54,21 +54,31 @@ in vec2 emissive_texcoord;  uniform float minimum_alpha; // PBR alphaMode: MASK, See: mAlphaCutoff, setAlphaCutoff() -vec2 encode_normal(vec3 n);  vec3 linear_to_srgb(vec3 c);  vec3 srgb_to_linear(vec3 c); +uniform vec4 clipPlane; +uniform float clipSign; + +void mirrorClip(vec3 pos); +  uniform mat3 normal_matrix;  void main()  { +    mirrorClip(vary_position); +      vec4 basecolor = texture(diffuseMap, base_color_texcoord.xy).rgba; +    basecolor.rgb = srgb_to_linear(basecolor.rgb); + +    basecolor *= vertex_color; +      if (basecolor.a < minimum_alpha)      {          discard;      } -    vec3 col = vertex_color.rgb * srgb_to_linear(basecolor.rgb); +    vec3 col = basecolor.rgb;      // from mikktspace.com      vec3 vNt = texture(bumpMap, normal_texcoord.xy).xyz*2.0-1.0; @@ -102,8 +112,8 @@ void main()      //emissive = tnorm*0.5+0.5;      // See: C++: addDeferredAttachments(), GLSL: softenLightF      frag_data[0] = max(vec4(col, 0.0), vec4(0));                                                   // Diffuse -    frag_data[1] = max(vec4(spec.rgb,vertex_color.a), vec4(0));                                    // PBR linear packed Occlusion, Roughness, Metal. -    frag_data[2] = max(vec4(encode_normal(tnorm), vertex_color.a, GBUFFER_FLAG_HAS_PBR), vec4(0)); // normal, environment intensity, flags +    frag_data[1] = max(vec4(spec.rgb,0.0), vec4(0));                                    // PBR linear packed Occlusion, Roughness, Metal. +    frag_data[2] = vec4(tnorm, GBUFFER_FLAG_HAS_PBR); // normal, environment intensity, flags      frag_data[3] = max(vec4(emissive,0), vec4(0));                                                // PBR sRGB Emissive  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl index 160ae7a215..5e0141910b 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl @@ -28,8 +28,9 @@  //deferred opaque implementation -#ifdef HAS_SKIN  uniform mat4 modelview_matrix; + +#ifdef HAS_SKIN  uniform mat4 projection_matrix;  mat4 getObjectSkinnedTransform();  #else @@ -59,6 +60,7 @@ out vec4 vertex_color;  out vec3 vary_tangent;  flat out float vary_sign;  out vec3 vary_normal; +out vec3 vary_position;  vec2 texture_transform(vec2 vertex_texcoord, vec4[2] khr_gltf_transform, mat4 sl_animation_transform);  vec3 tangent_space_transform(vec4 vertex_tangent, vec3 vertex_normal, vec4[2] khr_gltf_transform, mat4 sl_animation_transform); @@ -71,10 +73,11 @@ void main()  	mat = modelview_matrix * mat;  	vec3 pos = (mat*vec4(position.xyz,1.0)).xyz; - +    vary_position = pos;  	gl_Position = projection_matrix*vec4(pos,1.0);  #else +    vary_position = (modelview_matrix*vec4(position.xyz, 1.0)).xyz;  	//transform vertex  	gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);   #endif diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl new file mode 100644 index 0000000000..2efd50a46a --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl @@ -0,0 +1,401 @@ +/**  + * @file class1\deferred\terrainF.glsl + * + * $LicenseInfo:firstyear=2023&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2023, 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]*/ + +#define TERRAIN_PBR_DETAIL_EMISSIVE 0 +#define TERRAIN_PBR_DETAIL_OCCLUSION -1 +#define TERRAIN_PBR_DETAIL_NORMAL -2 +#define TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS -3 + +#if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3 +#define TerrainCoord vec4[3] +#elif TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 1 +#define TerrainCoord vec2 +#endif + +#define MIX_X    1 << 3 +#define MIX_Y    1 << 4 +#define MIX_Z    1 << 5 +#define MIX_W    1 << 6 + +struct TerrainMix +{ +    vec4 weight; +    int type; +}; + +TerrainMix get_terrain_mix_weights(float alpha1, float alpha2, float alphaFinal); + +struct PBRMix +{ +    vec4 col;       // RGB color with alpha, linear space +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION) +    vec3 orm;       // Occlusion, roughness, metallic +#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS) +    vec2 rm;        // Roughness, metallic +#endif +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL) +    vec3 vNt;       // Unpacked normal texture sample, vector +#endif +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) +    vec3 emissive;  // RGB emissive color, linear space +#endif +}; + +PBRMix init_pbr_mix(); + +PBRMix terrain_sample_and_multiply_pbr( +    TerrainCoord terrain_coord +    , sampler2D tex_col +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS) +    , sampler2D tex_orm +#endif +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL) +    , sampler2D tex_vNt +#endif +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) +    , sampler2D tex_emissive +#endif +    , vec4 factor_col +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION) +    , vec3 factor_orm +#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS) +    , vec2 factor_rm +#endif +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) +    , vec3 factor_emissive +#endif +    ); + +PBRMix mix_pbr(PBRMix mix1, PBRMix mix2, float mix2_weight); + +out vec4 frag_data[4]; + +uniform sampler2D alpha_ramp; + +// https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#additional-textures +uniform sampler2D detail_0_base_color; +uniform sampler2D detail_1_base_color; +uniform sampler2D detail_2_base_color; +uniform sampler2D detail_3_base_color; +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL) +uniform sampler2D detail_0_normal; +uniform sampler2D detail_1_normal; +uniform sampler2D detail_2_normal; +uniform sampler2D detail_3_normal; +#endif +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS) +uniform sampler2D detail_0_metallic_roughness; +uniform sampler2D detail_1_metallic_roughness; +uniform sampler2D detail_2_metallic_roughness; +uniform sampler2D detail_3_metallic_roughness; +#endif +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) +uniform sampler2D detail_0_emissive; +uniform sampler2D detail_1_emissive; +uniform sampler2D detail_2_emissive; +uniform sampler2D detail_3_emissive; +#endif + +uniform vec4[4] baseColorFactors; // See also vertex_color in pbropaqueV.glsl +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS) +uniform vec4 metallicFactors; +uniform vec4 roughnessFactors; +#endif +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) +uniform vec3[4] emissiveColors; +#endif +uniform vec4 minimum_alphas; // PBR alphaMode: MASK, See: mAlphaCutoff, setAlphaCutoff() + +#if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3 +in vec4[10] vary_coords; +#elif TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 1 +in vec4[2] vary_coords; +#endif +in vec3 vary_position; +in vec3 vary_normal; +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL) +in vec3 vary_tangents[4]; +flat in float vary_sign; +#endif +in vec4 vary_texcoord0; +in vec4 vary_texcoord1; + +void mirrorClip(vec3 position); + +float terrain_mix(TerrainMix tm, vec4 tms4); + +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL) +// from mikktspace.com +vec3 mikktspace(vec3 vNt, vec3 vT) +{ +    vec3 vN = vary_normal; +     +    vec3 vB = vary_sign * cross(vN, vT); +    vec3 tnorm = normalize( vNt.x * vT + vNt.y * vB + vNt.z * vN ); + +    tnorm *= gl_FrontFacing ? 1.0 : -1.0; + +    return tnorm; +} +#endif + +void main() +{ +    // Make sure we clip the terrain if we're in a mirror. +    mirrorClip(vary_position); + +    float alpha1 = texture(alpha_ramp, vary_texcoord0.zw).a; +    float alpha2 = texture(alpha_ramp,vary_texcoord1.xy).a; +    float alphaFinal = texture(alpha_ramp, vary_texcoord1.zw).a; + +    TerrainMix tm = get_terrain_mix_weights(alpha1, alpha2, alphaFinal); + +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION) +    // RGB = Occlusion, Roughness, Metal +    // default values, see LLViewerTexture::sDefaultPBRORMImagep +    //   occlusion 1.0 +    //   roughness 0.0 +    //   metal     0.0 +    vec3[4] orm_factors; +    orm_factors[0] = vec3(1.0, roughnessFactors.x, metallicFactors.x); +    orm_factors[1] = vec3(1.0, roughnessFactors.y, metallicFactors.y); +    orm_factors[2] = vec3(1.0, roughnessFactors.z, metallicFactors.z); +    orm_factors[3] = vec3(1.0, roughnessFactors.w, metallicFactors.w); +#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS) +    vec2[4] rm_factors; +    rm_factors[0] = vec2(roughnessFactors.x, metallicFactors.x); +    rm_factors[1] = vec2(roughnessFactors.y, metallicFactors.y); +    rm_factors[2] = vec2(roughnessFactors.z, metallicFactors.z); +    rm_factors[3] = vec2(roughnessFactors.w, metallicFactors.w); +#endif + +    PBRMix mix = init_pbr_mix(); +    PBRMix mix2; +    TerrainCoord terrain_texcoord; +    switch (tm.type & MIX_X) +    { +    case MIX_X: +#if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3 +        terrain_texcoord[0].xy = vary_coords[0].xy; +        terrain_texcoord[0].zw = vary_coords[0].zw; +        terrain_texcoord[1].xy = vary_coords[1].xy; +        terrain_texcoord[1].zw = vary_coords[1].zw; +        terrain_texcoord[2].xy = vary_coords[2].xy; +#elif TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 1 +        terrain_texcoord = vary_coords[0].xy; +#endif +        mix2 = terrain_sample_and_multiply_pbr( +            terrain_texcoord +            , detail_0_base_color +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS) +            , detail_0_metallic_roughness +#endif +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL) +            , detail_0_normal +#endif +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) +            , detail_0_emissive +#endif +            , baseColorFactors[0] +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION) +            , orm_factors[0] +#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS) +            , rm_factors[0] +#endif +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) +            , emissiveColors[0] +#endif +        ); +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL) +        mix2.vNt = mikktspace(mix2.vNt, vary_tangents[0]); +#endif +        mix = mix_pbr(mix, mix2, tm.weight.x); +        break; +    default: +        break; +    } +    switch (tm.type & MIX_Y) +    { +    case MIX_Y: +#if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3 +        terrain_texcoord[0].xy = vary_coords[2].zw; +        terrain_texcoord[0].zw = vary_coords[3].xy; +        terrain_texcoord[1].xy = vary_coords[3].zw; +        terrain_texcoord[1].zw = vary_coords[4].xy; +        terrain_texcoord[2].xy = vary_coords[4].zw; +#elif TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 1 +        terrain_texcoord = vary_coords[0].zw; +#endif +        mix2 = terrain_sample_and_multiply_pbr( +            terrain_texcoord +            , detail_1_base_color +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS) +            , detail_1_metallic_roughness +#endif +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL) +            , detail_1_normal +#endif +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) +            , detail_1_emissive +#endif +            , baseColorFactors[1] +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION) +            , orm_factors[1] +#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS) +            , rm_factors[1] +#endif +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) +            , emissiveColors[1] +#endif +        ); +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL) +        mix2.vNt = mikktspace(mix2.vNt, vary_tangents[1]); +#endif +        mix = mix_pbr(mix, mix2, tm.weight.y); +        break; +    default: +        break; +    } +    switch (tm.type & MIX_Z) +    { +    case MIX_Z: +#if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3 +        terrain_texcoord[0].xy = vary_coords[5].xy; +        terrain_texcoord[0].zw = vary_coords[5].zw; +        terrain_texcoord[1].xy = vary_coords[6].xy; +        terrain_texcoord[1].zw = vary_coords[6].zw; +        terrain_texcoord[2].xy = vary_coords[7].xy; +#elif TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 1 +        terrain_texcoord = vary_coords[1].xy; +#endif +        mix2 = terrain_sample_and_multiply_pbr( +            terrain_texcoord +            , detail_2_base_color +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS) +            , detail_2_metallic_roughness +#endif +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL) +            , detail_2_normal +#endif +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) +            , detail_2_emissive +#endif +            , baseColorFactors[2] +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION) +            , orm_factors[2] +#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS) +            , rm_factors[2] +#endif +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) +            , emissiveColors[2] +#endif +        ); +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL) +        mix2.vNt = mikktspace(mix2.vNt, vary_tangents[2]); +#endif +        mix = mix_pbr(mix, mix2, tm.weight.z); +        break; +    default: +        break; +    } +    switch (tm.type & MIX_W) +    { +    case MIX_W: +#if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3 +        terrain_texcoord[0].xy = vary_coords[7].zw; +        terrain_texcoord[0].zw = vary_coords[8].xy; +        terrain_texcoord[1].xy = vary_coords[8].zw; +        terrain_texcoord[1].zw = vary_coords[9].xy; +        terrain_texcoord[2].xy = vary_coords[9].zw; +#elif TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 1 +        terrain_texcoord = vary_coords[1].zw; +#endif +        mix2 = terrain_sample_and_multiply_pbr( +            terrain_texcoord +            , detail_3_base_color +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS) +            , detail_3_metallic_roughness +#endif +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL) +            , detail_3_normal +#endif +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) +            , detail_3_emissive +#endif +            , baseColorFactors[3] +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION) +            , orm_factors[3] +#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS) +            , rm_factors[3] +#endif +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) +            , emissiveColors[3] +#endif +        ); +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL) +        mix2.vNt = mikktspace(mix2.vNt, vary_tangents[3]); +#endif +        mix = mix_pbr(mix, mix2, tm.weight.w); +        break; +    default: +        break; +    } + +    float minimum_alpha = terrain_mix(tm, minimum_alphas); +    if (mix.col.a < minimum_alpha) +    { +        discard; +    } +    float base_color_factor_alpha = terrain_mix(tm, vec4(baseColorFactors[0].z, baseColorFactors[1].z, baseColorFactors[2].z, baseColorFactors[3].z)); + +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL) +    vec3 tnorm = normalize(mix.vNt); +#else +    vec3 tnorm = vary_normal; +#endif +    tnorm *= gl_FrontFacing ? 1.0 : -1.0; +    + +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) +#define emissive mix.emissive +#else +#define emissive vec3(0) +#endif +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION) +#define orm mix.orm +#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS) +#define orm vec3(1.0, mix.rm) +#else +// Matte plastic potato terrain +#define orm vec3(1.0, 1.0, 0.0) +#endif +    frag_data[0] = max(vec4(mix.col.xyz, 0.0), vec4(0));                                                   // Diffuse +    frag_data[1] = max(vec4(orm.rgb, base_color_factor_alpha), vec4(0));                                    // PBR linear packed Occlusion, Roughness, Metal. +    frag_data[2] = vec4(tnorm, GBUFFER_FLAG_HAS_PBR); // normal, flags +    frag_data[3] = max(vec4(emissive,0), vec4(0));                                                // PBR sRGB Emissive +} + diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl new file mode 100644 index 0000000000..7a7fd783ec --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl @@ -0,0 +1,468 @@ +/**  + * @file class1\deferred\pbrterrainUtilF.glsl + * + * $LicenseInfo:firstyear=2023&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2023, 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]*/ + +/** + * Triplanar mapping implementation adapted from Inigo Quilez' example shader, + * MIT license. + * https://www.shadertoy.com/view/MtsGWH + * Copyright © 2015 Inigo Quilez + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: The above copyright + * notice and this permission notice shall be included in all copies or + * substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", + * WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED + * TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#define TERRAIN_PBR_DETAIL_EMISSIVE 0 +#define TERRAIN_PBR_DETAIL_OCCLUSION -1 +#define TERRAIN_PBR_DETAIL_NORMAL -2 +#define TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS -3 + +in vec3 vary_vertex_normal; + +vec3 srgb_to_linear(vec3 c); + +// A relatively agressive threshold for terrain material mixing sampling +// cutoff. This ensures that only one or two materials are used in most places, +// making PBR terrain blending more performant. Should be greater than 0 to work. +#define TERRAIN_RAMP_MIX_THRESHOLD 0.1 +// A small threshold for triplanar mapping sampling cutoff. This and +// TERRAIN_TRIPLANAR_BLEND_FACTOR together ensures that only one or two samples +// per texture are used in most places, making triplanar mapping more +// performant. Should be greater than 0 to work. +// There's also an artistic design choice in the use of these factors, and the +// use of triplanar generally. Don't take these triplanar constants for granted. +#define TERRAIN_TRIPLANAR_MIX_THRESHOLD 0.01 + +#define SAMPLE_X 1 << 0 +#define SAMPLE_Y 1 << 1 +#define SAMPLE_Z 1 << 2 +#define MIX_X    1 << 3 +#define MIX_Y    1 << 4 +#define MIX_Z    1 << 5 +#define MIX_W    1 << 6 + +struct PBRMix +{ +    vec4 col;       // RGB color with alpha, linear space +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION) +    vec3 orm;       // Occlusion, roughness, metallic +#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS) +    vec2 rm;        // Roughness, metallic +#endif +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL) +    vec3 vNt;       // Unpacked normal texture sample, vector +#endif +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) +    vec3 emissive;  // RGB emissive color, linear space +#endif +}; + +PBRMix init_pbr_mix() +{ +    PBRMix mix; +    mix.col = vec4(0); +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION) +    mix.orm = vec3(0); +#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS) +    mix.rm = vec2(0); +#endif +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL) +    mix.vNt = vec3(0); +#endif +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) +    mix.emissive = vec3(0); +#endif +    return mix; +} + +// Usage example, for two weights: +// vec2 weights = ... // Weights must add up to 1 +// PBRMix mix = init_pbr_mix(); +// PBRMix mix1 = ... +// mix = mix_pbr(mix, mix1, weights.x); +// PBRMix mix2 = ... +// mix = mix_pbr(mix, mix2, weights.y); +PBRMix mix_pbr(PBRMix mix1, PBRMix mix2, float mix2_weight) +{ +    PBRMix mix; +    mix.col      = mix1.col      + (mix2.col      * mix2_weight); +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION) +    mix.orm      = mix1.orm      + (mix2.orm      * mix2_weight); +#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS) +    mix.rm       = mix1.rm       + (mix2.rm       * mix2_weight); +#endif +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL) +    mix.vNt      = mix1.vNt      + (mix2.vNt      * mix2_weight); +#endif +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) +    mix.emissive = mix1.emissive + (mix2.emissive * mix2_weight); +#endif +    return mix; +} + +PBRMix sample_pbr( +    vec2 uv +    , sampler2D tex_col +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS) +    , sampler2D tex_orm +#endif +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL) +    , sampler2D tex_vNt +#endif +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) +    , sampler2D tex_emissive +#endif +    ) +{ +    PBRMix mix; +    mix.col = texture(tex_col, uv); +    mix.col.rgb = srgb_to_linear(mix.col.rgb); +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION) +    mix.orm = texture(tex_orm, uv).xyz; +#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS) +    mix.rm = texture(tex_orm, uv).yz; +#endif +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL) +    mix.vNt = texture(tex_vNt, uv).xyz*2.0-1.0; +#endif +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) +    mix.emissive = srgb_to_linear(texture(tex_emissive, uv).xyz); +#endif +    return mix; +} + +struct TerrainTriplanar +{ +    vec3 weight; +    int type; +}; + +struct TerrainMix +{ +    vec4 weight; +    int type; +}; + +#define TerrainMixSample vec4[4] +#define TerrainMixSample3 vec3[4] + +TerrainMix get_terrain_mix_weights(float alpha1, float alpha2, float alphaFinal) +{ +    TerrainMix tm; +    vec4 sample_x = vec4(1,0,0,0); +    vec4 sample_y = vec4(0,1,0,0); +    vec4 sample_z = vec4(0,0,1,0); +    vec4 sample_w = vec4(0,0,0,1); + +    tm.weight = mix( mix(sample_w, sample_z, alpha2), mix(sample_y, sample_x, alpha1), alphaFinal ); +    tm.weight -= TERRAIN_RAMP_MIX_THRESHOLD; +    ivec4 usage = max(ivec4(0), ivec4(ceil(tm.weight))); +    // Prevent negative weights and keep weights balanced +    tm.weight = tm.weight*vec4(usage); +    tm.weight /= (tm.weight.x + tm.weight.y + tm.weight.z + tm.weight.w); + +    tm.type = (usage.x * MIX_X) | +              (usage.y * MIX_Y) | +              (usage.z * MIX_Z) | +              (usage.w * MIX_W); +    return tm; +} + +TerrainTriplanar _t_triplanar() +{ +    float sharpness = TERRAIN_TRIPLANAR_BLEND_FACTOR; +    float threshold = TERRAIN_TRIPLANAR_MIX_THRESHOLD; +    vec3 weight_signed = pow(abs(vary_vertex_normal), vec3(sharpness)); +    weight_signed /= (weight_signed.x + weight_signed.y + weight_signed.z); +    weight_signed -= vec3(threshold); +    TerrainTriplanar tw; +    // *NOTE: Make sure the threshold doesn't affect the materials +    tw.weight = max(vec3(0), weight_signed); +    tw.weight /= (tw.weight.x + tw.weight.y + tw.weight.z); +    ivec3 usage = ivec3(round(max(vec3(0), sign(weight_signed)))); +    tw.type = ((usage.x) * SAMPLE_X) | +              ((usage.y) * SAMPLE_Y) | +              ((usage.z) * SAMPLE_Z); +    return tw; +} + +// Assume weights add to 1 +float terrain_mix(TerrainMix tm, vec4 tms4) +{ +    return (tm.weight.x * tms4[0]) + +           (tm.weight.y * tms4[1]) + +           (tm.weight.z * tms4[2]) + +           (tm.weight.w * tms4[3]); +} + +#if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3 +// Triplanar mapping + +// Pre-transformed texture coordinates for each axial uv slice (Packing: xy, yz, (-x)z, unused) +#define TerrainCoord vec4[3] + +// If sign_or_zero is positive, use uv_unflippped, otherwise use uv_flipped +vec2 _t_uv(vec2 uv_unflipped, vec2 uv_flipped, float sign_or_zero) +{ +    return mix(uv_flipped, uv_unflipped, max(0.0, sign_or_zero)); +} + +vec3 _t_normal_post_1(vec3 vNt0, float sign_or_zero) +{ +    // Assume normal is unpacked +    vec3 vNt1 = vNt0; +    // Get sign +    float sign = sign_or_zero; +    // Handle case where sign is 0 +    sign = (2.0*sign) + 1.0; +    sign /= abs(sign); +    // If the sign is negative, rotate normal by 180 degrees +    vNt1.xy = (min(0, sign) * vNt1.xy) + (min(0, -sign) * -vNt1.xy); +    return vNt1; +} + +// Triplanar-specific normal texture fixes +vec3 _t_normal_post_x(vec3 vNt0) +{ +    vec3 vNt_x = _t_normal_post_1(vNt0, sign(vary_vertex_normal.x)); +    // *HACK: Transform normals according to orientation of the UVs +    vNt_x.xy = vec2(-vNt_x.y, vNt_x.x); +    return vNt_x; +} +vec3 _t_normal_post_y(vec3 vNt0) +{ +    vec3 vNt_y = _t_normal_post_1(vNt0, sign(vary_vertex_normal.y)); +    // *HACK: Transform normals according to orientation of the UVs +    vNt_y.xy = -vNt_y.xy; +    return vNt_y; +} +vec3 _t_normal_post_z(vec3 vNt0) +{ +    vec3 vNt_z = _t_normal_post_1(vNt0, sign(vary_vertex_normal.z)); +    return vNt_z; +} + +PBRMix terrain_sample_pbr( +    TerrainCoord terrain_coord +    , TerrainTriplanar tw +    , sampler2D tex_col +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS) +    , sampler2D tex_orm +#endif +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL) +    , sampler2D tex_vNt +#endif +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) +    , sampler2D tex_emissive +#endif +    ) +{ +    PBRMix mix = init_pbr_mix(); + +#define get_uv_x() _t_uv(terrain_coord[0].zw, terrain_coord[1].zw, sign(vary_vertex_normal.x)) +#define get_uv_y() _t_uv(terrain_coord[1].xy, terrain_coord[2].xy, sign(vary_vertex_normal.y)) +#define get_uv_z() _t_uv(terrain_coord[0].xy, vec2(0),             sign(vary_vertex_normal.z)) +    switch (tw.type & SAMPLE_X) +    { +    case SAMPLE_X: +        PBRMix mix_x = sample_pbr( +            get_uv_x() +            , tex_col +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS) +            , tex_orm +#endif +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL) +            , tex_vNt +#endif +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) +            , tex_emissive +#endif +            ); +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL) +        // Triplanar-specific normal texture fix +        mix_x.vNt = _t_normal_post_x(mix_x.vNt); +#endif +        mix = mix_pbr(mix, mix_x, tw.weight.x); +        break; +    default: +        break; +    } + +    switch (tw.type & SAMPLE_Y) +    { +    case SAMPLE_Y: +        PBRMix mix_y = sample_pbr( +            get_uv_y() +            , tex_col +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS) +            , tex_orm +#endif +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL) +            , tex_vNt +#endif +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) +            , tex_emissive +#endif +            ); +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL) +        // Triplanar-specific normal texture fix +        mix_y.vNt = _t_normal_post_y(mix_y.vNt); +#endif +        mix = mix_pbr(mix, mix_y, tw.weight.y); +        break; +    default: +        break; +    } + +    switch (tw.type & SAMPLE_Z) +    { +    case SAMPLE_Z: +        PBRMix mix_z = sample_pbr( +            get_uv_z() +            , tex_col +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS) +            , tex_orm +#endif +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL) +            , tex_vNt +#endif +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) +            , tex_emissive +#endif +            ); +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL) +        // Triplanar-specific normal texture fix +        // *NOTE: Bottom face has not been tested +        mix_z.vNt = _t_normal_post_z(mix_z.vNt); +#endif +        mix = mix_pbr(mix, mix_z, tw.weight.z); +        break; +    default: +        break; +    } +     +    return mix; +} + +#elif TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 1 + +#define TerrainCoord vec2 + +#define terrain_sample_pbr sample_pbr + +#endif + +PBRMix multiply_factors_pbr( +    PBRMix mix_in +    , vec4 factor_col +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION) +    , vec3 factor_orm +#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS) +    , vec2 factor_rm +#endif +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) +    , vec3 factor_emissive +#endif +    ) +{ +    PBRMix mix = mix_in; +    mix.col *= factor_col; +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION) +    mix.orm *= factor_orm; +#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS) +    mix.rm *= factor_rm; +#endif +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) +    mix.emissive *= factor_emissive; +#endif +    return mix; +} + +PBRMix terrain_sample_and_multiply_pbr( +    TerrainCoord terrain_coord +    , sampler2D tex_col +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS) +    , sampler2D tex_orm +#endif +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL) +    , sampler2D tex_vNt +#endif +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) +    , sampler2D tex_emissive +#endif +    , vec4 factor_col +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION) +    , vec3 factor_orm +#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS) +    , vec2 factor_rm +#endif +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) +    , vec3 factor_emissive +#endif +    ) +{ +    PBRMix mix = terrain_sample_pbr( +        terrain_coord +#if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3 +        , _t_triplanar() +#endif +        , tex_col +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS) +        , tex_orm +#endif +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL) +        , tex_vNt +#endif +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) +        , tex_emissive +#endif +        ); + +    mix = multiply_factors_pbr(mix +        , factor_col +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION) +        , factor_orm +#elif (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS) +        , factor_rm +#endif +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) +        , factor_emissive +#endif +    ); + +    return mix; +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl new file mode 100644 index 0000000000..167d980eb8 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl @@ -0,0 +1,175 @@ +/**  + * @file class1\environment\pbrterrainV.glsl + * + * $LicenseInfo:firstyear=2023&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2023, 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$ + */ + +#define TERRAIN_PBR_DETAIL_EMISSIVE 0 +#define TERRAIN_PBR_DETAIL_OCCLUSION -1 +#define TERRAIN_PBR_DETAIL_NORMAL -2 +#define TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS -3 + +uniform mat3 normal_matrix; +uniform mat4 texture_matrix0; +uniform mat4 modelview_matrix; +uniform mat4 modelview_projection_matrix; + +in vec3 position; +in vec3 normal; +in vec4 tangent; +in vec4 diffuse_color; +in vec2 texcoord1; + +out vec3 vary_vertex_normal; // Used by pbrterrainUtilF.glsl +out vec3 vary_normal; +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL) +out vec3 vary_tangents[4]; +flat out float vary_sign; +#endif +out vec4 vary_texcoord0; +out vec4 vary_texcoord1; +#if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3 +out vec4[10] vary_coords; +#elif TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 1 +out vec4[2] vary_coords; +#endif +out vec3 vary_position; + +// *HACK: Each material uses only one texture transform, but the KHR texture +// transform spec allows handling texture transforms separately for each +// individual texture info. +uniform vec4[5] terrain_texture_transforms; + +vec2 terrain_texture_transform(vec2 vertex_texcoord, vec4[2] khr_gltf_transform); +vec3 terrain_tangent_space_transform(vec4 vertex_tangent, vec3 vertex_normal, vec4[2] khr_gltf_transform); + +void main() +{ +    //transform vertex +	gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);  +    vary_position = (modelview_matrix*vec4(position.xyz, 1.0)).xyz; + +	vec3 n = normal_matrix * normal; +    vary_vertex_normal = normal; +	vec3 t = normal_matrix * tangent.xyz; + +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL) +    { +        vec4[2] ttt; +        // material 1 +        ttt[0].xyz = terrain_texture_transforms[0].xyz; +        ttt[1].x = terrain_texture_transforms[0].w; +        ttt[1].y = terrain_texture_transforms[1].x; +        vary_tangents[0] = normalize(terrain_tangent_space_transform(vec4(t, tangent.w), n, ttt)); +        // material 2 +        ttt[0].xyz = terrain_texture_transforms[1].yzw; +        ttt[1].xy = terrain_texture_transforms[2].xy; +        vary_tangents[1] = normalize(terrain_tangent_space_transform(vec4(t, tangent.w), n, ttt)); +        // material 3 +        ttt[0].xy = terrain_texture_transforms[2].zw; +        ttt[0].z = terrain_texture_transforms[3].x; +        ttt[1].xy = terrain_texture_transforms[3].yz; +        vary_tangents[2] = normalize(terrain_tangent_space_transform(vec4(t, tangent.w), n, ttt)); +        // material 4 +        ttt[0].x = terrain_texture_transforms[3].w; +        ttt[0].yz = terrain_texture_transforms[4].xy; +        ttt[1].xy = terrain_texture_transforms[4].zw; +        vary_tangents[3] = normalize(terrain_tangent_space_transform(vec4(t, tangent.w), n, ttt)); +    } + +    vary_sign = tangent.w; +#endif +    vary_normal = normalize(n); + +    // Transform and pass tex coords +    { +        vec4[2] ttt; +#if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3 +// Don't care about upside-down (transform_xy_flipped()) +#define transform_xy()             terrain_texture_transform(position.xy,               ttt) +#define transform_yz()             terrain_texture_transform(position.yz,               ttt) +#define transform_negx_z()         terrain_texture_transform(position.xz * vec2(-1, 1), ttt) +#define transform_yz_flipped()     terrain_texture_transform(position.yz * vec2(-1, 1), ttt) +#define transform_negx_z_flipped() terrain_texture_transform(position.xz,               ttt) +        // material 1 +        ttt[0].xyz = terrain_texture_transforms[0].xyz; +        ttt[1].x = terrain_texture_transforms[0].w; +        ttt[1].y = terrain_texture_transforms[1].x; +        vary_coords[0].xy = transform_xy(); +        vary_coords[0].zw = transform_yz(); +        vary_coords[1].xy = transform_negx_z(); +        vary_coords[1].zw = transform_yz_flipped(); +        vary_coords[2].xy = transform_negx_z_flipped(); +        // material 2 +        ttt[0].xyz = terrain_texture_transforms[1].yzw; +        ttt[1].xy = terrain_texture_transforms[2].xy; +        vary_coords[2].zw = transform_xy(); +        vary_coords[3].xy = transform_yz(); +        vary_coords[3].zw = transform_negx_z(); +        vary_coords[4].xy = transform_yz_flipped(); +        vary_coords[4].zw = transform_negx_z_flipped(); +        // material 3 +        ttt[0].xy = terrain_texture_transforms[2].zw; +        ttt[0].z = terrain_texture_transforms[3].x; +        ttt[1].xy = terrain_texture_transforms[3].yz; +        vary_coords[5].xy = transform_xy(); +        vary_coords[5].zw = transform_yz(); +        vary_coords[6].xy = transform_negx_z(); +        vary_coords[6].zw = transform_yz_flipped(); +        vary_coords[7].xy = transform_negx_z_flipped(); +        // material 4 +        ttt[0].x = terrain_texture_transforms[3].w; +        ttt[0].yz = terrain_texture_transforms[4].xy; +        ttt[1].xy = terrain_texture_transforms[4].zw; +        vary_coords[7].zw = transform_xy(); +        vary_coords[8].xy = transform_yz(); +        vary_coords[8].zw = transform_negx_z(); +        vary_coords[9].xy = transform_yz_flipped(); +        vary_coords[9].zw = transform_negx_z_flipped(); +#elif TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 1 +        // material 1 +        ttt[0].xyz = terrain_texture_transforms[0].xyz; +        ttt[1].x = terrain_texture_transforms[0].w; +        ttt[1].y = terrain_texture_transforms[1].x; +        vary_coords[0].xy = terrain_texture_transform(position.xy, ttt); +        // material 2 +        ttt[0].xyz = terrain_texture_transforms[1].yzw; +        ttt[1].xy = terrain_texture_transforms[2].xy; +        vary_coords[0].zw = terrain_texture_transform(position.xy, ttt); +        // material 3 +        ttt[0].xy = terrain_texture_transforms[2].zw; +        ttt[0].z = terrain_texture_transforms[3].x; +        ttt[1].xy = terrain_texture_transforms[3].yz; +        vary_coords[1].xy = terrain_texture_transform(position.xy, ttt); +        // material 4 +        ttt[0].x = terrain_texture_transforms[3].w; +        ttt[0].yz = terrain_texture_transforms[4].xy; +        ttt[1].xy = terrain_texture_transforms[4].zw; +        vary_coords[1].zw = terrain_texture_transform(position.xy, ttt); +#endif +    } +     +    vec4 tc = vec4(texcoord1,0,1); +    vary_texcoord0.zw = tc.xy; +    vary_texcoord1.xy = tc.xy-vec2(2.0, 0.0); +    vary_texcoord1.zw = tc.xy-vec2(1.0, 0.0); +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl index 3443785e1a..1629ed91c8 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl @@ -97,6 +97,7 @@ vec3 toneMapACES_Hill(vec3 color)  uniform float exposure;  uniform float gamma; +uniform float aces_mix;  vec3 toneMap(vec3 color)  { @@ -106,7 +107,7 @@ vec3 toneMap(vec3 color)      color *= exposure * exp_scale;      // mix ACES and Linear here as a compromise to avoid over-darkening legacy content -    color = mix(toneMapACES_Hill(color), color, 0.3); +    color = mix(toneMapACES_Hill(color), color, aces_mix);  #endif      return color; @@ -152,6 +153,15 @@ float noise(vec2 x) {  //============================= +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 legacyGamma(vec3 color)  { @@ -180,7 +190,8 @@ void main()      vec3 seed = (diff.rgb+vec3(1.0))*vec3(tc.xy, tc.x+tc.y);      vec3 nz = vec3(noise(seed.rg), noise(seed.gb), noise(seed.rb));      diff.rgb += nz*0.003; -     + +    //debugExposure(diff.rgb);      frag_color = max(diff, vec4(0));  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl b/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl index 9d9ba49d82..785c748234 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl @@ -27,6 +27,15 @@  in vec3 vary_HazeColor;  in float vary_LightNormPosDot; +#ifdef HAS_HDRI +in vec4 vary_position; +in vec3 vary_rel_pos; +uniform float sky_hdr_scale; +uniform float hdri_split_screen; +uniform mat3 env_mat; +uniform sampler2D environmentMap; +#endif +  uniform sampler2D rainbow_map;  uniform sampler2D halo_map; @@ -37,6 +46,9 @@ uniform float ice_level;  out vec4 frag_data[4];  vec3 srgb_to_linear(vec3 c); +vec3 linear_to_srgb(vec3 c); + +#define PI 3.14159265  /////////////////////////////////////////////////////////////////////////  // The fragment shader for the sky @@ -71,24 +83,42 @@ vec3 halo22(float d)  void main()  { -    // Potential Fill-rate optimization.  Add cloud calculation  -    // back in and output alpha of 0 (so that alpha culling kills  -    // the fragment) if the sky wouldn't show up because the clouds  -    // are fully opaque. - -    vec3 color = vary_HazeColor; - -    float  rel_pos_lightnorm = vary_LightNormPosDot; -    float optic_d = rel_pos_lightnorm; -    vec3  halo_22 = halo22(optic_d); -    color.rgb += rainbow(optic_d); -    color.rgb += halo_22; -    color.rgb *= 2.; -    color.rgb = clamp(color.rgb, vec3(0), vec3(5)); +    vec3 color; +#ifdef HAS_HDRI +    vec3 frag_coord = vary_position.xyz/vary_position.w; +    if (-frag_coord.x > ((1.0-hdri_split_screen)*2.0-1.0)) +    { +        vec3 pos = normalize(vary_rel_pos); +        pos = env_mat * pos; +        vec2 texCoord = vec2(atan(pos.z, pos.x) + PI, acos(pos.y)) / vec2(2.0 * PI, PI); +        color = textureLod(environmentMap, texCoord.xy, 0).rgb * sky_hdr_scale; +        color = min(color, vec3(8192*8192*16)); // stupidly large value arrived at by binary search -- avoids framebuffer corruption from some HDRIs + +        frag_data[2] = vec4(0.0,0.0,0.0,GBUFFER_FLAG_HAS_HDRI); +    } +    else +#endif +    { +        // Potential Fill-rate optimization.  Add cloud calculation  +        // back in and output alpha of 0 (so that alpha culling kills  +        // the fragment) if the sky wouldn't show up because the clouds  +        // are fully opaque. + +        color = vary_HazeColor; + +        float  rel_pos_lightnorm = vary_LightNormPosDot; +        float optic_d = rel_pos_lightnorm; +        vec3  halo_22 = halo22(optic_d); +        color.rgb += rainbow(optic_d); +        color.rgb += halo_22; +        color.rgb *= 2.; +        color.rgb = clamp(color.rgb, vec3(0), vec3(5)); + +        frag_data[2] = vec4(0.0,0.0,0.0,GBUFFER_FLAG_SKIP_ATMOS); +    }      frag_data[0] = vec4(0);      frag_data[1] = vec4(0); -    frag_data[2] = vec4(0.0,0.0,0.0,GBUFFER_FLAG_SKIP_ATMOS); //1.0 in norm.w masks off fog      frag_data[3] = vec4(color.rgb, 1.0);  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl b/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl index 17ce2dee5b..24d2db2183 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl @@ -35,6 +35,11 @@ in vec3 position;  out vec3 vary_HazeColor;  out float vary_LightNormPosDot; +#ifdef HAS_HDRI +out vec4 vary_position; +out vec3 vary_rel_pos; +#endif +  // Inputs  uniform vec3 camPosLocal; @@ -72,6 +77,11 @@ void main()      // Get relative position      vec3 rel_pos = position.xyz - camPosLocal.xyz + vec3(0, 50, 0); +#ifdef HAS_HDRI +    vary_rel_pos = rel_pos; +    vary_position = pos; +#endif +      // Adj position vector to clamp altitude      if (rel_pos.y > 0.)      { @@ -98,7 +108,7 @@ void main()      vec3 light_atten = (blue_density + vec3(haze_density * 0.25)) * (density_multiplier * max_y);      // Calculate relative weights -    vec3 combined_haze = abs(blue_density) + vec3(abs(haze_density)); +    vec3 combined_haze = max(abs(blue_density) + vec3(abs(haze_density)), vec3(1e-6));      vec3 blue_weight   = blue_density / combined_haze;      vec3 haze_weight   = haze_density / combined_haze; diff --git a/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl index f6d509e2c6..5f598f84a7 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl @@ -38,10 +38,11 @@ in vec3 vary_normal;  in vec4 vary_texcoord0;  in vec4 vary_texcoord1; -vec2 encode_normal(vec3 n); +void mirrorClip(vec3 position);  void main()  { +    mirrorClip(pos);      /// Note: This should duplicate the blending functionality currently used for the terrain rendering.      vec4 color0 = texture(detail_0, vary_texcoord0.xy); @@ -59,7 +60,7 @@ void main()      frag_data[0] = outColor;      frag_data[1] = vec4(0.0,0.0,0.0,-1.0);      vec3 nvn = normalize(vary_normal); -    frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, GBUFFER_FLAG_HAS_ATMOS); +    frag_data[2] = vec4(nvn.xyz, GBUFFER_FLAG_HAS_ATMOS);      frag_data[3] = vec4(0);  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl b/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl index f6d3b59e85..8e1e4b54d5 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl @@ -25,12 +25,12 @@  uniform mat3 normal_matrix;  uniform mat4 texture_matrix0; +uniform mat4 modelview_matrix;  uniform mat4 modelview_projection_matrix;  in vec3 position;  in vec3 normal;  in vec4 diffuse_color; -in vec2 texcoord0;  in vec2 texcoord1;  out vec3 pos; @@ -41,18 +41,16 @@ out vec4 vary_texcoord1;  uniform vec4 object_plane_s;  uniform vec4 object_plane_t; -vec4 texgen_object(vec4  vpos, vec4 tc, mat4 mat, vec4 tp0, vec4 tp1) +vec2 texgen_object(vec4 vpos, mat4 mat, vec4 tp0, vec4 tp1)  {      vec4 tcoord;      tcoord.x = dot(vpos, tp0);      tcoord.y = dot(vpos, tp1); -    tcoord.z = tc.z; -    tcoord.w = tc.w;      tcoord = mat * tcoord;  -    return tcoord;  +    return tcoord.xy;   }  void main() @@ -62,12 +60,12 @@ void main()      vec4 t_pos = modelview_projection_matrix * pre_pos;      gl_Position = t_pos; -    pos = t_pos.xyz; +    pos = (modelview_matrix*pre_pos).xyz;      vary_normal = normalize(normal_matrix * normal);      // Transform and pass tex coords -    vary_texcoord0.xy = texgen_object(vec4(position, 1.0), vec4(texcoord0,0,1), texture_matrix0, object_plane_s, object_plane_t).xy; +    vary_texcoord0.xy = texgen_object(vec4(position, 1.0), texture_matrix0, object_plane_s, object_plane_t);      vec4 t = vec4(texcoord1,0,1); diff --git a/indra/newview/app_settings/shaders/class1/deferred/textureUtilV.glsl b/indra/newview/app_settings/shaders/class1/deferred/textureUtilV.glsl index 636dfed4ba..bf5d106dab 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/textureUtilV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/textureUtilV.glsl @@ -48,6 +48,7 @@ vec2 khr_texture_transform(vec2 texcoord, vec2 scale, float rotation, vec2 offse      return (transform * vec3(texcoord, 1)).xy;  } +// A texture transform function for PBR materials applied to shape prims/Collada model prims  // vertex_texcoord - The UV texture coordinates sampled from the vertex at  //     runtime. Per SL convention, this is in a right-handed UV coordinate  //     system. Collada models also have right-handed UVs. @@ -65,7 +66,7 @@ vec2 texture_transform(vec2 vertex_texcoord, vec4[2] khr_gltf_transform, mat4 sl      // Apply texture animation first to avoid shearing and other artifacts      texcoord = (sl_animation_transform * vec4(texcoord, 0, 1)).xy;      // Convert to left-handed coordinate system. The offset of 1 is necessary -    // for rotations to be applied correctly. +    // for rotation and scale to be applied correctly.      texcoord.y = 1.0 - texcoord.y;      texcoord = khr_texture_transform(texcoord, khr_gltf_transform[0].xy, khr_gltf_transform[0].z, khr_gltf_transform[1].xy);      // Convert back to right-handed coordinate system @@ -77,6 +78,19 @@ vec2 texture_transform(vec2 vertex_texcoord, vec4[2] khr_gltf_transform, mat4 sl      return texcoord;  } +// Similar to texture_transform but no offset during coordinate system +// conversion, and no texture animation support. +vec2 terrain_texture_transform(vec2 vertex_texcoord, vec4[2] khr_gltf_transform) +{ +    vec2 texcoord = vertex_texcoord; + +    texcoord.y = -texcoord.y; +    texcoord = khr_texture_transform(texcoord, khr_gltf_transform[0].xy, khr_gltf_transform[0].z, khr_gltf_transform[1].xy); +    texcoord.y = -texcoord.y; + +    return texcoord; +} +  // Take the rotation only from both transforms and apply to the tangent. This  // accounts for the change of the topology of the normal texture when a texture  // rotation is applied to it. @@ -120,3 +134,26 @@ vec3 tangent_space_transform(vec4 vertex_tangent, vec3 vertex_normal, vec4[2] kh      return (weights.x * vertex_binormal.xyz) + (weights.y * vertex_tangent.xyz);  } + +// Similar to tangent_space_transform but no offset during coordinate system +// conversion, and no texture animation support. +vec3 terrain_tangent_space_transform(vec4 vertex_tangent, vec3 vertex_normal, vec4[2] khr_gltf_transform) +{ +    // Immediately convert to left-handed coordinate system ((0,1) -> (0, -1)) +    vec2 weights = vec2(0, -1); + +    // Apply KHR_texture_transform (rotation only) +    float khr_rotation = khr_gltf_transform[0].z; +    mat2 khr_rotation_mat = mat2( +        cos(khr_rotation),-sin(khr_rotation), +        sin(khr_rotation), cos(khr_rotation) +    ); +    weights = khr_rotation_mat * weights; + +    // Convert back to right-handed coordinate system +    weights.y = -weights.y; + +    vec3 vertex_binormal = vertex_tangent.w * cross(vertex_normal, vertex_tangent.xyz); + +    return (weights.x * vertex_binormal.xyz) + (weights.y * vertex_tangent.xyz); +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl b/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl index e2d87e68fa..708acd0194 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl @@ -32,13 +32,14 @@ uniform sampler2D diffuseMap;  in vec4 vertex_color;  in vec3 vary_normal;  in vec2 vary_texcoord0; +in vec3 vary_position;  uniform float minimum_alpha; -vec2 encode_normal(vec3 n); - +void mirrorClip(vec3 pos);  void main()   { +    mirrorClip(vary_position);  	vec4 col = texture(diffuseMap, vary_texcoord0.xy);  	if (col.a < minimum_alpha)  	{ @@ -48,6 +49,6 @@ void main()  	frag_data[0] = vec4(vertex_color.rgb*col.rgb, 0.0);  	frag_data[1] = vec4(0,0,0,0);  	vec3 nvn = normalize(vary_normal); -	frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, GBUFFER_FLAG_HAS_ATMOS); +	frag_data[2] = vec4(nvn.xyz, GBUFFER_FLAG_HAS_ATMOS);      frag_data[3] = vec4(0);  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/treeV.glsl b/indra/newview/app_settings/shaders/class1/deferred/treeV.glsl index ce8a10712c..c84fccd4c6 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/treeV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/treeV.glsl @@ -24,6 +24,7 @@   */  uniform mat4 texture_matrix0; +uniform mat4 modelview_matrix;  uniform mat4 modelview_projection_matrix;  uniform mat3 normal_matrix; @@ -34,11 +35,14 @@ in vec2 texcoord0;  out vec3 vary_normal;  out vec4 vertex_color;  out vec2 vary_texcoord0; +out vec3 vary_position;  void main()  {  	//transform vertex  	gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);  +    vary_position = (modelview_matrix*vec4(position.xyz, 1.0)).xyz; +  	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;  	vary_normal = normalize(normal_matrix * normal); diff --git a/indra/newview/app_settings/shaders/class1/environment/encodeNormF.glsl b/indra/newview/app_settings/shaders/class1/interface/normaldebugF.glsl index 6cd2445522..388042e7e0 100644 --- a/indra/newview/app_settings/shaders/class1/environment/encodeNormF.glsl +++ b/indra/newview/app_settings/shaders/class1/interface/normaldebugF.glsl @@ -1,9 +1,9 @@ -/** - * @file encodeNormF.glsl +/**  + * @file normaldebugF.glsl   * - * $LicenseInfo:firstyear=2018&license=viewerlgpl$ + * $LicenseInfo:firstyear=2023&license=viewerlgpl$   * Second Life Viewer Source Code - * Copyright (C) 2018, Linden Research, Inc. + * Copyright (C) 2023, 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 @@ -23,12 +23,11 @@   * $/LicenseInfo$   */ -// Lambert Azimuthal Equal-Area projection -// See: https://aras-p.info/texts/CompactNormalStorage.html -// Also see: A_bit_more_deferred_-_CryEngine3.ppt -vec2 encode_normal(vec3 n) +out vec4 frag_color; + +in vec4 vertex_color; + +void main()   { -	float f = sqrt(8 * n.z + 8); -	return n.xy / f + 0.5; +	frag_color = max(vertex_color, vec4(0));  } - diff --git a/indra/newview/app_settings/shaders/class1/interface/normaldebugG.glsl b/indra/newview/app_settings/shaders/class1/interface/normaldebugG.glsl new file mode 100644 index 0000000000..51d05cd507 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/interface/normaldebugG.glsl @@ -0,0 +1,76 @@ +/**  + * @file normaldebugG.glsl + * + * $LicenseInfo:firstyear=2023&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2023, 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$ + */ + +// *NOTE: Geometry shaders have a reputation for being slow. Consider using +// compute shaders instead, which have a reputation for being fast. This +// geometry shader in particular seems to run fine on my machine, but I won't +// vouch for this in performance-critical areas. +// -Cosmic,2023-09-28 + +out vec4 vertex_color; + +in vec4 normal_g[]; +#ifdef HAS_ATTRIBUTE_TANGENT +in vec4 tangent_g[]; +#endif + +layout(triangles) in; +#ifdef HAS_ATTRIBUTE_TANGENT +layout(line_strip, max_vertices = 12) out; +#else +layout(line_strip, max_vertices = 6) out; +#endif + +void triangle_normal_debug(int i) +{ +    // Normal +    vec4 normal_color = vec4(1.0, 1.0, 0.0, 1.0); +    gl_Position = gl_in[i].gl_Position; +    vertex_color = normal_color; +    EmitVertex(); +    gl_Position = normal_g[i]; +    vertex_color = normal_color; +    EmitVertex(); +    EndPrimitive(); + +#ifdef HAS_ATTRIBUTE_TANGENT +    // Tangent +    vec4 tangent_color = vec4(0.0, 1.0, 1.0, 1.0); +    gl_Position = gl_in[i].gl_Position; +    vertex_color = tangent_color; +    EmitVertex(); +    gl_Position = tangent_g[i]; +    vertex_color = tangent_color; +    EmitVertex(); +    EndPrimitive(); +#endif +} + +void main() +{ +    triangle_normal_debug(0); +    triangle_normal_debug(1); +    triangle_normal_debug(2); +} diff --git a/indra/newview/app_settings/shaders/class1/interface/normaldebugV.glsl b/indra/newview/app_settings/shaders/class1/interface/normaldebugV.glsl new file mode 100644 index 0000000000..b198bc2485 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/interface/normaldebugV.glsl @@ -0,0 +1,74 @@ +/**  + * @file normaldebugV.glsl + * + * $LicenseInfo:firstyear=2023&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2023, 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$ + */ + +in vec3 position; +in vec3 normal; +out vec4 normal_g; +#ifdef HAS_ATTRIBUTE_TANGENT +in vec4 tangent; +out vec4 tangent_g; +#endif + +uniform float debug_normal_draw_length; + +#ifdef HAS_SKIN +mat4 getObjectSkinnedTransform(); +#else +uniform mat3 normal_matrix; +#endif +uniform mat4 projection_matrix; +uniform mat4 modelview_matrix; + +// *NOTE: Should use the modelview_projection_matrix here in the non-skinned +// case for efficiency, but opting for the simplier implementation for now as +// this is debug code. Also, the skinned version hasn't beeen tested yet. +// world_pos = mat * vec4(position.xyz, 1.0) +vec4 get_screen_normal(vec3 position, vec4 world_pos, vec3 normal, mat4 mat) +{ +    vec4 world_norm = mat * vec4((position + normal), 1.0); +    world_norm.xyz -= world_pos.xyz; +    world_norm.xyz = debug_normal_draw_length * normalize(world_norm.xyz); +    world_norm.xyz += world_pos.xyz; +    return projection_matrix * world_norm; +} + +void main() +{ +#ifdef HAS_SKIN +    mat4 mat = getObjectSkinnedTransform(); +    mat = modelview_matrix * mat; +#else +#define mat modelview_matrix +#endif + +    vec4 world_pos = mat * vec4(position.xyz,1.0); + +	gl_Position = projection_matrix * world_pos; +	normal_g = get_screen_normal(position.xyz, world_pos, normal.xyz, mat); +#ifdef HAS_ATTRIBUTE_TANGENT +	tangent_g = get_screen_normal(position.xyz, world_pos, tangent.xyz, mat); +#endif +} + diff --git a/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl b/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl index 9ecdf0bf77..c1ed1bfe6e 100644 --- a/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl +++ b/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl @@ -38,6 +38,7 @@ in vec3 vary_dir;  uniform float mipLevel;  uniform int u_width;   uniform float max_probe_lod; +uniform float probe_strength;  // ============================================================================================================= @@ -129,7 +130,7 @@ vec4 prefilterEnvMap(vec3 R)  	float totalWeight = 0.0;  	float envMapDim = float(textureSize(reflectionProbes, 0).s);      float roughness = mipLevel/max_probe_lod; -    int numSamples = max(int(32*roughness), 1); +    int numSamples = max(int(PROBE_FILTER_SAMPLES*roughness), 1);      float numMips = max_probe_lod+1; @@ -163,5 +164,6 @@ void main()  {		  	vec3 N = normalize(vary_dir);  	frag_color = max(prefilterEnvMap(N), vec4(0)); +    frag_color.a *= probe_strength;  }  // ============================================================================================================= diff --git a/indra/newview/app_settings/shaders/class1/objects/bumpF.glsl b/indra/newview/app_settings/shaders/class1/objects/bumpF.glsl index 67c99530e3..142f2a5d71 100644 --- a/indra/newview/app_settings/shaders/class1/objects/bumpF.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/bumpF.glsl @@ -30,9 +30,13 @@ uniform sampler2D texture1;  in vec2 vary_texcoord0;  in vec2 vary_texcoord1; +in vec3 vary_position; + +void mirrorClip(vec3 pos);  void main()   { +    mirrorClip(vary_position);  	float tex0 = texture(texture0, vary_texcoord0.xy).a;  	float tex1 = texture(texture1, vary_texcoord1.xy).a; diff --git a/indra/newview/app_settings/shaders/class1/objects/bumpV.glsl b/indra/newview/app_settings/shaders/class1/objects/bumpV.glsl index 7d5417919e..b8a02fbdec 100644 --- a/indra/newview/app_settings/shaders/class1/objects/bumpV.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/bumpV.glsl @@ -23,6 +23,7 @@   * $/LicenseInfo$   */ +uniform mat4 modelview_matrix;  uniform mat4 texture_matrix0;  uniform mat4 modelview_projection_matrix; @@ -32,11 +33,11 @@ in vec2 texcoord1;  out vec2 vary_texcoord0;  out vec2 vary_texcoord1; +out vec3 vary_position;  #ifdef HAS_SKIN  mat4 getObjectSkinnedTransform();  uniform mat4 projection_matrix; -uniform mat4 modelview_matrix;  #endif  void main() @@ -46,8 +47,10 @@ void main()      mat4 mat = getObjectSkinnedTransform();      mat = modelview_matrix * mat;      vec4 pos = mat * vec4(position.xyz, 1.0); +    vary_position = pos.xyz;      gl_Position = projection_matrix * pos;  #else +    vary_position = (modelview_matrix * vec4(position.xyz, 1.0)).xyz;  	gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);  #endif  	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsFuncs.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsFuncs.glsl index a1da4b1f9a..d077670c96 100644 --- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsFuncs.glsl +++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsFuncs.glsl @@ -66,7 +66,7 @@ void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, ou      // I had thought blue_density and haze_density should have equal weighting,      // but attenuation due to haze_density tends to seem too strong -    vec3 combined_haze = blue_density + vec3(haze_density); +    vec3 combined_haze = max(blue_density + vec3(haze_density), vec3(1e-6));      vec3 blue_weight   = blue_density / combined_haze;      vec3 haze_weight   = vec3(haze_density) / combined_haze; @@ -98,7 +98,7 @@ void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, ou      haze_glow = max(haze_glow, .001);  // set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)      haze_glow *= glow.x;      // higher glow.x gives dimmer glow (because next step is 1 / "angle") -    haze_glow = pow(haze_glow, glow.z); +    haze_glow = clamp(pow(haze_glow, glow.z), -100000, 100000);      // glow.z should be negative, so we're doing a sort of (1 / "angle") function      // add "minimum anti-solar illumination" diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl index acd32a81b3..7a1a54a77a 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl @@ -68,7 +68,6 @@ void waterClip(vec3 pos);  vec3 srgb_to_linear(vec3 c);  vec3 linear_to_srgb(vec3 c); -vec2 encode_normal (vec3 n);  vec4 applySkyAndWaterFog(vec3 pos, vec3 additive, vec3 atten, vec4 color);  void calcAtmosphericVarsLinear(vec3 inPositionEye, vec3 norm, vec3 light_dir, out vec3 sunlit, out vec3 amblit, out vec3 atten, out vec3 additive); @@ -78,6 +77,8 @@ float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen);  float getAmbientClamp(); +void mirrorClip(vec3 pos); +  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_linear); @@ -167,6 +168,8 @@ vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 diffuse, vec3 v, vec3 n, vec  void main()   { +    mirrorClip(vary_position); +      vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5;      vec4 pos = vec4(vary_position, 1.0); diff --git a/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl b/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl index 003dd05e6f..059c2a64ce 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl @@ -90,6 +90,7 @@ float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen);  void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,           vec2 tc, vec3 pos, vec3 norm, float glossiness, bool transparent, vec3 amblit_linear); +void mirrorClip(vec3 pos);  void waterClip(vec3 pos);  void calcDiffuseSpecular(vec3 baseColor, float metallic, inout vec3 diffuseColor, inout vec3 specularColor); @@ -156,6 +157,8 @@ vec3 calcPointLightOrSpotLight(vec3 diffuseColor, vec3 specularColor,  void main()  { +    mirrorClip(vary_position); +      vec3 color = vec3(0,0,0);      vec3  light_dir   = (sun_up_factor == 1) ? sun_dir : moon_dir; diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl index 1ea57516a4..1bd5f5a718 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl @@ -35,7 +35,7 @@ in vec2 vary_fragcoord;  uniform vec3 sun_dir;  uniform float shadow_bias; -vec3 getNorm(vec2 pos_screen); +vec4 getNorm(vec2 pos_screen);  vec4 getPosition(vec2 pos_screen);  float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen); @@ -45,13 +45,13 @@ void main()  {      vec2 pos_screen = vary_fragcoord.xy;      vec4 pos        = getPosition(pos_screen); -    vec3 norm       = getNorm(pos_screen); +    vec4 norm       = getNorm(pos_screen);      vec4 col; -    col.r = sampleDirectionalShadow(pos.xyz, norm, pos_screen); +    col.r = sampleDirectionalShadow(pos.xyz, norm.xyz, pos_screen);      col.g = 1.0f; -    col.b = sampleSpotShadow(pos.xyz, norm, 0, pos_screen);  -    col.a = sampleSpotShadow(pos.xyz, norm, 1, pos_screen); +    col.b = sampleSpotShadow(pos.xyz, norm.xyz, 0, pos_screen);  +    col.a = sampleSpotShadow(pos.xyz, norm.xyz, 1, pos_screen);      frag_color = clamp(col, vec4(0), vec4(1));  } diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl index 0126e09d4c..e0333b6044 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl @@ -32,7 +32,7 @@ out vec4 frag_color;  in vec2 vary_fragcoord;  vec4 getPosition(vec2 pos_screen); -vec3 getNorm(vec2 pos_screen); +vec4 getNorm(vec2 pos_screen);  float sampleDirectionalShadow(vec3 shadow_pos, vec3 norm, vec2 pos_screen);  float sampleSpotShadow(vec3 shadow_pos, vec3 norm, int index, vec2 pos_screen); @@ -42,13 +42,13 @@ void main()  {      vec2 pos_screen = vary_fragcoord.xy;      vec4 pos  = getPosition(pos_screen); -    vec3 norm = getNorm(pos_screen); +    vec4 norm = getNorm(pos_screen);      vec4 col; -    col.r = sampleDirectionalShadow(pos.xyz, norm, pos_screen); -    col.g = calcAmbientOcclusion(pos, norm, pos_screen); -    col.b = sampleSpotShadow(pos.xyz, norm, 0, pos_screen); -    col.a = sampleSpotShadow(pos.xyz, norm, 1, pos_screen); +    col.r = sampleDirectionalShadow(pos.xyz, norm.xyz, pos_screen); +    col.g = calcAmbientOcclusion(pos, norm.xyz, pos_screen); +    col.b = sampleSpotShadow(pos.xyz, norm.xyz, 0, pos_screen); +    col.a = sampleSpotShadow(pos.xyz, norm.xyz, 1, pos_screen);      frag_color = clamp(col, vec4(0), vec4(1));  } diff --git a/indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl b/indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl index 8430cca325..c382a9fbc0 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl @@ -53,8 +53,11 @@ void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout  void applyLegacyEnv(inout vec3 color, vec3 legacyenv, vec4 spec, vec3 pos, vec3 norm, float envIntensity); +void mirrorClip(vec3 pos); +  void main()  { +    mirrorClip(vary_position);  #ifdef HAS_DIFFUSE_LOOKUP  	vec4 color = diffuseLookup(vary_texcoord0.xy);  #else diff --git a/indra/newview/app_settings/shaders/class3/deferred/hazeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/hazeF.glsl index 0b154e82ad..4af57e3b80 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/hazeF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/hazeF.glsl @@ -33,7 +33,7 @@ uniform vec3 moon_dir;  uniform int  sun_up_factor;  in vec2 vary_fragcoord; -vec3 getNorm(vec2 pos_screen); +vec4 getNorm(vec2 pos_screen);  vec4 getPositionWithDepth(vec2 pos_screen, float depth);  void calcAtmosphericVarsLinear(vec3 inPositionEye, vec3 norm, vec3 light_dir, out vec3 sunlit, out vec3 amblit, out vec3 atten, out vec3 additive); @@ -53,8 +53,7 @@ void main()      vec2  tc           = vary_fragcoord.xy;      float depth        = getDepth(tc.xy);      vec4  pos          = getPositionWithDepth(tc, depth); -    vec4  norm         = texture(normalMap, tc); -    norm.xyz           = getNorm(tc); +    vec4  norm         = getNorm(tc);      vec3  light_dir   = (sun_up_factor == 1) ? sun_dir : moon_dir;      vec3  color = vec3(0); diff --git a/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl index ec1e49eeb4..2a20eb79d2 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl @@ -45,6 +45,13 @@ void calcHalfVectors(vec3 lv, vec3 n, vec3 v, out vec3 h, out vec3 l, out float  vec3 srgb_to_linear(vec3 cs);  vec3 linear_to_srgb(vec3 cs); +uniform mat4 modelview_matrix; +uniform mat3 normal_matrix; + +in vec3 vary_position; + +void mirrorClip(vec3 pos); +  #if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)  out vec4 frag_color; @@ -66,12 +73,12 @@ uniform vec4 morphFactor;  uniform vec3 camPosLocal;  uniform mat3 env_mat; +uniform float is_mirror; +  uniform vec3 sun_dir;  uniform vec3 moon_dir;  in vec2 vary_fragcoord; -in vec3 vary_position; -  uniform mat4 proj_mat;  uniform mat4 inv_proj;  uniform vec2 screen_res; @@ -209,8 +216,6 @@ in vec3 vary_normal;  in vec4 vertex_color;  in vec2 vary_texcoord0; -vec2 encode_normal(vec3 n); -  // get the transformed normal and apply glossiness component from normal map  vec3 getNormal(inout float glossiness)  { @@ -285,12 +290,12 @@ float getShadow(vec3 pos, vec3 norm)  void main()  { +    mirrorClip(vary_position);      waterClip();      // diffcol == diffuse map combined with vertex color      vec4 diffcol = texture(diffuseMap, vary_texcoord0.xy);  	diffcol.rgb *= vertex_color.rgb; -      alphaMask(diffcol.a);      // spec == specular map combined with specular color @@ -299,8 +304,6 @@ void main()      float glossiness = specular_color.a;      vec3 norm = getNormal(glossiness); -    vec2 abnormal = encode_normal(norm.xyz); -      float emissive = getEmissive(diffcol);  #if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND) @@ -407,10 +410,15 @@ void main()  #else // mode is not DIFFUSE_ALPHA_MODE_BLEND, encode to gbuffer       // deferred path               // See: C++: addDeferredAttachment(), shader: softenLightF.glsl -    frag_data[0] = vec4(diffcol.rgb, emissive);        // gbuffer is sRGB for legacy materials -    frag_data[1] = vec4(spec.rgb, glossiness);           // XYZ = Specular color. W = Specular exponent. -    frag_data[2] = vec4(encode_normal(norm), env, GBUFFER_FLAG_HAS_ATMOS);;   // XY = Normal.  Z = Env. intensity. W = 1 skip atmos (mask off fog) -    frag_data[3] = vec4(0); + +    float flag = GBUFFER_FLAG_HAS_ATMOS; + +    frag_data[0] = max(vec4(diffcol.rgb, emissive), vec4(0));        // gbuffer is sRGB for legacy materials +    frag_data[1] = max(vec4(spec.rgb, glossiness), vec4(0));           // XYZ = Specular color. W = Specular exponent. +    frag_data[2] = vec4(norm, flag);   // XY = Normal.  Z = Env. intensity. W = 1 skip atmos (mask off fog) +    frag_data[3] = vec4(env, 0, 0, 0); +  #endif  } + diff --git a/indra/newview/app_settings/shaders/class3/deferred/multiPointLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/multiPointLightF.glsl index ec8168465e..edfd6cbced 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/multiPointLightF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/multiPointLightF.glsl @@ -48,7 +48,7 @@ in vec4 vary_fragcoord;  void calcHalfVectors(vec3 lv, vec3 n, vec3 v, out vec3 h, out vec3 l, out float nh, out float nl, out float nv, out float vh, out float lightDist);  float calcLegacyDistanceAttenuation(float distance, float falloff);  vec4 getPosition(vec2 pos_screen); -vec4 getNormalEnvIntensityFlags(vec2 screenpos, out vec3 n, out float envIntensity); +vec4 getNorm(vec2 screenpos);  vec2 getScreenXY(vec4 clip);  vec2 getScreenCoord(vec4 clip);  vec3 srgb_to_linear(vec3 c); @@ -74,9 +74,8 @@ void main()          discard;      } -    float envIntensity; // not used for this shader -    vec3 n; -    vec4 norm = getNormalEnvIntensityFlags(tc, n, envIntensity); // need `norm.w` for GET_GBUFFER_FLAG() +    vec4 norm = getNorm(tc); // need `norm.w` for GET_GBUFFER_FLAG() +    vec3 n = norm.xyz;      vec4 spec    = texture(specularRect, tc);      vec3 diffuse = texture(diffuseRect, tc).rgb; diff --git a/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl index 31af1208bd..60be9f4407 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl @@ -52,7 +52,7 @@ uniform vec4 viewport;  void calcHalfVectors(vec3 lv, vec3 n, vec3 v, out vec3 h, out vec3 l, out float nh, out float nl, out float nv, out float vh, out float lightDist);  float calcLegacyDistanceAttenuation(float distance, float falloff); -vec4 getNormalEnvIntensityFlags(vec2 screenpos, out vec3 n, out float envIntensity); +vec4 getNorm(vec2 screenpos);  vec4 getPosition(vec2 pos_screen);  vec2 getScreenXY(vec4 clip);  vec2 getScreenCoord(vec4 clip); @@ -72,9 +72,8 @@ void main()      vec2 tc          = getScreenCoord(vary_fragcoord);      vec3 pos         = getPosition(tc).xyz; -    float envIntensity; -    vec3 n; -    vec4 norm = getNormalEnvIntensityFlags(tc, n, envIntensity); // need `norm.w` for GET_GBUFFER_FLAG() +    vec4 norm = getNorm(tc); // need `norm.w` for GET_GBUFFER_FLAG() +    vec3 n = norm.xyz;      vec3 diffuse = texture(diffuseRect, tc).rgb;      vec4 spec    = texture(specularRect, tc); diff --git a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl index 906e66ecc8..90c84cc428 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl @@ -31,6 +31,7 @@ float tapScreenSpaceReflection(int totalSamples, vec2 tc, vec3 viewPos, vec3 n,  uniform samplerCubeArray   reflectionProbes;  uniform samplerCubeArray   irradianceProbes; +  uniform sampler2D sceneMap;  uniform int cube_snapshot;  uniform float max_probe_lod; @@ -47,6 +48,7 @@ layout (std140) uniform ReflectionProbes      /// box[0..2] - plane 0 .. 2 in [A,B,C,D] notation      //  box[3][0..2] - plane thickness      mat4 refBox[MAX_REFMAP_COUNT]; +    mat4 heroBox;      // list of bounding spheres for reflection probes sorted by distance to camera (closest first)      vec4 refSphere[MAX_REFMAP_COUNT];      // extra parameters  @@ -55,6 +57,7 @@ layout (std140) uniform ReflectionProbes      //  z - fade in      //  w - znear      vec4 refParams[MAX_REFMAP_COUNT]; +    vec4 heroSphere;      // index  of cube map in reflectionProbes for a corresponding reflection probe      // e.g. cube map channel of refSphere[2] is stored in refIndex[2]      // refIndex.x - cubemap channel in reflectionProbes @@ -70,6 +73,10 @@ layout (std140) uniform ReflectionProbes      // number of reflection probes present in refSphere      int refmapCount; + +    int heroShape; +    int heroMipCount; +    int heroProbeCount;  };  // Inputs @@ -365,11 +372,11 @@ return texCUBE(envMap, ReflDirectionWS);  // i - probe index in refBox/refSphere  // d - distance to nearest wall in clip space  // scale - scale of box, default 1.0 -vec3 boxIntersect(vec3 origin, vec3 dir, int i, out float d, float scale) +vec3 boxIntersect(vec3 origin, vec3 dir, mat4 i, out float d, float scale)  {      // Intersection with OBB convert to unit box space      // Transform in local unit parallax cube space (scaled and rotated) -    mat4 clipToLocal = refBox[i]; +    mat4 clipToLocal = i;      vec3 RayLS = mat3(clipToLocal) * dir;      vec3 PositionLS = (clipToLocal * vec4(origin, 1.0)).xyz; @@ -388,7 +395,7 @@ vec3 boxIntersect(vec3 origin, vec3 dir, int i, out float d, float scale)      return IntersectPositionCS;  } -vec3 boxIntersect(vec3 origin, vec3 dir, int i, out float d) +vec3 boxIntersect(vec3 origin, vec3 dir, mat4 i, out float d)  {      return boxIntersect(origin, dir, i, d, 1.0);  } @@ -443,9 +450,9 @@ void boxIntersectionDebug( in vec3 ro, in vec3 p, vec3 boxSize, inout vec4 col)  } -void boxIntersectDebug(vec3 origin, vec3 pos, int i, inout vec4 col) +void boxIntersectDebug(vec3 origin, vec3 pos, mat4 i, inout vec4 col)  { -    mat4 clipToLocal = refBox[i]; +    mat4 clipToLocal = i;      // transform into unit cube space      origin = (clipToLocal * vec4(origin, 1.0)).xyz; @@ -462,7 +469,7 @@ void boxIntersectDebug(vec3 origin, vec3 pos, int i, inout vec4 col)  //  r - radius of probe influence volume  // i - index of probe in refSphere  // dw - distance weight -float sphereWeight(vec3 pos, vec3 dir, vec3 origin, float r, int i, out float dw) +float sphereWeight(vec3 pos, vec3 dir, vec3 origin, float r, vec4 i, out float dw)  {      float r1 = r * 0.5; // 50% of radius (outer sphere to start interpolating down)       vec3 delta = pos.xyz - origin; @@ -471,7 +478,7 @@ float sphereWeight(vec3 pos, vec3 dir, vec3 origin, float r, int i, out float dw      float atten = 1.0 - max(d2 - r1, 0.0) / max((r - r1), 0.001);      float w = 1.0 / d2; -    w *= refParams[i].z; +    w *= i.z;      dw = w * atten * max(r, 1.0)*4; @@ -497,7 +504,7 @@ vec3 tapRefMap(vec3 pos, vec3 dir, out float w, out float dw, float lod, vec3 c,      if (refIndex[i].w < 0)      {  // box probe          float d = 0; -        v = boxIntersect(pos, dir, i, d); +        v = boxIntersect(pos, dir, refBox[i], d);          w = max(d, 0.001);      } @@ -511,7 +518,7 @@ vec3 tapRefMap(vec3 pos, vec3 dir, out float w, out float dw, float lod, vec3 c,          refIndex[i].w < 1 ? 4096.0*4096.0 : // <== effectively disable parallax correction for automatically placed probes to keep from bombing the world with obvious spheres                  rr); -        w = sphereWeight(pos, dir, refSphere[i].xyz, r, i, dw); +        w = sphereWeight(pos, dir, refSphere[i].xyz, r, refParams[i], dw);      }      v -= c; @@ -537,7 +544,7 @@ vec3 tapIrradianceMap(vec3 pos, vec3 dir, out float w, out float dw, vec3 c, int      if (refIndex[i].w < 0)      {          float d = 0.0; -        v = boxIntersect(pos, dir, i, d, 3.0); +        v = boxIntersect(pos, dir, refBox[i], d, 3.0);          w = max(d, 0.001);      }      else @@ -551,7 +558,7 @@ vec3 tapIrradianceMap(vec3 pos, vec3 dir, out float w, out float dw, vec3 c, int          refIndex[i].w < 1 ? 4096.0*4096.0 : // <== effectively disable parallax correction for automatically placed probes to keep from bombing the world with obvious spheres                  rr); -        w = sphereWeight(pos, dir, refSphere[i].xyz, r, i, dw); +        w = sphereWeight(pos, dir, refSphere[i].xyz, r, refParams[i], dw);      }      v -= c; @@ -681,6 +688,49 @@ vec3 sampleProbeAmbient(vec3 pos, vec3 dir, vec3 amblit)      return col[1]+col[0];  } +#if defined(HERO_PROBES) + +uniform vec4 clipPlane; +uniform samplerCubeArray   heroProbes; + +void tapHeroProbe(inout vec3 glossenv, vec3 pos, vec3 norm, float glossiness) +{ +    float clipDist = dot(pos.xyz, clipPlane.xyz) + clipPlane.w; +    float w = 0; +    float dw = 0; +    float falloffMult = 10; +    vec3 refnormpersp = reflect(pos.xyz, norm.xyz); +    if (heroShape < 1) +    { +        float d = 0; +        boxIntersect(pos, norm, heroBox, d, 1.0); +         +        w = max(d, 0); +    } +    else +    { +        float r = heroSphere.w; +         +        w = sphereWeight(pos, refnormpersp, heroSphere.xyz, r, vec4(1), dw); +    } + +    clipDist = clipDist * 0.95 + 0.05; +    clipDist = clamp(clipDist * falloffMult, 0, 1); +    w = clamp(w * falloffMult * clipDist, 0, 1); +    w = mix(0, w, clamp(glossiness - 0.75, 0, 1) * 4); // We only generate a quarter of the mips for the hero probes.  Linearly interpolate between normal probes and hero probes based upon glossiness. +    glossenv = mix(glossenv, textureLod(heroProbes, vec4(env_mat * refnormpersp, 0), (1.0-glossiness)*heroMipCount).xyz, w); +} + +#else + +void tapHeroProbe(inout vec3 glossenv, vec3 pos, vec3 norm, float glossiness) +{ +} + +#endif + + +  void doProbeSample(inout vec3 ambenv, inout vec3 glossenv,          vec2 tc, vec3 pos, vec3 norm, float glossiness, bool transparent, vec3 amblit)  { @@ -712,6 +762,8 @@ void doProbeSample(inout vec3 ambenv, inout vec3 glossenv,          glossenv = mix(glossenv, ssr.rgb, ssr.a);      }  #endif + +    tapHeroProbe(glossenv, pos, norm, glossiness);  }  void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv, @@ -747,7 +799,7 @@ void debugTapRefMap(vec3 pos, vec3 dir, float depth, int i, inout vec4 col)      {          if (refIndex[i].w < 0)          { -            boxIntersectDebug(origin, pos, i, col); +            boxIntersectDebug(origin, pos, refBox[i], col);          }          else          { @@ -799,6 +851,7 @@ void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout      {          float lod = (1.0-glossiness)*reflection_lods;          glossenv = sampleProbes(pos, normalize(refnormpersp), lod); +              }      if (envIntensity > 0.0) @@ -826,6 +879,9 @@ void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout      }  #endif +    tapHeroProbe(glossenv, pos, norm, glossiness); +    tapHeroProbe(legacyenv, pos, norm, 1.0); +      glossenv = clamp(glossenv, vec3(0), vec3(10));  } diff --git a/indra/newview/app_settings/shaders/class3/deferred/screenSpaceReflPostF.glsl b/indra/newview/app_settings/shaders/class3/deferred/screenSpaceReflPostF.glsl index dbf20fe2d8..deb276ef9d 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/screenSpaceReflPostF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/screenSpaceReflPostF.glsl @@ -40,14 +40,13 @@ uniform sampler2D specularRect;  uniform sampler2D diffuseRect;  uniform sampler2D diffuseMap; -vec3 getNorm(vec2 screenpos); +vec4 getNorm(vec2 screenpos);  float getDepth(vec2 pos_screen);  float linearDepth(float d, float znear, float zfar);  float linearDepth01(float d, float znear, float zfar);  vec4 getPositionWithDepth(vec2 pos_screen, float depth);  vec4 getPosition(vec2 pos_screen); -vec4 getNormalEnvIntensityFlags(vec2 screenpos, out vec3 n, out float envIntensity);  float random (vec2 uv); @@ -57,9 +56,7 @@ void main()  {      vec2  tc = vary_fragcoord.xy;      float depth = linearDepth01(getDepth(tc), zNear, zFar); -    float envIntensity; -    vec3 n; -    vec4 norm = getNormalEnvIntensityFlags(tc, n, envIntensity); // need `norm.w` for GET_GBUFFER_FLAG() +    vec4 norm = getNorm(tc); // need `norm.w` for GET_GBUFFER_FLAG()      vec3 pos = getPositionWithDepth(tc, getDepth(tc)).xyz;      vec4 spec    = texture(specularRect, tc);      vec2 hitpixel; @@ -84,7 +81,7 @@ void main()      vec4 collectedColor = vec4(0); -    float w = tapScreenSpaceReflection(4, tc, pos, n, collectedColor, diffuseMap, 0); +    float w = tapScreenSpaceReflection(4, tc, pos, norm.xyz, collectedColor, diffuseMap, 0);      collectedColor.rgb *= specCol.rgb; diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl index 5e8fe9301a..96c32734e4 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl @@ -50,6 +50,7 @@ uniform float ssao_irradiance_max;  #endif  // Inputs +uniform vec4 clipPlane;  uniform mat3 env_mat;  uniform mat3  ssao_effect_mat;  uniform vec3 sun_dir; @@ -60,7 +61,7 @@ in vec2 vary_fragcoord;  uniform mat4 inv_proj;  uniform vec2 screen_res; -vec3 getNorm(vec2 pos_screen); +vec4 getNorm(vec2 pos_screen);  vec4 getPositionWithDepth(vec2 pos_screen, float depth);  void calcAtmosphericVarsLinear(vec3 inPositionEye, vec3 norm, vec3 light_dir, out vec3 sunlit, out vec3 amblit, out vec3 atten, out vec3 additive); @@ -127,13 +128,13 @@ void main()      vec2  tc           = vary_fragcoord.xy;      float depth        = getDepth(tc.xy);      vec4  pos          = getPositionWithDepth(tc, depth); -    vec4  norm         = texture(normalMap, tc); -    float envIntensity = norm.z; -    norm.xyz           = getNorm(tc); +    vec4  norm         = getNorm(tc); +    vec3 colorEmissive = texture(emissiveRect, tc).rgb; +    float envIntensity = colorEmissive.r;      vec3  light_dir   = (sun_up_factor == 1) ? sun_dir : moon_dir;      vec4 baseColor     = texture(diffuseRect, tc); -    vec4 spec        = texture(specularRect, vary_fragcoord.xy); // NOTE: PBR linear Emissive +    vec4 spec        = texture(specularRect, tc); // NOTE: PBR linear Emissive  #if defined(HAS_SUN_SHADOW) || defined(HAS_SSAO)      vec2 scol_ambocc = texture(lightMap, vary_fragcoord.xy).rg; @@ -168,17 +169,17 @@ void main()      if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_PBR))      { -        vec3 orm = texture(specularRect, tc).rgb;  +        vec3 orm = spec.rgb;           float perceptualRoughness = orm.g;          float metallic = orm.b;          float ao = orm.r; -        vec3 colorEmissive = texture(emissiveRect, tc).rgb; +                  // PBR IBL          float gloss      = 1.0 - perceptualRoughness;          sampleReflectionProbes(irradiance, radiance, tc, pos.xyz, norm.xyz, gloss, false, amblit_linear); -         +          adjustIrradiance(irradiance, ambocc);          vec3 diffuseColor; @@ -188,10 +189,15 @@ void main()          vec3 v = -normalize(pos.xyz);          color = pbrBaseLight(diffuseColor, specularColor, metallic, v, norm.xyz, perceptualRoughness, light_dir, sunlit_linear, scol, radiance, irradiance, colorEmissive, ao, additive, atten);      } -    else if (!GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_ATMOS)) +    else if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_HDRI)) +    { +        // actual HDRI sky, just copy color value +        color = colorEmissive.rgb; +    } +    else if (GET_GBUFFER_FLAG(GBUFFER_FLAG_SKIP_ATMOS))      { -        //should only be true of WL sky, just port over base color value -        color = texture(emissiveRect, tc).rgb; +        //should only be true of WL sky, port over base color value and scale for fake HDR +        color = colorEmissive.rgb;          color = srgb_to_linear(color);          color *= sky_hdr_scale;      } @@ -209,7 +215,7 @@ void main()          vec3 legacyenv = vec3(0);          sampleReflectionProbesLegacy(irradiance, glossenv, legacyenv, tc, pos.xyz, norm.xyz, spec.a, envIntensity, false, amblit_linear); -         +          adjustIrradiance(irradiance, ambocc);          // apply lambertian IBL only (see pbrIbl) @@ -244,6 +250,7 @@ void main()              // add radiance map              applyGlossEnv(color, glossenv, spec, pos.xyz, norm.xyz); +          }          color.rgb = mix(color.rgb, baseColor.rgb, baseColor.a); diff --git a/indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl index d31b37fb60..319fa86148 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl @@ -72,7 +72,7 @@ uniform mat4 inv_proj;  void calcHalfVectors(vec3 lv, vec3 n, vec3 v, out vec3 h, out vec3 l, out float nh, out float nl, out float nv, out float vh, out float lightDist);  float calcLegacyDistanceAttenuation(float distance, float falloff);  bool clipProjectedLightVars(vec3 center, vec3 pos, out float dist, out float l_dist, out vec3 lv, out vec4 proj_tc ); -vec4 getNormalEnvIntensityFlags(vec2 screenpos, out vec3 n, out float envIntensity); +vec4 getNorm(vec2 screenpos);  vec3 getProjectedLightAmbiance(float amb_da, float attenuation, float lit, float nl, float noise, vec2 projected_uv);  vec3 getProjectedLightDiffuseColor(float light_distance, vec2 projected_uv );  vec2 getScreenCoord(vec4 clip); @@ -121,9 +121,8 @@ void main()          shadow = clamp(shadow, 0.0, 1.0);              } -    float envIntensity; -    vec3 n; -    vec4 norm = getNormalEnvIntensityFlags(tc, n, envIntensity); +    vec4 norm = getNorm(tc); +    vec3 n = norm.xyz;      float dist_atten = calcLegacyDistanceAttenuation(dist, falloff);      if (dist_atten <= 0.0) @@ -145,7 +144,6 @@ void main()      if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_PBR))      { -        vec3 colorEmissive = texture(emissiveRect, tc).rgb;           vec3 orm = spec.rgb;          float perceptualRoughness = orm.g;          float metallic = orm.b; @@ -182,6 +180,8 @@ void main()      }      else      { +        float envIntensity = texture(emissiveRect, tc).r; +          diffuse = srgb_to_linear(diffuse);          spec.rgb = srgb_to_linear(spec.rgb); diff --git a/indra/newview/app_settings/shaders/class3/deferred/waterHazeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/waterHazeF.glsl index f6b8299f91..f6bef1e498 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/waterHazeF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/waterHazeF.glsl @@ -56,7 +56,6 @@ void main()      }      vec4  pos          = getPositionWithDepth(tc, depth); -    vec4  norm         = texture(normalMap, tc);      vec4 fogged = getWaterFogView(pos.xyz); diff --git a/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl b/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl index 223e55eb69..ef086fc3be 100644 --- a/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl +++ b/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl @@ -55,9 +55,11 @@ in vec4 view;  in vec3 vary_position;  vec4 applyWaterFogViewLinearNoClip(vec3 pos, vec4 color); +void mirrorClip(vec3 position);  void main()   { +	mirrorClip(vary_position);  	vec4 color;      //get detail normals diff --git a/indra/newview/app_settings/shaders/class3/environment/waterF.glsl b/indra/newview/app_settings/shaders/class3/environment/waterF.glsl index b364e454e8..b2a81aa025 100644 --- a/indra/newview/app_settings/shaders/class3/environment/waterF.glsl +++ b/indra/newview/app_settings/shaders/class3/environment/waterF.glsl @@ -35,6 +35,8 @@ vec3 scaleSoftClipFragLinear(vec3 l);  void calcAtmosphericVarsLinear(vec3 inPositionEye, vec3 norm, vec3 light_dir, out vec3 sunlit, out vec3 amblit, out vec3 atten, out vec3 additive);  vec4 applyWaterFogViewLinear(vec3 pos, vec4 color); +void mirrorClip(vec3 pos); +  // PBR interface  vec2 BRDF(float NoV, float roughness); @@ -129,6 +131,7 @@ vec3 getPositionWithNDC(vec3 ndc);  void main()   { +    mirrorClip(vary_position);      vN = vary_normal;      vT = vary_tangent;      vB = cross(vN, vT); | 
