summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorPtolemy <ptolemy@lindenlab.com>2022-09-09 06:35:28 -0700
committerPtolemy <ptolemy@lindenlab.com>2022-09-09 06:35:28 -0700
commitc94a521c6ab4f6c42c61087df78252930e7865a3 (patch)
tree7d2a85f87a440d95d5a1b97e9240f645ee7b6c4b /indra
parent9cb8ed92105f2bd5f99da44e4d00b464d4bb659d (diff)
SL-17701: PBR: Work in progress alpha blending
Diffstat (limited to 'indra')
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/pbralphaF.glsl359
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/pbralphaV.glsl134
2 files changed, 493 insertions, 0 deletions
diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbralphaF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbralphaF.glsl
new file mode 100644
index 0000000000..9d58525fd7
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/pbralphaF.glsl
@@ -0,0 +1,359 @@
+/**
+ * @file class1\deferred\pbralphaF.glsl
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, 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]*/
+
+#define PBR_USE_IBL 1
+#define PBR_USE_SUN 1
+#define PBR_USE_IRRADIANCE_HACK 1
+
+#define DIFFUSE_ALPHA_MODE_NONE 0
+#define DIFFUSE_ALPHA_MODE_BLEND 1
+#define DIFFUSE_ALPHA_MODE_MASK 2
+#define DIFFUSE_ALPHA_MODE_EMISSIVE 3
+
+#define DEBUG_PBR_LIGHT_TYPE 0 // Output Diffuse=0.75, Emissive=0, ORM=0,0,0
+
+#define DEBUG_BASIC 0
+#define DEBUG_VERTEX 0
+#define DEBUG_NORMAL_MAP 0 // Output packed normal map "as is" to diffuse
+#define DEBUG_NORMAL_OUT 0 // Output unpacked normal to diffuse
+#define DEBUG_ORM 0 // Output Occlusion Roughness Metal "as is" to diffuse
+#define DEBUG_POSITION 0
+
+uniform sampler2D diffuseMap; //always in sRGB space
+uniform sampler2D bumpMap;
+uniform sampler2D emissiveMap;
+uniform sampler2D specularMap; // PBR: Packed: Occlusion, Metal, Roughness
+
+uniform float metallicFactor;
+uniform float roughnessFactor;
+uniform vec3 emissiveColor;
+
+#if defined(HAS_SUN_SHADOW) || defined(HAS_SSAO)
+uniform sampler2DRect lightMap;
+#endif
+
+uniform samplerCube environmentMap;
+uniform mat3 env_mat;
+uniform int sun_up_factor;
+uniform vec3 sun_dir;
+uniform vec3 moon_dir;
+
+#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
+ #ifdef DEFINE_GL_FRAGCOLOR
+ out vec4 frag_color;
+ #else
+ #define frag_color gl_FragColor
+ #endif
+#else
+ #ifdef DEFINE_GL_FRAGCOLOR
+ out vec4 frag_data[4];
+ #else
+ #define frag_data gl_FragData
+ #endif
+#endif
+
+
+VARYING vec3 vary_position;
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+#ifdef HAS_NORMAL_MAP
+VARYING vec3 vary_normal;
+VARYING vec3 vary_mat0;
+VARYING vec3 vary_mat1;
+VARYING vec3 vary_mat2;
+VARYING vec2 vary_texcoord1;
+#endif
+
+#ifdef HAS_SPECULAR_MAP
+ VARYING vec2 vary_texcoord2;
+#endif
+
+#ifdef HAS_ALPHA_MASK
+uniform float minimum_alpha; // PBR alphaMode: MASK, See: mAlphaCutoff, setAlphaCutoff()
+#endif
+
+// Lights
+// See: LLRender::syncLightState()
+uniform vec4 light_position[8];
+uniform vec3 light_direction[8]; // spot direction
+uniform vec4 light_attenuation[8]; // linear, quadratic, ?, ?
+uniform vec3 light_diffuse[8];
+
+vec2 encode_normal(vec3 n);
+vec3 srgb_to_linear(vec3 c);
+vec3 linear_to_srgb(vec3 c);
+
+// These are in deferredUtil.glsl but we can't set: mFeatures.isDeferred to include it
+vec3 BRDFLambertian( vec3 reflect0, vec3 reflect90, vec3 c_diff, float specWeight, float vh );
+vec3 BRDFSpecularGGX( vec3 reflect0, vec3 reflect90, float alphaRoughness, float specWeight, float vh, float nl, float nv, float nh );
+void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 additive, out vec3 atten, bool use_ao);
+void calcHalfVectors(vec3 lv, vec3 n, vec3 v, out vec3 h, out vec3 l, out float nh, out float nl, out float nv, out float vh, out float lightDist);
+float calcLegacyDistanceAttenuation(float distance, float falloff);
+vec2 getGGX( vec2 brdfPoint );
+void initMaterial( vec3 diffuse, vec3 packedORM,
+ out float alphaRough, out vec3 c_diff, out vec3 reflect0, out vec3 reflect90, out float specWeight );
+void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyEnv,
+ vec3 pos, vec3 norm, float glossiness, float envIntensity);
+
+vec3 hue_to_rgb(float hue);
+
+// lp = light position
+// la = light radius
+// fa = falloff
+vec3 calcPointLightOrSpotLight(vec3 reflect0, vec3 c_diff,
+ vec3 lightColor, vec3 diffuse, vec3 v, vec3 n, vec4 lp, vec3 ln,
+ float la, float fa, float is_pointlight, float ambiance)
+{
+ vec3 intensity = vec3(0);
+
+ vec3 lv = lp.xyz - v;
+ vec3 h, l;
+ float nh, nl, nv, vh, lightDist;
+ calcHalfVectors(lv,n,v,h,l,nh,nl,nv,vh,lightDist);
+
+ if (lightDist > 0.0)
+ {
+ float falloff_factor = (12.0 * fa) - 9.0;
+ float inverted_la = falloff_factor / la;
+
+ float dist = lightDist / inverted_la;
+
+ float dist_atten = calcLegacyDistanceAttenuation(dist,fa);
+ if (dist_atten <= 0.0)
+ return intensity;
+
+ vec3 reflect90 = vec3(1);
+ float specWeight = 1.0;
+
+ lv = normalize(lv);
+ float spot = max(dot(-ln, lv), is_pointlight);
+ nl *= spot * spot;
+
+ if (nl > 0.0)
+ intensity = dist_atten * nl * lightColor * BRDFLambertian(reflect0, reflect90, c_diff, specWeight, vh);
+ }
+ return intensity;
+}
+
+void main()
+{
+ vec3 light_dir = (sun_up_factor == 1) ? sun_dir : moon_dir;
+ vec3 pos = vary_position;
+
+#if defined(HAS_SUN_SHADOW) || defined(HAS_SSAO)
+ vec2 scol_ambocc = texture2DRect(lightMap, vary_fragcoord.xy).rg;
+ scol_ambocc = pow(scol_ambocc, vec2(light_gamma));
+ float scol = max(scol_ambocc.r, diffuse.a);
+ float ambocc = scol_ambocc.g;
+#else
+ float scol = 1.0;
+ float ambocc = 1.0;
+#endif
+
+ vec3 sunlit;
+ vec3 amblit;
+ vec3 additive;
+ vec3 atten;
+ calcAtmosphericVars(pos.xyz, light_dir, ambocc, sunlit, amblit, additive, atten, true);
+
+// IF .mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
+// vec3 col = vertex_color.rgb * diffuseLookup(vary_texcoord0.xy).rgb;
+// else
+ vec4 albedo = texture2D(diffuseMap, vary_texcoord0.xy).rgba;
+ albedo.rgb = srgb_to_linear(albedo.rgb);
+#ifdef HAS_ALPHA_MASK
+ if (albedo.a < minimum_alpha)
+ {
+ discard;
+ }
+#endif
+
+// vec3 base = vertex_color.rgb * albedo.rgb * albedo.a;
+ vec3 base = vertex_color.rgb * albedo.rgb;
+
+#ifdef HAS_NORMAL_MAP
+ vec4 norm = texture2D(bumpMap, vary_texcoord1.xy);
+ norm.xyz = normalize(norm.xyz * 2 - 1);
+
+ vec3 tnorm = vec3(dot(norm.xyz,vary_mat0),
+ dot(norm.xyz,vary_mat1),
+ dot(norm.xyz,vary_mat2));
+#else
+ vec4 norm = vec4(0,0,0,1.0);
+// vec3 tnorm = vary_normal;
+ vec3 tnorm = vec3(0,0,1);
+#endif
+
+ tnorm = normalize(tnorm.xyz);
+ norm.xyz = tnorm.xyz;
+
+ // RGB = Occlusion, Roughness, Metal
+ // default values, see LLViewerFetchedTexture::sWhiteImagep since roughnessFactor and metallicFactor are multiplied in
+ // occlusion 1.0
+ // roughness 0.0
+ // metal 0.0
+#ifdef HAS_SPECULAR_MAP
+ vec3 packedORM = texture2D(specularMap, vary_texcoord2.xy).rgb; // PBR linear packed Occlusion, Roughness, Metal. See: lldrawpoolapha.cpp
+#else
+ vec3 packedORM = vec3(1,0,0);
+#endif
+
+ packedORM.g *= roughnessFactor;
+ packedORM.b *= metallicFactor;
+
+ vec3 colorEmissive = emissiveColor;
+#ifdef HAS_EMISSIVE_MAP
+ colorEmissive *= texture2D(emissiveMap, vary_texcoord0.xy).rgb;
+#endif
+
+ vec3 colorDiffuse = vec3(0);
+ vec3 colorSpec = vec3(0);
+
+ float IOR = 1.5; // default Index Of Refraction 1.5 (dielectrics)
+ float ao = packedORM.r;
+ float perceptualRough = packedORM.g;
+ float metal = packedORM.b;
+
+ vec3 v = -normalize(vary_position.xyz);
+ vec3 n = norm.xyz;
+ vec3 t = vec3(1,0,0);
+ vec3 b = normalize(cross(n,t));
+ vec3 reflectVN = normalize(reflect(-v,n));
+
+ vec3 h, l;
+ float nh, nl, nv, vh, lightDist;
+ calcHalfVectors(light_dir, n, v, h, l, nh, nl, nv, vh, lightDist);
+
+ vec3 c_diff, reflect0, reflect90;
+ float alphaRough, specWeight;
+ initMaterial( base, packedORM, alphaRough, c_diff, reflect0, reflect90, specWeight );
+
+ // Common to RadianceGGX and RadianceLambertian
+ vec2 brdfPoint = clamp(vec2(nv, perceptualRough), vec2(0,0), vec2(1,1));
+ vec2 vScaleBias = getGGX( brdfPoint); // Environment BRDF: scale and bias applied to reflect0
+ vec3 fresnelR = max(vec3(1.0 - perceptualRough), reflect0) - reflect0; // roughness dependent fresnel
+ vec3 kSpec = reflect0 + fresnelR*pow(1.0 - nv, 5.0);
+
+ vec3 legacyenv;
+
+ vec3 irradiance = vec3(0);
+ vec3 specLight = vec3(0);
+ float gloss = 1.0 - perceptualRough;
+ sampleReflectionProbes(irradiance, specLight, legacyenv, pos.xyz, norm.xyz, gloss, 0.0);
+#if PBR_USE_IRRADIANCE_HACK
+ irradiance = max(amblit,irradiance) * ambocc;
+#else
+irradiance = vec3(amblit);
+#endif
+
+ vec3 FssEssGGX = kSpec*vScaleBias.x + vScaleBias.y;
+#if PBR_USE_IBL
+ colorSpec += specWeight * specLight * FssEssGGX;
+#endif
+
+ vec3 FssEssLambert = specWeight * kSpec * vScaleBias.x + vScaleBias.y; // NOTE: Very similar to FssEssRadiance but with extra specWeight term
+ float Ems = 1.0 - (vScaleBias.x + vScaleBias.y);
+ vec3 avg = specWeight * (reflect0 + (1.0 - reflect0) / 21.0);
+ vec3 AvgEms = avg * Ems;
+ vec3 FmsEms = AvgEms * FssEssLambert / (1.0 - AvgEms);
+ vec3 kDiffuse = c_diff * (1.0 - FssEssLambert + FmsEms);
+#if PBR_USE_IBL
+ colorDiffuse += (FmsEms + kDiffuse) * irradiance;
+#endif
+
+ colorDiffuse *= ao;
+ colorSpec *= ao;
+
+ // Sun/Moon Lighting
+ if (nl > 0.0 || nv > 0.0)
+ {
+ float scale = 4.9;
+ vec3 sunColor = srgb_to_linear(sunlit * scale); // NOTE: Midday should have strong sunlight
+
+ // scol = sun shadow
+ vec3 intensity = ambocc * sunColor * nl * scol;
+ vec3 sunDiffuse = intensity * BRDFLambertian (reflect0, reflect90, c_diff , specWeight, vh);
+ vec3 sunSpec = intensity * BRDFSpecularGGX(reflect0, reflect90, alphaRough, specWeight, vh, nl, nv, nh);
+#if PBR_USE_SUN
+ colorDiffuse += sunDiffuse;
+ colorSpec += sunSpec;
+#endif
+ }
+ vec3 col = colorDiffuse + colorEmissive + colorSpec;
+
+ vec3 light = vec3(0);
+
+ // Punctual lights
+#define LIGHT_LOOP(i) light += calcPointLightOrSpotLight( reflect0, c_diff, light_diffuse[i].rgb, albedo.rgb, pos.xyz, n, light_position[i], light_direction[i].xyz, light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z, light_attenuation[i].w );
+
+ LIGHT_LOOP(1)
+ LIGHT_LOOP(2)
+ LIGHT_LOOP(3)
+ LIGHT_LOOP(4)
+ LIGHT_LOOP(5)
+ LIGHT_LOOP(6)
+ LIGHT_LOOP(7)
+
+#if !defined(LOCAL_LIGHT_KILL)
+ col += light;
+#endif // !defined(LOCAL_LIGHT_KILL)
+
+#if DEBUG_PBR_LIGHT_TYPE
+ col.rgb = vec3(0.75);
+ emissive = vec3(0);
+ spec.rgb = vec3(0);
+#endif
+#if DEBUG_BASIC
+ col.rgb = vec3( 1, 0, 1 );
+#endif
+#if DEBUG_VERTEX
+ col.rgb = vertex_color.rgb;
+#endif
+#if DEBUG_NORMAL_MAP
+ col.rgb = texture2D(bumpMap, vary_texcoord1.xy).rgb;
+#endif
+#if DEBUG_NORMAL_OUT
+ col.rgb = vary_normal;
+#endif
+#if DEBUG_ORM
+ col.rgb = linear_to_srgb(spec);
+#endif
+#if DEBUG_POSITION
+ col.rgb = vary_position.xyz;
+#endif
+
+// col.rgb = linear_to_srgb(col.rgb);
+// frag_color = vec4(albedo.rgb,albedo.a);
+// frag_color = vec4(base.rgb,albedo.a);
+// frag_color = vec4(irradiance,albedo.a);
+// frag_color = vec4(colorDiffuse,albedo.a);
+// frag_color = vec4(colorEmissive,albedo.a);
+// frag_color = vec4(sun_dir,albedo.a);
+// frag_color = vec4(sunlit,albedo.a);
+ col = linear_to_srgb(col.rgb);
+ frag_color = vec4(col,albedo.a);
+}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbralphaV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbralphaV.glsl
new file mode 100644
index 0000000000..8cc3c11fa1
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/pbralphaV.glsl
@@ -0,0 +1,134 @@
+/**
+ * @file class1\deferred\pbralphaV.glsl
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, 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$
+ */
+
+#define DIFFUSE_ALPHA_MODE_IGNORE 0
+#define DIFFUSE_ALPHA_MODE_BLEND 1
+#define DIFFUSE_ALPHA_MODE_MASK 2
+#define DIFFUSE_ALPHA_MODE_EMISSIVE 3
+
+#ifdef HAS_SKIN
+uniform mat4 modelview_matrix;
+uniform mat4 projection_matrix;
+mat4 getObjectSkinnedTransform();
+#else
+uniform mat3 normal_matrix;
+uniform mat4 modelview_projection_matrix;
+#endif
+
+#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
+ #if !defined(HAS_SKIN)
+ uniform mat4 modelview_matrix;
+ #endif
+ VARYING vec3 vary_position;
+#endif
+
+uniform mat4 texture_matrix0;
+
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec4 diffuse_color;
+ATTRIBUTE vec3 normal;
+ATTRIBUTE vec2 texcoord0;
+
+
+#ifdef HAS_NORMAL_MAP
+ATTRIBUTE vec4 tangent;
+ATTRIBUTE vec2 texcoord1;
+
+VARYING vec3 vary_mat0;
+VARYING vec3 vary_mat1;
+VARYING vec3 vary_mat2;
+
+VARYING vec2 vary_texcoord1;
+#else
+VARYING vec3 vary_normal;
+#endif
+
+#ifdef HAS_SPECULAR_MAP
+ATTRIBUTE vec2 texcoord2;
+VARYING vec2 vary_texcoord2;
+#endif
+
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+
+void main()
+{
+#ifdef HAS_SKIN
+ mat4 mat = getObjectSkinnedTransform();
+ mat = modelview_matrix * mat;
+ vec3 pos = (mat*vec4(position.xyz,1.0)).xyz;
+#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
+ vary_position = pos;
+#endif
+ gl_Position = projection_matrix*vec4(pos,1.0);
+#else
+ //transform vertex
+ gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+#endif
+
+ vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
+
+#ifdef HAS_NORMAL_MAP
+ vary_texcoord1 = (texture_matrix0 * vec4(texcoord1,0,1)).xy;
+#endif
+
+#ifdef HAS_SPECULAR_MAP
+ vary_texcoord2 = (texture_matrix0 * vec4(texcoord2,0,1)).xy;
+#endif
+
+#ifdef HAS_SKIN
+ vec3 n = normalize((mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz);
+ #ifdef HAS_NORMAL_MAP
+ vec3 t = normalize((mat*vec4(tangent.xyz+position.xyz,1.0)).xyz-pos.xyz);
+ vec3 b = cross(n, t)*tangent.w;
+
+ vary_mat0 = vec3(t.x, b.x, n.x);
+ vary_mat1 = vec3(t.y, b.y, n.y);
+ vary_mat2 = vec3(t.z, b.z, n.z);
+ #else //HAS_NORMAL_MAP
+ vary_normal = n;
+ #endif //HAS_NORMAL_MAP
+#else //HAS_SKIN
+ vec3 n = normalize(normal_matrix * normal);
+ #ifdef HAS_NORMAL_MAP
+ vec3 t = normalize(normal_matrix * tangent.xyz);
+ vec3 b = cross(n,t)*tangent.w;
+
+ vary_mat0 = vec3(t.x, b.x, n.x);
+ vary_mat1 = vec3(t.y, b.y, n.y);
+ vary_mat2 = vec3(t.z, b.z, n.z);
+ #else //HAS_NORMAL_MAP
+ vary_normal = n;
+ #endif //HAS_NORMAL_MAP
+#endif //HAS_SKIN
+
+ vertex_color = diffuse_color;
+
+#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
+ #if !defined(HAS_SKIN)
+ vary_position = (modelview_matrix*vec4(position.xyz, 1.0)).xyz;
+ #endif
+#endif
+}