diff options
Diffstat (limited to 'indra/newview/app_settings/shaders/class1')
41 files changed, 1495 insertions, 124 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" | 
