diff options
Diffstat (limited to 'indra/newview/app_settings/shaders')
5 files changed, 205 insertions, 14 deletions
| diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl index 6ca35419f2..410c447c64 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl @@ -30,6 +30,9 @@  #define TERRAIN_PBR_DETAIL_NORMAL -2  #define TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS -3 +#define TERRAIN_PAINT_TYPE_HEIGHTMAP_WITH_NOISE 0 +#define TERRAIN_PAINT_TYPE_PBR_PAINTMAP 1 +  #if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3  #define TerrainCoord vec4[3]  #elif TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 1 @@ -48,6 +51,7 @@ struct TerrainMix  };  TerrainMix get_terrain_mix_weights(float alpha1, float alpha2, float alphaFinal); +TerrainMix get_terrain_usage_from_weight3(vec3 weight3);  struct PBRMix  { @@ -97,7 +101,11 @@ PBRMix mix_pbr(PBRMix mix1, PBRMix mix2, float mix2_weight);  out vec4 frag_data[4]; +#if TERRAIN_PAINT_TYPE == TERRAIN_PAINT_TYPE_HEIGHTMAP_WITH_NOISE  uniform sampler2D alpha_ramp; +#elif TERRAIN_PAINT_TYPE == TERRAIN_PAINT_TYPE_PBR_PAINTMAP +uniform sampler2D paint_map; +#endif  // https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#additional-textures  uniform sampler2D detail_0_base_color; @@ -133,19 +141,25 @@ uniform vec3[4] emissiveColors;  #endif  uniform vec4 minimum_alphas; // PBR alphaMode: MASK, See: mAlphaCutoff, setAlphaCutoff() -#if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3 -in vec4[10] vary_coords; -#elif TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 1 -in vec4[2] vary_coords; -#endif  in vec3 vary_position;  in vec3 vary_normal;  #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL)  in vec3 vary_tangents[4];  flat in float vary_signs[4];  #endif + +// vary_texcoord* are used for terrain composition, vary_coords are used for terrain UVs +#if TERRAIN_PAINT_TYPE == TERRAIN_PAINT_TYPE_HEIGHTMAP_WITH_NOISE  in vec4 vary_texcoord0;  in vec4 vary_texcoord1; +#elif TERRAIN_PAINT_TYPE == TERRAIN_PAINT_TYPE_PBR_PAINTMAP +in vec2 vary_texcoord; +#endif +#if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3 +in vec4[10] vary_coords; +#elif TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 1 +in vec4[2] vary_coords; +#endif  void mirrorClip(vec3 position); @@ -171,11 +185,16 @@ void main()      // Make sure we clip the terrain if we're in a mirror.      mirrorClip(vary_position); +    TerrainMix tm; +#if TERRAIN_PAINT_TYPE == TERRAIN_PAINT_TYPE_HEIGHTMAP_WITH_NOISE      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); +    tm = get_terrain_mix_weights(alpha1, alpha2, alphaFinal); +#elif TERRAIN_PAINT_TYPE == TERRAIN_PAINT_TYPE_PBR_PAINTMAP +    tm = get_terrain_usage_from_weight3(texture(paint_map, vary_texcoord).xyz); +#endif  #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_OCCLUSION)      // RGB = Occlusion, Roughness, Metal diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl index 5098de717e..dc43007dca 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl @@ -51,7 +51,12 @@  #define TERRAIN_PBR_DETAIL_NORMAL -2  #define TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS -3 +#define TERRAIN_PAINT_TYPE_HEIGHTMAP_WITH_NOISE 0 +#define TERRAIN_PAINT_TYPE_PBR_PAINTMAP 1 + +#if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3  in vec3 vary_vertex_normal; +#endif  vec3 srgb_to_linear(vec3 c); @@ -202,6 +207,45 @@ TerrainMix get_terrain_mix_weights(float alpha1, float alpha2, float alphaFinal)      return tm;  } +// A paintmap weight applier for 4 swatches. The input saves a channel by not +// storing swatch 1, and assuming the weights of the 4 swatches add to 1. +// The components of weight3 should be between 0 and 1 +// The sum of the components of weight3 should be between 0 and 1 +TerrainMix get_terrain_usage_from_weight3(vec3 weight3) +{ +    // These steps ensure the output weights add to between 0 and 1 +    weight3.xyz = max(vec3(0.0), weight3.xyz); +    weight3.xyz /= max(1.0, weight3.x + weight3.y + weight3.z); + +    TerrainMix tm; + +    // Extract the first weight from the other weights +    tm.weight.x = 1.0 - (weight3.x + weight3.y + weight3.z); +    tm.weight.yzw = weight3.xyz; +    ivec4 usage = max(ivec4(0), ivec4(ceil(tm.weight))); + +    tm.type = (usage.x * MIX_X) | +              (usage.y * MIX_Y) | +              (usage.z * MIX_Z) | +              (usage.w * MIX_W); +    return tm; +} + +// Inverse of get_terrain_usage_from_weight3, excluding usage flags +// The components of weight should be between 0 and 1 +// The sum of the components of weight should be 1 +vec3 get_weight3_from_terrain_weight(vec4 weight) +{ +    // These steps ensure the input weights add to 1 +    weight = max(vec4(0.0), weight); +    weight.x += 1.0 - sign(weight.x + weight.y + weight.z + weight.w); +    weight /= weight.x + weight.y + weight.z + weight.w; + +    // Then return the input weights with the first weight truncated +    return weight.yzw; +} + +#if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3  TerrainTriplanar _t_triplanar()  {      float sharpness = TERRAIN_TRIPLANAR_BLEND_FACTOR; @@ -219,6 +263,8 @@ TerrainTriplanar _t_triplanar()                ((usage.z) * SAMPLE_Z);      return tw;  } +#endif +  // Assume weights add to 1  float terrain_mix(TerrainMix tm, vec4 tms4) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl index c90b2b5926..6791a22a76 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl @@ -28,31 +28,47 @@  #define TERRAIN_PBR_DETAIL_NORMAL -2  #define TERRAIN_PBR_DETAIL_METALLIC_ROUGHNESS -3 +#define TERRAIN_PAINT_TYPE_HEIGHTMAP_WITH_NOISE 0 +#define TERRAIN_PAINT_TYPE_PBR_PAINTMAP 1 +  uniform mat3 normal_matrix;  uniform mat4 texture_matrix0;  uniform mat4 modelview_matrix;  uniform mat4 modelview_projection_matrix; +#if TERRAIN_PAINT_TYPE == TERRAIN_PAINT_TYPE_PBR_PAINTMAP +uniform float region_scale; +#endif  in vec3 position;  in vec3 normal;  in vec4 tangent;  in vec4 diffuse_color; +#if TERRAIN_PAINT_TYPE == TERRAIN_PAINT_TYPE_HEIGHTMAP_WITH_NOISE  in vec2 texcoord1; +#endif -out vec3 vary_vertex_normal; // Used by pbrterrainUtilF.glsl +out vec3 vary_position;  out vec3 vary_normal; +#if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3 +out vec3 vary_vertex_normal; // Used by pbrterrainUtilF.glsl +#endif  #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL)  out vec3 vary_tangents[4];  flat out float vary_signs[4];  #endif + +// vary_texcoord* are used for terrain composition, vary_coords are used for terrain UVs +#if TERRAIN_PAINT_TYPE == TERRAIN_PAINT_TYPE_HEIGHTMAP_WITH_NOISE  out vec4 vary_texcoord0;  out vec4 vary_texcoord1; +#elif TERRAIN_PAINT_TYPE == TERRAIN_PAINT_TYPE_PBR_PAINTMAP +out vec2 vary_texcoord; +#endif  #if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3  out vec4[10] vary_coords;  #elif TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 1  out vec4[2] vary_coords;  #endif -out vec3 vary_position;  // *HACK: Each material uses only one texture transform, but the KHR texture  // transform spec allows handling texture transforms separately for each @@ -69,7 +85,9 @@ void main()      vary_position = (modelview_matrix*vec4(position.xyz, 1.0)).xyz;      vec3 n = normal_matrix * normal; +#if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3      vary_vertex_normal = normal; +#endif      vec3 t = normal_matrix * tangent.xyz;  #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_NORMAL) @@ -110,9 +128,9 @@ void main()      // Transform and pass tex coords      {          vec4[2] ttt; +#define transform_xy()             terrain_texture_transform(position.xy,               ttt)  #if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3  // Don't care about upside-down (transform_xy_flipped()) -#define transform_xy()             terrain_texture_transform(position.xy,               ttt)  #define transform_yz()             terrain_texture_transform(position.yz,               ttt)  #define transform_negx_z()         terrain_texture_transform(position.xz * vec2(-1, 1), ttt)  #define transform_yz_flipped()     terrain_texture_transform(position.yz * vec2(-1, 1), ttt) @@ -157,26 +175,30 @@ void main()          ttt[0].xyz = terrain_texture_transforms[0].xyz;          ttt[1].x = terrain_texture_transforms[0].w;          ttt[1].y = terrain_texture_transforms[1].x; -        vary_coords[0].xy = terrain_texture_transform(position.xy, ttt); +        vary_coords[0].xy = transform_xy();          // material 2          ttt[0].xyz = terrain_texture_transforms[1].yzw;          ttt[1].xy = terrain_texture_transforms[2].xy; -        vary_coords[0].zw = terrain_texture_transform(position.xy, ttt); +        vary_coords[0].zw = transform_xy();          // material 3          ttt[0].xy = terrain_texture_transforms[2].zw;          ttt[0].z = terrain_texture_transforms[3].x;          ttt[1].xy = terrain_texture_transforms[3].yz; -        vary_coords[1].xy = terrain_texture_transform(position.xy, ttt); +        vary_coords[1].xy = transform_xy();          // material 4          ttt[0].x = terrain_texture_transforms[3].w;          ttt[0].yz = terrain_texture_transforms[4].xy;          ttt[1].xy = terrain_texture_transforms[4].zw; -        vary_coords[1].zw = terrain_texture_transform(position.xy, ttt); +        vary_coords[1].zw = transform_xy();  #endif      } -    vec4 tc = vec4(texcoord1,0,1); +#if TERRAIN_PAINT_TYPE == TERRAIN_PAINT_TYPE_HEIGHTMAP_WITH_NOISE +    vec2 tc = texcoord1.xy;      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); +#elif TERRAIN_PAINT_TYPE == TERRAIN_PAINT_TYPE_PBR_PAINTMAP +    vary_texcoord = position.xy / region_scale; +#endif  } diff --git a/indra/newview/app_settings/shaders/class1/interface/pbrTerrainBakeF.glsl b/indra/newview/app_settings/shaders/class1/interface/pbrTerrainBakeF.glsl new file mode 100644 index 0000000000..cf20653a0f --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/interface/pbrTerrainBakeF.glsl @@ -0,0 +1,62 @@ +/** + * @file terrainBakeF.glsl + * + * $LicenseInfo:firstyear=2007&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$ + */ + +/*[EXTRA_CODE_HERE]*/ + +out vec4 frag_color; + +struct TerrainMix +{ +    vec4 weight; +    int type; +}; + +TerrainMix get_terrain_mix_weights(float alpha1, float alpha2, float alphaFinal); + +uniform sampler2D alpha_ramp; + +// vary_texcoord* are used for terrain composition +in vec4 vary_texcoord0; +in vec4 vary_texcoord1; + +void main() +{ +    TerrainMix tm; +    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; + +    tm = get_terrain_mix_weights(alpha1, alpha2, alphaFinal); + +    // tm.weight.x can be ignored. The paintmap saves a channel by not storing +    // swatch 1, and assuming the weights of the 4 swatches add to 1. +    // TERRAIN_PAINT_PRECISION emulates loss of precision at lower bit depth +    // when a corresponding low-bit image format is not available. Because +    // integral values at one depth cannot be precisely represented at another +    // bit depth, rounding is required. To maximize numerical stability for +    // future conversions, bit depth conversions should round to the nearest +    // integer, not floor or ceil. +    frag_color = max(vec4(round(tm.weight.yzw * TERRAIN_PAINT_PRECISION) / TERRAIN_PAINT_PRECISION, 1.0), vec4(0)); +} diff --git a/indra/newview/app_settings/shaders/class1/interface/pbrTerrainBakeV.glsl b/indra/newview/app_settings/shaders/class1/interface/pbrTerrainBakeV.glsl new file mode 100644 index 0000000000..fd150b54ad --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/interface/pbrTerrainBakeV.glsl @@ -0,0 +1,42 @@ +/** + * @file pbrTerrainBakeV.glsl + * + * $LicenseInfo:firstyear=2007&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$ + */ + +uniform mat4 modelview_projection_matrix; + +in vec3 position; +in vec2 texcoord1; + +out vec4 vary_texcoord0; +out vec4 vary_texcoord1; + +void main() +{ +    gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); +    vec2 tc = texcoord1.xy; +    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); +} + | 
