summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPtolemy <ptolemy@lindenlab.com>2022-07-14 23:53:52 -0700
committerPtolemy <ptolemy@lindenlab.com>2022-07-14 23:53:52 -0700
commit53372ea8ae0654ae6065f963eabd6215f720544a (patch)
tree6dd56ad22674e7e4a60db372dd55e3da4e47f783
parent015cebd2a4d29dba883e06fe93065bee98f7f9c9 (diff)
SL-17702: PBR: First pass point lights
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl91
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl24
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl27
3 files changed, 112 insertions, 30 deletions
diff --git a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl
index 5dfdd2006e..e28d4f38e8 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl
@@ -29,11 +29,15 @@ uniform sampler2DRect depthMap;
uniform mat4 inv_proj;
uniform vec2 screen_res;
+const float M_PI = 3.14159265;
+
void calcHalfVectors(vec3 h, vec3 n, vec3 v, out float nh, out float nv, out float vh)
{
- nh = dot(n, h);
- nv = dot(n, v);
- vh = dot(v, h);
+// l = normalize(lv);
+// h = normalize(l + v);
+ nh = clamp(dot(n, h), 0.0, 1.0);
+ nv = clamp(dot(n, v), 0.0, 1.0);
+ vh = clamp(dot(v, h), 0.0, 1.0);
}
vec2 getScreenCoordinate(vec2 screenpos)
@@ -120,3 +124,84 @@ vec2 getScreenXY(vec4 clip)
}
// PBR Utils
+
+vec3 fresnelSchlick( vec3 reflect0, vec3 reflect90, float vh)
+{
+ return reflect0 + (reflect90 - reflect0) * pow(clamp(1.0 - vh, 0.0, 1.0), 5.0);
+}
+
+// Approximate Environment BRDF
+vec2 getGGXApprox( vec2 uv )
+{
+ // Reference: Physically Based Shading on Mobile
+ // https://www.unrealengine.com/en-US/blog/physically-based-shading-on-mobile
+ // EnvBRDFApprox( vec3 SpecularColor, float Roughness, float NoV )
+ float nv = uv.x;
+ float roughness = uv.y;
+
+ const vec4 c0 = vec4( -1, -0.0275, -0.572, 0.022 );
+ const vec4 c1 = vec4( 1, 0.0425, 1.04 , -0.04 );
+ vec4 r = roughness * c0 + c1;
+ float a004 = min( r.x * r.x, exp2( -9.28 * nv ) ) * r.x + r.y;
+ vec2 ScaleBias = vec2( -1.04, 1.04 ) * a004 + r.zw;
+ return ScaleBias;
+}
+
+#define PBR_USE_GGX_APPROX 1
+vec2 getGGX( vec2 brdfPoint )
+{
+#if PBR_USE_GGX_APPROX
+ return getGGXApprox( brdfPoint);
+#else
+ return texture2D(GGXLUT, brdfPoint).rg; // TODO: use GGXLUT
+#endif
+}
+
+// NOTE: This is different from the GGX texture
+float D_GGX( float nh, float alphaRough )
+{
+ float rough2 = alphaRough * alphaRough;
+ float f = (nh * nh) * (rough2 - 1.0) + 1.0;
+ return rough2 / (M_PI * f * f);
+}
+
+// NOTE: This is different from the GGX texture
+float V_GGX( float nl, float nv, float alphaRough )
+{
+ float rough2 = alphaRough * alphaRough;
+ float ggxv = nl * sqrt(nv * nv * (1.0 - rough2) + rough2);
+ float ggxl = nv * sqrt(nl * nl * (1.0 - rough2) + rough2);
+ float ggx = ggxv + ggxl;
+ if (ggx > 0.0)
+ {
+ return 0.5 / ggx;
+ }
+ return 0.0;
+}
+
+void initMaterial( vec3 diffuse, vec3 packedORM, out float alphaRough, out vec3 c_diff, out vec3 reflect0, out vec3 reflect90, out float specWeight )
+{
+ float metal = packedORM.b;
+ c_diff = mix(diffuse.rgb, vec3(0), metal);
+ float IOR = 1.5; // default Index Of Refraction 1.5 (dielectrics)
+ reflect0 = vec3(0.04); // -> incidence reflectance 0.04
+ reflect0 = mix( reflect0, diffuse.rgb, metal); // reflect at 0 degrees
+ reflect90 = vec3(1); // reflect at 90 degrees
+ specWeight = 1.0;
+
+ float perceptualRough = packedORM.g;
+ alphaRough = perceptualRough * perceptualRough;
+}
+
+vec3 BRDFLambertian( vec3 reflect0, vec3 reflect90, vec3 c_diff, float specWeight, float vh )
+{
+ return (1.0 - specWeight * fresnelSchlick( reflect0, reflect90, vh)) * (c_diff / M_PI);
+}
+
+vec3 BRDFSpecularGGX( vec3 reflect0, vec3 reflect90, float alphaRough, float specWeight, float vh, float nl, float nv, float nh )
+{
+ vec3 fresnel = fresnelSchlick( reflect0, reflect90, vh );
+ float vis = V_GGX( nl, nv, alphaRough );
+ float d = D_GGX( nh, alphaRough );
+ return specWeight * fresnel * vis * d;
+}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl
index 9db906bc5a..46de34e49a 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl
@@ -57,10 +57,13 @@ uniform vec2 screen_res;
uniform mat4 inv_proj;
uniform vec4 viewport;
+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 calcHalfVectors(vec3 h, vec3 n, vec3 v, out float nh, out float nv, out float vh);
vec4 getNormalEnvIntensityFlags(vec2 screenpos, out vec3 n, out float envIntensity);
vec4 getPosition(vec2 pos_screen);
vec2 getScreenXY(vec4 clip);
+void initMaterial( vec3 diffuse, vec3 packedORM, out float alphaRough, out vec3 c_diff, out vec3 reflect0, out vec3 reflect90, out float specWeight );
vec3 srgb_to_linear(vec3 c);
void main()
@@ -88,9 +91,7 @@ void main()
}
lv = normalize(lv);
- da = dot(n, lv);
-
- float noise = texture2D(noiseMap, tc/128.0).b;
+ da = dot(n, lv); // alias for: nl
vec3 diffuse = texture2DRect(diffuseRect, tc).rgb;
vec4 spec = texture2DRect(specularRect, tc);
@@ -108,6 +109,20 @@ void main()
vec3 colorEmissive = spec.rgb; // PBR sRGB Emissive. See: pbropaqueF.glsl
vec3 packedORM = texture2DRect(emissiveRect, tc).rgb; // PBR linear packed Occlusion, Roughness, Metal. See: pbropaqueF.glsl
+ vec3 c_diff, reflect0, reflect90;
+ float alphaRough, specWeight;
+ initMaterial( diffuse, packedORM, alphaRough, c_diff, reflect0, reflect90, specWeight );
+
+ vec3 l = lv; // already normalized
+ float nl = clamp(dot(n, l), 0.0, 1.0);
+
+ if (nl > 0.0 || nv > 0.0)
+ {
+ vec3 intensity = size * color;
+ colorDiffuse += intensity * nl * BRDFLambertian ( reflect0, reflect90, c_diff , specWeight, vh );
+ colorSpec += intensity * nl * BRDFSpecularGGX( reflect0, reflect90, alphaRough, specWeight, vh, nl, nv, nh );
+ }
+
final_color = colorDiffuse + colorSpec;
}
else
@@ -116,7 +131,8 @@ void main()
float dist_atten = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0);
dist_atten *= dist_atten;
dist_atten *= 2.0;
-
+
+ float noise = texture2D(noiseMap, tc/128.0).b;
float lit = da * dist_atten * noise;
final_color = color.rgb*lit*diffuse;
diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
index 3aef3ac8ba..59076d9760 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
@@ -23,16 +23,15 @@
* $/LicenseInfo$
*/
-#define PBR_USE_ATMOS 1
-#define PBR_USE_GGX_APPROX 1
-#define PBR_USE_GGX_EMS_HACK 1
+#define PBR_USE_ATMOS 0
+#define PBR_USE_GGX_EMS_HACK 0
#define PBR_USE_IRRADIANCE_HACK 1
#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_VERT2CAM1 0 // vertex2camera = 0,0,1
-#define DEBUG_PBR_SPECLIGHT051 1 // Force specLigh to be 0,0.5,1
+#define DEBUG_PBR_SPECLIGHT051 0 // Force specLigh to be 0,0.5,1
// Pass input through "as is"
#define DEBUG_PBR_DIFFUSE_MAP 0 // Output: use diffuse in G-Buffer
@@ -134,6 +133,7 @@ vec4 getPositionWithDepth(vec2 pos_screen, float depth);
void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 additive, out vec3 atten, bool use_ao);
float getAmbientClamp();
+vec2 getGGX( vec2 brdfPoint );
vec3 atmosFragLighting(vec3 l, vec3 additive, vec3 atten);
vec3 scaleSoftClipFrag(vec3 l);
vec3 fullbrightAtmosTransportFrag(vec3 light, vec3 additive, vec3 atten);
@@ -154,25 +154,6 @@ vec4 applyWaterFogView(vec3 pos, vec4 color);
uniform vec3 view_dir; // PBR
-// 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;
-#if PBR_USE_GGX_APPROX
- return getGGXApprox( brdfPoint);
-#endif
-}
-
vec3 calcBaseReflect0(float ior)
{
vec3 reflect0 = vec3(pow((ior - 1.0) / (ior + 1.0), 2.0));