From b2cf07f53ca9f0ab82d466063af8307631c50f31 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Sat, 17 Sep 2022 01:12:52 -0500 Subject: [PATCH 01/17] WIP - switch PBR implementations --- indra/llrender/llshadermgr.cpp | 1 + indra/llrender/llshadermgr.h | 1 + .../shaders/class1/deferred/deferredUtil.glsl | 266 ++++++++++++++++-- .../shaders/class1/deferred/genbrdflutF.glsl | 141 ++++++++++ .../shaders/class1/deferred/genbrdflutV.glsl | 39 +++ .../shaders/class1/deferred/pbralphaF.glsl | 6 +- .../class3/deferred/multiPointLightF.glsl | 2 +- .../class3/deferred/multiSpotLightF.glsl | 167 ----------- .../shaders/class3/deferred/pointLightF.glsl | 2 +- .../class3/deferred/reflectionProbeF.glsl | 4 +- .../shaders/class3/deferred/softenLightF.glsl | 93 +++--- indra/newview/llmaterialeditor.cpp | 4 +- indra/newview/llviewershadermgr.cpp | 14 + indra/newview/llviewershadermgr.h | 1 + indra/newview/pipeline.cpp | 27 +- indra/newview/pipeline.h | 1 + 16 files changed, 507 insertions(+), 262 deletions(-) create mode 100644 indra/newview/app_settings/shaders/class1/deferred/genbrdflutF.glsl create mode 100644 indra/newview/app_settings/shaders/class1/deferred/genbrdflutV.glsl 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); + // 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 FssEssGGX = kSpec*vScaleBias.x + vScaleBias.y; - colorSpec = radiance * FssEssGGX; + vec3 diffuse = diffuseLight * diffuseColor; + vec3 specular = specularLight * (specularColor * brdf.x + brdf.y); - // 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; + + return (diffuse + specular) * ao; +} - colorDiffuse *= ao; - colorSpec *= 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); + + 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,59 +259,9 @@ 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); + 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 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); 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 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; - vec3 colorDiffuse = vec3(0); - vec3 colorEmissive = spec.rgb; // PBR sRGB Emissive. See: pbropaqueF.glsl - vec3 colorSpec = vec3(0); + vec3 colorEmissive = texture2DRect(specularRect, tc).rgb; //specularRect is sRGB sampler, result is in linear space - 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 ); - - float gloss = 1.0 - perceptualRough; + // 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; - color.rgb = colorDiffuse + colorEmissive + colorSpec; + vec3 specularColor = mix(f0, baseColor.rgb, metallic); + + 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; From a32125bc0edcc583b185c08af0df1988855c0bac Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Sat, 17 Sep 2022 01:52:01 -0500 Subject: [PATCH 02/17] WIP - replace PBR implementation - point lights --- .../class3/deferred/multiPointLightF.glsl | 45 ++++++++++++------- .../shaders/class3/deferred/pointLightF.glsl | 36 ++++++++------- 2 files changed, 49 insertions(+), 32 deletions(-) diff --git a/indra/newview/app_settings/shaders/class3/deferred/multiPointLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/multiPointLightF.glsl index 3b57821758..4fbfaf9898 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/multiPointLightF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/multiPointLightF.glsl @@ -66,6 +66,14 @@ 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) @@ -87,38 +95,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 * 2.0; - 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); } } - - final_color = colorDiffuse + colorSpec; } else { diff --git a/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl index 0472f08852..88f165f315 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl @@ -68,6 +68,13 @@ 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); @@ -96,25 +103,22 @@ 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 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); - if (nl > 0.0) - { - 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); - } - - final_color = colorDiffuse + colorSpec; + vec3 v = -normalize(pos.xyz); + + vec3 intensity = dist_atten * color * 3.0; // Legacy attenuation + final_color += intensity*pbrPunctual(diffuseColor, specularColor, perceptualRoughness, metallic, n.xyz, v, normalize(lv)); } else { From 69ee8337026e4fc77205d501635822fc44989f62 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Sat, 17 Sep 2022 11:04:50 -0500 Subject: [PATCH 03/17] WIP - multiSpotLightF uses proper PBR shading, alpha is broken but pushing now in case my hard drive melts --- .../class3/deferred/multiSpotLightF.glsl | 44 +++++++++---------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl index cabc175da9..2294418e8a 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl @@ -93,6 +93,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) @@ -144,11 +151,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 @@ -160,31 +173,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 ); + 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; - + final_color += diffuse.rgb * amb_rgb; } - - final_color = colorDiffuse + colorSpec; } else { From 679060557555742b0631aec14b59ebcab64c081f Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Sat, 17 Sep 2022 13:04:23 -0500 Subject: [PATCH 04/17] WIP - Fix for alpha PBR lighting for point lights (spot lights treated as point lights for now) --- .../shaders/class1/deferred/pbralphaF.glsl | 160 +++++++----------- .../shaders/class3/deferred/pointLightF.glsl | 2 - 2 files changed, 65 insertions(+), 97 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbralphaF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbralphaF.glsl index ae542f5a1d..88ff4f0c96 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbralphaF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbralphaF.glsl @@ -73,7 +73,7 @@ VARYING vec2 vary_texcoord1; VARYING vec2 vary_texcoord2; VARYING vec3 vary_normal; VARYING vec3 vary_tangent; -flat in float vary_sign; +VARYING float vary_sign; #ifdef HAS_ALPHA_MASK @@ -107,71 +107,58 @@ 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); -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); - -/*void pbrIbl(out vec3 colorDiffuse, // diffuse color output - out vec3 colorSpec, // specular color output, +// 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, - float perceptualRough, // roughness factor - float gloss, // 1.0 - roughness factor - vec3 reflect0, - vec3 c_diff);*/ + float nv, // normal dot view vector + float perceptualRoughness); -// lp = light position -// la = linear attenuation, light radius -// fa = falloff -// See: LLRender::syncLightState() -vec3 calcPointLightOrSpotLight(vec3 reflect0, vec3 reflect90, float alphaRough, vec3 c_diff, - vec3 lightColor, vec3 diffuse, vec3 p, vec3 v, vec3 n, vec4 lp, vec3 ln, - float lightSize, float lightFalloff, float is_pointlight, float ambiance) +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 - p; - vec3 h, l; - float nh, nl, nv, vh, lightDist; - calcHalfVectors(lv,n,v,h,l,nh,nl,nv,vh,lightDist); - float dist = lightDist/lightSize; + float lightDist = length(lv); - if (dist <= 1.0 && nl > 0.0) + float dist = lightDist / lightSize; + if (dist <= 1.0) { - float dist_atten = calcLegacyDistanceAttenuation(dist,lightFalloff); + lv /= lightDist; - 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) - { - vec3 color = vec3(0); - intensity = dist_atten * nl * lightColor; - color += intensity * BRDFLambertian(reflect0, reflect90, c_diff, specWeight, vh); - color += intensity * BRDFSpecularGGX(reflect0, reflect90, alphaRough, specWeight, vh, nl, nv, nh); - return color; - } + 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; @@ -184,10 +171,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) @@ -196,9 +184,9 @@ void main() } #endif - vec3 base = vertex_color.rgb * albedo.rgb; + vec3 baseColor = vertex_color.rgb * albedo.rgb; - vec3 vNt = texture2D(bumpMap, vary_texcoord1.xy).xyz*2.0-1.0; + 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; @@ -214,61 +202,43 @@ void main() 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 - vec3 packedORM = texture2D(specularMap, vary_texcoord2.xy).rgb; // PBR linear packed Occlusion, Roughness, Metal. See: lldrawpoolapha.cpp + 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; // emissiveMap here is a vanilla RGB texture encoded as sRGB, manually convert to linear colorEmissive *= srgb_to_linear(texture2D(emissiveMap, vary_texcoord0.xy).rgb); - 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 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 ); - - float gloss = 1.0 - perceptualRough; + // PBR IBL + float gloss = 1.0 - perceptualRoughness; vec3 irradiance = vec3(0); vec3 radiance = vec3(0); - vec3 legacyenv = vec3(0); + vec3 legacyenv = 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); - // Sun/Moon Lighting - 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 col = colorDiffuse + colorEmissive + colorSpec; + vec3 specularColor = mix(f0, baseColor.rgb, metallic); + + vec3 v = -normalize(pos.xyz); + float NdotV = clamp(abs(dot(norm.xyz, v)), 0.001, 1.0); + + 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 += calcPointLightOrSpotLight( reflect0, reflect90, alphaRough, c_diff, light_diffuse[i].rgb, base.rgb, pos.xyz, v, n, light_position[i], light_direction[i].xyz, light_deferred_attenuation[i].x, light_deferred_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) @@ -278,12 +248,12 @@ void main() LIGHT_LOOP(6) LIGHT_LOOP(7) - col.rgb += light.rgb; + color.rgb += light.rgb; - col.rgb = linear_to_srgb(col.rgb); - col *= atten.r; - col += 2.0*additive; - col = scaleSoftClipFrag(col); + color.rgb = linear_to_srgb(color.rgb); + color *= atten.r; + color += 2.0*additive; + color = scaleSoftClipFrag(color); - frag_color = vec4(col,albedo.a * vertex_color.a); + frag_color = vec4(color,albedo.a * vertex_color.a); } diff --git a/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl index 88f165f315..1fc80016cb 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl @@ -115,8 +115,6 @@ void main() vec3 specularColor = mix(f0, baseColor.rgb, metallic); - vec3 v = -normalize(pos.xyz); - vec3 intensity = dist_atten * color * 3.0; // Legacy attenuation final_color += intensity*pbrPunctual(diffuseColor, specularColor, perceptualRoughness, metallic, n.xyz, v, normalize(lv)); } From 54e6c554c528262ed053b138c6159bc34f18d6dc Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Sat, 17 Sep 2022 13:53:37 -0500 Subject: [PATCH 05/17] Fix for crash when loading dae --- indra/newview/llmodelpreview.cpp | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp index 4b5e9a6510..076ebd80c2 100644 --- a/indra/newview/llmodelpreview.cpp +++ b/indra/newview/llmodelpreview.cpp @@ -1310,8 +1310,7 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe S32 tc_bytes_size = ((size_vertices * sizeof(LLVector2)) + 0xF) & ~0xF; LLVector4a* combined_positions = (LLVector4a*)ll_aligned_malloc<64>(sizeof(LLVector4a) * 3 * size_vertices + tc_bytes_size); LLVector4a* combined_normals = combined_positions + size_vertices; - LLVector4a* combined_tangents = combined_normals + size_vertices; - LLVector2* combined_tex_coords = (LLVector2*)(combined_tangents + size_vertices); + LLVector2* combined_tex_coords = (LLVector2*)(combined_normals + size_vertices); // copy indices and vertices into new buffers S32 combined_positions_shift = 0; @@ -1321,9 +1320,6 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe { const LLVolumeFace &face = base_model->getVolumeFace(face_idx); - // ensure tangents have been generated or loaded - llassert(face.mMikktSpaceTangents); - // Vertices S32 copy_bytes = face.mNumVertices * sizeof(LLVector4a); LLVector4a::memcpyNonAliased16((F32*)(combined_positions + combined_positions_shift), (F32*)face.mPositions, copy_bytes); @@ -1331,9 +1327,6 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe // Normals LLVector4a::memcpyNonAliased16((F32*)(combined_normals + combined_positions_shift), (F32*)face.mNormals, copy_bytes); - // Tangents - LLVector4a::memcpyNonAliased16((F32*)(combined_tangents + combined_positions_shift), (F32*)face.mMikktSpaceTangents, copy_bytes); - // Tex coords copy_bytes = face.mNumVertices * sizeof(LLVector2); memcpy((void*)(combined_tex_coords + combined_positions_shift), (void*)face.mTexCoords, copy_bytes); @@ -1437,8 +1430,7 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe LLVector4a* buffer_positions = (LLVector4a*)ll_aligned_malloc<64>(sizeof(LLVector4a) * 3 * size_vertices + tc_bytes_size); LLVector4a* buffer_normals = buffer_positions + size_vertices; - LLVector4a* buffer_tangents = buffer_normals + size_vertices; - LLVector2* buffer_tex_coords = (LLVector2*)(buffer_tangents + size_vertices); + LLVector2* buffer_tex_coords = (LLVector2*)(buffer_normals + size_vertices); S32 buffer_idx_size = (size_indices * sizeof(U16) + 0xF) & ~0xF; U16* buffer_indices = (U16*)ll_aligned_malloc_16(buffer_idx_size); S32* old_to_new_positions_map = new S32[size_vertices]; @@ -1519,7 +1511,6 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe // Copy vertice, normals, tcs buffer_positions[buf_positions_copied] = combined_positions[idx]; buffer_normals[buf_positions_copied] = combined_normals[idx]; - buffer_tangents[buf_positions_copied] = combined_tangents[idx]; buffer_tex_coords[buf_positions_copied] = combined_tex_coords[idx]; old_to_new_positions_map[idx] = buf_positions_copied; @@ -1564,7 +1555,6 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe LLVector4a::memcpyNonAliased16((F32*)new_face.mPositions, (F32*)buffer_positions, buf_positions_copied * sizeof(LLVector4a)); LLVector4a::memcpyNonAliased16((F32*)new_face.mNormals, (F32*)buffer_normals, buf_positions_copied * sizeof(LLVector4a)); - LLVector4a::memcpyNonAliased16((F32*)new_face.mMikktSpaceTangents, (F32*)buffer_tangents, buf_positions_copied * sizeof(LLVector4a)); U32 tex_size = (buf_positions_copied * sizeof(LLVector2) + 0xF)&~0xF; LLVector4a::memcpyNonAliased16((F32*)new_face.mTexCoords, (F32*)buffer_tex_coords, tex_size); From 13ac0f77ffe488ccdebfd28cabe8ed95d61aa684 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Sat, 17 Sep 2022 14:38:07 -0500 Subject: [PATCH 06/17] Make sure specular highlights from punctual lights don't fall off of polished surfaces --- .../shaders/class1/deferred/deferredUtil.glsl | 20 +++---------------- .../shaders/class3/deferred/softenLightF.glsl | 12 ++++++++--- 2 files changed, 12 insertions(+), 20 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl index 52345e7e51..d730d92054 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl @@ -351,23 +351,6 @@ 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); @@ -682,6 +665,9 @@ vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor, 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. diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl index 6dd140bff3..a8a3b5d33f 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl @@ -111,9 +111,6 @@ 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; @@ -147,6 +144,7 @@ void main() bool hasPBR = GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_PBR); if (hasPBR) { + 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; @@ -164,6 +162,10 @@ void main() 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); + + vec3 diffuseColor = baseColor.rgb*(vec3(1.0)-f0); diffuseColor *= 1.0 - metallic; @@ -187,6 +189,9 @@ void main() } else { + float envIntensity = norm.z; + norm.xyz = getNorm(tc); + float da = clamp(dot(norm.xyz, light_dir.xyz), 0.0, 1.0); da = pow(da, light_gamma); @@ -249,5 +254,6 @@ void main() frag_color.rgb = srgb_to_linear(color.rgb); } + frag_color.a = bloom; } From 48eea4de0a9304cd25af46defb52cb0adeeb87c4 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Sat, 17 Sep 2022 15:37:21 -0500 Subject: [PATCH 07/17] Adjust radiance maps to better match Substance --- .../app_settings/shaders/class1/deferred/deferredUtil.glsl | 3 ++- .../app_settings/shaders/class1/interface/radianceGenF.glsl | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl index d730d92054..d1c476792a 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl @@ -595,7 +595,8 @@ vec3 pbrIbl(vec3 diffuseColor, vec3 diffuse = diffuseLight * diffuseColor; vec3 specular = specularLight * (specularColor * brdf.x + brdf.y); - + specular *= 1.75; + return (diffuse + specular) * ao; } diff --git a/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl b/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl index 94fedce243..05c86de6d4 100644 --- a/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl +++ b/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl @@ -151,7 +151,7 @@ vec3 prefilterEnvMap(vec3 R, float roughness) 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; + color += textureLod(reflectionProbes, vec4(L,sourceIdx), mipLevel+0.75).rgb * dotNL; totalWeight += dotNL; } From b2553fc8b46e44dd74b2840e041b3cf46d2b39fc Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Sat, 17 Sep 2022 15:48:55 -0500 Subject: [PATCH 08/17] Fix for spotlights in background not matching foreground. Remove some unused functions. --- .../shaders/class1/deferred/deferredUtil.glsl | 104 ------------------ .../shaders/class1/deferred/pbralphaF.glsl | 2 - .../class3/deferred/multiSpotLightF.glsl | 1 - .../shaders/class3/deferred/spotLightF.glsl | 55 +++------ 4 files changed, 15 insertions(+), 147 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl index d1c476792a..0b97ee43e3 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl @@ -494,88 +494,9 @@ 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 @@ -720,28 +641,3 @@ vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor, return color; } - -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 scale = 32.0; - vec3 sunColor = sunlit * scale; - - // scol = sun shadow - vec3 intensity = sunColor * nl * scol; - vec3 sunDiffuse = intensity * BRDFLambertian (reflect0, reflect90, c_diff , 1.0, vh); - vec3 sunSpec = intensity * BRDFSpecularGGX(reflect0, reflect90, alphaRough, 1.0, vh, nl, nv, nh); - - colorDiffuse += sunDiffuse; - colorSpec += sunSpec; -} diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbralphaF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbralphaF.glsl index 88ff4f0c96..077c985092 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbralphaF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbralphaF.glsl @@ -92,8 +92,6 @@ 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); diff --git a/indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl index 2294418e8a..bcacc44d0b 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl @@ -74,7 +74,6 @@ 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); diff --git a/indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl index f23e9db040..787da799a5 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl @@ -83,7 +83,6 @@ 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 ); @@ -150,11 +149,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 @@ -166,46 +171,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 { From 29f92451f6dfb95b6d2e7e56d65a07df59ea9afd Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Sat, 17 Sep 2022 16:09:11 -0500 Subject: [PATCH 09/17] Cleanup more unused functions and fix spotLightF (whoops) --- .../shaders/class1/deferred/deferredUtil.glsl | 146 ------------------ .../shaders/class1/deferred/pbralphaF.glsl | 3 - .../class3/deferred/multiPointLightF.glsl | 4 - .../class3/deferred/multiSpotLightF.glsl | 3 - .../shaders/class3/deferred/pointLightF.glsl | 4 - .../shaders/class3/deferred/spotLightF.glsl | 11 +- 6 files changed, 8 insertions(+), 163 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl index 0b97ee43e3..2989332e98 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl @@ -24,9 +24,6 @@ */ - - - /* Parts of this file are taken from Sascha Willem's Vulkan GLTF refernce implementation MIT License @@ -351,149 +348,6 @@ vec3 hue_to_rgb(float hue) // PBR Utils -vec3 fresnelSchlick( vec3 reflect0, vec3 reflect90, float vh) -{ - return reflect0 + (reflect90 - reflect0) * pow(clamp(1.0 - vh, 0.0, 1.0), 5.0); -} - -// Approximate Environment BRDF -vec2 getGGXApprox( vec2 uv ) -{ - // Reference: Physically Based Shading on Mobile - // https://www.unrealengine.com/en-US/blog/physically-based-shading-on-mobile - // EnvBRDFApprox( vec3 SpecularColor, float Roughness, float NoV ) - float nv = uv.x; - float roughness = uv.y; - - const vec4 c0 = vec4( -1, -0.0275, -0.572, 0.022 ); - const vec4 c1 = vec4( 1, 0.0425, 1.04 , -0.04 ); - vec4 r = roughness * c0 + c1; - float a004 = min( r.x * r.x, exp2( -9.28 * nv ) ) * r.x + r.y; - vec2 ScaleBias = vec2( -1.04, 1.04 ) * a004 + r.zw; - return ScaleBias; -} - -#define PBR_USE_GGX_APPROX 1 -vec2 getGGX( vec2 brdfPoint ) -{ -#if PBR_USE_GGX_APPROX - return getGGXApprox( brdfPoint); -#else - return texture2D(GGXLUT, brdfPoint).rg; // TODO: use GGXLUT -#endif -} - - -// 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) -{ - float rangeAttenuation = getLightAttenuationPointSpot(lightRange, lightDistance); - return rangeAttenuation * lightColor; -} - -float getLightAttenuationSpot(vec3 spotDirection) -{ - return 1.0; -} - -vec3 getLightIntensitySpot(vec3 lightColor, float lightRange, float lightDistance, vec3 v) -{ - float spotAttenuation = getLightAttenuationSpot(-v); - return spotAttenuation * getLightIntensityPoint( lightColor, lightRange, lightDistance ); -} - -// 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 - 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 fresnel * vis * d; -} - vec2 BRDF(float NoV, float roughness) { return texture(brdfLut, vec2(NoV, roughness)).rg; diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbralphaF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbralphaF.glsl index 077c985092..aec2a90bda 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbralphaF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbralphaF.glsl @@ -98,9 +98,6 @@ 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); diff --git a/indra/newview/app_settings/shaders/class3/deferred/multiPointLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/multiPointLightF.glsl index 4fbfaf9898..2ee439f61a 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/multiPointLightF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/multiPointLightF.glsl @@ -52,15 +52,11 @@ 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 diff --git a/indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl index bcacc44d0b..6424e18079 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl @@ -73,18 +73,15 @@ uniform vec2 screen_res; uniform mat4 inv_proj; -vec3 BRDFLambertian( vec3 reflect0, vec3 reflect90, vec3 c_diff, float specWeight, float vh ); 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); diff --git a/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl index 1fc80016cb..27fca64ab3 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl @@ -57,15 +57,11 @@ 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, diff --git a/indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl index 787da799a5..c8d45eb429 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl @@ -82,17 +82,14 @@ uniform vec2 screen_res; uniform mat4 inv_proj; -vec3 BRDFLambertian( vec3 reflect0, vec3 reflect90, vec3 c_diff, float specWeight, float vh ); 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); @@ -100,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) @@ -147,6 +151,7 @@ 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 colorEmissive = spec.rgb; // PBR sRGB Emissive. See: pbropaqueF.glsl From cc0d3fdb00e970702fdc4e9a9e8935ed04df538f Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Sat, 17 Sep 2022 20:11:53 -0500 Subject: [PATCH 10/17] Fix for crash on NVIDIA hardware --- .../newview/app_settings/shaders/class1/deferred/pbralphaF.glsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbralphaF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbralphaF.glsl index aec2a90bda..1caf2b2b1a 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbralphaF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbralphaF.glsl @@ -73,7 +73,7 @@ VARYING vec2 vary_texcoord1; VARYING vec2 vary_texcoord2; VARYING vec3 vary_normal; VARYING vec3 vary_tangent; -VARYING float vary_sign; +flat in float vary_sign; #ifdef HAS_ALPHA_MASK From 655f8d8ee14598a9368d2593533ee190f878b6dd Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Sat, 17 Sep 2022 20:18:54 -0500 Subject: [PATCH 11/17] Fix for overbright and artifacted radiance maps on NVIDIA hardware --- .../app_settings/shaders/class1/deferred/deferredUtil.glsl | 2 +- .../app_settings/shaders/class1/interface/radianceGenF.glsl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl index 2989332e98..950776aa47 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl @@ -370,7 +370,7 @@ vec3 pbrIbl(vec3 diffuseColor, vec3 diffuse = diffuseLight * diffuseColor; vec3 specular = specularLight * (specularColor * brdf.x + brdf.y); - specular *= 1.75; + //specular *= 1.5; return (diffuse + specular) * ao; } diff --git a/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl b/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl index 05c86de6d4..94fedce243 100644 --- a/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl +++ b/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl @@ -151,7 +151,7 @@ vec3 prefilterEnvMap(vec3 R, float roughness) 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+0.75).rgb * dotNL; + color += textureLod(reflectionProbes, vec4(L,sourceIdx), mipLevel).rgb * dotNL; totalWeight += dotNL; } From 99fbb2e19c7cd3b7d8588800d8cab34e98a4580b Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Sat, 17 Sep 2022 21:02:31 -0500 Subject: [PATCH 12/17] RG16F PBR BRDF LUT --- indra/newview/pipeline.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index f07d809495..dd15b63fab 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -1366,7 +1366,7 @@ void LLPipeline::createLUTBuffers() delete [] ls; } - mPbrBrdfLut.allocate(512, 512, GL_RGB16, false, false); + mPbrBrdfLut.allocate(512, 512, GL_RG16F, false, false); mPbrBrdfLut.bindTarget(); gDeferredGenBrdfLutProgram.bind(); From 4f7c86a145877bdaae3e74900076b6790b7abc0e Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 19 Sep 2022 16:56:25 +0300 Subject: [PATCH 13/17] SL-18161 Fix viewer complaining about dupplicate FT_MATERIAL folders --- indra/newview/llinventorymodel.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index bd106df2cc..63152d167d 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -4334,7 +4334,11 @@ LLPointer LLInventoryModel::validate() const { LL_WARNS("Inventory") << "Fatal inventory corruption: system folder type has excess copies under root, type " << ft << " count " << count_under_root << LL_ENDL; validation_info->mDuplicateRequiredSystemFolders.insert(folder_type); - if (!is_automatic && folder_type != LLFolderType::FT_SETTINGS) + if (!is_automatic + && folder_type != LLFolderType::FT_SETTINGS + // FT_MATERIAL might need to be automatic like the rest of upload folders + && folder_type != LLFolderType::FT_MATERIAL + ) { // It is a fatal problem or can lead to fatal problems for COF, // outfits, trash and other non-automatic folders. From 718073717c70b1f7e7284a02641c0a0a7bf50367 Mon Sep 17 00:00:00 2001 From: "Howard (Aech Linden) Stearns" Date: Mon, 19 Sep 2022 12:16:49 -0700 Subject: [PATCH 14/17] SL-18128, SL-18128 - No glerror on Mac! --- indra/llappearance/lltexlayer.cpp | 9 ++++++++- indra/llrender/llglslshader.cpp | 6 ------ indra/llrender/llrender2dutils.cpp | 10 +++++++++- indra/llrender/llrendertarget.cpp | 2 -- indra/llrender/llvertexbuffer.cpp | 8 +------- 5 files changed, 18 insertions(+), 17 deletions(-) diff --git a/indra/llappearance/lltexlayer.cpp b/indra/llappearance/lltexlayer.cpp index 3430a25536..e1a3a83841 100644 --- a/indra/llappearance/lltexlayer.cpp +++ b/indra/llappearance/lltexlayer.cpp @@ -1509,7 +1509,14 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC } else { // platforms with working drivers... - glReadPixels(x, y, width, height, GL_ALPHA, GL_UNSIGNED_BYTE, alpha_data); + // We just want GL_ALPHA, but that isn't supported in OGL core profile 4. + static const size_t TEMP_BYTES_PER_PIXEL = 4; + U8* temp_data = (U8*)ll_aligned_malloc_32(mem_size * TEMP_BYTES_PER_PIXEL); + glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, temp_data); + for (size_t pixel = 0; pixel < pixels; pixel++) { + alpha_data[pixel] = temp_data[(pixel * TEMP_BYTES_PER_PIXEL) + 3]; + } + ll_aligned_free_32(temp_data); } } else diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp index 7cc5d33c49..55713eea80 100644 --- a/indra/llrender/llglslshader.cpp +++ b/indra/llrender/llglslshader.cpp @@ -227,7 +227,6 @@ void LLGLSLShader::stopProfile(U32 count, U32 mode) void LLGLSLShader::placeProfileQuery() { -#if 1 || !LL_DARWIN if (mTimerQuery == 0) { glGenQueries(1, &mSamplesQuery); @@ -269,12 +268,10 @@ void LLGLSLShader::placeProfileQuery() glBeginQuery(GL_SAMPLES_PASSED, mSamplesQuery); glBeginQuery(GL_TIME_ELAPSED, mTimerQuery); -#endif } void LLGLSLShader::readProfileQuery(U32 count, U32 mode) { -#if !LL_DARWIN glEndQuery(GL_TIME_ELAPSED); glEndQuery(GL_SAMPLES_PASSED); @@ -304,7 +301,6 @@ void LLGLSLShader::readProfileQuery(U32 count, U32 mode) sTotalDrawCalls++; mDrawCalls++; -#endif } @@ -676,7 +672,6 @@ void LLGLSLShader::mapUniform(GLint index, const vector * glGetActiveUniform(mProgramObject, index, 1024, &length, &size, &type, (GLchar *)name); -#if !LL_DARWIN if (size > 0) { switch(type) @@ -718,7 +713,6 @@ void LLGLSLShader::mapUniform(GLint index, const vector * } mTotalUniformSize += size; } -#endif S32 location = glGetUniformLocation(mProgramObject, name); if (location != -1) diff --git a/indra/llrender/llrender2dutils.cpp b/indra/llrender/llrender2dutils.cpp index 5cb1dc6b25..3d32d3ca31 100644 --- a/indra/llrender/llrender2dutils.cpp +++ b/indra/llrender/llrender2dutils.cpp @@ -1516,7 +1516,15 @@ void LLRender2D::loadIdentity() void LLRender2D::setLineWidth(F32 width) { gGL.flush(); - glLineWidth(width * lerp(LLRender::sUIGLScaleFactor.mV[VX], LLRender::sUIGLScaleFactor.mV[VY], 0.5f)); + // If outside the allowed range, glLineWidth fails with "invalid value". + // On Darwin, the range is [1, 1]. + static GLfloat range[2]{0.0}; + if (range[1] == 0) + { + glGetFloatv(GL_SMOOTH_LINE_WIDTH_RANGE, range); + } + width *= lerp(LLRender::sUIGLScaleFactor.mV[VX], LLRender::sUIGLScaleFactor.mV[VY], 0.5f); + glLineWidth(llclamp(width, range[0], range[1])); } LLPointer LLRender2D::getUIImageByID(const LLUUID& image_id, S32 priority) diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp index 015312e570..01e0b4336c 100644 --- a/indra/llrender/llrendertarget.cpp +++ b/indra/llrender/llrendertarget.cpp @@ -301,13 +301,11 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt) mTex.push_back(tex); mInternalFormat.push_back(color_fmt); -#if !LL_DARWIN if (gDebugGL) { //bind and unbind to validate target bindTarget(); flush(); } -#endif return true; diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index d05f916d95..981175d845 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -1327,7 +1327,6 @@ void LLVertexBuffer::setupVertexArray() if (attrib_integer[i]) { -#if !LL_DARWIN //glVertexattribIPointer requires GLSL 1.30 or later if (gGLManager.mGLSLVersionMajor > 1 || gGLManager.mGLSLVersionMinor >= 30) { @@ -1336,9 +1335,8 @@ void LLVertexBuffer::setupVertexArray() // Cast via intptr_t to make it painfully obvious to the // compiler that we're doing this intentionally. glVertexAttribIPointer(i, attrib_size[i], attrib_type[i], sTypeSize[i], - reinterpret_cast(intptr_t(mOffsets[i]))); + reinterpret_cast(intptr_t(mOffsets[i]))); } -#endif } else { @@ -2364,11 +2362,9 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask) if (data_mask & MAP_TEXTURE_INDEX && (gGLManager.mGLSLVersionMajor >= 2 || gGLManager.mGLSLVersionMinor >= 30)) //indexed texture rendering requires GLSL 1.30 or later { -#if !LL_DARWIN S32 loc = TYPE_TEXTURE_INDEX; void *ptr = (void*) (base + mOffsets[TYPE_VERTEX] + 12); glVertexAttribIPointer(loc, 1, GL_UNSIGNED_INT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr); -#endif } if (data_mask & MAP_VERTEX) { @@ -2459,11 +2455,9 @@ void LLVertexBuffer::setupVertexBufferFast(U32 data_mask) } if (data_mask & MAP_TEXTURE_INDEX) { -#if !LL_DARWIN S32 loc = TYPE_TEXTURE_INDEX; void* ptr = (void*)(base + mOffsets[TYPE_VERTEX] + 12); glVertexAttribIPointer(loc, 1, GL_UNSIGNED_INT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr); -#endif } if (data_mask & MAP_VERTEX) { From 04d3a29a699cd0a4c08ab096bfbab153e65c1fd1 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Mon, 19 Sep 2022 17:27:33 -0500 Subject: [PATCH 15/17] SL-18190 Faster better stronger radiance/irradiance maps --- indra/llrender/llglheaders.h | 7 - indra/llrender/llrendertarget.cpp | 2 + .../shaders/class1/deferred/deferredUtil.glsl | 2 +- .../class1/interface/irradianceGenF.glsl | 227 ++++++++++++++---- .../class1/interface/radianceGenF.glsl | 17 +- .../class1/interface/reflectionmipF.glsl | 4 + indra/newview/llreflectionmapmanager.cpp | 40 +-- 7 files changed, 220 insertions(+), 79 deletions(-) diff --git a/indra/llrender/llglheaders.h b/indra/llrender/llglheaders.h index 0aacf3bf0e..b80680a3d2 100644 --- a/indra/llrender/llglheaders.h +++ b/indra/llrender/llglheaders.h @@ -1061,13 +1061,6 @@ extern void glGetBufferPointervARB (GLenum, GLenum, GLvoid* *); #endif #if defined(TRACY_ENABLE) && LL_PROFILER_ENABLE_TRACY_OPENGL - // Tracy uses the following: - // glGenQueries - // glGetQueryiv - // glGetQueryObjectiv - #define glGenQueries glGenQueriesARB - #define glGetQueryiv glGetQueryivARB - #define glGetQueryObjectiv glGetQueryObjectivARB #include #endif diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp index 015312e570..2179b441e5 100644 --- a/indra/llrender/llrendertarget.cpp +++ b/indra/llrender/llrendertarget.cpp @@ -471,6 +471,7 @@ void LLRenderTarget::release() void LLRenderTarget::bindTarget() { + LL_PROFILE_GPU_ZONE("bindTarget"); llassert(mFBO); if (mFBO) @@ -577,6 +578,7 @@ void LLRenderTarget::bindTexture(U32 index, S32 channel, LLTexUnit::eTextureFilt void LLRenderTarget::flush(bool fetch_depth) { + LL_PROFILE_GPU_ZONE("rt flush"); gGL.flush(); llassert(mFBO); if (!mFBO) diff --git a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl index 950776aa47..49f85af53b 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl @@ -366,7 +366,7 @@ vec3 pbrIbl(vec3 diffuseColor, 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); 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 - -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. -*/ -// ============================================================================================================= +// Code below is derived from the Khronos GLTF Sample viewer: +// https://github.com/KhronosGroup/glTF-Sample-Viewer/blob/master/source/shaders/ibl_filtering.frag +#define MATH_PI 3.1415926535897932384626433832795 -#define PI 3.1415926535897932384626433832795 +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; + + 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 color = vec3(0); - 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); + 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/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 97277ee798..57ec51221e 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -410,8 +410,7 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) S32 mips = log2((F32)LL_REFLECTION_PROBE_RESOLUTION) + 0.5f; - //for (int i = 0; i < mMipChain.size(); ++i) - for (int i = 0; i < 1; ++i) + for (int i = 0; i < mMipChain.size(); ++i) { LL_PROFILE_GPU_ZONE("probe mip"); mMipChain[i].bindTarget(); @@ -447,10 +446,14 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) if (mip >= 0) { + LL_PROFILE_GPU_ZONE("probe mip copy"); mTexture->bind(0); //glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, probe->mCubeIndex * 6 + face, 0, 0, res, res); glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, targetIdx * 6 + face, 0, 0, res, res); - glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, probe->mCubeIndex * 6 + face, 0, 0, res, res); + if (i == 0) + { + glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, probe->mCubeIndex * 6 + face, 0, 0, res, res); + } mTexture->unbind(); } mMipChain[i].flush(); @@ -474,8 +477,12 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) static LLStaticHashedString sMipLevel("mipLevel"); + mMipChain[1].bindTarget(); + U32 res = mMipChain[1].getWidth(); + for (int i = 1; i < mMipChain.size(); ++i) { + LL_PROFILE_GPU_ZONE("probe radiance gen"); for (int cf = 0; cf < 6; ++cf) { // for each cube face LLCoordFrame frame; @@ -485,15 +492,11 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) frame.getOpenGLRotation(mat); gGL.loadMatrix(mat); - mMipChain[i].bindTarget(); static LLStaticHashedString sRoughness("roughness"); gRadianceGenProgram.uniform1f(sRoughness, (F32)i / (F32)(mMipChain.size() - 1)); gRadianceGenProgram.uniform1f(sMipLevel, llmax((F32)(i - 1), 0.f)); - if (i > 0) - { - gRadianceGenProgram.uniform1i(sSourceIdx, probe->mCubeIndex); - } + gGL.begin(gGL.QUADS); gGL.vertex3f(-1, -1, -1); gGL.vertex3f(1, -1, -1); @@ -501,12 +504,17 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) gGL.vertex3f(-1, 1, -1); gGL.end(); gGL.flush(); - - S32 res = mMipChain[i].getWidth(); + glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, i, 0, 0, probe->mCubeIndex * 6 + cf, 0, 0, res, res); - mMipChain[i].flush(); + } + + if (i != mMipChain.size() - 1) + { + res /= 2; + glViewport(0, 0, res, res); } } + gRadianceGenProgram.unbind(); //generate irradiance map @@ -514,7 +522,7 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) channel = gIrradianceGenProgram.enableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY); mTexture->bind(channel); - gIrradianceGenProgram.uniform1i(sSourceIdx, probe->mCubeIndex); + gIrradianceGenProgram.uniform1i(sSourceIdx, targetIdx); int start_mip = 0; // find the mip target to start with based on irradiance map resolution @@ -528,6 +536,8 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) for (int i = start_mip; i < mMipChain.size(); ++i) { + LL_PROFILE_GPU_ZONE("probe irradiance gen"); + glViewport(0, 0, mMipChain[i].getWidth(), mMipChain[i].getHeight()); for (int cf = 0; cf < 6; ++cf) { // for each cube face LLCoordFrame frame; @@ -537,8 +547,6 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) frame.getOpenGLRotation(mat); gGL.loadMatrix(mat); - mMipChain[i].bindTarget(); - gGL.begin(gGL.QUADS); gGL.vertex3f(-1, -1, -1); gGL.vertex3f(1, -1, -1); @@ -551,9 +559,11 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) mIrradianceMaps->bind(channel); glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, i - start_mip, 0, 0, probe->mCubeIndex * 6 + cf, 0, 0, res, res); mTexture->bind(channel); - mMipChain[i].flush(); } } + + mMipChain[1].flush(); + gIrradianceGenProgram.unbind(); } } From f7ecf0ee3859f496679bab9aaa6d3696c3264728 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 20 Sep 2022 01:51:15 +0300 Subject: [PATCH 16/17] SL-18065 Fix bake textures' fetch loop --- .../shaders/class1/deferred/genbrdflutF.glsl | 2 +- indra/newview/lltexturefetch.cpp | 14 +++++++------- indra/newview/lltexturefetch.h | 2 +- indra/newview/llviewertexture.cpp | 10 ++++++---- 4 files changed, 15 insertions(+), 13 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/genbrdflutF.glsl b/indra/newview/app_settings/shaders/class1/deferred/genbrdflutF.glsl index f3896191fa..73a70d8dc5 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/genbrdflutF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/genbrdflutF.glsl @@ -138,4 +138,4 @@ vec2 BRDF(float NoV, float roughness) 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/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 2b16ba14e2..987918fc1d 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -2430,13 +2430,13 @@ LLTextureFetch::~LLTextureFetch() // ~LLQueuedThread() called here } -bool LLTextureFetch::createRequest(FTType f_type, const std::string& url, const LLUUID& id, const LLHost& host, F32 priority, +S32 LLTextureFetch::createRequest(FTType f_type, const std::string& url, const LLUUID& id, const LLHost& host, F32 priority, S32 w, S32 h, S32 c, S32 desired_discard, bool needs_aux, bool can_use_http) { LL_PROFILE_ZONE_SCOPED; if (mDebugPause) { - return false; + return -1; } if (f_type == FTT_SERVER_BAKE) @@ -2452,7 +2452,7 @@ bool LLTextureFetch::createRequest(FTType f_type, const std::string& url, const << host << " != " << worker->mHost << LL_ENDL; removeRequest(worker, true); worker = NULL; - return false; + return -1; } } @@ -2505,13 +2505,13 @@ bool LLTextureFetch::createRequest(FTType f_type, const std::string& url, const { if (worker->wasAborted()) { - return false; // need to wait for previous aborted request to complete + return -1; // need to wait for previous aborted request to complete } worker->lockWorkMutex(); // +Mw if (worker->mState == LLTextureFetchWorker::DONE && worker->mDesiredSize == llmax(desired_size, TEXTURE_CACHE_ENTRY_SIZE) && worker->mDesiredDiscard == desired_discard) { worker->unlockWorkMutex(); // -Mw - return false; // similar request has failed or is in a transitional state + return -1; // similar request has failed or is in a transitional state } worker->mActiveCount++; worker->mNeedsAux = needs_aux; @@ -2546,10 +2546,10 @@ bool LLTextureFetch::createRequest(FTType f_type, const std::string& url, const worker->setCanUseHTTP(can_use_http) ; worker->unlockWorkMutex(); // -Mw } - + LL_DEBUGS(LOG_TXT) << "REQUESTED: " << id << " f_type " << fttype_to_string(f_type) << " Discard: " << desired_discard << " size " << desired_size << LL_ENDL; - return true; + return desired_discard; } diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h index dc3045fe8c..4297117f75 100644 --- a/indra/newview/lltexturefetch.h +++ b/indra/newview/lltexturefetch.h @@ -77,7 +77,7 @@ public: void shutDownImageDecodeThread(); // Threads: T* (but Tmain mostly) - bool createRequest(FTType f_type, const std::string& url, const LLUUID& id, const LLHost& host, F32 priority, + S32 createRequest(FTType f_type, const std::string& url, const LLUUID& id, const LLHost& host, F32 priority, S32 w, S32 h, S32 c, S32 discard, bool needs_aux, bool can_use_http); // Requests that a fetch operation be deleted from the queue. diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index 7c621e4564..6cf9665e3e 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -2206,16 +2206,18 @@ bool LLViewerFetchedTexture::updateFetch() } // bypass texturefetch directly by pulling from LLTextureCache - bool fetch_request_created = false; - fetch_request_created = LLAppViewer::getTextureFetch()->createRequest(mFTType, mUrl, getID(), getTargetHost(), decode_priority, + S32 fetch_request_discard = -1; + fetch_request_discard = LLAppViewer::getTextureFetch()->createRequest(mFTType, mUrl, getID(), getTargetHost(), decode_priority, w, h, c, desired_discard, needsAux(), mCanUseHTTP); - if (fetch_request_created) + if (fetch_request_discard >= 0) { LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - request created"); mHasFetcher = TRUE; mIsFetching = TRUE; - mRequestedDiscardLevel = desired_discard; + // in some cases createRequest can modify discard, as an example + // bake textures are always at discard 0 + mRequestedDiscardLevel = llmin(desired_discard, fetch_request_discard); mFetchState = LLAppViewer::getTextureFetch()->getFetchState(mID, mDownloadProgress, mRequestedDownloadPriority, mFetchPriority, mFetchDeltaTime, mRequestDeltaTime, mCanUseHTTP); } From d3b4c4aecef1b7815f6d47ffee1e00eb08cbb431 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Mon, 19 Sep 2022 19:07:34 -0500 Subject: [PATCH 17/17] SL-18190 Don't generate mips for irradiance maps because they're never sampled. --- indra/newview/llreflectionmapmanager.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 57ec51221e..2de31a5754 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -534,8 +534,9 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) } } - for (int i = start_mip; i < mMipChain.size(); ++i) + //for (int i = start_mip; i < mMipChain.size(); ++i) { + int i = start_mip; LL_PROFILE_GPU_ZONE("probe irradiance gen"); glViewport(0, 0, mMipChain[i].getWidth(), mMipChain[i].getHeight()); for (int cf = 0; cf < 6; ++cf)