diff options
Diffstat (limited to 'indra/newview/app_settings/shaders')
-rw-r--r-- | indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl | 50 | ||||
-rw-r--r-- | indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl | 387 |
2 files changed, 30 insertions, 407 deletions
diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl index 0a7c58451d..18f8c4aa73 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl @@ -36,18 +36,11 @@ #define MIX_Z 1 << 5 #define MIX_W 1 << 6 -#if 0 // TODO: Remove debug -#define TERRAIN_DEBUG 1 -#endif - // TODO: Decide if this struct needs to be declared struct TerrainMix { vec4 weight; int type; -#if TERRAIN_DEBUG - ivec4 usage; -#endif }; TerrainMix get_terrain_mix_weights(float alpha1, float alpha2, float alphaFinal); @@ -127,12 +120,7 @@ in vec4 vary_texcoord1; vec2 encode_normal(vec3 n); -float terrain_mix(vec4 samples, float alpha1, float alpha2, float alphaFinal); -// TODO: Clean these up -vec3 sample_and_mix_color3(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec3[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3); -vec4 sample_and_mix_color4(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec4[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3); -vec3 sample_and_mix_vector3(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec3[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3); -vec3 sample_and_mix_normal(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3); +float terrain_mix(TerrainMix tm, vec4 tms4); void main() { @@ -170,14 +158,14 @@ void main() , detail_0_base_color , detail_0_metallic_roughness , detail_0_normal - #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) , detail_0_emissive - #endif +#endif , baseColorFactors[0] , orm_factors[0] - #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) , emissiveColors[0] - #endif +#endif ); mix = mix_pbr(mix, mix2, tm.weight.x); break; @@ -192,14 +180,14 @@ void main() , detail_1_base_color , detail_1_metallic_roughness , detail_1_normal - #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) , detail_1_emissive - #endif +#endif , baseColorFactors[1] , orm_factors[1] - #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) , emissiveColors[1] - #endif +#endif ); mix = mix_pbr(mix, mix2, tm.weight.y); break; @@ -214,14 +202,14 @@ void main() , detail_2_base_color , detail_2_metallic_roughness , detail_2_normal - #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) , detail_2_emissive - #endif +#endif , baseColorFactors[2] , orm_factors[2] - #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) , emissiveColors[2] - #endif +#endif ); mix = mix_pbr(mix, mix2, tm.weight.z); break; @@ -236,14 +224,14 @@ void main() , detail_3_base_color , detail_3_metallic_roughness , detail_3_normal - #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) , detail_3_emissive - #endif +#endif , baseColorFactors[3] , orm_factors[3] - #if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) +#if (TERRAIN_PBR_DETAIL >= TERRAIN_PBR_DETAIL_EMISSIVE) , emissiveColors[3] - #endif +#endif ); mix = mix_pbr(mix, mix2, tm.weight.w); break; @@ -251,12 +239,12 @@ void main() break; } - float minimum_alpha = terrain_mix(minimum_alphas, alpha1, alpha2, alphaFinal); + float minimum_alpha = terrain_mix(tm, minimum_alphas); if (mix.col.a < minimum_alpha) { discard; } - float base_color_factor_alpha = terrain_mix(vec4(baseColorFactors[0].z, baseColorFactors[1].z, baseColorFactors[2].z, baseColorFactors[3].z), alpha1, alpha2, alphaFinal); + float base_color_factor_alpha = terrain_mix(tm, vec4(baseColorFactors[0].z, baseColorFactors[1].z, baseColorFactors[2].z, baseColorFactors[3].z)); // from mikktspace.com vec3 vNt = mix.vNt; diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl index 078c753a35..c18cf832f8 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainUtilF.glsl @@ -138,16 +138,10 @@ struct TerrainTriplanar int type; }; -#if 0 // TODO: Remove debug -#define TERRAIN_DEBUG 1 -#endif struct TerrainMix { vec4 weight; int type; -#if TERRAIN_DEBUG - ivec4 usage; -#endif }; #define TerrainMixSample vec4[4] @@ -172,9 +166,6 @@ TerrainMix get_terrain_mix_weights(float alpha1, float alpha2, float alphaFinal) (usage.y * MIX_Y) | (usage.z * MIX_Z) | (usage.w * MIX_W); -#if TERRAIN_DEBUG // TODO: Remove debug - tm.usage = usage; -#endif return tm; } @@ -196,32 +187,13 @@ TerrainTriplanar _t_triplanar() return tw; } -float terrain_mix(vec4 samples, float alpha1, float alpha2, float alphaFinal) -{ - TerrainMix tm = get_terrain_mix_weights(alpha1, alpha2, alphaFinal); - // Assume weights add to 1 - return tm.weight.x * samples.x + - tm.weight.y * samples.y + - tm.weight.z * samples.z + - tm.weight.w * samples.w; -} - -vec4 terrain_mix(TerrainMix tm, TerrainMixSample tms) -{ - // Assume weights add to 1 - return tm.weight.x * tms[0] + - tm.weight.y * tms[1] + - tm.weight.z * tms[2] + - tm.weight.w * tms[3]; -} - -vec3 terrain_mix(TerrainMix tm, TerrainMixSample3 tms3) +// Assume weights add to 1 +float terrain_mix(TerrainMix tm, vec4 tms4) { - // Assume weights add to 1 - return tm.weight.x * tms3[0] + - tm.weight.y * tms3[1] + - tm.weight.z * tms3[2] + - tm.weight.w * tms3[3]; + return (tm.weight.x * tms4[0]) + + (tm.weight.y * tms4[1]) + + (tm.weight.z * tms4[2]) + + (tm.weight.w * tms4[3]); } #if TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 3 @@ -230,17 +202,6 @@ vec3 terrain_mix(TerrainMix tm, TerrainMixSample3 tms3) // Pre-transformed texture coordinates for each axial uv slice (Packing: xy, yz, (-x)z, unused) #define TerrainCoord vec4[2] -vec4 _t_texture(sampler2D tex, vec2 uv_unflipped, float sign_or_zero) -{ - // Handle case where sign is 0 - float sign = (2.0*sign_or_zero) + 1.0; - sign /= abs(sign); - // If the vertex normal is negative, flip the texture back - // right-side up. - vec2 uv = uv_unflipped * vec2(sign, 1); - return texture(tex, uv); -} - vec2 _t_uv(vec2 uv_unflipped, float sign_or_zero) { // Handle case where sign is 0 @@ -287,132 +248,6 @@ vec3 _t_normal_post_z(vec3 vNt0) return vNt_z; } -struct TerrainSample -{ - vec4 x; - vec4 y; - vec4 z; -}; - -TerrainSample _t_sample(sampler2D tex, TerrainCoord terrain_coord, TerrainTriplanar tw) -{ - TerrainSample ts; - - // The switch..case is broken up into three parts deliberately. A single - // switch..case caused unexplained, "ant trail" seams in terrain. (as seen - // on Nvidia/Windows 10). The extra two branches are not free, but it's - // still a performance win compared to sampling along all three axes for - // every terrain fragment. - #define do_sample_x() _t_texture(tex, terrain_coord[0].zw, sign(vary_vertex_normal.x)) - #define do_sample_y() _t_texture(tex, terrain_coord[1].xy, sign(vary_vertex_normal.y)) - #define do_sample_z() _t_texture(tex, terrain_coord[0].xy, sign(vary_vertex_normal.z)) - switch (tw.type & SAMPLE_X) - { - case SAMPLE_X: - ts.x = do_sample_x(); - break; - default: - ts.x = vec4(1.0, 0.0, 1.0, 1.0); - break; - } - switch (tw.type & SAMPLE_Y) - { - case SAMPLE_Y: - ts.y = do_sample_y(); - break; - default: - ts.y = vec4(1.0, 0.0, 1.0, 1.0); - break; - } - switch (tw.type & SAMPLE_Z) - { - case SAMPLE_Z: - ts.z = do_sample_z(); - break; - default: - ts.z = vec4(1.0, 0.0, 1.0, 1.0); - break; - } - - return ts; -} - -struct TerrainSampleNormal -{ - vec3 x; - vec3 y; - vec3 z; -}; - -TerrainSampleNormal _t_sample_n(sampler2D tex, TerrainCoord terrain_coord, TerrainTriplanar tw) -{ - TerrainSample ts = _t_sample(tex, terrain_coord, tw); - TerrainSampleNormal tsn; - // Unpack normals - tsn.x = ts.x.xyz*2.0-1.0; - tsn.y = ts.y.xyz*2.0-1.0; - tsn.z = ts.z.xyz*2.0-1.0; - // Get sign - vec3 ns = sign(vary_vertex_normal); - // Handle case where sign is 0 - ns = (2.0*ns) + 1.0; - ns /= abs(ns); - // 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, TerrainTriplanar 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; -} - -// Triplanar sampling of things that are neither colors nor normals (i.e. orm) -vec4 terrain_texture(sampler2D tex, TerrainCoord terrain_coord) -{ - TerrainTriplanar tw = _t_triplanar(); - - TerrainSample ts = _t_sample(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); -} - -// Specialized triplanar normal texture sampling implementation, taking into -// account how the rotation of the texture affects the lighting and trying to -// negate that. -// *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. -// *NOTE: Bottom face has not been tested -vec3 terrain_texture_normal(sampler2D tex, TerrainCoord terrain_coord) -{ - TerrainTriplanar tw = _t_triplanar(); - - TerrainSampleNormal ts = _t_sample_n(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); -} - -// Triplanar sampling of colors. Colors are converted to linear space before blending. -vec4 terrain_texture_color(sampler2D tex, TerrainCoord terrain_coord) -{ - TerrainTriplanar tw = _t_triplanar(); - - 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); -} - PBRMix terrain_sample_pbr( TerrainCoord terrain_coord , TerrainTriplanar tw @@ -426,9 +261,9 @@ PBRMix terrain_sample_pbr( { PBRMix mix = init_pbr_mix(); - #define get_uv_x() _t_uv(terrain_coord[0].zw, sign(vary_vertex_normal.x)) - #define get_uv_y() _t_uv(terrain_coord[1].xy, sign(vary_vertex_normal.y)) - #define get_uv_z() _t_uv(terrain_coord[0].xy, sign(vary_vertex_normal.z)) +#define get_uv_x() _t_uv(terrain_coord[0].zw, sign(vary_vertex_normal.x)) +#define get_uv_y() _t_uv(terrain_coord[1].xy, sign(vary_vertex_normal.y)) +#define get_uv_z() _t_uv(terrain_coord[0].xy, sign(vary_vertex_normal.z)) switch (tw.type & SAMPLE_X) { case SAMPLE_X: @@ -482,6 +317,7 @@ PBRMix terrain_sample_pbr( #endif ); // Triplanar-specific normal texture fix + // *NOTE: Bottom face has not been tested mix_z.vNt = _t_normal_post_z(mix_z.vNt); mix = mix_pbr(mix, mix_z, tw.weight.z); break; @@ -493,214 +329,13 @@ PBRMix terrain_sample_pbr( } #elif TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 1 -#define TerrainCoord vec2 -vec4 terrain_texture(sampler2D tex, TerrainCoord terrain_coord) -{ - return texture(tex, terrain_coord); -} - -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; -} +#define TerrainCoord vec2 #define terrain_sample_pbr sample_pbr #endif -// The goal of _tmix_sample and related functions is to only sample textures when necessary, ignoring if the weights are low. -// *TODO: Currently, there is much more switch..case branching than needed. This could be simplified by branching per-material rather than per-texture. - -TerrainMixSample _tmix_sample(TerrainMix tm, TerrainCoord texcoord, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) -{ - TerrainMixSample tms; - - switch (tm.type & MIX_X) - { - case MIX_X: - tms[0] = terrain_texture(tex0, texcoord); - break; - default: - tms[0] = vec4(1.0, 0.0, 1.0, 1.0); - break; - } - switch (tm.type & MIX_Y) - { - case MIX_Y: - tms[1] = terrain_texture(tex1, texcoord); - break; - default: - tms[1] = vec4(1.0, 0.0, 1.0, 1.0); - break; - } - switch (tm.type & MIX_Z) - { - case MIX_Z: - tms[2] = terrain_texture(tex2, texcoord); - break; - default: - tms[2] = vec4(1.0, 0.0, 1.0, 1.0); - break; - } - switch (tm.type & MIX_W) - { - case MIX_W: - tms[3] = terrain_texture(tex3, texcoord); - break; - default: - tms[3] = vec4(1.0, 0.0, 1.0, 1.0); - break; - } - - return tms; -} - -TerrainMixSample _tmix_sample_color(TerrainMix tm, TerrainCoord texcoord, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) -{ - TerrainMixSample tmix; - - switch (tm.type & MIX_X) - { - case MIX_X: - tmix[0] = terrain_texture_color(tex0, texcoord); - break; - default: - tmix[0] = vec4(1.0, 0.0, 1.0, 1.0); - break; - } - switch (tm.type & MIX_Y) - { - case MIX_Y: - tmix[1] = terrain_texture_color(tex1, texcoord); - break; - default: - tmix[1] = vec4(1.0, 0.0, 1.0, 1.0); - break; - } - switch (tm.type & MIX_Z) - { - case MIX_Z: - tmix[2] = terrain_texture_color(tex2, texcoord); - break; - default: - tmix[2] = vec4(1.0, 0.0, 1.0, 1.0); - break; - } - switch (tm.type & MIX_W) - { - case MIX_W: - tmix[3] = terrain_texture_color(tex3, texcoord); - break; - default: - tmix[3] = vec4(1.0, 0.0, 1.0, 1.0); - break; - } - - return tmix; -} - -TerrainMixSample3 _tmix_sample_normal(TerrainMix tm, TerrainCoord texcoord, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) -{ - TerrainMixSample3 tmix3; - - switch (tm.type & MIX_X) - { - case MIX_X: - tmix3[0] = terrain_texture_normal(tex0, texcoord); - break; - default: - tmix3[0] = vec3(1.0, 0.0, 1.0); - break; - } - switch (tm.type & MIX_Y) - { - case MIX_Y: - tmix3[1] = terrain_texture_normal(tex1, texcoord); - break; - default: - tmix3[1] = vec3(1.0, 0.0, 1.0); - break; - } - switch (tm.type & MIX_Z) - { - case MIX_Z: - tmix3[2] = terrain_texture_normal(tex2, texcoord); - break; - default: - tmix3[2] = vec3(1.0, 0.0, 1.0); - break; - } - switch (tm.type & MIX_W) - { - case MIX_W: - tmix3[3] = terrain_texture_normal(tex3, texcoord); - break; - default: - tmix3[3] = vec3(1.0, 0.0, 1.0); - break; - } - - return tmix3; -} - -vec3 sample_and_mix_color3(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec3[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) -{ - TerrainMix tm = get_terrain_mix_weights(alpha1, alpha2, alphaFinal); - TerrainMixSample tms = _tmix_sample_color(tm, texcoord, tex0, tex1, tex2, tex3); - vec3[4] tms3; - tms3[0] = tms[0].xyz; - tms3[1] = tms[1].xyz; - tms3[2] = tms[2].xyz; - tms3[3] = tms[3].xyz; - tms3[0] *= factors[0]; - tms3[1] *= factors[1]; - tms3[2] *= factors[2]; - tms3[3] *= factors[3]; - return terrain_mix(tm, tms3); -} - -vec4 sample_and_mix_color4(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec4[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) -{ - TerrainMix tm = get_terrain_mix_weights(alpha1, alpha2, alphaFinal); - TerrainMixSample tms = _tmix_sample_color(tm, texcoord, tex0, tex1, tex2, tex3); - tms[0] *= factors[0]; - tms[1] *= factors[1]; - tms[2] *= factors[2]; - tms[3] *= factors[3]; - return terrain_mix(tm, tms); -} - -vec3 sample_and_mix_vector3(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec3[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) -{ - TerrainMix tm = get_terrain_mix_weights(alpha1, alpha2, alphaFinal); - TerrainMixSample tms = _tmix_sample(tm, texcoord, tex0, tex1, tex2, tex3); - vec3[4] tms3; - tms3[0] = tms[0].xyz; - tms3[1] = tms[1].xyz; - tms3[2] = tms[2].xyz; - tms3[3] = tms[3].xyz; - tms3[0] *= factors[0]; - tms3[1] *= factors[1]; - tms3[2] *= factors[2]; - tms3[3] *= factors[3]; - return terrain_mix(tm, tms3); -} - -// Returns the unpacked normal texture in range [-1, 1] -vec3 sample_and_mix_normal(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3) -{ - TerrainMix tm = get_terrain_mix_weights(alpha1, alpha2, alphaFinal); - TerrainMixSample3 tms3 = _tmix_sample_normal(tm, texcoord, tex0, tex1, tex2, tex3); - return terrain_mix(tm, tms3); -} - PBRMix multiply_factors_pbr( PBRMix mix_in , vec4 factor_col |