diff options
| author | RunitaiLinden <davep@lindenlab.com> | 2024-02-08 14:54:57 -0600 | 
|---|---|---|
| committer | RunitaiLinden <davep@lindenlab.com> | 2024-02-08 14:54:57 -0600 | 
| commit | 602be267ed55dc7cb3725bff1510d59bec950d39 (patch) | |
| tree | 695e72c4794bed40a2b32fdd65bda14901439d5c /indra/newview/app_settings/shaders | |
| parent | c721152c444ee7a13e4217f86dfcce34b7488ee5 (diff) | |
| parent | 4f6e3acece507b8be66b76db5609bdaec41307d4 (diff) | |
Merge branch 'release/materials_featurette' into materials_featurette/mirrors
Diffstat (limited to 'indra/newview/app_settings/shaders')
| -rw-r--r-- | indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl | 82 | ||||
| -rw-r--r-- | indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl | 77 | 
2 files changed, 154 insertions, 5 deletions
| diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl index db03e0885c..c83a6be85d 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] @@ -38,7 +41,6 @@  #define MIX_Z    1 << 5  #define MIX_W    1 << 6 -// TODO: Decide if this struct needs to be declared  struct TerrainMix  {      vec4 weight; @@ -47,12 +49,17 @@ struct TerrainMix  TerrainMix get_terrain_mix_weights(float alpha1, float alpha2, float alphaFinal); -// TODO: Decide if this struct needs to be declared  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 +70,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 +96,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 +121,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 +158,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 +169,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 +185,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 +215,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 +245,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 +275,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 +307,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 +317,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 +328,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 | 
