summaryrefslogtreecommitdiff
path: root/indra/newview/app_settings
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/app_settings')
-rw-r--r--indra/newview/app_settings/settings.xml285
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/avatarEyesV.glsl3
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl5
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl6
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl5
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl3
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl3
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl7
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/exposureF.glsl6
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/globalF.glsl45
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl18
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/materialV.glsl17
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl7
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl7
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl348
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl473
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl96
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl15
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/skyF.glsl60
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/skyV.glsl12
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl12
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/textureUtilV.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/treeF.glsl3
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/treeV.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/normaldebugF.glsl33
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/normaldebugG.glsl76
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/normaldebugV.glsl74
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class1/objects/bumpF.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class1/objects/bumpV.glsl5
-rw-r--r--indra/newview/app_settings/shaders/class1/windlight/atmosphericsFuncs.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl3
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl3
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/materialF.glsl18
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl80
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl15
-rw-r--r--indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class3/environment/waterF.glsl3
44 files changed, 1699 insertions, 87 deletions
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 2f7c256b49..e42906e78b 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -8732,7 +8732,7 @@
<key>OctreeAlphaDistanceFactor</key>
<map>
<key>Comment</key>
- <string>Multiplier on alpha object distance for determining octree node size </string>
+ <string>Multiplier on alpha object distance for determining octree node size. First two parameters are currently unused. Third parameter is distance at which to perform detailed alpha sorting.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -8741,7 +8741,7 @@
<array>
<real>0.1</real>
<real>0.0</real>
- <real>0.0</real>
+ <real>64.0</real>
</array>
</map>
@@ -8861,17 +8861,6 @@
<key>Value</key>
<real>32.0</real>
</map>
- <key>RenderCloudShadowAmbianceFactor</key>
- <map>
- <key>Comment</key>
- <string>Amount that cloud shadow (aka cloud coverage) contributes to reflection probe ambiance</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>F32</string>
- <key>Value</key>
- <real>0.1</real>
- </map>
<key>RenderCPUBasis</key>
<map>
<key>Comment</key>
@@ -9186,6 +9175,17 @@
<real>0.00</real>
</array>
</map>
+ <key>RenderMirrors</key>
+ <map>
+ <key>Comment</key>
+ <string>Renders realtime mirrors.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>RenderScreenSpaceReflections</key>
<map>
<key>Comment</key>
@@ -9296,6 +9296,17 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>RenderDesaturateIrradiance</key>
+ <map>
+ <key>Comment</key>
+ <string>Desaturate irradiance to remove blue tint</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
<key>RenderDebugAlphaMask</key>
<map>
<key>Comment</key>
@@ -9362,6 +9373,50 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <key>RenderHDRIExposure</key>
+ <map>
+ <key>Comment</key>
+ <string>Exposure adjustment of HDRI when previewing an HDRI. Units are EV. Sane values would be -10 to 10.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>0.0</real>
+ </map>
+ <key>RenderHDRIRotation</key>
+ <map>
+ <key>Comment</key>
+ <string>Rotation (in degrees) of environment when previewing an HDRI.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>0.0</real>
+ </map>
+ <key>RenderHDRISplitScreen</key>
+ <map>
+ <key>Comment</key>
+ <string>What percentage of screen to render using HDRI vs EEP sky.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>1.0</real>
+ </map>
+ <key>RenderHDRIIrradianceOnly</key>
+ <map>
+ <key>Comment</key>
+ <string>Only use HDRI sky for irradiance map when RenderHDRISplitScreen is 0</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>RenderMaxOpenGLVersion</key>
<map>
<key>Comment</key>
@@ -9395,6 +9450,17 @@
<key>Value</key>
<integer>16</integer>
</map>
+ <key>RenderMaxTextureResolution</key>
+ <map>
+ <key>Comment</key>
+ <string>Maximum texture resolution to download for non-boosted textures.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>U32</string>
+ <key>Value</key>
+ <integer>2048</integer>
+ </map>
<key>RenderDebugTextureBind</key>
<map>
<key>Comment</key>
@@ -10390,6 +10456,50 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <key>RenderHeroProbeResolution</key>
+ <map>
+ <key>Comment</key>
+ <string>Resolution to render hero probes used for mirrors, water, etc.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>1024</integer>
+ </map>
+ <key>RenderHeroProbeDistance</key>
+ <map>
+ <key>Comment</key>
+ <string>Distance in meters for hero probes to render out to.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>8</real>
+ </map>
+ <key>RenderHeroProbeUpdateRate</key>
+ <map>
+ <key>Comment</key>
+ <string>How many frames to wait for until it's time to render the probe. E.g., every other frame (1), every two frames (2), every three frames (3) etc.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>2</integer>
+ </map>
+ <key>RenderHeroProbeConservativeUpdateMultiplier</key>
+ <map>
+ <key>Comment</key>
+ <string>How many probe updates to wait until it's time to update faces that are not directly facing the camera. Acts as a multiplier. E.g., frames to the periphery of the camera updating once every 3 updates, vs ones directly facing the camera updating every update.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>16</integer>
+ </map>
<key>RenderReflectionProbeVolumes</key>
<map>
<key>Comment</key>
@@ -10756,6 +10866,17 @@
<key>Value</key>
<real>0.5</real>
</map>
+ <key>RenderDiffuseLuminanceScale</key>
+ <map>
+ <key>Comment</key>
+ <string>Luminance adjustment for diffuse surfaces to aid auto-exposure behavior</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>0.5</real>
+ </map>
<key>RenderShaderLODThreshold</key>
<map>
<key>Comment</key>
@@ -10814,7 +10935,7 @@
<key>RenderTerrainScale</key>
<map>
<key>Comment</key>
- <string>Terrain detail texture scale</string>
+ <string>Terrain detail texture scale (meters)</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -10822,6 +10943,83 @@
<key>Value</key>
<real>12.0</real>
</map>
+ <key>RenderTerrainPBREnabled</key>
+ <map>
+ <key>Comment</key>
+ <string>EXPERIMENTAL: Enable PBR Terrain features.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>RenderTerrainPBRForce</key>
+ <map>
+ <key>Comment</key>
+ <string>Force-load PBR terrain if enabled</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>RenderTerrainPBRDetail</key>
+ <map>
+ <key>Comment</key>
+ <string>Detail level for PBR terrain. 0 is full detail. Negative values drop rendering features, in accordance with the GLTF specification when possible, which reduces the number of texture binds.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>RenderTerrainPBRScale</key>
+ <map>
+ <key>Comment</key>
+ <string>PBR terrain detail texture scale (meters)</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>8.0</real>
+ </map>
+ <key>RenderTerrainPBRPlanarSampleCount</key>
+ <map>
+ <key>Comment</key>
+ <string>How many UV planes to sample PBR terrain textures from. 1 is "flat", 3 is triplanar mapping (aka box mapping)</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <real>3</real>
+ </map>
+ <key>RenderTerrainPBRTriplanarBlendFactor</key>
+ <map>
+ <key>Comment</key>
+ <string>Higher values create sharper transitions, but are more likely to produce artifacts.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>8.0</real>
+ </map>
+ <key>RenderTerrainPBRNormalsEnabled</key>
+ <map>
+ <key>Comment</key>
+ <string>EXPERIMENTAL: Change normal gen for PBR Terrain.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>RenderTrackerBeacon</key>
<map>
<key>Comment</key>
@@ -13752,6 +13950,17 @@
<key>Value</key>
<integer>2</integer>
</map>
+ <key>UIPreviewMaterial</key>
+ <map>
+ <key>Comment</key>
+ <string>Whether or not PBR material swatch is enabled</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <real>0</real>
+ </map>
<key>UIResizeBarHeight</key>
<map>
<key>Comment</key>
@@ -15667,7 +15876,7 @@
<key>Type</key>
<string>S32</string>
<key>Value</key>
- <integer>2048</integer>
+ <integer>1024</integer>
</map>
<key>max_texture_dimension_Y</key>
<map>
@@ -15678,7 +15887,7 @@
<key>Type</key>
<string>S32</string>
<key>Value</key>
- <integer>2048</integer>
+ <integer>1024</integer>
</map>
<!-- End of back compatibility settings -->
<key>teleport_offer_invitation_max_length</key>
@@ -16554,6 +16763,50 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <key>LocalTerrainAsset1</key>
+ <map>
+ <key>Comment</key>
+ <string>If set to a non-null UUID, overrides the terrain asset locally for all regions with material assets. Local terrain assets are not visible to others. Please keep in mind that this debug setting may be temporary. Do not rely on this setting existing in future viewer builds.</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>String</string>
+ <key>Value</key>
+ <string>00000000-0000-0000-0000-000000000000</string>
+ </map>
+ <key>LocalTerrainAsset2</key>
+ <map>
+ <key>Comment</key>
+ <string>If set to a non-null UUID, overrides the terrain asset locally for all regions with material assets. Local terrain assets are not visible to others. Please keep in mind that this debug setting may be temporary. Do not rely on this setting existing in future viewer builds.</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>String</string>
+ <key>Value</key>
+ <string>00000000-0000-0000-0000-000000000000</string>
+ </map>
+ <key>LocalTerrainAsset3</key>
+ <map>
+ <key>Comment</key>
+ <string>If set to a non-null UUID, overrides the terrain asset locally for all regions with material assets. Local terrain assets are not visible to others. Please keep in mind that this debug setting may be temporary. Do not rely on this setting existing in future viewer builds.</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>String</string>
+ <key>Value</key>
+ <string>00000000-0000-0000-0000-000000000000</string>
+ </map>
+ <key>LocalTerrainAsset4</key>
+ <map>
+ <key>Comment</key>
+ <string>If set to a non-null UUID, overrides the terrain asset locally for all regions with material assets. Local terrain assets are not visible to others. Please keep in mind that this debug setting may be temporary. Do not rely on this setting existing in future viewer builds.</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>String</string>
+ <key>Value</key>
+ <string>00000000-0000-0000-0000-000000000000</string>
+ </map>
<key>PathfindingRetrieveNeighboringRegion</key>
<map>
<key>Comment</key>
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..c0607d0149 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl
@@ -33,11 +33,15 @@ 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)
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/bumpF.glsl b/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl
index 35f483f633..a22c174349 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl
@@ -37,11 +37,15 @@ 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)
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/diffuseAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl
index 6f3b94f734..e8ead91504 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl
@@ -31,14 +31,20 @@ 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)
diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl
index e5f2af2c53..a07c892d8e 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl
@@ -28,6 +28,7 @@
out vec4 frag_data[4];
in vec3 vary_normal;
+in vec3 vary_position;
uniform float minimum_alpha;
@@ -36,8 +37,12 @@ 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)
diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl
index 68fb8bf499..76776ede2c 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl
@@ -32,11 +32,14 @@ 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
diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl
index 93d561504e..b983acf657 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl
@@ -30,12 +30,15 @@ out vec4 frag_data[4];
in vec3 vary_normal;
in vec4 vertex_color;
in vec2 vary_texcoord0;
+in vec3 vary_position;
+void mirrorClip(vec3 pos);
vec2 encode_normal(vec3 n);
vec3 linear_to_srgb(vec3 c);
void main()
{
+ mirrorClip(vary_position);
vec3 col = vertex_color.rgb * diffuseLookup(vary_texcoord0.xy).rgb;
vec3 spec;
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/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/pbropaqueF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl
index faa273b834..0683236460 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl
@@ -58,10 +58,17 @@ 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;
if (basecolor.a < minimum_alpha)
{
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..57c0a6024f
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl
@@ -0,0 +1,348 @@
+/**
+ * @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[2]
+#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[2] vary_coords;
+#endif
+in vec3 vary_position;
+in vec3 vary_normal;
+in vec3 vary_tangent;
+flat in float vary_sign;
+in vec4 vary_texcoord0;
+in vec4 vary_texcoord1;
+
+vec2 encode_normal(vec3 n);
+void mirrorClip(vec3 position);
+
+float terrain_mix(TerrainMix tm, vec4 tms4);
+
+void main()
+{
+ // Make sure we clip the terrain if we're in a mirror.
+ mirrorClip(vary_position);
+
+#if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3
+ TerrainCoord terrain_texcoord = vary_coords;
+#elif TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 1
+ TerrainCoord terrain_texcoord = vary_texcoord0.xy;
+#endif
+
+ 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;
+ switch (tm.type & MIX_X)
+ {
+ case MIX_X:
+ 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
+ );
+ mix = mix_pbr(mix, mix2, tm.weight.x);
+ break;
+ default:
+ break;
+ }
+ switch (tm.type & MIX_Y)
+ {
+ case MIX_Y:
+ 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
+ );
+ mix = mix_pbr(mix, mix2, tm.weight.y);
+ break;
+ default:
+ break;
+ }
+ switch (tm.type & MIX_Z)
+ {
+ case MIX_Z:
+ 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
+ );
+ mix = mix_pbr(mix, mix2, tm.weight.z);
+ break;
+ default:
+ break;
+ }
+ switch (tm.type & MIX_W)
+ {
+ case MIX_W:
+ 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
+ );
+ 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)
+ // from mikktspace.com
+ vec3 vNt = mix.vNt;
+ vec3 vN = vary_normal;
+ vec3 vT = vary_tangent.xyz;
+
+ 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;
+#else
+ vec3 tnorm = vary_normal;
+ tnorm *= gl_FrontFacing ? 1.0 : -1.0;
+#endif
+
+
+#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] = max(vec4(encode_normal(tnorm), base_color_factor_alpha, GBUFFER_FLAG_HAS_PBR), vec4(0)); // 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/pbrterrainUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl
new file mode 100644
index 0000000000..935c3f9301
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl
@@ -0,0 +1,473 @@
+/**
+ * @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[2]
+
+vec2 _t_uv(vec2 uv_unflipped, float sign_or_zero)
+{
+ // Handle case where sign is 0
+ float sign = (2.0*sign_or_zero) + 1.0;
+ sign /= abs(sign);
+ // If the vertex normal is negative, flip the texture back
+ // right-side up.
+ vec2 uv = uv_unflipped * vec2(sign, 1);
+ return uv;
+}
+
+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, sign(vary_vertex_normal.x))
+#define get_uv_y() _t_uv(terrain_coord[1].xy, sign(vary_vertex_normal.y))
+#define get_uv_z() _t_uv(terrain_coord[0].xy, 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..489fc26e3f
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl
@@ -0,0 +1,96 @@
+/**
+ * @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$
+ */
+
+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;
+
+#if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3
+out vec4[2] vary_coords;
+#endif
+out vec3 vary_vertex_normal; // Used by pbrterrainUtilF.glsl
+out vec3 vary_normal;
+out vec3 vary_tangent;
+flat out float vary_sign;
+out vec4 vary_texcoord0;
+out vec4 vary_texcoord1;
+out vec3 vary_position;
+
+// *HACK: tangent_space_transform should use texture_normal_transform, or maybe
+// we shouldn't use tangent_space_transform at all. See the call to
+// tangent_space_transform below.
+uniform vec4[2] texture_base_color_transform;
+
+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);
+
+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;
+
+ vary_tangent = normalize(t);
+ // *TODO: Decide if we want this. It may be better to just calculate the
+ // tangents on-the-fly in the fragment shader, due to the subtleties of the
+ // effect of triplanar mapping on UVs.
+ // *HACK: Should be using texture_normal_transform here. The KHR texture
+ // transform spec requires handling texture transforms separately for each
+ // individual texture.
+ vary_tangent = normalize(tangent_space_transform(vec4(t, tangent.w), n, texture_base_color_transform, texture_matrix0));
+ vary_sign = tangent.w;
+ vary_normal = normalize(n);
+
+ // Transform and pass tex coords
+ // *HACK: texture_base_color_transform is used for all of these here, but
+ // the KHR texture transform spec requires handling texture transforms
+ // separately for each individual texture.
+#if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3
+ // xy
+ vary_coords[0].xy = texture_transform(position.xy, texture_base_color_transform, texture_matrix0);
+ // yz
+ vary_coords[0].zw = texture_transform(position.yz, texture_base_color_transform, texture_matrix0);
+ // (-x)z
+ vary_coords[1].xy = texture_transform(position.xz * vec2(-1, 1), texture_base_color_transform, texture_matrix0);
+#elif TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 1
+ vary_texcoord0.xy = texture_transform(position.xy, texture_base_color_transform, texture_matrix0);
+#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..2dba7cb9d9 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl
@@ -39,9 +39,11 @@ 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);
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..732333311c 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/textureUtilV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/textureUtilV.glsl
@@ -65,7 +65,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
diff --git a/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl b/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl
index e2d87e68fa..f108faf283 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl
@@ -32,13 +32,16 @@ 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)
{
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/interface/normaldebugF.glsl b/indra/newview/app_settings/shaders/class1/interface/normaldebugF.glsl
new file mode 100644
index 0000000000..388042e7e0
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/interface/normaldebugF.glsl
@@ -0,0 +1,33 @@
+/**
+ * @file normaldebugF.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$
+ */
+
+out vec4 frag_color;
+
+in vec4 vertex_color;
+
+void main()
+{
+ 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..40b7f9cf0e 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), -10, 10);
// 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..4aef22c296 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl
@@ -78,6 +78,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 +169,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/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/materialF.glsl b/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl
index ec1e49eeb4..0476b98e10 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;
@@ -285,12 +292,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
@@ -407,9 +414,12 @@ void main()
#else // mode is not DIFFUSE_ALPHA_MODE_BLEND, encode to gbuffer
// deferred path // See: C++: addDeferredAttachment(), shader: softenLightF.glsl
+
+ float flag = GBUFFER_FLAG_HAS_ATMOS;
+
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[2] = vec4(encode_normal(norm), env, flag);; // XY = Normal. Z = Env. intensity. W = 1 skip atmos (mask off fog)
frag_data[3] = vec4(0);
#endif
}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl
index 906e66ecc8..4f2475b101 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);
+
+ 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/softenLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
index 5e8fe9301a..9b9739ba22 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;
@@ -178,7 +179,7 @@ void main()
float gloss = 1.0 - perceptualRoughness;
sampleReflectionProbes(irradiance, radiance, tc, pos.xyz, norm.xyz, gloss, false, amblit_linear);
-
+
adjustIrradiance(irradiance, ambocc);
vec3 diffuseColor;
@@ -188,9 +189,14 @@ 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 = texture(emissiveRect, tc).rgb;
+ }
+ else if (GET_GBUFFER_FLAG(GBUFFER_FLAG_SKIP_ATMOS))
{
- //should only be true of WL sky, just port over base color value
+ //should only be true of WL sky, port over base color value and scale for fake HDR
color = texture(emissiveRect, tc).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/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);