summaryrefslogtreecommitdiff
path: root/indra/newview/app_settings/shaders/class1/deferred
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 /indra/newview/app_settings/shaders/class1/deferred
parent015cebd2a4d29dba883e06fe93065bee98f7f9c9 (diff)
SL-17702: PBR: First pass point lights
Diffstat (limited to 'indra/newview/app_settings/shaders/class1/deferred')
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl91
1 files changed, 88 insertions, 3 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;
+}