diff options
author | Ptolemy <ptolemy@lindenlab.com> | 2022-07-14 23:53:52 -0700 |
---|---|---|
committer | Ptolemy <ptolemy@lindenlab.com> | 2022-07-14 23:53:52 -0700 |
commit | 53372ea8ae0654ae6065f963eabd6215f720544a (patch) | |
tree | 6dd56ad22674e7e4a60db372dd55e3da4e47f783 | |
parent | 015cebd2a4d29dba883e06fe93065bee98f7f9c9 (diff) |
SL-17702: PBR: First pass point lights
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)); |