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 | |
parent | e6777d566fddc79d1194a2090e5df5b609285d89 (diff) |
DRTVWR-592: (WIP) (has debug) Convert colors to linear before triplanar blending. General refactor.
Diffstat (limited to 'indra')
-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]; |