summaryrefslogtreecommitdiff
path: root/indra/newview/app_settings/shaders
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/app_settings/shaders')
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl12
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaMaskShadowF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaShadowF.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaShadowV.glsl6
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/avatarAlphaMaskShadowF.glsl6
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowF.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowV.glsl6
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl320
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/genbrdflutF.glsl141
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/genbrdflutV.glsl39
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/materialF.glsl29
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/pbralphaF.glsl292
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/pbralphaV.glsl63
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl95
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl78
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/irradianceGenF.glsl223
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl17
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/reflectionmipF.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/multiPointLightF.glsl67
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl217
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl61
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl6
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl672
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl66
24 files changed, 884 insertions, 1546 deletions
diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl
index 02b2daf0ac..fc1cee1f59 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl
@@ -262,27 +262,15 @@ void main()
vec3 sun_contrib = min(final_da, shadow) * sunlit;
-#if !defined(AMBIENT_KILL)
color.rgb = amblit;
color.rgb *= ambient;
-#endif // !defined(AMBIENT_KILL)
-vec3 post_ambient = color.rgb;
-
-#if !defined(SUNLIGHT_KILL)
color.rgb += sun_contrib;
-#endif // !defined(SUNLIGHT_KILL)
-
-vec3 post_sunlight = color.rgb;
color.rgb *= diffuse_srgb.rgb;
-vec3 post_diffuse = color.rgb;
-
color.rgb = atmosFragLighting(color.rgb, additive, atten);
-vec3 post_atmo = color.rgb;
-
vec4 light = vec4(0,0,0,0);
color.rgb = scaleSoftClipFrag(color.rgb);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaMaskShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaMaskShadowF.glsl
index c64b6ba240..c2372fcbc0 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaMaskShadowF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaMaskShadowF.glsl
@@ -58,7 +58,7 @@ void main()
frag_color = vec4(1,1,1,1);
-#if !DEPTH_CLAMP
+#if !defined(DEPTH_CLAMP)
gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
#endif
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaShadowF.glsl
index b54c580ce9..d0a049d372 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaShadowF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaShadowF.glsl
@@ -35,7 +35,7 @@ uniform sampler2D diffuseMap;
VARYING float pos_w;
VARYING float target_pos_x;
-#if !DEPTH_CLAMP
+#if !defined(DEPTH_CLAMP)
VARYING vec4 post_pos;
#endif
@@ -61,7 +61,7 @@ void main()
frag_color = vec4(1,1,1,1);
-#if !DEPTH_CLAMP
+#if !defined(DEPTH_CLAMP)
gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
#endif
diff --git a/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaShadowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaShadowV.glsl
index 31b93dc36a..a7bf4d7780 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaShadowV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaShadowV.glsl
@@ -1,5 +1,5 @@
/**
- * @file attachmentShadowV.glsl
+ * @file attachmentAlphaShadowV.glsl
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2007, Linden Research, Inc.
@@ -35,7 +35,7 @@ ATTRIBUTE vec2 texcoord0;
mat4 getObjectSkinnedTransform();
void passTextureIndex();
-#if !DEPTH_CLAMP
+#if !defined(DEPTH_CLAMP)
VARYING vec4 post_pos;
#endif
VARYING vec2 vary_texcoord0;
@@ -61,7 +61,7 @@ void main()
vertex_color = diffuse_color;
-#if !DEPTH_CLAMP
+#if !defined(DEPTH_CLAMP)
p.z = max(p.z, -p.w+0.01);
post_pos = p;
gl_Position = p;
diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaMaskShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaMaskShadowF.glsl
index b8ce54bcb1..f231213ac8 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaMaskShadowF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaMaskShadowF.glsl
@@ -1,5 +1,5 @@
/**
- * @file treeShadowF.glsl
+ * @file avatarAlphaMaskShadowF.glsl
*
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -32,7 +32,7 @@ out vec4 frag_color;
uniform float minimum_alpha;
uniform sampler2D diffuseMap;
-#if !DEPTH_CLAMP
+#if !defined(DEPTH_CLAMP)
VARYING vec4 post_pos;
#endif
@@ -59,7 +59,7 @@ void main()
frag_color = vec4(1,1,1,1);
-#if !DEPTH_CLAMP
+#if !defined(DEPTH_CLAMP)
gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
#endif
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowF.glsl
index 1b16e4eb09..0e66c722b6 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowF.glsl
@@ -33,7 +33,7 @@ uniform float minimum_alpha;
uniform sampler2D diffuseMap;
-#if !DEPTH_CLAMP
+#if !defined(DEPTH_CLAMP)
VARYING vec4 post_pos;
#endif
@@ -61,7 +61,7 @@ void main()
frag_color = vec4(1,1,1,1);
-#if !DEPTH_CLAMP
+#if !defined(DEPTH_CLAMP)
gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
#endif
diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowV.glsl
index 1c5b142ebd..40ac7b1f95 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowV.glsl
@@ -1,5 +1,5 @@
/**
- * @file avatarShadowV.glsl
+ * @file avatarAlphaShadowV.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -34,7 +34,7 @@ ATTRIBUTE vec3 position;
ATTRIBUTE vec3 normal;
ATTRIBUTE vec2 texcoord0;
-#if !DEPTH_CLAMP
+#if !defined(DEPTH_CLAMP)
VARYING vec4 post_pos;
#endif
VARYING float pos_w;
@@ -66,7 +66,7 @@ void main()
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
-#if !DEPTH_CLAMP
+#if !defined(DEPTH_CLAMP)
post_pos = pos;
gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl
index 449cbeaa28..49f85af53b 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl
@@ -23,9 +23,35 @@
* $/LicenseInfo$
*/
+
+/* Parts of this file are taken from Sascha Willem's Vulkan GLTF refernce implementation
+MIT License
+
+Copyright (c) 2018 Sascha Willems
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
uniform sampler2DRect normalMap;
uniform sampler2DRect depthMap;
uniform sampler2D projectionMap; // rgba
+uniform sampler2D brdfLut;
// projected lighted params
uniform mat4 proj_mat; //screen space to light space projector
@@ -322,162 +348,150 @@ vec3 hue_to_rgb(float hue)
// PBR Utils
-// ior Index of Refraction, normally 1.5
-// returns reflect0
-float calcF0(float ior)
-{
- float f0 = (1.0 - ior) / (1.0 + ior);
- return f0 * f0;
-}
-
-vec3 fresnel(float vh, vec3 f0, vec3 f90 )
-{
- float x = 1.0 - abs(vh);
- float x2 = x*x;
- float x5 = x2*x2*x;
- vec3 fr = f0 + (f90 - f0)*x5;
- return fr;
-}
-
-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
-}
-
-
-// Reference: float getRangeAttenuation(float range, float distance)
-float getLightAttenuationPointSpot(float range, float distance)
-{
-#if 1
- return distance;
-#else
- float range2 = pow(range, 2.0);
-
- // support negative range as unlimited
- if (range <= 0.0)
- {
- return 1.0 / range2;
- }
-
- return max(min(1.0 - pow(distance / range, 4.0), 1.0), 0.0) / range2;
-#endif
-}
-
-vec3 getLightIntensityPoint(vec3 lightColor, float lightRange, float lightDistance)
+vec2 BRDF(float NoV, float roughness)
{
- float rangeAttenuation = getLightAttenuationPointSpot(lightRange, lightDistance);
- return rangeAttenuation * lightColor;
+ return texture(brdfLut, vec2(NoV, roughness)).rg;
}
-float getLightAttenuationSpot(vec3 spotDirection)
+// set colorDiffuse and colorSpec to the results of GLTF PBR style IBL
+vec3 pbrIbl(vec3 diffuseColor,
+ vec3 specularColor,
+ vec3 radiance, // radiance map sample
+ vec3 irradiance, // irradiance map sample
+ float ao, // ambient occlusion factor
+ float nv, // normal dot view vector
+ float perceptualRough)
{
- return 1.0;
-}
-
-vec3 getLightIntensitySpot(vec3 lightColor, float lightRange, float lightDistance, vec3 v)
-{
- float spotAttenuation = getLightAttenuationSpot(-v);
- return spotAttenuation * getLightIntensityPoint( lightColor, lightRange, lightDistance );
-}
+ // retrieve a scale and bias to F0. See [1], Figure 3
+ vec2 brdf = BRDF(clamp(nv, 0, 1), 1.0-perceptualRough);
+ vec3 diffuseLight = irradiance;
+ vec3 specularLight = radiance;
+
+ vec3 diffuse = diffuseLight * diffuseColor;
+ vec3 specular = specularLight * (specularColor * brdf.x + brdf.y);
-// 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
-// See:
-// Real Time Rendering, 4th Edition
-// Page 341
-// Equation 9.43
-// Also see:
-// https://google.github.io/filament/Filament.md.html#materialsystem/specularbrdf/geometricshadowing(specularg)
-// 4.4.2 Geometric Shadowing (specular G)
-float V_GGX( float nl, float nv, float alphaRough )
-{
-#if 1
- // Note: When roughness is zero, has discontuinity in the bottom hemisphere
- 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;
-#else
- // See: smithVisibility_GGXCorrelated, V_SmithCorrelated, etc.
- float rough2 = alphaRough * alphaRough;
- float ggxv = nl * sqrt(nv * (nv - rough2 * nv) + rough2);
- float ggxl = nv * sqrt(nl * (nl - rough2 * nl) + rough2);
- return 0.5 / (ggxv + ggxl);
-#endif
-
-}
-
-// NOTE: Assumes a hard-coded IOR = 1.5
-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, vec3(0), metal);
- float IOR = 1.5; // default Index Of Refraction 1.5 (dielectrics)
- reflect0 = vec3(0.04); // -> incidence reflectance 0.04
-// reflect0 = vec3(calcF0(IOR));
- reflect0 = mix(reflect0, diffuse, metal); // reflect at 0 degrees
- reflect90 = vec3(1); // reflect at 90 degrees
- specWeight = 1.0;
-
- // When roughness is zero blender shows a tiny specular
- float perceptualRough = max(packedORM.g, 0.1);
- alphaRough = perceptualRough * perceptualRough;
-}
-
-vec3 BRDFDiffuse(vec3 color)
-{
- return color * ONE_OVER_PI;
-}
-
-vec3 BRDFLambertian( vec3 reflect0, vec3 reflect90, vec3 c_diff, float specWeight, float vh )
-{
- return (1.0 - specWeight * fresnelSchlick( reflect0, reflect90, vh)) * BRDFDiffuse(c_diff);
-}
-
-vec3 BRDFSpecularGGX( vec3 reflect0, vec3 reflect90, float alphaRough, float specWeight, float vh, float nl, float nv, float nh )
-{
- vec3 fresnel = fresnelSchlick( reflect0, reflect90, vh ); // Fresnel
- float vis = V_GGX( nl, nv, alphaRough ); // Visibility
- float d = D_GGX( nh, alphaRough ); // Distribution
- return specWeight * fresnel * vis * d;
+ //specular *= 1.5;
+
+ return (diffuse + specular) * ao;
+}
+
+// Encapsulate the various inputs used by the various functions in the shading equation
+// We store values in this struct to simplify the integration of alternative implementations
+// of the shading terms, outlined in the Readme.MD Appendix.
+struct PBRInfo
+{
+ float NdotL; // cos angle between normal and light direction
+ float NdotV; // cos angle between normal and view direction
+ float NdotH; // cos angle between normal and half vector
+ float LdotH; // cos angle between light direction and half vector
+ float VdotH; // cos angle between view direction and half vector
+ float perceptualRoughness; // roughness value, as authored by the model creator (input to shader)
+ float metalness; // metallic value at the surface
+ vec3 reflectance0; // full reflectance color (normal incidence angle)
+ vec3 reflectance90; // reflectance color at grazing angle
+ float alphaRoughness; // roughness mapped to a more linear change in the roughness (proposed by [2])
+ vec3 diffuseColor; // color contribution from diffuse lighting
+ vec3 specularColor; // color contribution from specular lighting
+};
+
+// Basic Lambertian diffuse
+// Implementation from Lambert's Photometria https://archive.org/details/lambertsphotome00lambgoog
+// See also [1], Equation 1
+vec3 diffuse(PBRInfo pbrInputs)
+{
+ return pbrInputs.diffuseColor / M_PI;
+}
+
+// The following equation models the Fresnel reflectance term of the spec equation (aka F())
+// Implementation of fresnel from [4], Equation 15
+vec3 specularReflection(PBRInfo pbrInputs)
+{
+ return pbrInputs.reflectance0 + (pbrInputs.reflectance90 - pbrInputs.reflectance0) * pow(clamp(1.0 - pbrInputs.VdotH, 0.0, 1.0), 5.0);
+}
+
+// This calculates the specular geometric attenuation (aka G()),
+// where rougher material will reflect less light back to the viewer.
+// This implementation is based on [1] Equation 4, and we adopt their modifications to
+// alphaRoughness as input as originally proposed in [2].
+float geometricOcclusion(PBRInfo pbrInputs)
+{
+ float NdotL = pbrInputs.NdotL;
+ float NdotV = pbrInputs.NdotV;
+ float r = pbrInputs.alphaRoughness;
+
+ float attenuationL = 2.0 * NdotL / (NdotL + sqrt(r * r + (1.0 - r * r) * (NdotL * NdotL)));
+ float attenuationV = 2.0 * NdotV / (NdotV + sqrt(r * r + (1.0 - r * r) * (NdotV * NdotV)));
+ return attenuationL * attenuationV;
+}
+
+// The following equation(s) model the distribution of microfacet normals across the area being drawn (aka D())
+// Implementation from "Average Irregularity Representation of a Roughened Surface for Ray Reflection" by T. S. Trowbridge, and K. P. Reitz
+// Follows the distribution function recommended in the SIGGRAPH 2013 course notes from EPIC Games [1], Equation 3.
+float microfacetDistribution(PBRInfo pbrInputs)
+{
+ float roughnessSq = pbrInputs.alphaRoughness * pbrInputs.alphaRoughness;
+ float f = (pbrInputs.NdotH * roughnessSq - pbrInputs.NdotH) * pbrInputs.NdotH + 1.0;
+ return roughnessSq / (M_PI * f * f);
+}
+
+vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor,
+ float perceptualRoughness,
+ float metallic,
+ vec3 n, // normal
+ vec3 v, // surface point to camera
+ vec3 l) //surface point to light
+{
+ // make sure specular highlights from punctual lights don't fall off of polished surfaces
+ perceptualRoughness = max(perceptualRoughness, 8.0/255.0);
+
+ float alphaRoughness = perceptualRoughness * perceptualRoughness;
+
+ // Compute reflectance.
+ float reflectance = max(max(specularColor.r, specularColor.g), specularColor.b);
+
+ // For typical incident reflectance range (between 4% to 100%) set the grazing reflectance to 100% for typical fresnel effect.
+ // For very low reflectance range on highly diffuse objects (below 4%), incrementally reduce grazing reflecance to 0%.
+ float reflectance90 = clamp(reflectance * 25.0, 0.0, 1.0);
+ vec3 specularEnvironmentR0 = specularColor.rgb;
+ vec3 specularEnvironmentR90 = vec3(1.0, 1.0, 1.0) * reflectance90;
+
+ vec3 h = normalize(l+v); // Half vector between both l and v
+ vec3 reflection = -normalize(reflect(v, n));
+ reflection.y *= -1.0f;
+
+ float NdotL = clamp(dot(n, l), 0.001, 1.0);
+ float NdotV = clamp(abs(dot(n, v)), 0.001, 1.0);
+ float NdotH = clamp(dot(n, h), 0.0, 1.0);
+ float LdotH = clamp(dot(l, h), 0.0, 1.0);
+ float VdotH = clamp(dot(v, h), 0.0, 1.0);
+
+ PBRInfo pbrInputs = PBRInfo(
+ NdotL,
+ NdotV,
+ NdotH,
+ LdotH,
+ VdotH,
+ perceptualRoughness,
+ metallic,
+ specularEnvironmentR0,
+ specularEnvironmentR90,
+ alphaRoughness,
+ diffuseColor,
+ specularColor
+ );
+
+ // Calculate the shading terms for the microfacet specular shading model
+ vec3 F = specularReflection(pbrInputs);
+ float G = geometricOcclusion(pbrInputs);
+ float D = microfacetDistribution(pbrInputs);
+
+ const vec3 u_LightColor = vec3(1.0);
+
+ // Calculation of analytical lighting contribution
+ vec3 diffuseContrib = (1.0 - F) * diffuse(pbrInputs);
+ vec3 specContrib = F * G * D / (4.0 * NdotL * NdotV);
+ // Obtain final intensity as reflectance (BRDF) scaled by the energy of the light (cosine law)
+ vec3 color = NdotL * u_LightColor * (diffuseContrib + specContrib);
+
+ return color;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/genbrdflutF.glsl b/indra/newview/app_settings/shaders/class1/deferred/genbrdflutF.glsl
new file mode 100644
index 0000000000..73a70d8dc5
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/genbrdflutF.glsl
@@ -0,0 +1,141 @@
+/**
+ * @file class1/deferred/genbrdflut.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$
+ */
+
+/* Taken from Sascha Willem's Vulkan GLTF refernce implementation
+MIT License
+
+Copyright (c) 2018 Sascha Willems
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+/*[EXTRA_CODE_HERE]*/
+
+VARYING vec2 vary_uv;
+
+out vec4 outColor;
+
+#define NUM_SAMPLES 1024
+
+const float PI = 3.1415926536;
+
+// Based omn http://byteblacksmith.com/improvements-to-the-canonical-one-liner-glsl-rand-for-opengl-es-2-0/
+float random(vec2 co)
+{
+ float a = 12.9898;
+ float b = 78.233;
+ float c = 43758.5453;
+ float dt= dot(co.xy ,vec2(a,b));
+ float sn= mod(dt,3.14);
+ return fract(sin(sn) * c);
+}
+
+vec2 hammersley2d(uint i, uint N)
+{
+ // Radical inverse based on http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html
+ uint bits = (i << 16u) | (i >> 16u);
+ bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);
+ bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u);
+ bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u);
+ bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);
+ float rdi = float(bits) * 2.3283064365386963e-10;
+ return vec2(float(i) /float(N), rdi);
+}
+
+// Based on http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_slides.pdf
+vec3 importanceSample_GGX(vec2 Xi, float roughness, vec3 normal)
+{
+ // Maps a 2D point to a hemisphere with spread based on roughness
+ float alpha = roughness * roughness;
+ float phi = 2.0 * PI * Xi.x + random(normal.xz) * 0.1;
+ float cosTheta = sqrt((1.0 - Xi.y) / (1.0 + (alpha*alpha - 1.0) * Xi.y));
+ float sinTheta = sqrt(1.0 - cosTheta * cosTheta);
+ vec3 H = vec3(sinTheta * cos(phi), sinTheta * sin(phi), cosTheta);
+
+ // Tangent space
+ vec3 up = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);
+ vec3 tangentX = normalize(cross(up, normal));
+ vec3 tangentY = normalize(cross(normal, tangentX));
+
+ // Convert to world Space
+ return normalize(tangentX * H.x + tangentY * H.y + normal * H.z);
+}
+
+// Geometric Shadowing function
+float G_SchlicksmithGGX(float dotNL, float dotNV, float roughness)
+{
+ float k = (roughness * roughness) / 2.0;
+ float GL = dotNL / (dotNL * (1.0 - k) + k);
+ float GV = dotNV / (dotNV * (1.0 - k) + k);
+ return GL * GV;
+}
+
+vec2 BRDF(float NoV, float roughness)
+{
+ // Normal always points along z-axis for the 2D lookup
+ const vec3 N = vec3(0.0, 0.0, 1.0);
+ vec3 V = vec3(sqrt(1.0 - NoV*NoV), 0.0, NoV);
+
+ vec2 LUT = vec2(0.0);
+ for(uint i = 0u; i < NUM_SAMPLES; i++) {
+ vec2 Xi = hammersley2d(i, NUM_SAMPLES);
+ vec3 H = importanceSample_GGX(Xi, roughness, N);
+ vec3 L = 2.0 * dot(V, H) * H - V;
+
+ float dotNL = max(dot(N, L), 0.0);
+ float dotNV = max(dot(N, V), 0.0);
+ float dotVH = max(dot(V, H), 0.0);
+ float dotNH = max(dot(H, N), 0.0);
+
+ if (dotNL > 0.0) {
+ float G = G_SchlicksmithGGX(dotNL, dotNV, roughness);
+ float G_Vis = (G * dotVH) / (dotNH * dotNV);
+ float Fc = pow(1.0 - dotVH, 5.0);
+ LUT += vec2((1.0 - Fc) * G_Vis, Fc * G_Vis);
+ }
+ }
+ return LUT / float(NUM_SAMPLES);
+}
+
+void main()
+{
+ outColor = vec4(BRDF(vary_uv.s, 1.0-vary_uv.t), 0.0, 1.0);
+}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/genbrdflutV.glsl b/indra/newview/app_settings/shaders/class1/deferred/genbrdflutV.glsl
new file mode 100644
index 0000000000..682244478b
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/genbrdflutV.glsl
@@ -0,0 +1,39 @@
+/**
+ * @file class3\deferred\genbrdflutV.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$
+ */
+
+uniform mat4 modelview_projection_matrix;
+
+ATTRIBUTE vec3 position;
+
+VARYING vec2 vary_uv;
+
+void main()
+{
+ //transform vertex
+ vec4 pos = modelview_projection_matrix * vec4(position.xyz, 1.0);
+ vary_uv = position.xy*0.5+0.5;
+
+ gl_Position = vec4(position.xyz, 1.0);
+}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl
index 6f087632a5..e87d90aa9e 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl
@@ -345,35 +345,6 @@ void main()
if (spec.a > 0.0) // specular reflection
{
- /* // Reverting this specular calculation to previous 'dumbshiny' version - DJH 6/17/2020
- // Preserving the refactored version as a comment for potential reconsideration,
- // overriding the general rule to avoid pollutiong the source with commented code.
- //
- // If you're reading this in 2021+, feel free to obliterate.
-
- vec3 npos = -normalize(pos.xyz);
-
- //vec3 ref = dot(pos+lv, norm);
- vec3 h = normalize(light_dir.xyz + npos);
- float nh = dot(norm.xyz, h);
- float nv = dot(norm.xyz, npos);
- float vh = dot(npos, h);
- float sa = nh;
- float fres = pow(1 - dot(h, npos), 5)*0.4 + 0.5;
-
- float gtdenom = 2 * nh;
- float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh));
-
- if (nh > 0.0)
- {
- float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt / (nh*da);
- vec3 sp = sun_contrib*scol / 6.0f;
- sp = clamp(sp, vec3(0), vec3(1));
- bloom = dot(sp, sp) / 4.0;
- color += sp * spec.rgb;
- }
- */
-
float sa = dot(refnormpersp, sun_dir.xyz);
vec3 dumbshiny = sunlit * shadow * (texture2D(lightFunc, vec2(sa, spec.a)).r);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbralphaF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbralphaF.glsl
index bde015d109..1caf2b2b1a 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/pbralphaF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/pbralphaF.glsl
@@ -25,24 +25,11 @@
/*[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;
@@ -56,8 +43,6 @@ uniform vec3 emissiveColor;
uniform sampler2DRect lightMap;
#endif
-uniform samplerCube environmentMap;
-uniform mat3 env_mat;
uniform int sun_up_factor;
uniform vec3 sun_dir;
uniform vec3 moon_dir;
@@ -84,18 +69,12 @@ uniform vec3 moon_dir;
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
+VARYING vec2 vary_texcoord2;
+VARYING vec3 vary_normal;
+VARYING vec3 vary_tangent;
+flat in float vary_sign;
-#ifdef HAS_SPECULAR_MAP
- VARYING vec2 vary_texcoord2;
-#endif
#ifdef HAS_ALPHA_MASK
uniform float minimum_alpha; // PBR alphaMode: MASK, See: mAlphaCutoff, setAlphaCutoff()
@@ -107,67 +86,74 @@ uniform vec4 light_position[8];
uniform vec3 light_direction[8]; // spot direction
uniform vec4 light_attenuation[8]; // linear, quadratic, is omni, unused, See: LLPipeline::setupHWLights() and syncLightState()
uniform vec3 light_diffuse[8];
+uniform vec2 light_deferred_attenuation[8]; // light size and falloff
-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);
+vec3 atmosFragLighting(vec3 l, vec3 additive, vec3 atten);
+vec3 scaleSoftClipFrag(vec3 l);
+
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 );
float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen);
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 = linear attenuation, light radius
-// fa = falloff
-// See: LLRender::syncLightState()
-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)
+// PBR interface
+vec3 pbrIbl(vec3 diffuseColor,
+ vec3 specularColor,
+ vec3 radiance, // radiance map sample
+ vec3 irradiance, // irradiance map sample
+ float ao, // ambient occlusion factor
+ float nv, // normal dot view vector
+ float perceptualRoughness);
+
+vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor,
+ float perceptualRoughness,
+ float metallic,
+ vec3 n, // normal
+ vec3 v, // surface point to camera
+ vec3 l); //surface point to light
+
+vec3 calcPointLightOrSpotLight(vec3 diffuseColor, vec3 specularColor,
+ float perceptualRoughness,
+ float metallic,
+ vec3 n, // normal
+ vec3 p, // pixel position
+ vec3 v, // view vector (negative normalized pixel position)
+ vec3 lp, // light position
+ vec3 ld, // light direction (for spotlights)
+ vec3 lightColor,
+ float lightSize, float falloff, float is_pointlight, float ambiance)
{
- vec3 intensity = vec3(0);
+ vec3 color = vec3(0,0,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);
+ vec3 lv = lp.xyz - p;
- if (lightDist > 0.0)
- {
- float falloff_factor = (12.0 * fa) - 9.0;
- float inverted_la = falloff_factor / la;
-
- float dist = lightDist / inverted_la;
+ float lightDist = length(lv);
- float dist_atten = calcLegacyDistanceAttenuation(dist,fa);
- if (dist_atten <= 0.0)
- return intensity;
+ float dist = lightDist / lightSize;
+ if (dist <= 1.0)
+ {
+ lv /= lightDist;
- vec3 reflect90 = vec3(1);
- float specWeight = 1.0;
+ float dist_atten = calcLegacyDistanceAttenuation(dist, falloff);
- lv = normalize(lv);
- float spot = max(dot(-ln, lv), is_pointlight);
- nl *= spot * spot;
+ vec3 intensity = dist_atten * lightColor * 3.0;
- if (nl > 0.0)
- intensity = dist_atten * nl * lightColor * BRDFLambertian(reflect0, reflect90, c_diff, specWeight, vh);
+ color = intensity*pbrPunctual(diffuseColor, specularColor, perceptualRoughness, metallic, n.xyz, v, lv);
}
- return intensity;
+
+ return color;
}
void main()
{
+ vec3 color = vec3(0,0,0);
+
vec3 light_dir = (sun_up_factor == 1) ? sun_dir : moon_dir;
vec3 pos = vary_position;
@@ -180,10 +166,11 @@ void main()
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;
+ vec4 albedo = texture(diffuseMap, vary_texcoord0.xy).rgba;
albedo.rgb = srgb_to_linear(albedo.rgb);
#ifdef HAS_ALPHA_MASK
if (albedo.a < minimum_alpha)
@@ -192,128 +179,61 @@ void main()
}
#endif
-// vec3 base = vertex_color.rgb * albedo.rgb * albedo.a;
- vec3 base = vertex_color.rgb * albedo.rgb;
+ vec3 baseColor = vertex_color.rgb * albedo.rgb;
-#ifdef HAS_NORMAL_MAP
- vec4 norm = texture2D(bumpMap, vary_texcoord1.xy);
- norm.xyz = normalize(norm.xyz * 2 - 1);
+ vec3 vNt = texture(bumpMap, vary_texcoord1.xy).xyz*2.0-1.0;
+ float sign = vary_sign;
+ vec3 vN = vary_normal;
+ vec3 vT = vary_tangent.xyz;
+
+ vec3 vB = sign * cross(vN, vT);
+ vec3 norm = normalize( vNt.x * vT + vNt.y * vB + vNt.z * vN );
- 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;
+ norm *= gl_FrontFacing ? 1.0 : -1.0;
-#if HAS_SHADOW
+#ifdef HAS_SHADOW
vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5;
frag *= screen_res;
scol = sampleDirectionalShadow(pos.xyz, norm.xyz, frag);
#endif
- // 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
+ vec3 orm = texture(specularMap, vary_texcoord2.xy).rgb; //orm is packed into "emissiveRect" to keep the data in linear color space
- packedORM.g *= roughnessFactor;
- packedORM.b *= metallicFactor;
+ float perceptualRoughness = orm.g * roughnessFactor;
+ float metallic = orm.b * metallicFactor;
+ float ao = orm.r;
+ // emissiveColor is the emissive color factor from GLTF and is already in linear space
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;
+ // emissiveMap here is a vanilla RGB texture encoded as sRGB, manually convert to linear
+ colorEmissive *= srgb_to_linear(texture2D(emissiveMap, vary_texcoord0.xy).rgb);
+ // PBR IBL
+ float gloss = 1.0 - perceptualRoughness;
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 radiance = vec3(0);
+ vec3 legacyenv = vec3(0);
+ sampleReflectionProbes(irradiance, radiance, legacyenv, pos.xyz, norm.xyz, gloss, 0.0);
+ irradiance = max(srgb_to_linear(amblit),irradiance) * ambocc*4.0;
- vec3 FssEssGGX = kSpec*vScaleBias.x + vScaleBias.y;
-#if PBR_USE_IBL
- colorSpec += specWeight * specLight * FssEssGGX;
-#endif
+ vec3 f0 = vec3(0.04);
+
+ vec3 diffuseColor = baseColor.rgb*(vec3(1.0)-f0);
+ diffuseColor *= 1.0 - metallic;
- 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
+ vec3 specularColor = mix(f0, baseColor.rgb, metallic);
- colorDiffuse *= ao;
- colorSpec *= ao;
+ vec3 v = -normalize(pos.xyz);
+ float NdotV = clamp(abs(dot(norm.xyz, v)), 0.001, 1.0);
- // 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;
+ color += pbrIbl(diffuseColor, specularColor, radiance, irradiance, ao, NdotV, perceptualRoughness);
+ color += pbrPunctual(diffuseColor, specularColor, perceptualRoughness, metallic, norm.xyz, v, light_dir) * sunlit*8.0 * scol;
+ color += colorEmissive;
+
vec3 light = vec3(0);
// Punctual lights
-#define LIGHT_LOOP(i) light += srgb_to_linear(vec3(scol)) * calcPointLightOrSpotLight( reflect0, c_diff, srgb_to_linear(2.2*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 );
+#define LIGHT_LOOP(i) light += calcPointLightOrSpotLight(diffuseColor, specularColor, perceptualRoughness, metallic, norm.xyz, pos.xyz, v, light_position[i].xyz, light_direction[i].xyz, light_diffuse[i].rgb, light_deferred_attenuation[i].x, light_deferred_attenuation[i].y, light_attenuation[i].z, light_attenuation[i].w);
LIGHT_LOOP(1)
LIGHT_LOOP(2)
@@ -323,42 +243,12 @@ irradiance = vec3(amblit);
LIGHT_LOOP(6)
LIGHT_LOOP(7)
-#if !defined(LOCAL_LIGHT_KILL)
- col += light;
-#endif // !defined(LOCAL_LIGHT_KILL)
+ color.rgb += light.rgb;
-#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
+ color.rgb = linear_to_srgb(color.rgb);
+ color *= atten.r;
+ color += 2.0*additive;
+ color = scaleSoftClipFrag(color);
-// 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);
+ frag_color = vec4(color,albedo.a * vertex_color.a);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbralphaV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbralphaV.glsl
index e0672f09e4..b3880ab178 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/pbralphaV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/pbralphaV.glsl
@@ -54,29 +54,20 @@ uniform float near_clip;
ATTRIBUTE vec3 position;
ATTRIBUTE vec4 diffuse_color;
ATTRIBUTE vec3 normal;
-ATTRIBUTE vec2 texcoord0;
-
-
-#ifdef HAS_NORMAL_MAP
ATTRIBUTE vec4 tangent;
+ATTRIBUTE vec2 texcoord0;
ATTRIBUTE vec2 texcoord1;
+ATTRIBUTE vec2 texcoord2;
-VARYING vec3 vary_mat0;
-VARYING vec3 vary_mat1;
-VARYING vec3 vary_mat2;
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
VARYING vec2 vary_texcoord1;
-#else
+VARYING vec2 vary_texcoord2;
VARYING vec3 vary_normal;
-#endif
+VARYING vec3 vary_tangent;
+flat out float vary_sign;
-#ifdef HAS_SPECULAR_MAP
-ATTRIBUTE vec2 texcoord2;
-VARYING vec2 vary_texcoord2;
-#endif
-
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
void main()
{
@@ -94,46 +85,26 @@ void main()
#endif
gl_Position = vert;
-#if HAS_SHADOW
+#ifdef HAS_SHADOW
vary_fragcoord.xyz = vert.xyz + vec3(0,0,near_clip);
#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
+ vec3 n = (mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz;
+ vec3 t = (mat*vec4(tangent.xyz+position.xyz,1.0)).xyz-pos.xyz;
#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
+ vec3 n = normal_matrix * normal;
+ vec3 t = normal_matrix * tangent.xyz;
#endif //HAS_SKIN
-
+
+ vary_tangent = normalize(t);
+ vary_sign = tangent.w;
+ vary_normal = normalize(n);
+
vertex_color = diffuse_color;
#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl
index 69019667de..ea28cca0cb 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl
@@ -25,60 +25,34 @@
/*[EXTRA_CODE_HERE]*/
-#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 float metallicFactor;
uniform float roughnessFactor;
uniform vec3 emissiveColor;
+uniform sampler2D bumpMap;
+uniform sampler2D emissiveMap;
+uniform sampler2D specularMap; // Packed: Occlusion, Metal, Roughness
-#ifdef HAS_NORMAL_MAP
- uniform sampler2D bumpMap;
- VARYING vec3 vary_tangent;
- flat in float vary_sign;
-#endif
-
-#ifdef HAS_EMISSIVE_MAP
- uniform sampler2D emissiveMap;
-#endif
-
-#ifdef HAS_SPECULAR_MAP
- uniform sampler2D specularMap; // Packed: Occlusion, Metal, Roughness
-#endif
-
-uniform samplerCube environmentMap;
-uniform mat3 env_mat;
-
-#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_data[4];
-#else
-#define frag_data gl_FragData
-#endif
VARYING vec3 vary_position;
VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-#ifdef HAS_NORMAL_MAP
VARYING vec3 vary_normal;
-VARYING vec2 vary_texcoord1;
-#endif
+VARYING vec3 vary_tangent;
+flat in float vary_sign;
-#ifdef HAS_SPECULAR_MAP
- VARYING vec2 vary_texcoord2;
-#endif
+VARYING vec2 vary_texcoord0;
+VARYING vec2 vary_texcoord1;
+VARYING vec2 vary_texcoord2;
uniform float minimum_alpha; // PBR alphaMode: MASK, See: mAlphaCutoff, setAlphaCutoff()
vec2 encode_normal(vec3 n);
vec3 linear_to_srgb(vec3 c);
+vec3 srgb_to_linear(vec3 c);
+
+uniform mat3 normal_matrix;
void main()
{
@@ -91,14 +65,14 @@ void main()
discard;
}
- vec3 col = vertex_color.rgb * albedo.rgb;
+ vec3 col = vertex_color.rgb * srgb_to_linear(albedo.rgb);
// from mikktspace.com
- vec4 vNt = texture2D(bumpMap, vary_texcoord1.xy)*2.0-1.0;
+ vec3 vNt = texture2D(bumpMap, vary_texcoord1.xy).xyz*2.0-1.0;
float sign = vary_sign;
vec3 vN = vary_normal;
vec3 vT = vary_tangent.xyz;
-
+
vec3 vB = sign * cross(vN, vT);
vec3 tnorm = normalize( vNt.x * vT + vNt.y * vB + vNt.z * vN );
@@ -107,52 +81,25 @@ void main()
// occlusion 1.0
// roughness 0.0
// metal 0.0
-#ifdef HAS_SPECULAR_MAP
vec3 spec = texture2D(specularMap, vary_texcoord2.xy).rgb;
-#else
- vec3 spec = vec3(1,0,0);
-#endif
spec.g *= roughnessFactor;
spec.b *= metallicFactor;
vec3 emissive = emissiveColor;
-#ifdef HAS_EMISSIVE_MAP
- emissive *= texture2D(emissiveMap, vary_texcoord0.xy).rgb;
-#endif
-
-#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
+ emissive *= srgb_to_linear(texture2D(emissiveMap, vary_texcoord0.xy).rgb);
tnorm *= gl_FrontFacing ? 1.0 : -1.0;
+ //spec.rgb = vec3(1,1,0);
//col = vec3(0,0,0);
//emissive = vary_tangent.xyz*0.5+0.5;
- //emissive = vec3(vary_sign*0.5+0.5);
+ //emissive = vec3(sign*0.5+0.5);
+ //emissive = vNt * 0.5 + 0.5;
+ //emissive = tnorm*0.5+0.5;
// See: C++: addDeferredAttachments(), GLSL: softenLightF
- frag_data[0] = vec4(col, 0.0); // Diffuse
- frag_data[1] = vec4(emissive, vertex_color.a); // PBR sRGB Emissive
+ frag_data[0] = vec4(linear_to_srgb(col), 0.0); // Diffuse
+ frag_data[1] = vec4(linear_to_srgb(emissive), vertex_color.a); // PBR sRGB Emissive
frag_data[2] = vec4(encode_normal(tnorm), vertex_color.a, GBUFFER_FLAG_HAS_PBR); // normal, environment intensity, flags
frag_data[3] = vec4(spec.rgb,0); // PBR linear packed Occlusion, Roughness, Metal.
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl
index e17d91af38..5573c02a60 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl
@@ -37,41 +37,24 @@ 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 texcoord0;
ATTRIBUTE vec2 texcoord1;
+ATTRIBUTE vec2 texcoord2;
+VARYING vec2 vary_texcoord0;
VARYING vec2 vary_texcoord1;
-#endif
-
-#ifdef HAS_SPECULAR_MAP
-ATTRIBUTE vec2 texcoord2;
VARYING vec2 vary_texcoord2;
-#endif
VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
+
VARYING vec3 vary_tangent;
flat out float vary_sign;
-
VARYING vec3 vary_normal;
void main()
@@ -83,64 +66,27 @@ void main()
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
+ vec3 n = (mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz;
+ vec3 t = (mat*vec4(tangent.xyz+position.xyz,1.0)).xyz-pos.xyz;
#else //HAS_SKIN
- vec3 n = normalize(normal_matrix * normal);
-#ifdef HAS_NORMAL_MAP
- vec3 t = normalize(normal_matrix * tangent.xyz);
- vary_tangent = t;
- vary_sign = tangent.w;
- vary_normal = n;
+ vec3 n = normal_matrix * normal;
+ vec3 t = normal_matrix * tangent.xyz;
+#endif
- //vec3 b = cross(n,t)*tangent.w;
- //vec3 t = cross(b,n) * binormal.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
+ vary_tangent = normalize(t);
+ vary_sign = tangent.w;
+ vary_normal = normalize(n);
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
}
diff --git a/indra/newview/app_settings/shaders/class1/interface/irradianceGenF.glsl b/indra/newview/app_settings/shaders/class1/interface/irradianceGenF.glsl
index 4681fa1abd..63e2fce40f 100644
--- a/indra/newview/app_settings/shaders/class1/interface/irradianceGenF.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/irradianceGenF.glsl
@@ -38,63 +38,190 @@ uniform int sourceIdx;
VARYING vec3 vary_dir;
-// =============================================================================================================
-// Parts of this file are (c) 2018 Sascha Willems
-// SNIPPED FROM https://github.com/SaschaWillems/Vulkan-glTF-PBR/blob/master/data/shaders/irradiancecube.frag
-/*
-MIT License
-Copyright (c) 2018 Sascha Willems
+// Code below is derived from the Khronos GLTF Sample viewer:
+// https://github.com/KhronosGroup/glTF-Sample-Viewer/blob/master/source/shaders/ibl_filtering.frag
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
+#define MATH_PI 3.1415926535897932384626433832795
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-*/
-// =============================================================================================================
+float u_roughness = 1.0;
+int u_sampleCount = 16;
+float u_lodBias = 2.0;
+int u_width = 64;
+// Hammersley Points on the Hemisphere
+// CC BY 3.0 (Holger Dammertz)
+// http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html
+// with adapted interface
+float radicalInverse_VdC(uint bits)
+{
+ bits = (bits << 16u) | (bits >> 16u);
+ bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);
+ bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u);
+ bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u);
+ bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);
+ return float(bits) * 2.3283064365386963e-10; // / 0x100000000
+}
+
+// hammersley2d describes a sequence of points in the 2d unit square [0,1)^2
+// that can be used for quasi Monte Carlo integration
+vec2 hammersley2d(int i, int N) {
+ return vec2(float(i)/float(N), radicalInverse_VdC(uint(i)));
+}
+
+// Hemisphere Sample
+
+// TBN generates a tangent bitangent normal coordinate frame from the normal
+// (the normal must be normalized)
+mat3 generateTBN(vec3 normal)
+{
+ vec3 bitangent = vec3(0.0, 1.0, 0.0);
+
+ float NdotUp = dot(normal, vec3(0.0, 1.0, 0.0));
+ float epsilon = 0.0000001;
+ /*if (1.0 - abs(NdotUp) <= epsilon)
+ {
+ // Sampling +Y or -Y, so we need a more robust bitangent.
+ if (NdotUp > 0.0)
+ {
+ bitangent = vec3(0.0, 0.0, 1.0);
+ }
+ else
+ {
+ bitangent = vec3(0.0, 0.0, -1.0);
+ }
+ }*/
+
+ vec3 tangent = normalize(cross(bitangent, normal));
+ bitangent = cross(normal, tangent);
+
+ return mat3(tangent, bitangent, normal);
+}
+
+struct MicrofacetDistributionSample
+{
+ float pdf;
+ float cosTheta;
+ float sinTheta;
+ float phi;
+};
+
+MicrofacetDistributionSample Lambertian(vec2 xi, float roughness)
+{
+ MicrofacetDistributionSample lambertian;
+
+ // Cosine weighted hemisphere sampling
+ // http://www.pbr-book.org/3ed-2018/Monte_Carlo_Integration/2D_Sampling_with_Multidimensional_Transformations.html#Cosine-WeightedHemisphereSampling
+ lambertian.cosTheta = sqrt(1.0 - xi.y);
+ lambertian.sinTheta = sqrt(xi.y); // equivalent to `sqrt(1.0 - cosTheta*cosTheta)`;
+ lambertian.phi = 2.0 * MATH_PI * xi.x;
+
+ lambertian.pdf = lambertian.cosTheta / MATH_PI; // evaluation for solid angle, therefore drop the sinTheta
+
+ return lambertian;
+}
+
+
+// getImportanceSample returns an importance sample direction with pdf in the .w component
+vec4 getImportanceSample(int sampleIndex, vec3 N, float roughness)
+{
+ // generate a quasi monte carlo point in the unit square [0.1)^2
+ vec2 xi = hammersley2d(sampleIndex, u_sampleCount);
+
+ MicrofacetDistributionSample importanceSample;
+
+ // generate the points on the hemisphere with a fitting mapping for
+ // the distribution (e.g. lambertian uses a cosine importance)
+ importanceSample = Lambertian(xi, roughness);
+
+ // transform the hemisphere sample to the normal coordinate frame
+ // i.e. rotate the hemisphere to the normal direction
+ vec3 localSpaceDirection = normalize(vec3(
+ importanceSample.sinTheta * cos(importanceSample.phi),
+ importanceSample.sinTheta * sin(importanceSample.phi),
+ importanceSample.cosTheta
+ ));
+ mat3 TBN = generateTBN(N);
+ vec3 direction = TBN * localSpaceDirection;
+
+ return vec4(direction, importanceSample.pdf);
+}
+
+// Mipmap Filtered Samples (GPU Gems 3, 20.4)
+// https://developer.nvidia.com/gpugems/gpugems3/part-iii-rendering/chapter-20-gpu-based-importance-sampling
+// https://cgg.mff.cuni.cz/~jaroslav/papers/2007-sketch-fis/Final_sap_0073.pdf
+float computeLod(float pdf)
+{
+ // // Solid angle of current sample -- bigger for less likely samples
+ // float omegaS = 1.0 / (float(u_sampleCount) * pdf);
+ // // Solid angle of texel
+ // // note: the factor of 4.0 * MATH_PI
+ // float omegaP = 4.0 * MATH_PI / (6.0 * float(u_width) * float(u_width));
+ // // Mip level is determined by the ratio of our sample's solid angle to a texel's solid angle
+ // // note that 0.5 * log2 is equivalent to log4
+ // float lod = 0.5 * log2(omegaS / omegaP);
+
+ // babylon introduces a factor of K (=4) to the solid angle ratio
+ // this helps to avoid undersampling the environment map
+ // this does not appear in the original formulation by Jaroslav Krivanek and Mark Colbert
+ // log4(4) == 1
+ // lod += 1.0;
+
+ // We achieved good results by using the original formulation from Krivanek & Colbert adapted to cubemaps
+ // https://cgg.mff.cuni.cz/~jaroslav/papers/2007-sketch-fis/Final_sap_0073.pdf
+ float lod = 0.5 * log2( 6.0 * float(u_width) * float(u_width) / (float(u_sampleCount) * pdf));
+
+
+ return lod;
+}
+
+vec3 filterColor(vec3 N)
+{
+ //return textureLod(uCubeMap, N, 3.0).rgb;
+ vec3 color = vec3(0.f);
+ float weight = 0.0f;
-#define PI 3.1415926535897932384626433832795
+ for(int i = 0; i < u_sampleCount; ++i)
+ {
+ vec4 importanceSample = getImportanceSample(i, N, 1.0);
+ vec3 H = vec3(importanceSample.xyz);
+ float pdf = importanceSample.w;
+
+ // mipmap filtered samples (GPU Gems 3, 20.4)
+ float lod = computeLod(pdf);
+
+ // apply the bias to the lod
+ lod += u_lodBias;
+
+ lod = clamp(lod, 0, 7);
+ // sample lambertian at a lower resolution to avoid fireflies
+ vec3 lambertian = textureLod(reflectionProbes, vec4(H, sourceIdx), lod).rgb;
+
+ color += lambertian;
+ }
+
+ if(weight != 0.0f)
+ {
+ color /= weight;
+ }
+ else
+ {
+ color /= float(u_sampleCount);
+ }
+
+ return color.rgb ;
+}
+
+// entry point
void main()
{
- float deltaPhi = (2.0 * PI) / 11.25;
- float deltaTheta = (0.5 * PI) / 4.0;
- float mipLevel = 2;
-
- vec3 N = normalize(vary_dir);
- vec3 up = vec3(0.0, 1.0, 0.0);
- vec3 right = normalize(cross(up, N));
- up = normalize(cross(N, right));
-
- const float TWO_PI = PI * 2.0;
- const float HALF_PI = PI * 0.5;
-
- vec3 color = vec3(0.0);
- uint sampleCount = 0u;
- for (float phi = 0.0; phi < TWO_PI; phi += deltaPhi) {
- for (float theta = 0.0; theta < HALF_PI; theta += deltaTheta) {
- vec3 tempVec = cos(phi) * right + sin(phi) * up;
- vec3 sampleVector = cos(theta) * N + sin(theta) * tempVec;
- color += textureLod(reflectionProbes, vec4(sampleVector, sourceIdx), mipLevel).rgb * cos(theta) * sin(theta);
- sampleCount++;
- }
- }
- frag_color = vec4(PI * color / float(sampleCount), 1.0);
+ vec3 color = vec3(0);
+
+ color = filterColor(vary_dir);
+
+ frag_color = vec4(color,1.0);
}
-// =============================================================================================================
diff --git a/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl b/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl
index 94fedce243..7c175eab5f 100644
--- a/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl
@@ -66,7 +66,7 @@ SOFTWARE.
// =============================================================================================================
-uniform float roughness;
+//uniform float roughness;
uniform float mipLevel;
@@ -123,14 +123,18 @@ float D_GGX(float dotNH, float roughness)
return (alpha2)/(PI * denom*denom);
}
-vec3 prefilterEnvMap(vec3 R, float roughness)
+vec3 prefilterEnvMap(vec3 R)
{
vec3 N = R;
vec3 V = R;
vec3 color = vec3(0.0);
float totalWeight = 0.0;
float envMapDim = 256.0;
- int numSamples = 32/max(int(mipLevel), 1);
+ int numSamples = 8;
+
+ float numMips = 7.0;
+
+ float roughness = (mipLevel+1)/numMips;
for(uint i = 0u; i < numSamples; i++) {
vec2 Xi = hammersley2d(i, numSamples);
@@ -150,8 +154,9 @@ vec3 prefilterEnvMap(vec3 R, float roughness)
// Solid angle of 1 pixel across all cube faces
float omegaP = 4.0 * PI / (6.0 * envMapDim * envMapDim);
// Biased (+1.0) mip level for better result
- //float mipLevel = roughness == 0.0 ? 0.0 : max(0.5 * log2(omegaS / omegaP) + 1.0, 0.0f);
- color += textureLod(reflectionProbes, vec4(L,sourceIdx), mipLevel).rgb * dotNL;
+ //float mip = roughness == 0.0 ? 0.0 : max(0.5 * log2(omegaS / omegaP) + 1.0, 0.0f);
+ float mip = clamp(0.5 * log2(omegaS / omegaP) + 1.0, 0.0f, 7.f);
+ color += textureLod(reflectionProbes, vec4(L,sourceIdx), mip).rgb * dotNL;
totalWeight += dotNL;
}
@@ -162,7 +167,7 @@ vec3 prefilterEnvMap(vec3 R, float roughness)
void main()
{
vec3 N = normalize(vary_dir);
- frag_color = vec4(prefilterEnvMap(N, roughness), 1.0);
+ frag_color = vec4(prefilterEnvMap(N), 1.0);
}
// =============================================================================================================
diff --git a/indra/newview/app_settings/shaders/class1/interface/reflectionmipF.glsl b/indra/newview/app_settings/shaders/class1/interface/reflectionmipF.glsl
index ea687aab4f..e8452a9c14 100644
--- a/indra/newview/app_settings/shaders/class1/interface/reflectionmipF.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/reflectionmipF.glsl
@@ -39,6 +39,7 @@ VARYING vec2 vary_texcoord0;
void main()
{
+#if 0
float w[9];
float c = 1.0/16.0; //corner weight
@@ -72,4 +73,7 @@ void main()
//color /= wsum;
frag_color = vec4(color, 1.0);
+#else
+ frag_color = vec4(texture2DRect(screenMap, vary_texcoord0.xy).rgb, 1.0);
+#endif
}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/multiPointLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/multiPointLightF.glsl
index c7c241b76e..2ee439f61a 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/multiPointLightF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/multiPointLightF.glsl
@@ -27,11 +27,6 @@
/*[EXTRA_CODE_HERE]*/
-#define DEBUG_ANY_LIGHT_TYPE 0 // Output red light cone
-#define DEBUG_PBR_LIGHT_TYPE 0 // Output PBR objects in red
-#define DEBUG_LEG_LIGHT_TYPE 0 // Show Legacy objects in red
-#define DEBUG_POINT_ZERO 0 // Output zero for point lights
-
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
#else
@@ -57,20 +52,24 @@ uniform mat4 inv_proj;
VARYING vec4 vary_fragcoord;
-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 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);
-vec3 getLightIntensityPoint(vec3 lightColor, float lightRange, float lightDistance);
vec4 getPosition(vec2 pos_screen);
vec4 getNormalEnvIntensityFlags(vec2 screenpos, out vec3 n, out float envIntensity);
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);
// Util
vec3 hue_to_rgb(float hue);
+vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor,
+ float perceptualRoughness,
+ float metallic,
+ vec3 n, // normal
+ vec3 v, // surface point to camera
+ vec3 l); //surface point to light
+
+
void main()
{
#if defined(LOCAL_LIGHT_KILL)
@@ -92,41 +91,43 @@ void main()
vec3 diffuse = texture2DRect(diffuseRect, tc).rgb;
vec3 h, l, v = -normalize(pos);
- float nh, nl, nv, vh, lightDist;
+ float nh, nv, vh, lightDist;
if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_PBR))
{
- vec3 colorDiffuse = vec3(0);
- vec3 colorSpec = vec3(0);
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 orm = texture2DRect(emissiveRect, tc).rgb; //orm is packed into "emissiveRect" to keep the data in linear color space
+ float perceptualRoughness = orm.g;
+ float metallic = orm.b;
+ vec3 f0 = vec3(0.04);
+ vec3 baseColor = diffuse.rgb;
+
+ vec3 diffuseColor = baseColor.rgb*(vec3(1.0)-f0);
+ diffuseColor *= 1.0 - metallic;
- vec3 c_diff, reflect0, reflect90;
- float alphaRough, specWeight;
- initMaterial( diffuse, packedORM, alphaRough, c_diff, reflect0, reflect90, specWeight );
+ vec3 specularColor = mix(f0, baseColor.rgb, metallic);
for (int light_idx = 0; light_idx < LIGHT_COUNT; ++light_idx)
{
vec3 lightColor = light_col[ light_idx ].rgb; // Already in linear, see pipeline.cpp: volume->getLightLinearColor();
float falloff = light_col[ light_idx ].a;
- float lightSize = light [ light_idx ].w;
- vec3 lv =(light [ light_idx ].xyz - pos);
- calcHalfVectors(lv, n, v, h, l, nh, nl, nv, vh, lightDist);
+ float lightSize = light[ light_idx ].w;
+ vec3 lv = light[ light_idx ].xyz - pos;
+
+ lightDist = length(lv);
float dist = lightDist / lightSize;
- if (dist <= 1.0 && nl > 0.0)
+ if (dist <= 1.0)
{
+ lv /= lightDist;
+
float dist_atten = calcLegacyDistanceAttenuation(dist, falloff);
- vec3 intensity = dist_atten * nl * lightColor;
- colorDiffuse += intensity * BRDFLambertian (reflect0, reflect90, c_diff , specWeight, vh);
- colorSpec += intensity * BRDFSpecularGGX(reflect0, reflect90, alphaRough, specWeight, vh, nl, nv, nh);
+
+ vec3 intensity = dist_atten * lightColor * 3.0;
+
+ final_color += intensity*pbrPunctual(diffuseColor, specularColor, perceptualRoughness, metallic, n.xyz, v, lv);
}
}
-
- #if DEBUG_PBR_LIGHT_TYPE
- colorDiffuse = vec3(0.5,0,0); colorSpec = vec3(0);
- #endif
- final_color = colorDiffuse + colorSpec;
}
else
{
@@ -174,18 +175,8 @@ void main()
}
}
}
- #if DEBUG_LEG_LIGHT_TYPE
- final_color.rgb = vec3(0.5,0,0.0);
- #endif
}
-#if DEBUG_POINT_ZERO
- final_color = vec3(0);
-#endif
-#if DEBUG_ANY_LIGHT_TYPE
- final_color = vec3(0.3333,0,0);
-#endif
-
frag_color.rgb = final_color;
frag_color.a = 0.0;
#endif // LOCAL_LIGHT_KILL
diff --git a/indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl
index bc4b4eb7e1..6424e18079 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl
@@ -28,40 +28,6 @@
/*[EXTRA_CODE_HERE]*/
-#define DEBUG_ANY_LIGHT_TYPE 0 // Output blue light cone
-#define DEBUG_LEG_LIGHT_TYPE 0 // Show Legacy objects in blue
-#define DEBUG_PBR_LIGHT_TYPE 0 // Ouput gray if PBR multiSpot lights object
-#define DEBUG_PBR_SPOT 0
-#define DEBUG_PBR_SPOT_DIFFUSE 0 // PBR diffuse lit
-#define DEBUG_PBR_SPOT_SPECULAR 0 // PBR spec lit
-
-#define DEBUG_LIGHT_FRUSTUM 0 // If projected light effects a surface
-#define DEBUG_AMBIANCE_COLOR 0 // calculated ambiance color
-#define DEBUG_AMBIANCE_AOE 0 // area of effect using inverse ambiance color
-#define DEBUG_AMBIANCE_FINAL 0 // light color * ambiance color
-#define DEBUG_NOISE 0 // monochrome noise
-#define DEBUG_SHADOW 0 // Show inverted shadow
-#define DEBUG_SPOT_DIFFUSE 0 // dot(n,l) * dist_atten
-#define DEBUG_SPOT_NL 0 // monochome area effected by light
-#define DEBUG_SPOT_SPEC_POS 0
-#define DEBUG_SPOT_REFLECTION 0 // color: pos reflected along n
-#define DEBUG_SPOT_ZERO 0 // Output zero for spotlight
-
-#define DEBUG_PBR_LIGHT_H 0 // Half vector
-#define DEBUG_PBR_LIHGT_L 0 // Light vector
-#define DEBUG_PBR_LIGHT_NH 0 // colorized dot(n,h)
-#define DEBUG_PBR_LIGHT_NL 0 // colorized dot(n,l)
-#define DEBUG_PBR_LIGHT_NV 0 // colorized dot(n,v)
-#define DEBUG_PBR_LIGHT_VH 0 // colorized dot(v,h)
-#define DEBUG_PBR_LIGHT_DIFFUSE_COLOR 0 // non PBR spotlight
-#define DEBUG_PBR_LIGHT_SPECULAR_COLOR 0 // non PBR spotlight
-#define DEBUG_PBR_LIGHT_INTENSITY 0 // Light intensity
-#define DEBUG_PBR_LIGHT_INTENSITY_NL 0 // Light intensity * dot(n,l)
-#define DEBUG_PBR_LIGHT_BRDF_DIFFUSE 0 // like "fullbright" if no "nl" factor
-#define DEBUG_PBR_LIGHT_BRDF_SPECULAR 0
-#define DEBUG_PBR_LIGHT_BRDF_FINAL 0 // BRDF Diffuse + BRDF Specular
-
-
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
#else
@@ -107,19 +73,15 @@ uniform vec2 screen_res;
uniform mat4 inv_proj;
-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 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);
vec3 colorized_dot(float x);
bool clipProjectedLightVars(vec3 center, vec3 pos, out float dist, out float l_dist, out vec3 lv, out vec4 proj_tc );
-vec3 getLightIntensitySpot(vec3 lightColor, float lightRange, float lightDistance, vec3 v);
vec4 getNormalEnvIntensityFlags(vec2 screenpos, out vec3 n, out float envIntensity);
vec3 getProjectedLightAmbiance(float amb_da, float attenuation, float lit, float nl, float noise, vec2 projected_uv);
vec3 getProjectedLightDiffuseColor(float light_distance, vec2 projected_uv );
vec3 getProjectedLightSpecularColor(vec3 pos, vec3 n);
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 cs);
vec4 texture2DLodSpecular(vec2 tc, float lod);
@@ -127,6 +89,13 @@ vec4 getPosition(vec2 pos_screen);
const float M_PI = 3.14159265;
+vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor,
+ float perceptualRoughness,
+ float metallic,
+ vec3 n, // normal
+ vec3 v, // surface point to camera
+ vec3 l); //surface point to light
+
void main()
{
#if defined(LOCAL_LIGHT_KILL)
@@ -178,11 +147,17 @@ void main()
if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_PBR))
{
- vec3 colorDiffuse = vec3(0);
- vec3 colorSpec = vec3(0);
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
- float metal = packedORM.b;
+ vec3 orm = texture2DRect(emissiveRect, tc).rgb; //orm is packed into "emissiveRect" to keep the data in linear color space
+ float perceptualRoughness = orm.g;
+ float metallic = orm.b;
+ vec3 f0 = vec3(0.04);
+ vec3 baseColor = diffuse.rgb;
+
+ vec3 diffuseColor = baseColor.rgb*(vec3(1.0)-f0);
+ diffuseColor *= 1.0 - metallic;
+
+ vec3 specularColor = mix(f0, baseColor.rgb, metallic);
// We need this additional test inside a light's frustum since a spotlight's ambiance can be applied
if (proj_tc.x > 0.0 && proj_tc.x < 1.0
@@ -194,111 +169,16 @@ void main()
if (nl > 0.0)
{
amb_da += (nl*0.5 + 0.5) * proj_ambiance;
- lit = nl * dist_atten;
-
- vec3 c_diff, reflect0, reflect90;
- float alphaRough, specWeight;
- initMaterial( diffuse, packedORM, alphaRough, c_diff, reflect0, reflect90, specWeight );
-
+
dlit = getProjectedLightDiffuseColor( l_dist, proj_tc.xy );
- slit = getProjectedLightSpecularColor( pos, n );
-
- float exposure = M_PI;
- dlit *= exposure;
- slit *= exposure;
-
- colorDiffuse = shadow * lit * dlit * BRDFLambertian ( reflect0, reflect90, c_diff , specWeight, vh );
- colorSpec = shadow * lit * slit * BRDFSpecularGGX( reflect0, reflect90, alphaRough, specWeight, vh, nl, nv, nh );
- colorSpec += shadow * lit * BRDFSpecularGGX( reflect0, reflect90, alphaRough, specWeight, vh, nl, nv, nh );
-
- #if DEBUG_PBR_SPOT_DIFFUSE
- colorDiffuse = dlit.rgb; colorSpec = vec3(0);
- #endif
- #if DEBUG_PBR_SPOT_SPECULAR
- colorDiffuse = vec3(0); colorSpec = slit.rgb;
- #endif
- #if DEBUG_PBR_SPOT
- colorDiffuse = dlit; colorSpec = vec3(0);
- colorDiffuse *= nl;
- colorDiffuse *= shadow;
- #endif
+
+ vec3 intensity = dist_atten * dlit * 3.0 * shadow; // Legacy attenuation
+ final_color += intensity*pbrPunctual(diffuseColor, specularColor, perceptualRoughness, metallic, n.xyz, v, normalize(lv));
}
amb_rgb = getProjectedLightAmbiance( amb_da, dist_atten, lit, nl, 1.0, proj_tc.xy );
- colorDiffuse += diffuse.rgb * amb_rgb;
-
- #if DEBUG_AMBIANCE_FINAL
- colorDiffuse = diffuse.rgb * amb_rgb; colorSpec = vec3(0);
- #endif
- #if DEBUG_LIGHT_FRUSTUM
- colorDiffuse = vec3(0,1,0); colorSpec = vec3(0);
- #endif
- #if DEBUG_NOISE
- float noise = texture2D(noiseMap, tc/128.0).b;
- colorDiffuse = vec3(noise); colorSpec = vec3(0);
- #endif
+ final_color += diffuse.rgb * amb_rgb;
}
-
- #if DEBUG_PBR_LIGHT_TYPE
- colorDiffuse = vec3(0.5,0,0); colorSpec = vec3(0);
- #endif
-
- #if DEBUG_PBR_LIGHT_H
- colorDiffuse = h*0.5 + 0.5; colorSpec = vec3(0);
- #endif
- #if DEBUG_PBR_LIHGT_L
- colorDiffuse = l*0.5 + 0.5; colorSpec = vec3(0);
- #endif
- #if DEBUG_PBR_LIGHT_NH
- colorDiffuse = colorized_dot(nh); colorSpec = vec3(0);
- #endif
- #if DEBUG_PBR_LIGHT_NL
- colorDiffuse = colorized_dot(nl); colorSpec = vec3(0);
- #endif
- #if DEBUG_PBR_LIGHT_NV
- colorDiffuse = colorized_dot(nv); colorSpec = vec3(0);
- #endif
- #if DEBUG_PBR_LIGHT_VH
- colorDiffuse = colorized_dot(vh); colorSpec = vec3(0);
- #endif
- #if DEBUG_PBR_LIGHT_DIFFUSE_COLOR
- colorDiffuse = dlit;
- #endif
- #if DEBUG_PBR_LIGHT_SPECULAR_COLOR
- colorDiffuse = slit;
- #endif
- #if DEBUG_PBR_LIGHT_INTENSITY
- colorDiffuse = getLightIntensitySpot( color, size, lightDist, v ); colorSpec = vec3(0);
-// colorDiffuse = nl * dist_atten;
- #endif
- #if DEBUG_PBR_LIGHT_INTENSITY_NL
- colorDiffuse = getLightIntensitySpot( color, size, lightDist, v ) * nl; colorSpec = vec3(0);
- #endif
- #if DEBUG_PBR_LIGHT_BRDF_DIFFUSE
- vec3 c_diff, reflect0, reflect90;
- float alphaRough, specWeight;
- initMaterial( diffuse, packedORM, alphaRough, c_diff, reflect0, reflect90, specWeight );
-
- colorDiffuse = BRDFLambertian ( reflect0, reflect90, c_diff , specWeight, vh );
- colorSpec = vec3(0);
- #endif
- #if DEBUG_PBR_LIGHT_BRDF_SPECULAR
- vec3 c_diff, reflect0, reflect90;
- float alphaRough, specWeight;
- initMaterial( diffuse, packedORM, alphaRough, c_diff, reflect0, reflect90, specWeight );
-
- colorDiffuse = vec3(0);
- colorSpec = BRDFSpecularGGX( reflect0, reflect90, alphaRough, specWeight, vh, nl, nv, nh );
- #endif
- #if DEBUG_PBR_LIGHT_BRDF_FINAL
- vec3 c_diff, reflect0, reflect90;
- float alphaRough, specWeight;
- initMaterial( diffuse, packedORM, alphaRough, c_diff, reflect0, reflect90, specWeight );
- colorDiffuse = nl * BRDFLambertian ( reflect0, reflect90, c_diff , specWeight, vh );
- colorSpec = nl * BRDFSpecularGGX( reflect0, reflect90, alphaRough, specWeight, vh, nl, nv, nh );
- #endif
-
- final_color = colorDiffuse + colorSpec;
}
else
{
@@ -326,9 +206,6 @@ void main()
amb_rgb = getProjectedLightAmbiance( amb_da, dist_atten, lit, nl, noise, proj_tc.xy );
final_color += diffuse.rgb * amb_rgb;
-#if DEBUG_LEG_LIGHT_TYPE
- final_color = vec3(0,0,0.5);
-#endif
}
if (spec.a > 0.0)
@@ -376,58 +253,8 @@ void main()
}
}
}
- #if DEBUG_SPOT_REFLECTION
- final_color = ref;
- #endif
- }
-
-#if DEBUG_LIGHT_FRUSTUM
- if (proj_tc.x > 0.0 && proj_tc.x < 1.0
- && proj_tc.y > 0.0 && proj_tc.y < 1.0)
- {
- final_color = vec3(0,0,1);
}
-#endif
- }
-
-#if DEBUG_AMBIANCE_AOE
- if (proj_tc.x > 0.0 && proj_tc.x < 1.0
- && proj_tc.y > 0.0 && proj_tc.y < 1.0)
- {
- final_color = 1.0 - amb_rgb;
}
-#endif
-#if DEBUG_AMBIANCE_COLOR
- if (proj_tc.x > 0.0 && proj_tc.x < 1.0
- && proj_tc.y > 0.0 && proj_tc.y < 1.0)
- {
- final_color = amb_rgb;
- }
-#endif
-#if DEBUG_SHADOW
- final_color = 1.0 - vec3(shadow);
-#endif
-#if DEBUG_SPOT_DIFFUSE
- final_color = vec3(nl * dist_atten);
-#endif
-#if DEBUG_SPOT_NL
- final_color =vec3(nl);
-#endif
-#if DEBUG_SPOT_SPEC_POS
- vec3 ref = reflect(normalize(pos), n);
- vec3 pdelta = proj_p-pos;
- float ds = dot(ref, proj_n);
- final_color = pos + ref * dot(pdelta, proj_n)/ds;
-#endif
-#if DEBUG_SPOT_REFLECTION
- final_color = reflect(normalize(pos), n);
-#endif
-#if DEBUG_SPOT_ZERO
- final_color = vec3(0,0,0);
-#endif
-#if DEBUG_ANY_LIGHT_TYPE
- final_color = vec3(0,0,0.3333);
-#endif
//not sure why, but this line prevents MATBUG-194
final_color = max(final_color, vec3(0.0));
diff --git a/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl
index 6f39b0173b..27fca64ab3 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl
@@ -27,11 +27,6 @@
/*[EXTRA_CODE_HERE]*/
-#define DEBUG_ANY_LIGHT_TYPE 0 // Output magenta light cone
-#define DEBUG_LEG_LIGHT_TYPE 0 // Show Legacy objects in green
-#define DEBUG_PBR_LIGHT_TYPE 0 // Show PBR objects in blue
-#define DEBUG_POINT_ZERO 0 // Output zero for point light
-
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
#else
@@ -62,17 +57,20 @@ 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 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);
-vec3 getLightIntensityPoint(vec3 lightColor, float lightRange, float lightDistance);
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);
+vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor,
+ float perceptualRoughness,
+ float metallic,
+ vec3 n, // normal
+ vec3 v, // surface point to camera
+ vec3 l); //surface point to light
+
void main()
{
vec3 final_color = vec3(0);
@@ -101,28 +99,20 @@ void main()
if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_PBR))
{
- vec3 colorDiffuse = vec3(0);
- vec3 colorSpec = vec3(0);
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
- float lightSize = size;
- vec3 lightColor = color; // Already in linear, see pipeline.cpp: volume->getLightLinearColor();
-
- vec3 c_diff, reflect0, reflect90;
- float alphaRough, specWeight;
- initMaterial( diffuse, packedORM, alphaRough, c_diff, reflect0, reflect90, specWeight );
-
- if (nl > 0.0)
- {
- vec3 intensity = dist_atten * nl * lightColor; // Legacy attenuation
- colorDiffuse += intensity * BRDFLambertian (reflect0, reflect90, c_diff , specWeight, vh);
- colorSpec += intensity * BRDFSpecularGGX(reflect0, reflect90, alphaRough, specWeight, vh, nl, nv, nh);
- }
-
-#if DEBUG_PBR_LIGHT_TYPE
- colorDiffuse = vec3(0,0,0.5); colorSpec = vec3(0);
-#endif
- final_color = colorDiffuse + colorSpec;
+ vec3 orm = texture2DRect(emissiveRect, tc).rgb; //orm is packed into "emissiveRect" to keep the data in linear color space
+ float perceptualRoughness = orm.g;
+ float metallic = orm.b;
+ vec3 f0 = vec3(0.04);
+ vec3 baseColor = diffuse.rgb;
+
+ vec3 diffuseColor = baseColor.rgb*(vec3(1.0)-f0);
+ diffuseColor *= 1.0 - metallic;
+
+ vec3 specularColor = mix(f0, baseColor.rgb, metallic);
+
+ vec3 intensity = dist_atten * color * 3.0; // Legacy attenuation
+ final_color += intensity*pbrPunctual(diffuseColor, specularColor, perceptualRoughness, metallic, n.xyz, v, normalize(lv));
}
else
{
@@ -156,19 +146,8 @@ void main()
{
discard;
}
-
-#if DEBUG_LEG_LIGHT_TYPE
- final_color.rgb = vec3(0,0.25,0);
-#endif
}
-#if DEBUG_POINT_ZERO
- final_color = vec3(0);
-#endif
-#if DEBUG_ANY_LIGHT_TYPE
- final_color = vec3(0.25,0,0.25);
-#endif
-
frag_color.rgb = final_color;
frag_color.a = 0.0;
}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl
index 3ff039261b..463709de9e 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl
@@ -364,7 +364,7 @@ vec3 tapIrradianceMap(vec3 pos, vec3 dir, vec3 c, float r2, int i)
v -= c;
v = env_mat * v;
{
- return textureLod(irradianceProbes, vec4(v.xyz, refIndex[i].x), 0).rgb * refParams[i].x;
+ return texture(irradianceProbes, vec4(v.xyz, refIndex[i].x)).rgb * refParams[i].x;
}
}
@@ -524,14 +524,14 @@ void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv, inout vec3 l
vec3 pos, vec3 norm, float glossiness, float envIntensity)
{
// TODO - don't hard code lods
- float reflection_lods = 8;
+ float reflection_lods = 7;
preProbeSample(pos);
vec3 refnormpersp = reflect(pos.xyz, norm.xyz);
ambenv = sampleProbeAmbient(pos, norm);
- if (glossiness > 0.0)
+ //if (glossiness > 0.0)
{
float lod = (1.0-glossiness)*reflection_lods;
glossenv = sampleProbes(pos, normalize(refnormpersp), lod, 1.f);
diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
index d78c47a36a..a8a3b5d33f 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
@@ -23,106 +23,6 @@
* $/LicenseInfo$
*/
-#define PBR_USE_ATMOS 1
-#define PBR_USE_IBL 1
-#define PBR_USE_SUN 1
-
-#define PBR_USE_LINEAR_ALBEDO 1
-#define PBR_USE_DEFAULT_IRRADIANCE 0 // PBR: irradiance, skins/default/textures/default_irradiance.png
-#define PBR_USE_IRRADIANCE_HACK 1
-
-#define DEBUG_PBR_LIGHT_TYPE 0 // Output no global light to make it easier to see pointLight and spotLight
-#define DEBUG_PBR_PACK_ORM0 0 // Rough=0, Metal=0
-#define DEBUG_PBR_PACK_ORM1 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 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
-#define DEBUG_PBR_EMISSIVE 0 // Output: Emissive
-#define DEBUG_PBR_METAL 0 // Output: grayscale Metal map
-#define DEBUG_PBR_NORMAL_MAP 0 // Output: Normal -- also need to set DEBUG_NORMAL_MAP in pbropaqueF
-#define DEBUG_PBR_OCCLUSION 0 // Output: grayscale Occlusion map
-#define DEBUG_PBR_ORM 0 // Output: Packed Occlusion Roughness Metal
-#define DEBUG_PBR_ROUGH_PERCEPTUAL 0 // Output: grayscale Perceptual Roughness map
-#define DEBUG_PBR_ROUGH_ALPHA 0 // Output: grayscale Alpha Roughness
-
-#define DEBUG_PBR_TANGENT 0 // Output: Tangent
-#define DEBUG_PBR_BITANGENT 0 // Output: Bitangent
-#define DEBUG_PBR_DOT_BV 0 // Output: graysacle dot(Bitangent,Vertex2Camera)
-#define DEBUG_PBR_DOT_TV 0 // Output: grayscale dot(Tangent ,Vertex2Camera)
-
-// IBL Spec
-#define DEBUG_PBR_NORMAL 0 // Output: passed in normal
-#define DEBUG_PBR_V2C_RAW 0 // Output: vertex2camera
-#define DEBUG_PBR_DOT_NV 0 // Output: grayscale dot(Normal ,Vertex2Camera)
-#define DEBUG_PBR_BRDF_UV 0 // Output: red green BRDF UV (GGX input)
-#define DEBUG_PBR_BRDF_SCALE_BIAS 0 // Output: red green BRDF Scale Bias (GGX output)
-#define DEBUG_PBR_BRDF_SCALE_ONLY 0 // Output: grayscale BRDF Scale
-#define DEBUG_PBR_BRDF_BIAS_ONLY 0 // Output: grayscale BRDER Bias
-#define DEBUG_PBR_FRESNEL 0 // Output: roughness dependent fresnel
-#define DEBUG_PBR_KSPEC 0 // Output: K spec
-#define DEBUG_PBR_REFLECTION_DIR 0 // Output: reflection dir
-#define DEBUG_PBR_SPEC_IBL 0 // Output: IBL specularity
-#define DEBUG_PBR_SPEC_LEGACY 0 // Output: legacyenv
-#define DEBUG_PBR_SPEC_REFLECTION 0 // Output: environment reflection
-#define DEBUG_PBR_FSS_ESS_GGX 0 // Output: FssEssGGX
-#define DEBUG_PBR_SPEC 0 // Output: Final spec
-
-// IBL Diffuse
-#define DEBUG_PBR_DIFFUSE_C 0 // Output: diffuse non metal mix
-#define DEBUG_PBR_IRRADIANCE_RAW 0 // Output: Diffuse Irradiance pre-mix
-#define DEBUG_PBR_IRRADIANCE 0 // Output: Diffuse Irradiance, NOTE: SSAO is factored in
-#define DEBUG_PBR_FSS_ESS_LAMBERT 0 // Output: FssEssLambert
-#define DEBUG_PBR_EMS 0 // Output: Ems = (1 - BRDF Scale + BRDF Bias)
-#define DEBUG_PBR_EMS_AVG 0 // Output: Avg Ems
-#define DEBUG_PBR_AVG 0 // Output: Avg
-#define DEBUG_PBR_FMS_EMS 0 // Output: FmsEms
-#define DEBUG_PBR_DIFFUSE_K 0 // Output: diffuse FssEssLambert + FmsEms
-#define DEBUG_PBR_DIFFUSE_PRE_AO 0 // Output: diffuse pre AO
-#define DEBUG_PBR_DIFFUSE 0 // Output: diffuse post AO
-
-// Atmospheric Lighting
-#define DEBUG_PBR_AMBENV 0 // Output: ambient environment
-#define DEBUG_PBR_AMBOCC 0 // Output: ambient occlusion
-#define DEBUG_PBR_DA_RAW 0 // Output: da pre pow()
-#define DEBUG_PBR_DA_POW 0 // Output: da post pow()
-#define DEBUG_PBR_SUN_LIT 0 // Ouput: sunlit
-#define DEBUG_PBR_SUN_CONTRIB 0 // Output: sun_contrib
-#define DEBUG_PBR_SKY_ADDITIVE 0 // Output: additive
-#define DEBUG_PBR_SKY_ATTEN 0 // Output: greyscale atten.r
-
-// Sun
-#define DEBUG_PBR_SUN_FULL_BRIGHT 0 // Sunlit color = <1,1,1>
-#define DEBUG_PBR_SUN_OUT_DIFFUSE 0 // Final sun diffuse : intensity * nl * diffuse
-#define DEBUG_PBR_SUN_OUT_SPECULAR 0 // Final sun specular: intensity * nl * specular
-#define DEBUG_PBR_SUN_LAMBERT 0 // BRDF Diffuse: Lambertian Diffuse color
-#define DEBUG_PBR_SUN_LAMBERT_NL 0 // BRDF Diffuse: nl * Lambertian Diffuse color
-#define DEBUG_PBR_SUN_H 0 // Half Vector
-#define DEBUG_PBR_SUN_L 0 // Light Vector
-#define DEBUG_PBR_SUN_V 0 // Surface to Light Vector
-#define DEBUG_PBR_SUN_NH 0 // dot(n,h)
-#define DEBUG_PBR_SUN_NL 0 // dot(n,l)
-#define DEBUG_PBR_SUN_NV 0 // dot(n,v)
-#define DEBUG_PBR_SUN_VH 0 // dot(v,h)
-#define DEBUG_PBR_SUN_REFLECT0 0 // reflect0 only
-#define DEBUG_PBR_SUN_SPEC_FRESNEL 0 // Fresnel
-#define DEBUG_PBR_SUN_SPEC_D 0 // D(h)
-#define DEBUG_PBR_SUN_SPEC_V 0 // V(l,v,h)
-#define DEBUG_PBR_SUN_SPEC_DF 0 // D() * F()
-#define DEBUG_PBR_SUN_SPEC_DV 0 // D() * V()
-#define DEBUG_PBR_SUN_SPEC_FV 0 // F() * V()
-#define DEBUG_PBR_SUN_SPEC_DFV 0 // D() * F() * V()
-#define DEBUG_PBR_SUN_SPEC_NL_DFV 0 // nl * D() * F() * V()
-#define DEBUG_PBR_SUN_FINAL 0 // LAMBERT_NL + BRDF()
-
-#define DEBUG_PBR_IOR 0 // Output: grayscale IOR
-#define DEBUG_PBR_REFLECT0_BASE 0 // Output: black reflect0 default from ior
-#define DEBUG_PBR_REFLECT0_MIX 0 // Output: diffuse reflect0 calculated from ior
-#define DEBUG_PBR_REFLECTANCE 0 // Output: diffuse reflectance -- NOT USED
-#define DEBUG_PBR_SPEC_WEIGHT 0 // Output: specWeight
-#define DEBUG_PBR_V2C_REMAP 0 // Output: vertex2camera (remap [-1,1] -> [0,1])
#extension GL_ARB_texture_rectangle : enable
#extension GL_ARB_shader_texture_lod : enable
@@ -169,16 +69,7 @@ uniform vec2 screen_res;
vec3 getNorm(vec2 pos_screen);
vec4 getPositionWithDepth(vec2 pos_screen, float depth);
-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);
-float calcF0(float ior);
-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 getAmbientClamp();
-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 );
vec3 atmosFragLighting(vec3 l, vec3 additive, vec3 atten);
vec3 scaleSoftClipFrag(vec3 l);
vec3 fullbrightAtmosTransportFrag(vec3 light, vec3 additive, vec3 atten);
@@ -193,18 +84,26 @@ void applyLegacyEnv(inout vec3 color, vec3 legacyenv, vec4 spec, vec3 pos, vec3
vec3 linear_to_srgb(vec3 c);
vec3 srgb_to_linear(vec3 c);
-// Debug Utils
-vec3 BRDFDiffuse(vec3 color);
-vec3 colorize_dot(float x);
-vec3 fresnelSchlick( vec3 reflect0, vec3 reflect90, float vh);
-float D_GGX( float nh, float alphaRough );
-float V_GGX( float nl, float nv, float alphaRough );
-
#ifdef WATER_FOG
vec4 applyWaterFogView(vec3 pos, vec4 color);
#endif
-uniform vec3 view_dir; // PBR
+// PBR interface
+vec3 pbrIbl(vec3 diffuseColor,
+ vec3 specularColor,
+ vec3 radiance, // radiance map sample
+ vec3 irradiance, // irradiance map sample
+ float ao, // ambient occlusion factor
+ float nv, // normal dot view vector
+ float perceptualRoughness);
+
+vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor,
+ float perceptualRoughness,
+ float metallic,
+ vec3 n, // normal
+ vec3 v, // surface point to camera
+ vec3 l); //surface point to light
+
void main()
{
@@ -212,14 +111,11 @@ void main()
float depth = texture2DRect(depthMap, tc.xy).r;
vec4 pos = getPositionWithDepth(tc, depth);
vec4 norm = texture2DRect(normalMap, tc);
- float envIntensity = norm.z;
- norm.xyz = getNorm(tc);
-
vec3 light_dir = (sun_up_factor == 1) ? sun_dir : moon_dir;
float light_gamma = 1.0 / 1.3;
vec4 diffuse = texture2DRect(diffuseRect, tc);
- vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy); // NOTE: PBR sRGB Emissive
+ vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy); // NOTE: PBR linear Emissive
#if defined(HAS_SUN_SHADOW) || defined(HAS_SSAO)
vec2 scol_ambocc = texture2DRect(lightMap, vary_fragcoord.xy).rg;
@@ -241,8 +137,6 @@ void main()
calcAtmosphericVars(pos.xyz, light_dir, ambocc, sunlit, amblit, additive, atten, true);
- //vec3 amb_vec = env_mat * norm.xyz;
-
vec3 ambenv;
vec3 glossenv;
vec3 legacyenv;
@@ -250,492 +144,116 @@ void main()
bool hasPBR = GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_PBR);
if (hasPBR)
{
- // 5.22.2. material.pbrMetallicRoughness.baseColorTexture
- // The first three components (RGB) MUST be encoded with the sRGB transfer function.
- //
- // 5.19.7. material.emissiveTexture
- // This texture contains RGB components encoded with the sRGB transfer function.
- //
- // 5.22.5. material.pbrMetallicRoughness.metallicRoughnessTexture
- // These values MUST be encoded with a linear transfer function.
-
- vec3 colorDiffuse = vec3(0);
- vec3 colorEmissive = spec.rgb; // PBR sRGB Emissive. See: pbropaqueF.glsl
- vec3 colorSpec = vec3(0);
-// vec3 colorClearCoat = vec3(0);
-// vec3 colorSheen = vec3(0);
-// vec3 colorTransmission = vec3(0);
-
- vec3 packedORM = texture2DRect(emissiveRect, tc).rgb; // PBR linear packed Occlusion, Roughness, Metal. See: pbropaqueF.glsl
-#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 Refraction 1.5 (dielectrics)
-#if DEBUG_PBR_REFLECT0_BASE
- vec3 debug_reflect0 = vec3(calcF0(IOR));
-#endif
- float ao = packedORM.r;
- float metal = packedORM.b;
- vec3 v = -normalize(pos.xyz);
-#if DEBUG_PBR_VERT2CAM1
- v = vec3(0,0,1);
-#endif
- 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));
-
- vec3 h, l;
- float nh, nl, nv, vh, lightDist;
- calcHalfVectors(light_dir, n, v, h, l, nh, nl, nv, vh, lightDist);
-
- float tv = clamp(dot(t,v),0,1);
- float bv = clamp(dot(b,v),0,1);
-
- // Reference: getMetallicRoughnessInfo
-#if PBR_USE_LINEAR_ALBEDO
- vec3 base = diffuse.rgb;
-#else
- vec3 base = linear_to_srgb(diffuse.rgb);
-#endif
- float perceptualRough = packedORM.g; // NOTE: do NOT clamp here to be consistent with Blender, Blender is wrong and Substance is right
- vec3 c_diff, reflect0, reflect90;
- float alphaRough, specWeight;
- initMaterial( base, packedORM, alphaRough, c_diff, reflect0, reflect90, specWeight );
-#if DEBUG_PBR_REFLECTANCE
- float reflectance = max( max( reflect0.r, reflect0.g ), reflect0.b );
-#endif
+ norm.xyz = getNorm(tc);
+ vec3 orm = texture2DRect(emissiveRect, tc).rgb; //orm is packed into "emissiveRect" to keep the data in linear color space
+ float perceptualRoughness = orm.g;
+ float metallic = orm.b;
+ float ao = orm.r * ambocc;
- // 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 colorEmissive = texture2DRect(specularRect, tc).rgb; //specularRect is sRGB sampler, result is in linear space
- // Reference: getIBLRadianceGGX
- // https://forum.substance3d.com/index.php?topic=3243.0
- // Glossiness
- // This map is the inverse of the roughness map.
+ // PBR IBL
+ float gloss = 1.0 - perceptualRoughness;
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 DEBUG_PBR_IRRADIANCE_RAW
- vec3 debug_irradiance = irradiance;
-#endif
+ vec3 radiance = vec3(0);
+ sampleReflectionProbes(irradiance, radiance, legacyenv, pos.xyz, norm.xyz, gloss, 0.0);
+ irradiance = max(srgb_to_linear(amblit),irradiance) * ambocc*4.0;
-#if PBR_USE_DEFAULT_IRRADIANCE
- vec2 iruv = vec2(0.5f + 0.5f * atan(reflectVN.z, reflectVN.x) / M_PI, 1.f - acos(reflectVN.y) / M_PI);
- irradiance = texture2D(altDiffuseMap, iruv).rgb * ambocc;
-#endif
-#if PBR_USE_IRRADIANCE_HACK
- irradiance = max(amblit,irradiance) * ambocc;
-#endif
-#if DEBUG_PBR_SPECLIGHT051
- specLight = vec3(0,0.5,1.0);
- irradiance = specLight;
-#endif
- vec3 FssEssGGX = kSpec*vScaleBias.x + vScaleBias.y;
-#if DEBUG_PBR_SPEC_IBL
- vec3 debug_color_spec = specWeight * specLight * FssEssGGX;
-#endif
-#if PBR_USE_IBL
- colorSpec += specWeight * specLight * FssEssGGX;
-#endif
+ vec3 f0 = vec3(0.04);
+ vec3 baseColor = diffuse.rgb;
+
+ //baseColor.rgb = vec3(0,0,0);
+ //colorEmissive = srgb_to_linear(norm.xyz*0.5+0.5);
- // Reference: getIBLRadianceLambertian
- 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
- #if DEBUG_PBR_DIFFUSE_PRE_AO
- vec3 debug_diffuse = colorDiffuse;
- #endif
- colorDiffuse *= ao; // Occlusion -- NOTE: pbropaque will need occlusion_strength pre-multiplied into spec.r
- colorSpec *= ao;
+ vec3 diffuseColor = baseColor.rgb*(vec3(1.0)-f0);
+ diffuseColor *= 1.0 - metallic;
- // Add in sun/moon reflection
- if (nl > 0.0 || nv > 0.0)
- {
- float scale = 4.9;
- vec3 sunColor = srgb_to_linear(sunlit * scale); // NOTE: Midday should have strong sunlight
-#if DEBUG_PBR_SUN_FULL_BRIGHT
- sunColor = vec3(1);
-#endif
- // scol = sun shadow
- vec3 intensity = ambocc * sunColor * nl * scol;
-#if PBR_USE_LINEAR_ALBEDO
- vec3 sunDiffuse = intensity * BRDFLambertian (reflect0, reflect90, c_diff , specWeight, vh);
- vec3 sunSpec = intensity * BRDFSpecularGGX(reflect0, reflect90, alphaRough, specWeight, vh, nl, nv, nh);
-#else
- vec3 sunDiffuse = base * intensity * BRDFLambertian (reflect0, reflect90, c_diff , specWeight, vh);
- vec3 sunSpec = intensity * BRDFSpecularGGX(reflect0, reflect90, alphaRough, specWeight, vh, nl, nv, nh);
-#endif
- // Disabling PBR bloom due to two reasons:
- // 1. The glTF 2.0 Specification does not specify bloom,
- // 2. As the camera moves there are lots of bloom shimmering.
- //bloom = dot(sunSpec, sunSpec) / (scale * scale * scale);
-
- #if DEBUG_PBR_SUN_SPEC_FRESNEL
- colorDiffuse = vec3(0);
- colorSpec = fresnelSchlick( reflect0, reflect90, vh );
- bloom = 0;
- #endif
- #if DEBUG_PBR_SUN_SPEC_D
- colorDiffuse = vec3(0);
- colorSpec = vec3(D_GGX( nh, alphaRough ));
- bloom = 0;
- #endif
- #if DEBUG_PBR_SUN_SPEC_V
- colorDiffuse = vec3(0);
- colorSpec = vec3(V_GGX( nl, nv, alphaRough ));
- bloom = 0;
- #endif
- #if DEBUG_PBR_SUN_SPEC_DF
- colorDiffuse = vec3(0);
- colorSpec = fresnelSchlick( reflect0, reflect90, vh );
- colorSpec *= D_GGX( nh, alphaRough );
- bloom = 0;
- #endif
- #if DEBUG_PBR_SUN_SPEC_DV
- colorDiffuse = vec3(0);
- colorSpec = vec3(D_GGX( nh, alphaRough ));
- colorSpec *= vec3(V_GGX( nl, nv, alphaRough ));
- bloom = 0;
- #endif
- #if DEBUG_PBR_SUN_SPEC_FV
- colorDiffuse = vec3(0);
- colorSpec = fresnelSchlick( reflect0, reflect90, vh );
- colorSpec *= V_GGX( nl, nv, alphaRough );
- bloom = 0;
- #endif
- #if DEBUG_PBR_SUN_SPEC_DFV
- colorDiffuse = vec3(0);
- colorSpec = fresnelSchlick( reflect0, reflect90, vh );
- colorSpec *= D_GGX( nh, alphaRough );
- colorSpec *= V_GGX( nl, nv, alphaRough );
- bloom = 0;
- #endif
- #if DEBUG_PBR_SUN_SPEC_NL_DFV
- colorDiffuse = vec3(0);
- colorSpec = nl * BRDFSpecularGGX(reflect0, reflect90, alphaRough, specWeight, vh, nl, nv, nh);
- #endif
- #if DEBUG_PBR_SUN_FINAL
- colorDiffuse = nl * BRDFLambertian (reflect0, reflect90, c_diff , specWeight, vh);
- colorSpec = nl * BRDFSpecularGGX(reflect0, reflect90, alphaRough, specWeight, vh, nl, nv, nh);
- #endif
-
- #if DEBUG_PBR_SUN_OUT_DIFFUSE
- colorDiffuse = linear_to_srgb(sunDiffuse);
- colorSpec = vec3(0);
- bloom = 0.0;
- #endif
- #if DEBUG_PBR_SUN_OUT_SPECULAR
- colorDiffuse = linear_to_srgb(sunSpec);
- colorSpec = vec3(0);
- #endif
- #if DEBUG_PBR_SUN_REFLECT0
- colorDiffuse = reflect0;
- colorSpec = vec3(0);
- #endif
-
-#if PBR_USE_SUN
- colorDiffuse += sunDiffuse;
- colorSpec += sunSpec;
-#endif
- }
+ vec3 specularColor = mix(f0, baseColor.rgb, metallic);
-#if DEBUG_PBR_SUN_LAMBERT
- colorDiffuse = BRDFLambertian (reflect0, reflect90, c_diff , specWeight, vh);
- colorSpec = vec3(0);
- bloom = 0;
-#endif
-#if DEBUG_PBR_SUN_LAMBERT_NL
- colorDiffuse = nl * BRDFLambertian (reflect0, reflect90, c_diff , specWeight, vh);
- colorSpec = vec3(0);
- bloom = 0;
-#endif
+ vec3 v = -normalize(pos.xyz);
+ float NdotV = clamp(abs(dot(norm.xyz, v)), 0.001, 1.0);
+
+ color.rgb += pbrIbl(diffuseColor, specularColor, radiance, irradiance, ao, NdotV, perceptualRoughness);
+ color.rgb += pbrPunctual(diffuseColor, specularColor, perceptualRoughness, metallic, norm.xyz, v, normalize(light_dir)) * sunlit*8.0 * scol;
+ color.rgb += colorEmissive;
- #if DEBUG_PBR_SUN_H
- colorDiffuse = h*0.5 + 0.5; colorSpec = vec3(0);
- #endif
- #if DEBUG_PBR_SUN_L
- colorDiffuse = l*0.5 + 0.5; colorSpec = vec3(0);
- #endif
- #if DEBUG_PBR_SUN_V
- colorDiffuse = v*0.5 + 0.5; colorSpec = vec3(0);
- #endif
- #if DEBUG_PBR_SUN_NH
- colorDiffuse = colorize_dot(nh); colorSpec = vec3(0);
- #endif
- #if DEBUG_PBR_SUN_NL
- colorDiffuse = colorize_dot(nl); colorSpec = vec3(0);
- #endif
- #if DEBUG_PBR_SUN_NV
- colorDiffuse = colorize_dot(nv); colorSpec = vec3(0);
- #endif
- #if DEBUG_PBR_SUN_VH
- colorDiffuse = colorize_dot(vh); colorSpec = vec3(0);
- #endif
-
- color.rgb = colorDiffuse + colorEmissive + colorSpec;
-
-#if PBR_USE_ATMOS
color = linear_to_srgb(color);
color *= atten.r;
color += 2.0*additive;
color = scaleSoftClipFrag(color);
color = srgb_to_linear(color);
-#endif // PBR_USE_ATMOS
- #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_NORMAL_MAP
- color.rgb = diffuse.rgb;
- #endif
- #if DEBUG_PBR_OCCLUSION
- color.rgb = vec3(ao);
- #endif
- #if DEBUG_PBR_ORM
- color.rgb = packedORM;
- #endif
- #if DEBUG_PBR_ROUGH_PERCEPTUAL
- color.rgb = vec3(perceptualRough);
- #endif
- #if DEBUG_PBR_ROUGH_ALPHA
- color.rgb = vec3(alphaRough);
- #endif
- #if DEBUG_PBR_NORMAL
- color.rgb = norm.xyz*0.5 + vec3(0.5);
- color.rgb = srgb_to_linear(color.rgb);
- #endif
- #if DEBUG_PBR_TANGENT
- color.rgb = t;
- #endif
- #if DEBUG_PBR_BITANGENT
- color.rgb = b;
- #endif
- #if DEBUG_PBR_DOT_NV
- color.rgb = vec3(nv);
- #endif
- #if DEBUG_PBR_DOT_TV
- color.rgb = vec3(tv);
- #endif
- #if DEBUG_PBR_DOT_BV
- color.rgb = vec3(bv);
- #endif
+ frag_color.rgb = color.rgb; //output linear since local lights will be added to this shader's results
+ }
+ else
+ {
+ float envIntensity = norm.z;
+ norm.xyz = getNorm(tc);
- #if DEBUG_PBR_AVG
- color.rgb = avg;
- #endif
- #if DEBUG_PBR_BRDF_UV
- color.rgb = vec3(brdfPoint,0.0);
- color.rgb = linear_to_srgb(color.rgb);
- #endif
- #if DEBUG_PBR_BRDF_SCALE_BIAS
- color.rgb = vec3(vScaleBias,0.0);
- #endif
- #if DEBUG_PBR_DIFFUSE_C
- color.rgb = c_diff;
- #endif
- #if DEBUG_PBR_BRDF_SCALE_ONLY
- color.rgb = vec3(vScaleBias.x);
- #endif
- #if DEBUG_PBR_BRDF_BIAS_ONLY
- color.rgb = vec3(vScaleBias.y);
- #endif
- #if DEBUG_PBR_DIFFUSE_K
- color.rgb = kDiffuse;
- #endif
- #if DEBUG_PBR_DIFFUSE_MAP
- color.rgb = diffuse.rgb;
- #endif
- #if DEBUG_PBR_DIFFUSE_PRE_AO
- color.rgb = debug_diffuse;
- #endif
- #if DEBUG_PBR_EMS
- color.rgb = vec3(Ems);
- #endif
- #if DEBUG_PBR_EMS_AVG
- color.rgb = AvgEms;
- #endif
- #if DEBUG_PBR_FMS_EMS
- color.rgb = FmsEms;
- #endif
- #if DEBUG_PBR_FSS_ESS_GGX
- color.rgb = FssEssGGX; // spec
- #endif
- #if DEBUG_PBR_FSS_ESS_LAMBERT
- color.rgb = FssEssLambert; // diffuse
- #endif
- #if DEBUG_PBR_FRESNEL
- color.rgb = fresnelR;
- #endif
- #if DEBUG_PBR_IOR
- color.rgb = vec3(IOR);
- #endif
- #if DEBUG_PBR_IRRADIANCE_RAW
- color.rgb = debug_irradiance;
- bloom = 0;
- #endif
- #if DEBUG_PBR_IRRADIANCE
- color.rgb = irradiance;
- bloom = 0;
- #endif
- #if DEBUG_PBR_KSPEC
- color.rgb = kSpec;
- #endif
- #if DEBUG_PBR_REFLECT0_BASE
- color.rgb = vec3(debug_reflect0);
- #endif
- #if DEBUG_PBR_REFLECT0_MIX
- color.rgb = vec3(reflect0);
- #endif
- #if DEBUG_PBR_REFLECTANCE
- color.rgb = vec3(reflectance);
- #endif
- #if DEBUG_PBR_REFLECTION_DIR
- color.rgb = reflect(-v, n); // NOTE: equivalent to normalize(reflect(pos.xyz, norm.xyz));
- #endif
- #if DEBUG_PBR_SPEC
- color.rgb = colorSpec;
- #endif
- #if DEBUG_PBR_SPEC_REFLECTION
- color.rgb = specLight;
- #endif
- #if DEBUG_PBR_SPEC_WEIGHT
- color.rgb = vec3(specWeight);
- #endif
- #if DEBUG_PBR_V2C_RAW
- color.rgb = v;
- #endif
- #if DEBUG_PBR_V2C_REMAP
- color.rgb = v*0.5 + vec3(0.5);
- #endif
+ float da = clamp(dot(norm.xyz, light_dir.xyz), 0.0, 1.0);
+ da = pow(da, light_gamma);
- #if DEBUG_PBR_DA_RAW
- color.rgb = vec3(debug_da);
- #endif
- #if DEBUG_PBR_DA_POW
- color.rgb = vec3(da);
- #endif
- #if DEBUG_PBR_SKY_ADDITIVE
- color.rgb = additive;
- #endif
- #if DEBUG_PBR_SKY_ATTEN
- color.rgb = vec3(atten.r);
- #endif
- #if DEBUG_PBR_SUN_LIT
- color.rgb = sunlit;
- #endif
- #if DEBUG_PBR_SUN_CONTRIB
- color.rgb = sun_contrib;
- #endif
- #if DEBUG_PBR_LIGHT_TYPE
- color.rgb = vec3(0);
- #endif
+ diffuse.rgb = linear_to_srgb(diffuse.rgb); // SL-14035
- frag_color.rgb = color.rgb; // PBR is done in linear
- }
-else
-{
- float da = clamp(dot(norm.xyz, light_dir.xyz), 0.0, 1.0);
-#if DEBUG_PBR_DA_RAW
- float debug_da = da;
-#endif
- da = pow(da, light_gamma);
+ sampleReflectionProbes(ambenv, glossenv, legacyenv, pos.xyz, norm.xyz, spec.a, envIntensity);
+ ambenv.rgb = linear_to_srgb(ambenv.rgb);
+ glossenv.rgb = linear_to_srgb(glossenv.rgb);
+ legacyenv.rgb = linear_to_srgb(legacyenv.rgb);
- diffuse.rgb = linear_to_srgb(diffuse.rgb); // SL-14035
+ amblit = max(ambenv, amblit);
+ color.rgb = amblit*ambocc;
- sampleReflectionProbes(ambenv, glossenv, legacyenv, pos.xyz, norm.xyz, spec.a, envIntensity);
- ambenv.rgb = linear_to_srgb(ambenv.rgb);
- glossenv.rgb = linear_to_srgb(glossenv.rgb);
- legacyenv.rgb = linear_to_srgb(legacyenv.rgb);
+ vec3 sun_contrib = min(da, scol) * sunlit;
+ color.rgb += sun_contrib;
+ color.rgb = min(color.rgb, vec3(1,1,1));
+ color.rgb *= diffuse.rgb;
- amblit = max(ambenv, amblit);
- color.rgb = amblit*ambocc;
+ vec3 refnormpersp = reflect(pos.xyz, norm.xyz);
- //float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0);
- //ambient *= 0.5;
- //ambient *= ambient;
- //ambient = (1.0 - ambient);
- //color.rgb *= ambient;
+ if (spec.a > 0.0) // specular reflection
+ {
+ float sa = dot(normalize(refnormpersp), light_dir.xyz);
+ vec3 dumbshiny = sunlit * scol * (texture2D(lightFunc, vec2(sa, spec.a)).r);
- vec3 sun_contrib = min(da, scol) * sunlit;
- color.rgb += sun_contrib;
- color.rgb = min(color.rgb, vec3(1,1,1));
- color.rgb *= diffuse.rgb;
+ // add the two types of shiny together
+ vec3 spec_contrib = dumbshiny * spec.rgb;
+ bloom = dot(spec_contrib, spec_contrib) / 6;
+ color.rgb += spec_contrib;
- vec3 refnormpersp = reflect(pos.xyz, norm.xyz);
+ // add reflection map - EXPERIMENTAL WORK IN PROGRESS
+ applyGlossEnv(color, glossenv, spec, pos.xyz, norm.xyz);
+ }
- if (spec.a > 0.0) // specular reflection
- {
- float sa = dot(normalize(refnormpersp), light_dir.xyz);
- vec3 dumbshiny = sunlit * scol * (texture2D(lightFunc, vec2(sa, spec.a)).r);
+ color.rgb = mix(color.rgb, diffuse.rgb, diffuse.a);
- // add the two types of shiny together
- vec3 spec_contrib = dumbshiny * spec.rgb;
- bloom = dot(spec_contrib, spec_contrib) / 6;
- color.rgb += spec_contrib;
+ if (envIntensity > 0.0)
+ { // add environmentmap
+ //fudge darker
+ legacyenv *= 0.5*diffuse.a+0.5;
+ applyLegacyEnv(color, legacyenv, spec, pos.xyz, norm.xyz, envIntensity);
+ }
- // add reflection map - EXPERIMENTAL WORK IN PROGRESS
- applyGlossEnv(color, glossenv, spec, pos.xyz, norm.xyz);
- }
+ if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_ATMOS))
+ {
+ color = mix(atmosFragLighting(color, additive, atten), fullbrightAtmosTransportFrag(color, additive, atten), diffuse.a);
+ color = mix(scaleSoftClipFrag(color), fullbrightScaleSoftClip(color), diffuse.a);
+ }
- color.rgb = mix(color.rgb, diffuse.rgb, diffuse.a);
+ #ifdef WATER_FOG
+ vec4 fogged = applyWaterFogView(pos.xyz, vec4(color, bloom));
+ color = fogged.rgb;
+ bloom = fogged.a;
+ #endif
- if (envIntensity > 0.0)
- { // add environmentmap
- //fudge darker
- legacyenv *= 0.5*diffuse.a+0.5;
- applyLegacyEnv(color, legacyenv, spec, pos.xyz, norm.xyz, envIntensity);
+ // convert to linear as fullscreen lights need to sum in linear colorspace
+ // and will be gamma (re)corrected downstream...
+ //color = ambenv;
+ //color.b = diffuse.a;
+ frag_color.rgb = srgb_to_linear(color.rgb);
}
- if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_ATMOS))
- {
- color = mix(atmosFragLighting(color, additive, atten), fullbrightAtmosTransportFrag(color, additive, atten), diffuse.a);
- color = mix(scaleSoftClipFrag(color), fullbrightScaleSoftClip(color), diffuse.a);
- }
-#ifdef WATER_FOG
- vec4 fogged = applyWaterFogView(pos.xyz, vec4(color, bloom));
- color = fogged.rgb;
- bloom = fogged.a;
-#endif
- #if DEBUG_PBR_LIGHT_TYPE
- color.rgb = vec3(0);
- #endif
- // convert to linear as fullscreen lights need to sum in linear colorspace
- // and will be gamma (re)corrected downstream...
- //color = ambenv;
- //color.b = diffuse.a;
- frag_color.rgb = srgb_to_linear(color.rgb);
-}
-#if DEBUG_PBR_AMBOCC
- frag_color.rgb = vec3(ambocc);
-#endif
-#if DEBUG_PBR_AMBENV
- frag_color.rgb = ambenv;
-#endif
frag_color.a = bloom;
}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl
index f23e9db040..c8d45eb429 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl
@@ -82,18 +82,14 @@ uniform vec2 screen_res;
uniform mat4 inv_proj;
-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 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);
bool clipProjectedLightVars(vec3 center, vec3 pos, out float dist, out float l_dist, out vec3 lv, out vec4 proj_tc );
-vec3 getLightIntensitySpot(vec3 lightColor, float lightRange, float lightDistance, vec3 v);
vec4 getNormalEnvIntensityFlags(vec2 screenpos, out vec3 n, out float envIntensity);
vec3 getProjectedLightAmbiance(float amb_da, float attenuation, float lit, float nl, float noise, vec2 projected_uv);
vec3 getProjectedLightDiffuseColor(float light_distance, vec2 projected_uv );
vec3 getProjectedLightSpecularColor(vec3 pos, vec3 n);
vec2 getScreenXY(vec4 clip_point);
-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);
vec4 texture2DLodSpecular(vec2 tc, float lod);
@@ -101,6 +97,13 @@ vec4 getPosition(vec2 pos_screen);
const float M_PI = 3.14159265;
+vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor,
+ float perceptualRoughness,
+ float metallic,
+ vec3 n, // normal
+ vec3 v, // surface point to camera
+ vec3 l); //surface point to light
+
void main()
{
#if defined(LOCAL_LIGHT_KILL)
@@ -148,13 +151,20 @@ void main()
vec3 dlit = vec3(0, 0, 0);
vec3 slit = vec3(0, 0, 0);
+ vec3 amb_rgb = vec3(0);
if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_PBR))
{
- vec3 colorDiffuse = vec3(0);
- vec3 colorSpec = vec3(0);
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
- float metal = packedORM.b;
+ vec3 orm = texture2DRect(emissiveRect, tc).rgb; //orm is packed into "emissiveRect" to keep the data in linear color space
+ float perceptualRoughness = orm.g;
+ float metallic = orm.b;
+ vec3 f0 = vec3(0.04);
+ vec3 baseColor = diffuse.rgb;
+
+ vec3 diffuseColor = baseColor.rgb*(vec3(1.0)-f0);
+ diffuseColor *= 1.0 - metallic;
+
+ vec3 specularColor = mix(f0, baseColor.rgb, metallic);
// We need this additional test inside a light's frustum since a spotlight's ambiance can be applied
if (proj_tc.x > 0.0 && proj_tc.x < 1.0
@@ -166,46 +176,16 @@ void main()
if (nl > 0.0)
{
amb_da += (nl*0.5 + 0.5) * proj_ambiance;
- lit = nl * dist_atten;
-
- vec3 c_diff, reflect0, reflect90;
- float alphaRough, specWeight;
- initMaterial( diffuse, packedORM, alphaRough, c_diff, reflect0, reflect90, specWeight );
-
+
dlit = getProjectedLightDiffuseColor( l_dist, proj_tc.xy );
- slit = getProjectedLightSpecularColor( pos, n );
- float exposure = M_PI;
- dlit *= exposure;
- slit *= exposure;
-
- colorDiffuse = shadow * lit * dlit * BRDFLambertian ( reflect0, reflect90, c_diff , specWeight, vh );
- colorSpec = shadow * lit * slit * BRDFSpecularGGX( reflect0, reflect90, alphaRough, specWeight, vh, nl, nv, nh );
- colorSpec += shadow * lit * BRDFSpecularGGX( reflect0, reflect90, alphaRough, specWeight, vh, nl, nv, nh );
-
- #if DEBUG_PBR_SPOT_DIFFUSE
- colorDiffuse = dlit.rgb; colorSpec = vec3(0);
- #endif
- #if DEBUG_PBR_SPOT_SPECULAR
- colorDiffuse = vec3(0); colorSpec = slit.rgb;
- #endif
- #if DEBUG_PBR_SPOT
- colorDiffuse = dlit; colorSpec = vec3(0);
- colorDiffuse *= nl;
- colorDiffuse *= shadow;
- #endif
+ vec3 intensity = dist_atten * dlit * 3.0 * shadow; // Legacy attenuation
+ final_color += intensity*pbrPunctual(diffuseColor, specularColor, perceptualRoughness, metallic, n.xyz, v, normalize(lv));
}
- vec3 amb_rgb = getProjectedLightAmbiance( amb_da, dist_atten, lit, nl, 1.0, proj_tc.xy );
- colorDiffuse += diffuse.rgb * amb_rgb;
-
+ amb_rgb = getProjectedLightAmbiance( amb_da, dist_atten, lit, nl, 1.0, proj_tc.xy );
+ final_color += diffuse.rgb * amb_rgb;
}
-
- #if DEBUG_PBR_LIGHT_TYPE
- colorDiffuse = vec3(0.5,0,0); colorSpec = vec3(0.0);
- #endif
-
- final_color = colorDiffuse + colorSpec;
}
else
{