summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorDave Parks <davep@lindenlab.com>2022-09-17 01:12:52 -0500
committerDave Parks <davep@lindenlab.com>2022-09-17 01:12:52 -0500
commitb2cf07f53ca9f0ab82d466063af8307631c50f31 (patch)
treeb0d9d4709ca926cbb49b53f4483bdf6b5bad62ff /indra
parentdc1ed195119d9ccc2b21111ea16663ffce4942c8 (diff)
WIP - switch PBR implementations
Diffstat (limited to 'indra')
-rw-r--r--indra/llrender/llshadermgr.cpp1
-rw-r--r--indra/llrender/llshadermgr.h1
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl268
-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/pbralphaF.glsl6
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/multiPointLightF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl167
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl97
-rw-r--r--indra/newview/llmaterialeditor.cpp4
-rw-r--r--indra/newview/llviewershadermgr.cpp14
-rw-r--r--indra/newview/llviewershadermgr.h1
-rw-r--r--indra/newview/pipeline.cpp27
-rw-r--r--indra/newview/pipeline.h1
16 files changed, 510 insertions, 265 deletions
diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp
index 2ea1c0d698..b609a74e32 100644
--- a/indra/llrender/llshadermgr.cpp
+++ b/indra/llrender/llshadermgr.cpp
@@ -1324,6 +1324,7 @@ void LLShaderMgr::initAttribsAndUniforms()
mReservedUniforms.push_back("diffuseRect");
mReservedUniforms.push_back("specularRect");
mReservedUniforms.push_back("emissiveRect");
+ mReservedUniforms.push_back("brdfLut");
mReservedUniforms.push_back("noiseMap");
mReservedUniforms.push_back("lightFunc");
mReservedUniforms.push_back("lightMap");
diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h
index 249eeace31..aa002014a7 100644
--- a/indra/llrender/llshadermgr.h
+++ b/indra/llrender/llshadermgr.h
@@ -177,6 +177,7 @@ public:
DEFERRED_DIFFUSE, // "diffuseRect"
DEFERRED_SPECULAR, // "specularRect"
DEFERRED_EMISSIVE, // "emissiveRect"
+ DEFERRED_BRDF_LUT, // "brdfLut"
DEFERRED_NOISE, // "noiseMap"
DEFERRED_LIGHTFUNC, // "lightFunc"
DEFERRED_LIGHT, // "lightMap"
diff --git a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl
index 652e609718..52345e7e51 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl
@@ -23,9 +23,38 @@
* $/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
@@ -482,38 +511,227 @@ vec3 BRDFSpecularGGX( vec3 reflect0, vec3 reflect90, float alphaRough, float spe
return fresnel * vis * d;
}
+// 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 * M_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;
+}
+
+#define NUM_SAMPLES 16
+
+vec2 BRDF(float NoV, float roughness)
+{
+#if 0
+ // 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);
+#else
+ return texture(brdfLut, vec2(NoV, roughness)).rg;
+#endif
+}
+
// set colorDiffuse and colorSpec to the results of GLTF PBR style IBL
-void pbrIbl(out vec3 colorDiffuse, // diffuse color output
- out vec3 colorSpec, // specular color output,
+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, // roughness factor
- float gloss, // 1.0 - roughness factor
- vec3 reflect0, // see also: initMaterial
- vec3 c_diff)
+ float perceptualRough)
{
- // 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(gloss), reflect0) - reflect0; // roughness dependent fresnel
- vec3 kSpec = reflect0 + fresnelR*pow(1.0 - nv, 5.0);
-
- vec3 FssEssGGX = kSpec*vScaleBias.x + vScaleBias.y;
- colorSpec = radiance * FssEssGGX;
+ // 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;
- // Reference: getIBLRadianceLambertian fs
- vec3 FssEssLambert = 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 = (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);
- colorDiffuse = (FmsEms + kDiffuse) * irradiance;
+ vec3 diffuse = diffuseLight * diffuseColor;
+ vec3 specular = specularLight * (specularColor * brdf.x + brdf.y);
+
+
+ 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
+{
+ 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);
- colorDiffuse *= ao;
- colorSpec *= ao;
+ return color;
}
void pbrDirectionalLight(inout vec3 colorDiffuse,
@@ -529,7 +747,7 @@ void pbrDirectionalLight(inout vec3 colorDiffuse,
float nv,
float nh)
{
- float scale = 16.0;
+ float scale = 32.0;
vec3 sunColor = sunlit * scale;
// scol = sun shadow
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..f3896191fa
--- /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);
+} \ No newline at end of file
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/pbralphaF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbralphaF.glsl
index 9d3339f607..ae542f5a1d 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/pbralphaF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/pbralphaF.glsl
@@ -120,7 +120,7 @@ void pbrDirectionalLight(inout vec3 colorDiffuse,
float nv,
float nh);
-void pbrIbl(out vec3 colorDiffuse, // diffuse color output
+/*void pbrIbl(out vec3 colorDiffuse, // diffuse color output
out vec3 colorSpec, // specular color output,
vec3 radiance, // radiance map sample
vec3 irradiance, // irradiance map sample
@@ -129,7 +129,7 @@ void pbrIbl(out vec3 colorDiffuse, // diffuse color output
float perceptualRough, // roughness factor
float gloss, // 1.0 - roughness factor
vec3 reflect0,
- vec3 c_diff);
+ vec3 c_diff);*/
// lp = light position
// la = linear attenuation, light radius
@@ -255,7 +255,7 @@ void main()
sampleReflectionProbes(irradiance, radiance, legacyenv, pos.xyz, norm.xyz, gloss, 0.0);
irradiance = max(amblit,irradiance) * ambocc;
- pbrIbl(colorDiffuse, colorSpec, radiance, irradiance, ao, nv, perceptualRough, gloss, reflect0, c_diff);
+ //pbrIbl(colorDiffuse, colorSpec, radiance, irradiance, ao, nv, perceptualRough, gloss, reflect0, c_diff);
// Sun/Moon Lighting
if (nl > 0.0 || nv > 0.0)
diff --git a/indra/newview/app_settings/shaders/class3/deferred/multiPointLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/multiPointLightF.glsl
index d8175aa260..3b57821758 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/multiPointLightF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/multiPointLightF.glsl
@@ -112,7 +112,7 @@ void main()
if (dist <= 1.0 && nl > 0.0)
{
float dist_atten = calcLegacyDistanceAttenuation(dist, falloff);
- vec3 intensity = dist_atten * nl * lightColor;
+ vec3 intensity = dist_atten * nl * lightColor * 2.0;
colorDiffuse += intensity * BRDFLambertian (reflect0, reflect90, c_diff , specWeight, vh);
colorSpec += intensity * BRDFSpecularGGX(reflect0, reflect90, alphaRough, specWeight, vh, nl, nv, nh);
}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl
index bc4b4eb7e1..cabc175da9 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
@@ -211,93 +177,13 @@ void main()
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
}
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
}
- #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 +212,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 +259,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 509f9f6dd0..0472f08852 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl
@@ -109,7 +109,7 @@ void main()
if (nl > 0.0)
{
- vec3 intensity = dist_atten * nl * lightColor; // Legacy attenuation
+ vec3 intensity = dist_atten * nl * lightColor * 2.0; // Legacy attenuation
colorDiffuse += intensity * BRDFLambertian (reflect0, reflect90, c_diff , specWeight, vh);
colorSpec += intensity * BRDFSpecularGGX(reflect0, reflect90, alphaRough, specWeight, vh, nl, nv, nh);
}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl
index 3ff039261b..37fe5f53a2 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl
@@ -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 1a7e11a1cd..6dd140bff3 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
@@ -89,34 +89,21 @@ vec4 applyWaterFogView(vec3 pos, vec4 color);
#endif
// PBR interface
-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);
-void initMaterial( vec3 diffuse, vec3 packedORM,
- out float alphaRough, out vec3 c_diff, out vec3 reflect0, out vec3 reflect90, out float specWeight );
-// perform PBR image based lighting according to GLTF spec
-// all parameters are in linear space
-void pbrIbl(out vec3 colorDiffuse, // diffuse color output
- out vec3 colorSpec, // specular color output,
+vec3 pbrIbl(vec3 diffuseColor,
+ vec3 specularColor,
vec3 radiance, // radiance map sample
vec3 irradiance, // irradiance map sample
float ao, // ambient occlusion factor
- float nv,
- float perceptualRough, // roughness factor
- float gloss, // 1.0 - roughness factor
- vec3 reflect0,
- vec3 c_diff);
-
-void pbrDirectionalLight(inout vec3 colorDiffuse,
- inout vec3 colorSpec,
- vec3 sunlit,
- float scol,
- vec3 reflect0,
- vec3 reflect90,
- vec3 c_diff,
- float alphaRough,
- float vh,
- float nl,
- float nv,
- float nh);
+ 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()
{
@@ -160,51 +147,34 @@ 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 packedORM = texture2DRect(emissiveRect, tc).rgb; // PBR linear packed Occlusion, Roughness, Metal. See: pbropaqueF.glsl
- float IOR = 1.5; // default Index Of Refraction 1.5 (dielectrics)
- float ao = packedORM.r;
- float metal = packedORM.b;
- vec3 v = -normalize(pos.xyz);
- vec3 n = norm.xyz;
-
- vec3 h, l;
- float nh, nl, nv, vh, lightDist;
- calcHalfVectors(light_dir, n, v, h, l, nh, nl, nv, vh, lightDist);
-
- 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( diffuse.rgb, packedORM, alphaRough, c_diff, reflect0, reflect90, specWeight );
+ 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;
- float gloss = 1.0 - perceptualRough;
+ vec3 colorEmissive = texture2DRect(specularRect, tc).rgb; //specularRect is sRGB sampler, result is in linear space
+
+ // PBR IBL
+ float gloss = 1.0 - perceptualRoughness;
vec3 irradiance = vec3(0);
vec3 radiance = vec3(0);
sampleReflectionProbes(irradiance, radiance, legacyenv, pos.xyz, norm.xyz, gloss, 0.0);
- irradiance = max(amblit,irradiance) * ambocc;
+ irradiance = max(srgb_to_linear(amblit),irradiance) * ambocc*4.0;
- pbrIbl(colorDiffuse, colorSpec, radiance, irradiance, ao, nv, perceptualRough, gloss, reflect0, c_diff);
+ vec3 f0 = vec3(0.04);
+ vec3 baseColor = diffuse.rgb;
- // Add in sun/moon punctual light
- if (nl > 0.0 || nv > 0.0)
- {
- pbrDirectionalLight(colorDiffuse, colorSpec, srgb_to_linear(sunlit), scol, reflect0, reflect90, c_diff, alphaRough, vh, nl, nv, nh);
- }
+ vec3 diffuseColor = baseColor.rgb*(vec3(1.0)-f0);
+ diffuseColor *= 1.0 - metallic;
+
+ vec3 specularColor = mix(f0, baseColor.rgb, metallic);
- color.rgb = colorDiffuse + colorEmissive + colorSpec;
+ 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;
color = linear_to_srgb(color);
color *= atten.r;
@@ -212,6 +182,7 @@ void main()
color = scaleSoftClipFrag(color);
color = srgb_to_linear(color);
+
frag_color.rgb = color.rgb; //output linear since local lights will be added to this shader's results
}
else
diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp
index b4e5e14885..bdc66a85fc 100644
--- a/indra/newview/llmaterialeditor.cpp
+++ b/indra/newview/llmaterialeditor.cpp
@@ -204,14 +204,14 @@ void LLMaterialEditor::setAlbedoUploadId(const LLUUID& id)
LLColor4 LLMaterialEditor::getAlbedoColor()
{
- LLColor4 ret = LLColor4(childGetValue("albedo color"));
+ LLColor4 ret = linearColor4(LLColor4(childGetValue("albedo color")));
ret.mV[3] = getTransparency();
return ret;
}
void LLMaterialEditor::setAlbedoColor(const LLColor4& color)
{
- childSetValue("albedo color", color.getValue());
+ childSetValue("albedo color", srgbColor4(color).getValue());
setTransparency(color.mV[3]);
}
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index 296a383ed0..63d9a03aba 100644
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -252,6 +252,7 @@ LLGLSLShader gDeferredSkinnedFullbrightShinyProgram;
LLGLSLShader gDeferredSkinnedFullbrightProgram;
LLGLSLShader gDeferredSkinnedFullbrightAlphaMaskProgram;
LLGLSLShader gNormalMapGenProgram;
+LLGLSLShader gDeferredGenBrdfLutProgram;
// Deferred materials shaders
LLGLSLShader gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2];
@@ -1244,6 +1245,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredHighlightSpecularProgram.unload();
gNormalMapGenProgram.unload();
+ gDeferredGenBrdfLutProgram.unload();
+
for (U32 i = 0; i < LLMaterial::SHADER_COUNT*2; ++i)
{
gDeferredMaterialProgram[i].unload();
@@ -2855,6 +2858,17 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
success = gNormalMapGenProgram.createShader(NULL, NULL);
}
+ if (success && gGLManager.mHasCubeMapArray)
+ {
+ gDeferredGenBrdfLutProgram.mName = "Brdf Gen Shader";
+ gDeferredGenBrdfLutProgram.mShaderFiles.clear();
+ gDeferredGenBrdfLutProgram.mShaderFiles.push_back(make_pair("deferred/genbrdflutV.glsl", GL_VERTEX_SHADER));
+ gDeferredGenBrdfLutProgram.mShaderFiles.push_back(make_pair("deferred/genbrdflutF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredGenBrdfLutProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = gDeferredGenBrdfLutProgram.createShader(NULL, NULL);
+ }
+
+
return success;
}
diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h
index 464efd6e3f..a2ae984caa 100644
--- a/indra/newview/llviewershadermgr.h
+++ b/indra/newview/llviewershadermgr.h
@@ -305,6 +305,7 @@ extern LLGLSLShader gDeferredWLMoonProgram;
extern LLGLSLShader gDeferredStarProgram;
extern LLGLSLShader gDeferredFullbrightShinyProgram;
extern LLGLSLShader gNormalMapGenProgram;
+extern LLGLSLShader gDeferredGenBrdfLutProgram;
// Deferred materials shaders
extern LLGLSLShader gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2];
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 7f42fb71e4..f07d809495 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -1182,6 +1182,8 @@ void LLPipeline::releaseLUTBuffers()
LLImageGL::deleteTextures(1, &mLightFunc);
mLightFunc = 0;
}
+
+ mPbrBrdfLut.release();
}
void LLPipeline::releaseShadowBuffers()
@@ -1363,6 +1365,21 @@ void LLPipeline::createLUTBuffers()
delete [] ls;
}
+
+ mPbrBrdfLut.allocate(512, 512, GL_RGB16, false, false);
+ mPbrBrdfLut.bindTarget();
+ gDeferredGenBrdfLutProgram.bind();
+
+ gGL.begin(LLRender::TRIANGLE_STRIP);
+ gGL.vertex2f(-1, -1);
+ gGL.vertex2f(-1, 1);
+ gGL.vertex2f(1, -1);
+ gGL.vertex2f(1, 1);
+ gGL.end();
+ gGL.flush();
+
+ gDeferredGenBrdfLutProgram.unbind();
+ mPbrBrdfLut.flush();
}
}
@@ -8165,6 +8182,13 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_
deferred_target->bindTexture(3, channel, LLTexUnit::TFO_POINT); // frag_data[3]
}
+ channel = shader.enableTexture(LLShaderMgr::DEFERRED_BRDF_LUT, LLTexUnit::TT_TEXTURE);
+ if (channel > -1)
+ {
+ mPbrBrdfLut.bindTexture(0, channel);
+ }
+
+
channel = shader.enableTexture(LLShaderMgr::DEFERRED_DEPTH, deferred_depth_target->getUsage());
if (channel > -1)
{
@@ -8304,7 +8328,7 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_
}
bindReflectionProbes(shader);
-
+
if (gAtmosphere)
{
// bind precomputed textures necessary for calculating sun and sky luminance
@@ -9212,6 +9236,7 @@ void LLPipeline::unbindDeferredShader(LLGLSLShader &shader)
shader.disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, deferred_target->getUsage());
shader.disableTexture(LLShaderMgr::DEFERRED_SPECULAR, deferred_target->getUsage());
shader.disableTexture(LLShaderMgr::DEFERRED_EMISSIVE, deferred_target->getUsage());
+ shader.disableTexture(LLShaderMgr::DEFERRED_BRDF_LUT);
shader.disableTexture(LLShaderMgr::DEFERRED_DEPTH, deferred_depth_target->getUsage());
shader.disableTexture(LLShaderMgr::DEFERRED_LIGHT, deferred_light_target->getUsage());
shader.disableTexture(LLShaderMgr::DIFFUSE_MAP);
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index cd7d0b88d8..5665469c1a 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -682,6 +682,7 @@ public:
LLRenderTarget mHighlight;
LLRenderTarget mPhysicsDisplay;
+ LLRenderTarget mPbrBrdfLut;
LLCullResult mSky;
LLCullResult mReflectedObjects;