diff options
| author | Cosmic Linden <cosmic@lindenlab.com> | 2023-10-13 10:40:07 -0700 | 
|---|---|---|
| committer | Cosmic Linden <cosmic@lindenlab.com> | 2023-10-13 10:40:07 -0700 | 
| commit | 53a5055ab72c3fb77892a3e43c769c3b19c1e97d (patch) | |
| tree | 9f46d15cebed35510111d94f486a6e1caf50c63f /indra/newview | |
| parent | e6777d566fddc79d1194a2090e5df5b609285d89 (diff) | |
DRTVWR-592: (WIP) (has debug) Convert colors to linear before triplanar blending. General refactor.
Diffstat (limited to 'indra/newview')
| -rw-r--r-- | indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl | 11 | ||||
| -rw-r--r-- | indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl | 249 | 
2 files changed, 160 insertions, 100 deletions
diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl index 7febbe280e..ba917416ce 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl @@ -135,6 +135,17 @@ void main()      tnorm *= gl_FrontFacing ? 1.0 : -1.0; +#if 0 // TODO: Remove debug +    //col.xyz = (tnorm + 1.0) / 2.0;// TODO: Remove +    //col.xyz = (vary_normal + 1.0) / 2.0;// TODO: Remove +    //col.xyz = spec; // TODO: Remove +    //col.xyz = vec3(1); // TODO: Remove +    //float weight = 1.0; spec.rgb = (weight * spec.rgb) + ((1 - weight) * vec3(1.0, 1.0, 1.0)); // TODO: Remove +    tnorm = vary_normal; // TODO: Remove +    spec.r = 1.0; // TODO: Remove +    spec.gb = vec2(1.0, 0.0); // TODO: Remove +    emissive.rgb = vec3(0); // TODO: Remove +#endif      frag_data[0] = max(vec4(col.xyz, 0.0), vec4(0));                                                   // Diffuse      frag_data[1] = max(vec4(spec.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 diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl index b89edc9731..c72bc65cca 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl @@ -69,7 +69,15 @@ vec4 terrain_mix(vec4[4] samples, float alpha1, float alpha2, float alphaFinal)  // Pre-transformed texture coordinates for each axial uv slice (Packing: xy, yz, (-x)z, unused)  #define TerrainCoord vec4[2] +#if 0 // TODO: Revert  #define TERRAIN_TRIPLANAR_MIX_THRESHOLD 0.01 +#else +#define TERRAIN_TRIPLANAR_MIX_THRESHOLD 0.01 +#endif + +// Positive value prevents artifacts when weights are close to zero +// TODO: Wait a minute... this doesn't prevent artifacts :( (or does it?) +#define TERRAIN_TRIPLANAR_OVERDRAW_THRESHOLD 0.0  vec4 _t_texture(sampler2D tex, vec2 uv_unflipped, float sign)  { @@ -79,35 +87,60 @@ vec4 _t_texture(sampler2D tex, vec2 uv_unflipped, float sign)      return texture(tex, uv);  } -vec3 _t_texture_n(sampler2D tex, vec2 uv_unflipped, float sign) +vec4 _t_texture_c(sampler2D tex, vec2 uv_unflipped, float sign)  { -    // Unpack normal from pixel to vector -    vec3 n = _t_texture(tex, uv_unflipped, sign).xyz*2.0-1.0; -    // If the sign is negative, rotate normal by 180 degrees -    n.xy = (min(0, sign) * n.xy) + (min(0, -sign) * -n.xy); -    return n; +    vec4 c = _t_texture(tex, uv_unflipped, sign); +    c.xyz = srgb_to_linear(c.xyz); +    return c;  } -vec4 terrain_texture(sampler2D tex, TerrainCoord terrain_coord) +#define SAMPLE_X 1 << 2 +#define SAMPLE_Y 1 << 1 +#define SAMPLE_Z 1 << 0 +#define terrain_coord_x terrain_coord[0].zw +#define terrain_coord_y terrain_coord[1].xy +#define terrain_coord_z terrain_coord[0].xy +#define TERRAIN_DEBUG 1 // TODO: Remove debug +struct TerrainWeight +{ +    vec3 weight; +#if TERRAIN_DEBUG +    vec3 usage; +#endif +    int type; +}; + +TerrainWeight _t_weight(TerrainCoord terrain_coord)  {      float sharpness = TERRAIN_TRIPLANAR_BLEND_FACTOR; -    vec3 weight = normalize(pow(abs(vary_vertex_normal), vec3(sharpness)));      float threshold = TERRAIN_TRIPLANAR_MIX_THRESHOLD; -    weight = max(vec3(0), sign(weight - threshold)); - -    #define SAMPLE_X 1 << 2 -    #define SAMPLE_Y 1 << 1 -    #define SAMPLE_Z 1 << 0 -    int sample_type = (int(weight.x) * SAMPLE_X) | -                      (int(weight.y) * SAMPLE_Y) | -                      (int(weight.z) * SAMPLE_Z); -    #define terrain_coord_x terrain_coord[0].zw -    #define terrain_coord_y terrain_coord[1].xy -    #define terrain_coord_z terrain_coord[0].xy +    vec3 weight_signed = normalize(pow(abs(vary_vertex_normal), vec3(sharpness))); +    weight_signed -= vec3(threshold); +    TerrainWeight tw; +    tw.weight = max(vec3(0), weight_signed); +    vec3 usage = max(vec3(0), sign(weight_signed + TERRAIN_TRIPLANAR_OVERDRAW_THRESHOLD)); +#if TERRAIN_DEBUG +    tw.usage = usage; +#endif +    tw.type = (int(usage.x) * SAMPLE_X) | +              (int(usage.y) * SAMPLE_Y) | +              (int(usage.z) * SAMPLE_Z); +    return tw; +} + +struct TerrainSample +{      vec4 x;      vec4 y;      vec4 z; -    switch (sample_type) +}; + +TerrainSample _t_sample(sampler2D tex, TerrainCoord terrain_coord, TerrainWeight tw) +{ +    vec4 x; +    vec4 y; +    vec4 z; +    switch (tw.type)      {          case SAMPLE_X | SAMPLE_Y | SAMPLE_Z:              x = _t_texture(tex, terrain_coord_x, sign(vary_vertex_normal.x)); @@ -117,37 +150,98 @@ vec4 terrain_texture(sampler2D tex, TerrainCoord terrain_coord)          case SAMPLE_X | SAMPLE_Y:              x = _t_texture(tex, terrain_coord_x, sign(vary_vertex_normal.x));              y = _t_texture(tex, terrain_coord_y, sign(vary_vertex_normal.y)); -            z = vec4(0); +            z = x;              break;          case SAMPLE_X | SAMPLE_Z:              x = _t_texture(tex, terrain_coord_x, sign(vary_vertex_normal.x)); -            y = vec4(0);              z = _t_texture(tex, terrain_coord_z, sign(vary_vertex_normal.z)); +            y = x;              break;          case SAMPLE_Y | SAMPLE_Z: -            x = vec4(0);              y = _t_texture(tex, terrain_coord_y, sign(vary_vertex_normal.y));              z = _t_texture(tex, terrain_coord_z, sign(vary_vertex_normal.z)); +            x = y;              break;          case SAMPLE_X:              x = _t_texture(tex, terrain_coord_x, sign(vary_vertex_normal.x)); -            y = vec4(0); -            z = vec4(0); +            y = x; +            z = x;              break;          case SAMPLE_Y: -            x = vec4(0);              y = _t_texture(tex, terrain_coord_y, sign(vary_vertex_normal.y)); -            z = vec4(0); +            x = y; +            z = y;              break;          case SAMPLE_Z: +            z = _t_texture(tex, terrain_coord_z, sign(vary_vertex_normal.z)); +            x = z; +            y = z; +            break;          default:              x = vec4(0); -            y = vec4(0); -            z = _t_texture(tex, terrain_coord_z, sign(vary_vertex_normal.z)); +            y = x; +            z = x;              break;      } -    return ((x * weight.x) + (y * weight.y) + (z * weight.z)) / (weight.x + weight.y + weight.z); +    TerrainSample ts; +    ts.x = x; +    ts.y = y; +    ts.z = z; +    return ts; +} + +struct TerrainSampleNormal +{ +    vec3 x; +    vec3 y; +    vec3 z; +}; + +TerrainSampleNormal _t_sample_n(sampler2D tex, TerrainCoord terrain_coord, TerrainWeight tw) +{ +    TerrainSample ts = _t_sample(tex, terrain_coord, tw); +    TerrainSampleNormal tsn; +    tsn.x = ts.x.xyz; +    tsn.y = ts.y.xyz; +    tsn.z = ts.z.xyz; +    vec3 ns = sign(vary_vertex_normal); +    // If the sign is negative, rotate normal by 180 degrees +    tsn.x.xy = (min(0, ns.x) * tsn.x.xy) + (min(0, -ns.x) * -tsn.x.xy); +    tsn.y.xy = (min(0, ns.y) * tsn.y.xy) + (min(0, -ns.y) * -tsn.y.xy); +    tsn.z.xy = (min(0, ns.z) * tsn.z.xy) + (min(0, -ns.z) * -tsn.z.xy); +    // *HACK: Transform normals according to orientation of the UVs +    tsn.x.xy = vec2(-tsn.x.y, tsn.x.x); +    tsn.y.xy = -tsn.y.xy; +    return tsn; +} + +TerrainSample _t_sample_c(sampler2D tex, TerrainCoord terrain_coord, TerrainWeight tw) +{ +    TerrainSample ts = _t_sample(tex, terrain_coord, tw); +    ts.x.xyz = srgb_to_linear(ts.x.xyz); +    ts.y.xyz = srgb_to_linear(ts.y.xyz); +    ts.z.xyz = srgb_to_linear(ts.z.xyz); +    return ts; +} + +vec4 terrain_texture(sampler2D tex, TerrainCoord terrain_coord) +{ +    TerrainWeight tw = _t_weight(terrain_coord); + +    TerrainSample ts = _t_sample(tex, terrain_coord, tw); + +#if 1 +    return ((ts.x * tw.weight.x) + (ts.y * tw.weight.y) + (ts.z * tw.weight.z)) / (tw.weight.x + tw.weight.y + tw.weight.z); +#else // TODO: Remove debug +    //return vec4(((tw.usage - normalize(tw.weight))) / 0.5, 1.0); +#if 1 +    return vec4(tw.usage, 1.0); +#else +    //return vec4(tw.usage, 1.0); +    return vec4((tw.usage + weight) / 2.0, 1.0); +#endif +#endif  }  // Specialized triplanar normal texture sampling implementation, taking into @@ -156,74 +250,26 @@ vec4 terrain_texture(sampler2D tex, TerrainCoord terrain_coord)  // *TODO: Decide if we want this. It may be better to just calculate the  // tangents on-the-fly here rather than messing with the normals, due to the  // subtleties of the effects of triplanar mapping on UVs. These sampled normals -// are only valid on the faces of a cube, and the pregenerated tangents are -// only valid for uv = xy. +// are only valid on the faces of a cube.  // *NOTE: Bottom face has not been tested  vec3 terrain_texture_normal(sampler2D tex, TerrainCoord terrain_coord)  { -    float sharpness = TERRAIN_TRIPLANAR_BLEND_FACTOR; -    vec3 weight = normalize(pow(abs(vary_vertex_normal), vec3(sharpness))); -    float threshold = TERRAIN_TRIPLANAR_MIX_THRESHOLD; -    weight = max(vec3(0), sign(weight - threshold)); - -    #define SAMPLE_X 1 << 2 -    #define SAMPLE_Y 1 << 1 -    #define SAMPLE_Z 1 << 0 -    int sample_type = (int(weight.x) * SAMPLE_X) | -                      (int(weight.y) * SAMPLE_Y) | -                      (int(weight.z) * SAMPLE_Z); -    #define terrain_coord_x terrain_coord[0].zw -    #define terrain_coord_y terrain_coord[1].xy -    #define terrain_coord_z terrain_coord[0].xy -    vec3 x; -    vec3 y; -    vec3 z; -    switch (sample_type) -    { -        case SAMPLE_X | SAMPLE_Y | SAMPLE_Z: -            x = _t_texture_n(tex, terrain_coord_x, sign(vary_vertex_normal.x)); -            y = _t_texture_n(tex, terrain_coord_y, sign(vary_vertex_normal.y)); -            z = _t_texture_n(tex, terrain_coord_z, sign(vary_vertex_normal.z)); -            break; -        case SAMPLE_X | SAMPLE_Y: -            x = _t_texture_n(tex, terrain_coord_x, sign(vary_vertex_normal.x)); -            y = _t_texture_n(tex, terrain_coord_y, sign(vary_vertex_normal.y)); -            z = vec3(0); -            break; -        case SAMPLE_X | SAMPLE_Z: -            x = _t_texture_n(tex, terrain_coord_x, sign(vary_vertex_normal.x)); -            y = vec3(0); -            z = _t_texture_n(tex, terrain_coord_z, sign(vary_vertex_normal.z)); -            break; -        case SAMPLE_Y | SAMPLE_Z: -            x = vec3(0); -            y = _t_texture_n(tex, terrain_coord_y, sign(vary_vertex_normal.y)); -            z = _t_texture_n(tex, terrain_coord_z, sign(vary_vertex_normal.z)); -            break; -        case SAMPLE_X: -            x = _t_texture_n(tex, terrain_coord_x, sign(vary_vertex_normal.x)); -            y = vec3(0); -            z = vec3(0); -            break; -        case SAMPLE_Y: -            x = vec3(0); -            y = _t_texture_n(tex, terrain_coord_y, sign(vary_vertex_normal.y)); -            z = vec3(0); -            break; -        case SAMPLE_Z: -        default: -            x = vec3(0); -            y = vec3(0); -            z = _t_texture_n(tex, terrain_coord_z, sign(vary_vertex_normal.z)); -            break; -    } +    TerrainWeight tw = _t_weight(terrain_coord); -    // *HACK: Transform normals according to orientation of the UVs -    x.xy = vec2(-x.y, x.x); -    y.xy = -y.xy; +    TerrainSampleNormal ts = _t_sample_n(tex, terrain_coord, tw); -    return ((x * weight.x) + (y * weight.y) + (z * weight.z)) / (weight.x + weight.y + weight.z); +    return ((ts.x * tw.weight.x) + (ts.y * tw.weight.y) + (ts.z * tw.weight.z)) / (tw.weight.x + tw.weight.y + tw.weight.z);  } + +vec4 terrain_texture_color(sampler2D tex, TerrainCoord terrain_coord) +{ +    TerrainWeight tw = _t_weight(terrain_coord); + +    TerrainSample ts = _t_sample_c(tex, terrain_coord, tw); + +    return ((ts.x * tw.weight.x) + (ts.y * tw.weight.y) + (ts.z * tw.weight.z)) / (tw.weight.x + tw.weight.y + tw.weight.z); +} +  #elif TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 1  #define TerrainCoord vec2  vec4 terrain_texture(sampler2D tex, TerrainCoord terrain_coord) @@ -235,6 +281,13 @@ vec3 terrain_texture_normal(sampler2D tex, TerrainCoord terrain_coord)  {      return texture(tex, terrain_coord).xyz*2.0-1.0;  } + +vec4 terrain_texture_color(sampler2D tex, TerrainCoord terrain_coord) +{ +    vec4 col = texture(tex, terrain_coord); +    col.xyz = srgb_to_linear(col.xyz); +    return col; +}  #endif  vec3 sample_and_mix_color3(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec3[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) @@ -258,14 +311,10 @@ vec3 sample_and_mix_color3(float alpha1, float alpha2, float alphaFinal, Terrain  vec4 sample_and_mix_color4(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec4[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3)  {      vec4[4] samples; -    samples[0] = terrain_texture(tex0, texcoord); -    samples[1] = terrain_texture(tex1, texcoord); -    samples[2] = terrain_texture(tex2, texcoord); -    samples[3] = terrain_texture(tex3, texcoord); -    samples[0].xyz = srgb_to_linear(samples[0].xyz); -    samples[1].xyz = srgb_to_linear(samples[1].xyz); -    samples[2].xyz = srgb_to_linear(samples[2].xyz); -    samples[3].xyz = srgb_to_linear(samples[3].xyz); +    samples[0] = terrain_texture_color(tex0, texcoord); +    samples[1] = terrain_texture_color(tex1, texcoord); +    samples[2] = terrain_texture_color(tex2, texcoord); +    samples[3] = terrain_texture_color(tex3, texcoord);      samples[0] *= factors[0];      samples[1] *= factors[1];      samples[2] *= factors[2];  | 
