summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
authorCosmic Linden <cosmic@lindenlab.com>2023-10-13 09:57:40 -0700
committerCosmic Linden <cosmic@lindenlab.com>2023-10-13 09:57:40 -0700
commit7376b3e4b9c03f3ff3aa0c431c66916ac655a692 (patch)
tree8d82474383a36d7333e25230f9bcf587b49d2638 /indra/newview
parent763a9b5249640ef71d532ff3c9c28418bd90fb68 (diff)
DRTVWR-592: (WIP) (does not run) PBR terrain rendering - begin work on shaders, uniforms
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl142
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl21
2 files changed, 130 insertions, 33 deletions
diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl
index 2426199056..f355b8ef98 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainF.glsl
@@ -25,40 +25,140 @@
out vec4 frag_data[4];
-uniform sampler2D detail_0;
-uniform sampler2D detail_1;
-uniform sampler2D detail_2;
-uniform sampler2D detail_3;
uniform sampler2D alpha_ramp;
-in vec3 pos;
+// TODO: Bind the right textures and uniforms during shader setup
+// *TODO: 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;
+uniform sampler2D detail_0_normal;
+uniform sampler2D detail_1_normal;
+uniform sampler2D detail_2_normal;
+uniform sampler2D detail_3_normal;
+uniform sampler2D detail_0_metallic_roughness;
+uniform sampler2D detail_1_metallic_roughness;
+uniform sampler2D detail_2_metallic_roughness;
+uniform sampler2D detail_3_metallic_roughness;
+uniform sampler2D detail_0_emissive;
+uniform sampler2D detail_1_emissive;
+uniform sampler2D detail_2_emissive;
+uniform sampler2D detail_3_emissive;
+
+// TODO: Needs new uniforms
+// *TODO: More efficient packing?
+uniform vec4 metallicFactors;
+uniform vec4 roughnessFactors;
+uniform vec3[4] emissiveColors;
+uniform vec4 minimum_alphas; // PBR alphaMode: MASK, See: mAlphaCutoff, setAlphaCutoff()
+
in vec3 vary_normal;
-in vec3 vary_tangent; // TODO: Decide if we want to keep this
-flat in float vary_sign; // TODO: Decide if we want to keep this
+in vec3 vary_tangent;
+flat in float vary_sign;
in vec4 vary_texcoord0;
in vec4 vary_texcoord1;
vec2 encode_normal(vec3 n);
+vec3 linear_to_srgb(vec3 c);
+vec3 srgb_to_linear(vec3 c);
-void main()
+// TODO: This mixing function feels like it can be optimized. The terrain code's use of texcoord1 is dubious. It feels like the same thing can be accomplished with less memory bandwidth by calculating the offsets on-the-fly
+float terrain_mix(vec4 samples, float alpha1, float alpha2, float alphaFinal)
+{
+ return mix( mix(samples.w, samples.z, alpha2), mix(samples.y, samples.x, alpha1), alphaFinal );
+}
+
+vec3 terrain_mix(vec3[4] samples, float alpha1, float alpha2, float alphaFinal)
+{
+ return mix( mix(samples[3], samples[2], alpha2), mix(samples[1], samples[0], alpha1), alphaFinal );
+}
+
+vec4 terrain_mix(vec4[4] samples, float alpha1, float alpha2, float alphaFinal)
+{
+ return mix( mix(samples[3], samples[2], alpha2), mix(samples[1], samples[0], alpha1), alphaFinal );
+}
+
+vec4 sample_and_mix_color(float alpha1, float alpha2, float alphaFinal, vec2 texcoord, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3)
+{
+ vec4[4] samples;
+ samples[0] = srgb_to_linear(texture2D(tex0, texcoord));
+ samples[1] = srgb_to_linear(texture2D(tex1, texcoord));
+ samples[2] = srgb_to_linear(texture2D(tex2, texcoord));
+ samples[3] = srgb_to_linear(texture2D(tex3, texcoord));
+ return terrain_mix(samples, alpha1, alpha2, alphaFinal);
+}
+
+vec4 sample_and_mix_vector(float alpha1, float alpha2, float alphaFinal, vec2 texcoord, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3)
{
- vec4 color0 = texture2D(detail_0, vary_texcoord0.xy);
- vec4 color1 = texture2D(detail_1, vary_texcoord0.xy);
- vec4 color2 = texture2D(detail_2, vary_texcoord0.xy);
- vec4 color3 = texture2D(detail_3, vary_texcoord0.xy);
+ vec4[4] samples;
+ samples[0] = texture2D(tex0, texcoord);
+ samples[1] = texture2D(tex1, texcoord);
+ samples[2] = texture2D(tex2, texcoord);
+ samples[3] = texture2D(tex3, texcoord);
+ return terrain_mix(samples, alpha1, alpha2, alphaFinal);
+}
+// TODO: Implement
+// TODO: Don't forget calls to srgb_to_linear during texture sampling
+// TODO: Wherever base color alpha is not 1.0, blend with black
+void main()
+{
float alpha1 = texture2D(alpha_ramp, vary_texcoord0.zw).a;
float alpha2 = texture2D(alpha_ramp,vary_texcoord1.xy).a;
float alphaFinal = texture2D(alpha_ramp, vary_texcoord1.zw).a;
- vec4 outColor = mix( mix(color3, color2, alpha2), mix(color1, color0, alpha1), alphaFinal );
-
- outColor.a = 0.0; // yes, downstream atmospherics
+
+ vec4 base_color = sample_and_mix_color(alpha1, alpha2, alphaFinal, vary_texcoord0.xy, detail_0_basecolor, detail_1_basecolor, detail_2_basecolor, detail_3_basecolor);
+ vec4 normal_texture = sample_and_mix_vector(alpha1, alpha2, alphaFinal, vary_texcoord0.xy, detail_0_normal, detail_1_normal, detail_2_normal, detail_3_normal);
+ vec4 metallic_roughness = sample_and_mix_vector(alpha1, alpha2, alphaFinal, vary_texcoord0.xy, detail_0_metallic_roughness, detail_1_metallic_roughness, detail_2_metallic_roughness, detail_3_metallic_roughness);
+ vec4 emissive_texture = sample_and_mix_color(alpha1, alpha2, alphaFinal, vary_texcoord0.xy, detail_0_emissive, detail_1_emissive, detail_2_emissive, detail_3_emissive);
+
+ float metallicFactor = terrain_mix(metallicFactors, alpha1, alpha2, alphaFinal);
+ float roughnessFactor = terrain_mix(roughnessFactors, alpha1, alpha2, alphaFinal);
+ vec3 emissiveColor = terrain_mix(emissiveColors, alpha1, alpha2, alphaFinal);
+ float minimum_alpha = terrain_mix(minimum_alphas, alpha1, alpha2, alphaFinal);
+
+ // TODO: OOh, we need blending for every GLTF uniform too
+ // TODO: Unfork
+ if (base_color.a < minimum_alpha)
+ {
+ base_color.rgb *= vec3(0.0);
+ }
+
+ vec3 col = base_color.rgb;
+
+ // from mikktspace.com
+ vec3 vNt = normal_texture.xyz*2.0-1.0;
+ float sign = vary_sign;
+ vec3 vN = vary_normal;
+ vec3 vT = vary_tangent.xyz;
+
+ vec3 vB = sign * cross(vN, vT);
+ vec3 tnorm = normalize( vNt.x * vT + vNt.y * vB + vNt.z * vN );
+
+ // RGB = Occlusion, Roughness, Metal
+ // default values, see LLViewerTexture::sDefaultPBRORMImagep
+ // occlusion 1.0
+ // roughness 0.0
+ // metal 0.0
+ vec3 spec = metallic_roughness.rgb;
- frag_data[0] = outColor;
- frag_data[0] = vec4((0.5 * (1.0 + vary_sign)) * vary_tangent.xyz, 1.0); // TODO: Remove
- frag_data[1] = vec4(0.0,0.0,0.0,-1.0);
- vec3 nvn = normalize(vary_normal);
- frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, GBUFFER_FLAG_HAS_ATMOS);
- frag_data[3] = vec4(0);
+ spec.g *= roughness_factor;
+ spec.b *= metallic_factor;
+
+ vec3 emissive = emssive_color;
+ emissive *= emissive_texture.rgb;
+
+ tnorm *= gl_FrontFacing ? 1.0 : -1.0;
+
+
+ frag_data[0] = max(vec4(col, 0.0), vec4(0)); // Diffuse
+ // TODO: What is packed into vertex_color.a?
+ frag_data[1] = max(vec4(spec.rgb,vertex_color.a), vec4(0)); // PBR linear packed Occlusion, Roughness, Metal.
+ // TODO: What is environment intensity and do we want it?
+ frag_data[2] = max(vec4(encode_normal(tnorm), 0.0, GBUFFER_FLAG_HAS_PBR | GBUFFER_FLAG_HAS_ATMOS), 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/pbrterrainV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl
index fcc4448a80..cbfe9f3ea5 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/pbrterrainV.glsl
@@ -34,15 +34,12 @@ in vec4 diffuse_color;
in vec2 texcoord0;
in vec2 texcoord1;
-out vec3 pos;
out vec3 vary_normal;
-out vec3 vary_tangent; // TODO: Decide if we want to keep this
-flat out float vary_sign; // TODO: Decide if we want to keep this
+out vec3 vary_tangent;
+flat out float vary_sign;
out vec4 vary_texcoord0;
out vec4 vary_texcoord1;
-out vec4 debug_tangent; // TODO: Remove
-
uniform vec4 object_plane_s;
uniform vec4 object_plane_t;
@@ -63,17 +60,17 @@ vec4 texgen_object(vec4 vpos, vec4 tc, mat4 mat, vec4 tp0, vec4 tp1)
void main()
{
//transform vertex
- vec4 pre_pos = vec4(position.xyz, 1.0);
- vec4 t_pos = modelview_projection_matrix * pre_pos;
+ gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
- gl_Position = t_pos;
- pos = t_pos.xyz;
+ vec3 n = normal_matrix * normal;
+ vec3 t = normal_matrix * tangent.xyz;
- vary_normal = normalize(normal_matrix * normal);
- vary_tangent = normalize(normal_matrix * tangent.xyz); // TODO: Decide if we want to keep this
- vary_sign = tangent.w; // TODO: Decide if we want to keep this
+ vary_tangent = normalize(t);
+ vary_sign = tangent.w;
+ vary_normal = normalize(n);
// Transform and pass tex coords
+ // *NOTE: KHR texture transform is ignored for now
vary_texcoord0.xy = texgen_object(vec4(position, 1.0), vec4(texcoord0,0,1), texture_matrix0, object_plane_s, object_plane_t).xy;
vec4 t = vec4(texcoord1,0,1);