WIP - switch PBR implementations
parent
dc1ed19511
commit
b2cf07f53c
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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]);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -682,6 +682,7 @@ public:
|
|||
|
||||
LLRenderTarget mHighlight;
|
||||
LLRenderTarget mPhysicsDisplay;
|
||||
LLRenderTarget mPbrBrdfLut;
|
||||
|
||||
LLCullResult mSky;
|
||||
LLCullResult mReflectedObjects;
|
||||
|
|
|
|||
Loading…
Reference in New Issue