summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/newview/app_settings/settings.xml2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl80
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl77
-rw-r--r--indra/newview/lldrawpoolterrain.cpp87
-rw-r--r--indra/newview/llviewershadermgr.h14
5 files changed, 217 insertions, 43 deletions
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index e1fb82be32..85b90a8da5 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -10858,7 +10858,7 @@
<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, which reduces the number of texture binds. Some Intel and Mac graphics drivers do not support more than 16 texture binds. Because PBR terrain exceeds this limit at the highest detail level, reducing texture binds is necessary for compatibility.</string>
+ <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>
diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl
index db03e0885c..adb3319934 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl
@@ -26,6 +26,9 @@
/*[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]
@@ -51,8 +54,14 @@ 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
@@ -63,13 +72,21 @@ 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
@@ -81,21 +98,23 @@ out vec4 frag_data[4];
uniform sampler2D alpha_ramp;
-// *TODO: More configurable quality level which disables PBR features on machines
-// with limited texture availability
// 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;
@@ -104,8 +123,10 @@ 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
@@ -139,6 +160,7 @@ void main()
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
@@ -149,6 +171,13 @@ void main()
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;
@@ -158,13 +187,21 @@ void main()
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
@@ -180,13 +217,21 @@ void main()
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
@@ -202,13 +247,21 @@ void main()
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
@@ -224,13 +277,21 @@ void main()
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
@@ -248,6 +309,7 @@ void main()
}
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;
@@ -257,6 +319,10 @@ void main()
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)
@@ -264,8 +330,16 @@ void main()
#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(mix.orm.rgb, base_color_factor_alpha), vec4(0)); // PBR linear packed Occlusion, Roughness, Metal.
+ 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
index 316b751590..935c3f9301 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl
@@ -47,6 +47,9 @@
*/
#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;
@@ -75,8 +78,14 @@ vec3 srgb_to_linear(vec3 c);
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
@@ -86,8 +95,14 @@ 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
@@ -105,8 +120,14 @@ 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
@@ -116,8 +137,12 @@ PBRMix mix_pbr(PBRMix mix1, PBRMix mix2, float mix2_weight)
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
@@ -126,8 +151,14 @@ PBRMix sample_pbr(
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
@@ -254,8 +285,12 @@ 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
@@ -272,14 +307,20 @@ PBRMix terrain_sample_pbr(
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:
@@ -292,14 +333,20 @@ PBRMix terrain_sample_pbr(
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:
@@ -312,15 +359,21 @@ PBRMix terrain_sample_pbr(
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:
@@ -341,7 +394,11 @@ PBRMix terrain_sample_pbr(
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
@@ -349,7 +406,11 @@ PBRMix multiply_factors_pbr(
{
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
@@ -359,13 +420,21 @@ PBRMix multiply_factors_pbr(
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
@@ -377,8 +446,12 @@ PBRMix terrain_sample_and_multiply_pbr(
, _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
@@ -386,7 +459,11 @@ PBRMix terrain_sample_and_multiply_pbr(
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
diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp
index fc8e9fcfe5..3a943f27f6 100644
--- a/indra/newview/lldrawpoolterrain.cpp
+++ b/indra/newview/lldrawpoolterrain.cpp
@@ -54,8 +54,6 @@
const F32 DETAIL_SCALE = 1.f/16.f;
int DebugDetailMap = 0;
-const S32 PBR_DETAIL_EMISSIVE = 0;
-
S32 LLDrawPoolTerrain::sPBRDetailMode = 0;
F32 LLDrawPoolTerrain::sDetailScale = DETAIL_SCALE;
F32 LLDrawPoolTerrain::sPBRDetailScale = DETAIL_SCALE;
@@ -399,31 +397,37 @@ void LLDrawPoolTerrain::renderFullShaderPBR(BOOL local_materials)
gGL.getTexUnit(detail_basecolor[i])->setTextureAddressMode(LLTexUnit::TAM_WRAP);
gGL.getTexUnit(detail_basecolor[i])->activate();
- detail_normal[i] = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_NORMAL + i);
- if (detail_normal_texturep)
- {
- gGL.getTexUnit(detail_normal[i])->bind(detail_normal_texturep);
- }
- else
+ if (sPBRDetailMode >= TERRAIN_PBR_DETAIL_NORMAL)
{
- gGL.getTexUnit(detail_normal[i])->bind(LLViewerFetchedTexture::sFlatNormalImagep);
+ detail_normal[i] = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_NORMAL + i);
+ if (detail_normal_texturep)
+ {
+ gGL.getTexUnit(detail_normal[i])->bind(detail_normal_texturep);
+ }
+ else
+ {
+ gGL.getTexUnit(detail_normal[i])->bind(LLViewerFetchedTexture::sFlatNormalImagep);
+ }
+ gGL.getTexUnit(detail_normal[i])->setTextureAddressMode(LLTexUnit::TAM_WRAP);
+ gGL.getTexUnit(detail_normal[i])->activate();
}
- gGL.getTexUnit(detail_normal[i])->setTextureAddressMode(LLTexUnit::TAM_WRAP);
- gGL.getTexUnit(detail_normal[i])->activate();
- detail_metalrough[i] = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_METALLIC_ROUGHNESS + i);
- if (detail_metalrough_texturep)
+ if (sPBRDetailMode >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
{
- gGL.getTexUnit(detail_metalrough[i])->bind(detail_metalrough_texturep);
- }
- else
- {
- gGL.getTexUnit(detail_metalrough[i])->bind(LLViewerFetchedTexture::sWhiteImagep);
+ detail_metalrough[i] = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_METALLIC_ROUGHNESS + i);
+ if (detail_metalrough_texturep)
+ {
+ gGL.getTexUnit(detail_metalrough[i])->bind(detail_metalrough_texturep);
+ }
+ else
+ {
+ gGL.getTexUnit(detail_metalrough[i])->bind(LLViewerFetchedTexture::sWhiteImagep);
+ }
+ gGL.getTexUnit(detail_metalrough[i])->setTextureAddressMode(LLTexUnit::TAM_WRAP);
+ gGL.getTexUnit(detail_metalrough[i])->activate();
}
- gGL.getTexUnit(detail_metalrough[i])->setTextureAddressMode(LLTexUnit::TAM_WRAP);
- gGL.getTexUnit(detail_metalrough[i])->activate();
- if (sPBRDetailMode >= PBR_DETAIL_EMISSIVE)
+ if (sPBRDetailMode >= TERRAIN_PBR_DETAIL_EMISSIVE)
{
detail_emissive[i] = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_EMISSIVE + i);
if (detail_emissive_texturep)
@@ -499,9 +503,12 @@ void LLDrawPoolTerrain::renderFullShaderPBR(BOOL local_materials)
minimum_alphas[i] = min_alpha;
}
shader->uniform4fv(LLShaderMgr::TERRAIN_BASE_COLOR_FACTORS, terrain_material_count, (F32*)base_color_factors);
- shader->uniform4f(LLShaderMgr::TERRAIN_METALLIC_FACTORS, metallic_factors[0], metallic_factors[1], metallic_factors[2], metallic_factors[3]);
- shader->uniform4f(LLShaderMgr::TERRAIN_ROUGHNESS_FACTORS, roughness_factors[0], roughness_factors[1], roughness_factors[2], roughness_factors[3]);
- if (sPBRDetailMode >= PBR_DETAIL_EMISSIVE)
+ if (sPBRDetailMode >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
+ {
+ shader->uniform4f(LLShaderMgr::TERRAIN_METALLIC_FACTORS, metallic_factors[0], metallic_factors[1], metallic_factors[2], metallic_factors[3]);
+ shader->uniform4f(LLShaderMgr::TERRAIN_ROUGHNESS_FACTORS, roughness_factors[0], roughness_factors[1], roughness_factors[2], roughness_factors[3]);
+ }
+ if (sPBRDetailMode >= TERRAIN_PBR_DETAIL_EMISSIVE)
{
shader->uniform3fv(LLShaderMgr::TERRAIN_EMISSIVE_COLORS, terrain_material_count, (F32*)emissive_colors);
}
@@ -521,9 +528,15 @@ void LLDrawPoolTerrain::renderFullShaderPBR(BOOL local_materials)
for (U32 i = 0; i < terrain_material_count; ++i)
{
sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_BASE_COLOR + i);
- sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_NORMAL + i);
- sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_METALLIC_ROUGHNESS + i);
- if (sPBRDetailMode >= PBR_DETAIL_EMISSIVE)
+ if (sPBRDetailMode >= TERRAIN_PBR_DETAIL_NORMAL)
+ {
+ sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_NORMAL + i);
+ }
+ if (sPBRDetailMode >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
+ {
+ sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_METALLIC_ROUGHNESS + i);
+ }
+ if (sPBRDetailMode >= TERRAIN_PBR_DETAIL_EMISSIVE)
{
sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0_EMISSIVE + i);
}
@@ -532,15 +545,21 @@ void LLDrawPoolTerrain::renderFullShaderPBR(BOOL local_materials)
gGL.getTexUnit(detail_basecolor[i])->disable();
gGL.getTexUnit(detail_basecolor[i])->activate();
- gGL.getTexUnit(detail_normal[i])->unbind(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(detail_normal[i])->disable();
- gGL.getTexUnit(detail_normal[i])->activate();
+ if (sPBRDetailMode >= TERRAIN_PBR_DETAIL_NORMAL)
+ {
+ gGL.getTexUnit(detail_normal[i])->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(detail_normal[i])->disable();
+ gGL.getTexUnit(detail_normal[i])->activate();
+ }
- gGL.getTexUnit(detail_metalrough[i])->unbind(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(detail_metalrough[i])->disable();
- gGL.getTexUnit(detail_metalrough[i])->activate();
+ if (sPBRDetailMode >= TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS)
+ {
+ gGL.getTexUnit(detail_metalrough[i])->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(detail_metalrough[i])->disable();
+ gGL.getTexUnit(detail_metalrough[i])->activate();
+ }
- if (sPBRDetailMode >= PBR_DETAIL_EMISSIVE)
+ if (sPBRDetailMode >= TERRAIN_PBR_DETAIL_EMISSIVE)
{
gGL.getTexUnit(detail_emissive[i])->unbind(LLTexUnit::TT_TEXTURE);
gGL.getTexUnit(detail_emissive[i])->disable();
diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h
index 4273c3e70c..824c66ab49 100644
--- a/indra/newview/llviewershadermgr.h
+++ b/indra/newview/llviewershadermgr.h
@@ -281,15 +281,19 @@ extern LLGLSLShader gDeferredPBROpaqueProgram;
extern LLGLSLShader gDeferredPBRAlphaProgram;
extern LLGLSLShader gHUDPBRAlphaProgram;
-// Encodes detail level for dropping textures, in accordance with the GLTF spec
+// Encodes detail level for dropping textures, in accordance with the GLTF spec where possible
// 0 is highest detail, -1 drops emissive, etc
+// Dropping metallic roughness is off-spec - Reserve for potato machines as needed
// https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#additional-textures
enum TerrainPBRDetail : S32
{
- TERRAIN_PBR_DETAIL_MAX = 0,
- TERRAIN_PBR_DETAIL_EMISSIVE = 0,
- TERRAIN_PBR_DETAIL_OCCLUSION = -1,
- TERRAIN_PBR_DETAIL_MIN = -1,
+ TERRAIN_PBR_DETAIL_MAX = 0,
+ TERRAIN_PBR_DETAIL_EMISSIVE = 0,
+ TERRAIN_PBR_DETAIL_OCCLUSION = -1,
+ TERRAIN_PBR_DETAIL_NORMAL = -2,
+ TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS = -3,
+ TERRAIN_PBR_DETAIL_BASE_COLOR = -4,
+ TERRAIN_PBR_DETAIL_MIN = -4,
};
extern LLGLSLShader gDeferredPBRTerrainProgram;
#endif