summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPtolemy <ptolemy@lindenlab.com>2022-06-23 16:18:11 -0700
committerPtolemy <ptolemy@lindenlab.com>2022-06-23 16:18:11 -0700
commit661f554886511a4062c91b0ce656bb0130937244 (patch)
treeb816cccc4ab57484f8c7faa63793995d42cba81c
parent29533c345443f127fa0ef2f9499ccfd59a971842 (diff)
SL-17274: Add WIP PBR Shader
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl180
1 files changed, 179 insertions, 1 deletions
diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
index 56fa4d0c4e..f2ae699130 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
@@ -23,6 +23,28 @@
* $/LicenseInfo$
*/
+#define DEBUG_PBR_PACKORM0 0 // Rough=0, Metal=0
+#define DEBUG_PBR_PACKORM1 0 // Rough=1, Metal=1
+#define DEBUG_PBR_TANGENT1 1 // Tangent = 1,0,0
+
+#define DEBUG_PBR_RAW_DIFF 0 // Output: use diffuse in G-Buffer
+#define DEBUG_PBR_RAW_SPEC 0 // Output: use spec in G-Buffer
+#define DEBUG_PBR_IRRADIANCE 0 // Output: Diffuse Irradiance
+#define DEBUG_PBR_DIFFUSE 0 // Output: Radiance Lambertian
+#define DEBUG_PBR_ORM 0 // Output: Packed Occlusion Roughness Metal
+#define DEBUG_PBR_ROUGH 0 // Output: grayscale roughenss
+#define DEBUG_PBR_METAL 0 // Output: grayscale metal
+#define DEBUG_PBR_REFLECTANCE 0 // Output: diffuse reflectance
+#define DEBUG_PBR_SPEC 0 // Output: Final spec
+#define DEBUG_PBR_SPEC_REFLECTION 0 // Output: reflection
+#define DEBUG_PBR_NORMAL 0 // Output: passed in normal
+#define DEBUG_PBR_VIEW 0 // Output: view_dir
+#define DEBUG_PBR_BRDF 0 // Output: Environment BRDF
+#define DEBUG_PBR_DOT_NV 0 // Output:
+#define DEBUG_PBR_DOT_TV 0 // Output:
+#define DEBUG_PBR_DOT_BV 0 // Output:
+#define DEBUG_PBR_FRESNEL 0 // Output: roughness dependent fresnel
+
#extension GL_ARB_texture_rectangle : enable
#extension GL_ARB_shader_texture_lod : enable
@@ -87,6 +109,32 @@ vec4 applyWaterFogView(vec3 pos, vec4 color);
uniform vec3 view_dir; // PBR
+#define getDiffuseLightPBR(n) ambenv
+#define getSpecularPBR(reflection) glossenv
+
+// Approximate Environment BRDF
+vec2 getGGXApprox( vec2 uv )
+{
+ vec2 st = vec2(1.) - uv;
+ float d = (st.x * st.x * 0.5) * (st.y * st.y);
+ float scale = 1.0 - d;
+ float bias = d;
+ return vec2( scale, bias );
+}
+
+vec2 getGGX( vec2 brdfPoint )
+{
+ // TODO: use GGXLUT
+ // texture2D(GGXLUT, brdfPoint).rg;
+ return getGGXApprox( brdfPoint);
+}
+
+vec3 calcBaseReflect0(float ior)
+{
+ vec3 reflect0 = vec3(pow((ior - 1.0) / (ior + 1.0), 2.0));
+ return reflect0;
+}
+
void main()
{
vec2 tc = vary_fragcoord.xy;
@@ -133,6 +181,136 @@ void main()
vec3 legacyenv;
sampleReflectionProbes(ambenv, glossenv, legacyenv, pos.xyz, norm.xyz, spec.a, envIntensity);
+ bool hasPBR = GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_PBR);
+ if (hasPBR)
+ {
+ vec3 colorDiffuse = vec3(0);
+ vec3 colorEmissive = vec3(0);
+ vec3 colorSpec = vec3(0);
+// vec3 colorClearCoat = vec3(0);
+// vec3 colorSheen = vec3(0);
+// vec3 colorTransmission = vec3(0);
+
+ vec3 packedORM = spec.rgb; // Packed: Occlusion Roughness Metal
+#if DEBUG_PBR_PACK_ORM0
+ packedORM = vec3(0,0,0);
+#endif
+#if DEBUG_PBR_PACK_ORM1
+ packedORM = vec3(1,1,1);
+#endif
+ float IOR = 1.5; // default Index Of Reflection 1.5
+ vec3 reflect0 = vec3(0.04); // -> incidence reflectance 0.04
+
+ IOR = 0.0; // TODO: Set from glb
+ reflect0 = calcBaseReflect0(IOR);
+
+ float metal = packedORM.b;
+ vec3 reflect90 = vec3(0);
+ vec3 v = view_dir;
+ vec3 n = norm.xyz;
+// vec3 t = texture2DRect(tangentMap, tc).rgb;
+#if DEBUG_PBR_TANGENT1
+ vec3 t = vec3(1,0,0);
+#endif
+ vec3 b = cross( n,t);
+ vec3 reflectVN = normalize(reflect(-v,n));
+
+ float dotNV = clamp(dot(n,v),0,1);
+ float dotTV = clamp(dot(n,t),0,1);
+ float dotBV = clamp(dot(n,b),0,1);
+
+ // Reference: getMetallicRoughnessInfo
+ float perceptualRough = packedORM.g;
+ float alphaRough = perceptualRough * perceptualRough;
+ vec3 colorDiff = mix( diffuse.rgb, vec3(0) , metal);
+ reflect0 = mix( reflect0 , diffuse.rgb, metal); // reflect at 0 degrees
+ reflect90 = vec3(1); // reflect at 90 degrees
+ float reflectance = max( max( reflect0.r, reflect0.g ), reflect0.b );
+
+ // Common to RadianceGGX and RadianceLambertian
+ float specWeight = 1.0;
+ vec2 brdfPoint = clamp(vec2(dotNV, 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 - dotNV, 5.0);
+
+ // Reference: getIBLRadianceGGX
+ vec3 specLight = getSpecularPBR(reflection);
+#if HAS_IBL
+ kSpec = mix( kSpec, iridescenceFresnel, iridescenceFactor);
+#endif
+ vec3 FssEssRadiance = kSpec*vScaleBias.x + vScaleBias.y;
+ colorSpec += specWeight * specLight * FssEssRadiance;
+
+ // Reference: getIBLRadianceLambertian
+ vec3 irradiance = getDiffuseLightPBR(n);
+ 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 = colorDiffuse * (1.0 - FssEssLambert + FmsEms);
+ colorDiffuse += (FmsEms + kDiffuse) * irradiance;
+
+ color.rgb = colorDiffuse + colorEmissive + colorSpec;
+
+ #if DEBUG_PBR_BRDF
+ color.rgb = vec3(vScaleBias,0);
+ #endif
+ #if DEBUG_PBR_FRESNEL
+ color.rgb = fresnelR;
+ #endif
+ #if DEBUG_PBR_RAW_DIFF
+ color.rgb = diffuse.rgb;
+ #endif
+ #if DEBUG_PBR_RAW_SPEC
+ color.rgb = spec.rgb;
+ #endif
+ #if DEBUG_PBR_REFLECTANCE
+ color.rgb = vec3(reflectance);
+ #endif
+ #if DEBUG_PBR_IRRADIANCE
+ color.rgb = irradiance;
+ #endif
+ #if DEBUG_PBR_DIFFUSE
+ color.rgb = colorDiffuse;
+ #endif
+ #if DEBUG_PBR_EMISSIVE
+ color.rgb = colorEmissive;
+ #endif
+ #if DEBUG_PBR_METAL
+ color.rgb = vec3(metal);
+ #endif
+ #if DEBUG_PBR_ROUGH
+ color.rgb = vec3(perceptualRough);
+ #endif
+ #if DEBUG_PBR_SPEC
+ color.rgb = colorSpec;
+ #endif
+ #if DEBUG_PBR_SPEC_REFLECTION
+ color.rgb = specLight;
+ #endif
+ #if DEBUG_PBR_ORM
+ color.rgb = packedORM;
+ #endif
+ #if DEBUG_PBR_NORMAL
+ color.rgb = norm.xyz;
+ #endif
+ #if DEBUG_PBR_VIEW
+ color.rgb = view_dir;
+ #endif
+ #if DEBUG_PBR_DOT_NV
+ color.rgb = vec3(dotNV);
+ #endif
+ #if DEBUG_PBR_DOT_TV
+ color.rgb = vec3(dotTV);
+ #endif
+ #if DEBUG_PBR_DOT_BV
+ color.rgb = vec3(dotBV);
+ #endif
+ }
+else
+{
amblit = max(ambenv, amblit);
color.rgb = amblit*ambocc;
@@ -183,7 +361,7 @@ void main()
color = fogged.rgb;
bloom = fogged.a;
#endif
-
+}
// convert to linear as fullscreen lights need to sum in linear colorspace
// and will be gamma (re)corrected downstream...
//color = vec3(ambocc);