current position:Home>Simple analysis of Babylon PBR (I) only indirect light

Simple analysis of Babylon PBR (I) only indirect light

2021-08-26 00:47:49 Na Ming

PBRMetallicRoughnessMaterial | Babylon.js Playground (babylonjs.com)

image.png

Simple analysis

  • normal
//normal
vec3 normalW = normalize(vNormalW);
 Copy code 
  • albedoOpacityOut diffuse Color and transparency
void albedoOpacityBlock(const in vec4 vAlbedoColor, out albedoOpacityOutParams outParams) {
    vec3 surfaceAlbedo = vAlbedoColor.rgb;
    float alpha = vAlbedoColor.a;
    #define CUSTOM_FRAGMENT_UPDATE_ALBEDO
    outParams.surfaceAlbedo = surfaceAlbedo;
    outParams.alpha = alpha;
}
albedoOpacityOutParams albedoOpacityOut;
albedoOpacityBlock(vAlbedoColor, albedoOpacityOut);
 Copy code 
  • aoOut Pure black
void ambientOcclusionBlock(out ambientOcclusionOutParams outParams) {
    vec3 ambientOcclusionColor = vec3(1., 1., 1.);
    outParams.ambientOcclusionColor = ambientOcclusionColor;
}
ambientOcclusionOutParams aoOut;
ambientOcclusionBlock(aoOut);
 Copy code 
  • reflectivitySampler surfaceMetallicOrReflectivityColorMap Just for the metallicity show

image.png

  • reflectivityOut diffusecolor specularcolor roughness
//reflectivityOut
vec3 surfaceAlbedo = albedoOpacityOut.surfaceAlbedo; // User entered diffuse
vec2 uvOffset = vec2(0.0, 0.0);
reflectivityOutParams reflectivityOut;
vec4 surfaceMetallicOrReflectivityColorMap = texture2D(reflectivitySampler, vReflectivityUV + uvOffset); // It's a graph of metallicity and roughness   There are green and blue 
vec4 metallicReflectanceFactors = vMetallicReflectanceFactors; // vMetallicReflectanceFactors  yes 0.04 0.04  Basic reflectivity   Without color 
reflectivityBlock(vReflectivityColor, surfaceAlbedo, metallicReflectanceFactors, vReflectivityInfos, surfaceMetallicOrReflectivityColorMap, reflectivityOut);
void reflectivityBlock(const in vec4 vReflectivityColor, const in vec3 surfaceAlbedo, const in vec4 metallicReflectanceFactors, const in vec3 reflectivityInfos, const in vec4 surfaceMetallicOrReflectivityColorMap, out reflectivityOutParams outParams) {
    float microSurface = vReflectivityColor.a; // User entered a
    vec3 surfaceReflectivityColor = vReflectivityColor.rgb; // The user enters the color of the highlight  specularcolor
    vec2 metallicRoughness = surfaceReflectivityColor.rg; //
    metallicRoughness.r *= surfaceMetallicOrReflectivityColorMap.b; //r It's metallicity 
    metallicRoughness.g *= surfaceMetallicOrReflectivityColorMap.g; //g It's roughness 
    #define CUSTOM_FRAGMENT_UPDATE_METALLICROUGHNESS
    microSurface = 1.0 - metallicRoughness.g;
    vec3 baseColor = surfaceAlbedo; // User entered diffuse
    vec3 metallicF0 = metallicReflectanceFactors.rgb; // Base reflectance without color 
    outParams.surfaceAlbedo = mix(baseColor.rgb * (1.0 - metallicF0), vec3(0., 0., 0.), metallicRoughness.r); //diffusecolor
    surfaceReflectivityColor = mix(metallicF0, baseColor, metallicRoughness.r); //specularcolor
    microSurface = saturate(microSurface); 
    float roughness = 1. - microSurface; 
    outParams.microSurface = microSurface;
    outParams.roughness = roughness; // Roughness 
    outParams.surfaceReflectivityColor = surfaceReflectivityColor; //specularcolor
}
 Copy code 
  • surfaceAlbedo Namely diffusecolor
//surfaceAlbedo 
surfaceAlbedo = reflectivityOut.surfaceAlbedo;
 Copy code 
  • brdflut Indirect light specular term
vec3 getBRDFLookup(float NdotV, float perceptualRoughness) {
    vec2 UV = vec2(NdotV, perceptualRoughness);
    vec4 brdfLookup = texture2D(environmentBrdfSampler, UV);
    return brdfLookup.rgb;
}
//environmentBrdf
vec3 viewDirectionW = normalize(vEyePosition.xyz - vPositionW);
float NdotVUnclamped = dot(normalW, viewDirectionW);
float NdotV = absEps(NdotVUnclamped);
float roughness = reflectivityOut.roughness;
vec3 environmentBrdf = getBRDFLookup(NdotV, roughness);
 Copy code 
  • reflectionOut
    • environmentIrradiance Mainly indirect light diffuse term
    • environmentRadiance Mainly indirect light preflitter
#define MINIMUMVARIANCE 0.0005
float convertRoughnessToAverageSlope(float roughness) {
    return square(roughness) + MINIMUMVARIANCE;
}
reflectionOutParams reflectionOut;
float alphaG = convertRoughnessToAverageSlope(roughness);
reflectionBlock(vPositionW, normalW, alphaG, vReflectionMicrosurfaceInfos, vReflectionInfos, vReflectionColor, reflectionSampler, vEnvironmentIrradiance, reflectionOut);
void reflectionBlock(const in vec3 vPositionW, const in vec3 normalW, const in float alphaG, const in vec3 vReflectionMicrosurfaceInfos, const in vec2 vReflectionInfos, const in vec3 vReflectionColor, const in samplerCube reflectionSampler, const in vec3 vEnvironmentIrradiance, out reflectionOutParams outParams) {
    vec4 environmentRadiance = vec4(0., 0., 0., 0.);
    vec3 reflectionCoords = vec3(0.);
    createReflectionCoords(vPositionW, normalW, reflectionCoords);
    sampleReflectionTexture(alphaG, vReflectionMicrosurfaceInfos, vReflectionInfos, vReflectionColor, reflectionSampler, reflectionCoords, environmentRadiance);
    vec3 environmentIrradiance = vec3(0., 0., 0.);
    environmentIrradiance = vEnvironmentIrradiance; // It has been solved in the vertex shader   It's the color value 
    environmentIrradiance *= vReflectionColor.rgb; // This is rgb yes  1,1,1  I don't know what the use is  
    outParams.environmentRadiance = environmentRadiance; // Indirect light prefillter term 
    outParams.environmentIrradiance = environmentIrradiance; // Indirect light diffuse
    outParams.reflectionCoords = reflectionCoords; // It doesn't work 
}
void createReflectionCoords(const in vec3 vPositionW, const in vec3 normalW, out vec3 reflectionCoords) {
    vec3 reflectionVector = computeReflectionCoords(vec4(vPositionW, 1.0), normalW);
    reflectionCoords = reflectionVector;
}
void sampleReflectionTexture(const in float alphaG, const in vec3 vReflectionMicrosurfaceInfos, const in vec2 vReflectionInfos, const in vec3 vReflectionColor, const in samplerCube reflectionSampler, const vec3 reflectionCoords, out vec4 environmentRadiance) {
    float reflectionLOD = getLodFromAlphaG(vReflectionMicrosurfaceInfos.x, alphaG);
    reflectionLOD = reflectionLOD * vReflectionMicrosurfaceInfos.y + vReflectionMicrosurfaceInfos.z;
    float requestedReflectionLOD = reflectionLOD;
    environmentRadiance = sampleReflectionLod(reflectionSampler, reflectionCoords, reflectionLOD);
    environmentRadiance.rgb *= vReflectionInfos.x;
    environmentRadiance.rgb *= vReflectionColor.rgb;
}
 Copy code 
  • energyConservationFactor Multi surface scattering
//energyConservationFactor
vec3 specularEnvironmentR0 = reflectivityOut.surfaceReflectivityColor.rgb; //specularcolor
vec3 specularEnvironmentR90 = vec3(metallicReflectanceFactors.a); // 1,1,1
clearcoatOutParams clearcoatOut;
clearcoatOut.specularEnvironmentR0 = specularEnvironmentR0;
vec3 energyConservationFactor = getEnergyConservationFactor(clearcoatOut.specularEnvironmentR0, environmentBrdf);
vec3 getEnergyConservationFactor(const vec3 specularEnvironmentR0, const vec3 environmentBrdf) {
    return 1.0 + specularEnvironmentR0 * (1.0 / environmentBrdf.y - 1.0);
}
 Copy code 
  • subSurfaceOut
    • specularEnvironmentReflectance Indirect light brdflut term
//subSurfaceOut
float ambientMonochrome = getLuminance(aoOut.ambientOcclusionColor); //1,1,1
float seo = environmentRadianceOcclusion(ambientMonochrome, NdotVUnclamped);
vec3 specularEnvironmentReflectance = getReflectanceFromBRDFLookup(clearcoatOut.specularEnvironmentR0, specularEnvironmentR90, environmentBrdf);
specularEnvironmentReflectance *= seo;
subSurfaceOutParams subSurfaceOut;
subSurfaceOut.specularEnvironmentReflectance = specularEnvironmentReflectance;
float environmentRadianceOcclusion(float ambientOcclusion, float NdotVUnclamped) {
    float temp = NdotVUnclamped + ambientOcclusion;
    return saturate(square(temp) - 1.0 + ambientOcclusion);
}
vec3 getReflectanceFromBRDFLookup(const vec3 specularEnvironmentR0, const vec3 specularEnvironmentR90, const vec3 environmentBrdf) {
    vec3 reflectance = (specularEnvironmentR90 - specularEnvironmentR0) * environmentBrdf.x + specularEnvironmentR0 * environmentBrdf.y;
    return reflectance;
}
 Copy code 
  • finalIrradiance Indirect light diffuse term
//finalIrradiance
vec3 finalIrradiance = reflectionOut.environmentIrradiance;
finalIrradiance *= surfaceAlbedo.rgb;
finalIrradiance *= vLightingIntensity.z;
finalIrradiance *= aoOut.ambientOcclusionColor;
 Copy code 
  • finalRadianceScaled Indirect light specular term
//finalRadianceScaled
vec3 finalRadiance = reflectionOut.environmentRadiance.rgb; //prefillter term 
finalRadiance *= subSurfaceOut.specularEnvironmentReflectance; // 
vec3 finalRadianceScaled = finalRadiance * vLightingIntensity.z;
finalRadianceScaled *= energyConservationFactor;
 Copy code 
  • finalEmissive Self luminous item
//emissive
vec3 finalEmissive = vEmissiveColor;
finalEmissive *= vLightingIntensity.y;
 Copy code 
  • finalDiffuse This is the total term of the formula strange
//finalDiffuse
vec3 ambientOcclusionForDirectDiffuse = aoOut.ambientOcclusionColor;
vec3 diffuseBase = vec3(0., 0., 0.);
vec3 finalDiffuse = diffuseBase;    
finalDiffuse *= surfaceAlbedo.rgb;
finalDiffuse = max(finalDiffuse, 0.0);
finalDiffuse *= vLightingIntensity.x;
finalDiffuse *= ambientOcclusionForDirectDiffuse;
 Copy code 

main function

void main(void) {
    #define CUSTOM_FRAGMENT_MAIN_BEGIN

    //normal
    vec3 normalW = normalize(vNormalW);

    //albedoOpacityOut
    albedoOpacityOutParams albedoOpacityOut;
    albedoOpacityBlock(vAlbedoColor, albedoOpacityOut);
    #define CUSTOM_FRAGMENT_UPDATE_ALPHA
    #define CUSTOM_FRAGMENT_BEFORE_LIGHTS

    //ao
    ambientOcclusionOutParams aoOut;
    ambientOcclusionBlock(aoOut);

    //reflectivityOut
    vec3 surfaceAlbedo = albedoOpacityOut.surfaceAlbedo;
    vec2 uvOffset = vec2(0.0, 0.0);
    reflectivityOutParams reflectivityOut;
    vec4 surfaceMetallicOrReflectivityColorMap = texture2D(reflectivitySampler, vReflectivityUV + uvOffset);
    vec4 metallicReflectanceFactors = vMetallicReflectanceFactors;
    reflectivityBlock(vReflectivityColor, surfaceAlbedo, metallicReflectanceFactors, vReflectivityInfos, surfaceMetallicOrReflectivityColorMap, reflectivityOut);
    
    //surfaceAlbedo
    surfaceAlbedo = reflectivityOut.surfaceAlbedo;

    //environmentBrdf
    vec3 viewDirectionW = normalize(vEyePosition.xyz - vPositionW);
    float NdotVUnclamped = dot(normalW, viewDirectionW);
    float NdotV = absEps(NdotVUnclamped);
    float roughness = reflectivityOut.roughness;
    vec3 environmentBrdf = getBRDFLookup(NdotV, roughness);

    //reflectionOut
    reflectionOutParams reflectionOut;
    float alphaG = convertRoughnessToAverageSlope(roughness);
    reflectionBlock(vPositionW, normalW, alphaG, vReflectionMicrosurfaceInfos, vReflectionInfos, vReflectionColor, reflectionSampler, vEnvironmentIrradiance, reflectionOut);

    //energyConservationFactor
    vec3 specularEnvironmentR0 = reflectivityOut.surfaceReflectivityColor.rgb;
    vec3 specularEnvironmentR90 = vec3(metallicReflectanceFactors.a);
    clearcoatOutParams clearcoatOut;
    clearcoatOut.specularEnvironmentR0 = specularEnvironmentR0;
    vec3 energyConservationFactor = getEnergyConservationFactor(clearcoatOut.specularEnvironmentR0, environmentBrdf);

    //subSurfaceOut
    float ambientMonochrome = getLuminance(aoOut.ambientOcclusionColor);
    float seo = environmentRadianceOcclusion(ambientMonochrome, NdotVUnclamped);
    vec3 specularEnvironmentReflectance = getReflectanceFromBRDFLookup(clearcoatOut.specularEnvironmentR0, specularEnvironmentR90, environmentBrdf);
    specularEnvironmentReflectance *= seo;
    subSurfaceOutParams subSurfaceOut;
    subSurfaceOut.specularEnvironmentReflectance = specularEnvironmentReflectance;

    //finalIrradiance
    vec3 finalIrradiance = reflectionOut.environmentIrradiance;
    finalIrradiance *= surfaceAlbedo.rgb;
    finalIrradiance *= vLightingIntensity.z;
    finalIrradiance *= aoOut.ambientOcclusionColor;

    //finalRadianceScaled
    vec3 finalRadiance = reflectionOut.environmentRadiance.rgb;
    finalRadiance *= subSurfaceOut.specularEnvironmentReflectance;
    vec3 finalRadianceScaled = finalRadiance * vLightingIntensity.z;
    finalRadianceScaled *= energyConservationFactor;
    
    //finalAmbient
    vec3 finalAmbient = vAmbientColor; // It's usually  0,0,0
    finalAmbient *= surfaceAlbedo.rgb;
    finalAmbient *= aoOut.ambientOcclusionColor;

    //emissive
    vec3 finalEmissive = vEmissiveColor;
    finalEmissive *= vLightingIntensity.y;

    //finalDiffuse
    vec3 ambientOcclusionForDirectDiffuse = aoOut.ambientOcclusionColor;
    vec3 diffuseBase = vec3(0., 0., 0.);
    vec3 finalDiffuse = diffuseBase;    
    finalDiffuse *= surfaceAlbedo.rgb;
    finalDiffuse = max(finalDiffuse, 0.0);
    finalDiffuse *= vLightingIntensity.x;
    finalDiffuse *= ambientOcclusionForDirectDiffuse;

    //finalColor
    #define CUSTOM_FRAGMENT_BEFORE_FINALCOLORCOMPOSITION
    float alpha = albedoOpacityOut.alpha;
    vec4 finalColor = vec4(finalAmbient + // 0,0,0
        finalDiffuse +
        finalIrradiance +
        finalRadianceScaled +
        finalEmissive, alpha);
    #define CUSTOM_FRAGMENT_BEFORE_FOG
    finalColor = max(finalColor, 0.0); //max
    finalColor = applyImageProcessing(finalColor); //gamma
    finalColor.a *= visibility;
    #define CUSTOM_FRAGMENT_BEFORE_FRAGCOLOR
    gl_FragColor = finalColor;
}

 Copy code 

original text

#define PBR
#define NUM_SAMPLES 0
#define MAINUV1
#define UV1
#define ALBEDODIRECTUV 0
#define DETAILDIRECTUV 0
#define DETAIL_NORMALBLENDMETHOD 0
#define AMBIENTDIRECTUV 0
#define OPACITYDIRECTUV 0
#define ALPHATESTVALUE 0.4
#define SPECULAROVERALPHA
#define RADIANCEOVERALPHA
#define EMISSIVEDIRECTUV 0
#define REFLECTIVITY
#define REFLECTIVITYDIRECTUV 1
#define LODBASEDMICROSFURACE
#define MICROSURFACEMAPDIRECTUV 0
#define METALLICWORKFLOW
#define ROUGHNESSSTOREINMETALMAPGREEN
#define METALLNESSSTOREINMETALMAPBLUE
#define METALLIC_REFLECTANCEDIRECTUV 0
#define REFLECTANCEDIRECTUV 0
#define ENVIRONMENTBRDF
#define NORMAL
#define BUMPDIRECTUV 0
#define NORMALXYSCALE
#define LIGHTMAPDIRECTUV 0
#define REFLECTION
#define REFLECTIONMAP_3D
#define REFLECTIONMAP_CUBIC
#define USESPHERICALFROMREFLECTIONMAP
#define SPHERICAL_HARMONICS
#define USESPHERICALINVERTEX
#define RADIANCEOCCLUSION
#define HORIZONOCCLUSION
#define PREPASS_IRRADIANCE_INDEX -1
#define PREPASS_ALBEDO_INDEX -1
#define PREPASS_DEPTH_INDEX -1
#define PREPASS_NORMAL_INDEX -1
#define PREPASS_POSITION_INDEX -1
#define PREPASS_VELOCITY_INDEX -1
#define PREPASS_REFLECTIVITY_INDEX -1
#define SCENE_MRT_COUNT 0
#define NUM_BONE_INFLUENCERS 0
#define BonesPerMesh 0
#define NUM_MORPH_INFLUENCERS 0
#define VIGNETTEBLENDMODEMULTIPLY
#define SAMPLER3DGREENDEPTH
#define SAMPLER3DBGRMAP
#define USEPHYSICALLIGHTFALLOFF
#define CLEARCOAT_TEXTUREDIRECTUV 0
#define CLEARCOAT_TEXTURE_ROUGHNESSDIRECTUV 0
#define CLEARCOAT_BUMPDIRECTUV 0
#define CLEARCOAT_REMAP_F0
#define CLEARCOAT_TINT_TEXTUREDIRECTUV 0
#define ANISOTROPIC_TEXTUREDIRECTUV 0
#define BRDF_V_HEIGHT_CORRELATED
#define MS_BRDF_ENERGY_CONSERVATION
#define SPECULAR_GLOSSINESS_ENERGY_CONSERVATION
#define SHEEN_TEXTUREDIRECTUV 0
#define SHEEN_TEXTURE_ROUGHNESSDIRECTUV 0
#define SS_THICKNESSANDMASK_TEXTUREDIRECTUV 0
#define SS_REFRACTIONINTENSITY_TEXTUREDIRECTUV 0
#define SS_TRANSLUCENCYINTENSITY_TEXTUREDIRECTUV 0
#define DEBUGMODE 0

#define SHADER_NAME fragment:pbr
#extension GL_EXT_shader_texture_lod : enable
#define CUSTOM_FRAGMENT_BEGIN
precision highp float;
#define FROMLINEARSPACE
uniform vec4 vEyePosition;
uniform vec3 vReflectionColor;
uniform vec4 vAlbedoColor;
uniform vec4 vLightingIntensity;
uniform vec4 vReflectivityColor;
uniform vec4 vMetallicReflectanceFactors;
uniform vec3 vEmissiveColor;
uniform float visibility;
uniform vec3 vAmbientColor;
uniform vec3 vReflectivityInfos;
uniform vec2 vReflectionInfos;
uniform mat4 reflectionMatrix;
uniform vec3 vReflectionMicrosurfaceInfos;
uniform vec3 vSphericalL00;
uniform vec3 vSphericalL1_1;
uniform vec3 vSphericalL10;
uniform vec3 vSphericalL11;
uniform vec3 vSphericalL2_2;
uniform vec3 vSphericalL2_1;
uniform vec3 vSphericalL20;
uniform vec3 vSphericalL21;
uniform vec3 vSphericalL22;
varying vec3 vPositionW;
varying vec2 vMainUV1;
varying vec3 vNormalW;
varying vec3 vEnvironmentIrradiance;
#define vReflectivityUV vMainUV1
uniform sampler2D reflectivitySampler;
#define sampleReflection(s, c) textureCube(s, c)
uniform samplerCube reflectionSampler;
#define sampleReflectionLod(s, c, l) textureCubeLodEXT(s, c, l)
uniform sampler2D environmentBrdfSampler;
const float PI = 3.1415926535897932384626433832795;
const float HALF_MIN = 5.96046448e-08;
const float LinearEncodePowerApprox = 2.2;
const float GammaEncodePowerApprox = 1.0 / LinearEncodePowerApprox;
const vec3 LuminanceEncodeApprox = vec3(0.2126, 0.7152, 0.0722);
const float Epsilon = 0.0000001;
#define saturate(x) clamp(x, 0.0, 1.0)
#define absEps(x) abs(x)+Epsilon
#define maxEps(x) max(x, Epsilon)
#define saturateEps(x) clamp(x, Epsilon, 1.0)
mat3 transposeMat3(mat3 inMatrix) {
    vec3 i0 = inMatrix[0];
    vec3 i1 = inMatrix[1];
    vec3 i2 = inMatrix[2];
    mat3 outMatrix = mat3(vec3(i0.x, i1.x, i2.x), vec3(i0.y, i1.y, i2.y), vec3(i0.z, i1.z, i2.z));
    return outMatrix;
}
mat3 inverseMat3(mat3 inMatrix) {
    float a00 = inMatrix[0][0], a01 = inMatrix[0][1], a02 = inMatrix[0][2];
    float a10 = inMatrix[1][0], a11 = inMatrix[1][1], a12 = inMatrix[1][2];
    float a20 = inMatrix[2][0], a21 = inMatrix[2][1], a22 = inMatrix[2][2];
    float b01 = a22 * a11 - a12 * a21;
    float b11 = -a22 * a10 + a12 * a20;
    float b21 = a21 * a10 - a11 * a20;
    float det = a00 * b01 + a01 * b11 + a02 * b21;
    return mat3(b01, (-a22 * a01 + a02 * a21), (a12 * a01 - a02 * a11), b11, (a22 * a00 - a02 * a20), (-a12 * a00 + a02 * a10), b21, (-a21 * a00 + a01 * a20), (a11 * a00 - a01 * a10)) / det;
}
float toLinearSpace(float color) {
    return pow(color, LinearEncodePowerApprox);
}
vec3 toLinearSpace(vec3 color) {
    return pow(color, vec3(LinearEncodePowerApprox));
}
vec4 toLinearSpace(vec4 color) {
    return vec4(pow(color.rgb, vec3(LinearEncodePowerApprox)), color.a);
}
vec3 toGammaSpace(vec3 color) {
    return pow(color, vec3(GammaEncodePowerApprox));
}
vec4 toGammaSpace(vec4 color) {
    return vec4(pow(color.rgb, vec3(GammaEncodePowerApprox)), color.a);
}
float toGammaSpace(float color) {
    return pow(color, GammaEncodePowerApprox);
}
float square(float value) {
    return value * value;
}
float pow5(float value) {
    float sq = value * value;
    return sq * sq * value;
}
float getLuminance(vec3 color) {
    return clamp(dot(color, LuminanceEncodeApprox), 0., 1.);
}
float getRand(vec2 seed) {
    return fract(sin(dot(seed.xy, vec2(12.9898, 78.233))) * 43758.5453);
}
float dither(vec2 seed, float varianceAmount) {
    float rand = getRand(seed);
    float dither = mix(-varianceAmount / 255.0, varianceAmount / 255.0, rand);
    return dither;
}
const float rgbdMaxRange = 255.0;
vec4 toRGBD(vec3 color) {
    float maxRGB = maxEps(max(color.r, max(color.g, color.b)));
    float D = max(rgbdMaxRange / maxRGB, 1.);
    D = clamp(floor(D) / 255.0, 0., 1.);
    vec3 rgb = color.rgb * D;
    rgb = toGammaSpace(rgb);
    return vec4(clamp(rgb, 0., 1.), D);
}
vec3 fromRGBD(vec4 rgbd) {
    rgbd.rgb = toLinearSpace(rgbd.rgb);
    return rgbd.rgb / rgbd.a;
}
vec3 parallaxCorrectNormal(vec3 vertexPos, vec3 origVec, vec3 cubeSize, vec3 cubePos) {
    vec3 invOrigVec = vec3(1.0, 1.0, 1.0) / origVec;
    vec3 halfSize = cubeSize * 0.5;
    vec3 intersecAtMaxPlane = (cubePos + halfSize - vertexPos) * invOrigVec;
    vec3 intersecAtMinPlane = (cubePos - halfSize - vertexPos) * invOrigVec;
    vec3 largestIntersec = max(intersecAtMaxPlane, intersecAtMinPlane);
    float distance = min(min(largestIntersec.x, largestIntersec.y), largestIntersec.z);
    vec3 intersectPositionWS = vertexPos + origVec * distance;
    return intersectPositionWS - cubePos;
}
bool testLightingForSSS(float diffusionProfile) {
    return diffusionProfile < 1.;
}
vec3 hemisphereCosSample(vec2 u) {
    float phi = 2. * PI * u.x;
    float cosTheta2 = 1. - u.y;
    float cosTheta = sqrt(cosTheta2);
    float sinTheta = sqrt(1. - cosTheta2);
    return vec3(sinTheta * cos(phi), sinTheta * sin(phi), cosTheta);
}
vec3 hemisphereImportanceSampleDggx(vec2 u, float a) {
    float phi = 2. * PI * u.x;
    float cosTheta2 = (1. - u.y) / (1. + (a + 1.) * ((a - 1.) * u.y));
    float cosTheta = sqrt(cosTheta2);
    float sinTheta = sqrt(1. - cosTheta2);
    return vec3(sinTheta * cos(phi), sinTheta * sin(phi), cosTheta);
}
vec3 hemisphereImportanceSampleDCharlie(vec2 u, float a) {
    float phi = 2. * PI * u.x;
    float sinTheta = pow(u.y, a / (2. * a + 1.));
    float cosTheta = sqrt(1. - sinTheta * sinTheta);
    return vec3(sinTheta * cos(phi), sinTheta * sin(phi), cosTheta);
}
#define RECIPROCAL_PI2 0.15915494
#define RECIPROCAL_PI 0.31830988618
#define MINIMUMVARIANCE 0.0005
float convertRoughnessToAverageSlope(float roughness) {
    return square(roughness) + MINIMUMVARIANCE;
}
float fresnelGrazingReflectance(float reflectance0) {
    float reflectance90 = saturate(reflectance0 * 25.0);
    return reflectance90;
}
vec2 getAARoughnessFactors(vec3 normalVector) {
    return vec2(0.);
}
vec4 applyImageProcessing(vec4 result) {
    result.rgb = toGammaSpace(result.rgb);
    result.rgb = saturate(result.rgb);
    return result;
}
vec3 computeEnvironmentIrradiance(vec3 normal) {
    return vSphericalL00 + vSphericalL1_1 * (normal.y) + vSphericalL10 * (normal.z) + vSphericalL11 * (normal.x) + vSphericalL2_2 * (normal.y * normal.x) + vSphericalL2_1 * (normal.y * normal.z) + vSphericalL20 * ((3.0 * normal.z * normal.z) - 1.0) + vSphericalL21 * (normal.z * normal.x) + vSphericalL22 * (normal.x * normal.x - (normal.y * normal.y));
}
struct preLightingInfo {
    vec3 lightOffset;
    float lightDistanceSquared;
    float lightDistance;
    float attenuation;
    vec3 L;
    vec3 H;
    float NdotV;
    float NdotLUnclamped;
    float NdotL;
    float VdotH;
    float roughness;
};
preLightingInfo computePointAndSpotPreLightingInfo(vec4 lightData, vec3 V, vec3 N) {
    preLightingInfo result;
    result.lightOffset = lightData.xyz - vPositionW;
    result.lightDistanceSquared = dot(result.lightOffset, result.lightOffset);
    result.lightDistance = sqrt(result.lightDistanceSquared);
    result.L = normalize(result.lightOffset);
    result.H = normalize(V + result.L);
    result.VdotH = saturate(dot(V, result.H));
    result.NdotLUnclamped = dot(N, result.L);
    result.NdotL = saturateEps(result.NdotLUnclamped);
    return result;
}
preLightingInfo computeDirectionalPreLightingInfo(vec4 lightData, vec3 V, vec3 N) {
    preLightingInfo result;
    result.lightDistance = length(-lightData.xyz);
    result.L = normalize(-lightData.xyz);
    result.H = normalize(V + result.L);
    result.VdotH = saturate(dot(V, result.H));
    result.NdotLUnclamped = dot(N, result.L);
    result.NdotL = saturateEps(result.NdotLUnclamped);
    return result;
}
preLightingInfo computeHemisphericPreLightingInfo(vec4 lightData, vec3 V, vec3 N) {
    preLightingInfo result;
    result.NdotL = dot(N, lightData.xyz) * 0.5 + 0.5;
    result.NdotL = saturateEps(result.NdotL);
    result.NdotLUnclamped = result.NdotL;
    return result;
}
float computeDistanceLightFalloff_Standard(vec3 lightOffset, float range) {
    return max(0., 1.0 - length(lightOffset) / range);
}
float computeDistanceLightFalloff_Physical(float lightDistanceSquared) {
    return 1.0 / maxEps(lightDistanceSquared);
}
float computeDistanceLightFalloff_GLTF(float lightDistanceSquared, float inverseSquaredRange) {
    float lightDistanceFalloff = 1.0 / maxEps(lightDistanceSquared);
    float factor = lightDistanceSquared * inverseSquaredRange;
    float attenuation = saturate(1.0 - factor * factor);
    attenuation *= attenuation;
    lightDistanceFalloff *= attenuation;
    return lightDistanceFalloff;
}
float computeDistanceLightFalloff(vec3 lightOffset, float lightDistanceSquared, float range, float inverseSquaredRange) {
    return computeDistanceLightFalloff_Physical(lightDistanceSquared);
}
float computeDirectionalLightFalloff_Standard(vec3 lightDirection, vec3 directionToLightCenterW, float cosHalfAngle, float exponent) {
    float falloff = 0.0;
    float cosAngle = maxEps(dot(-lightDirection, directionToLightCenterW));
    if(cosAngle >= cosHalfAngle) {
        falloff = max(0., pow(cosAngle, exponent));
    }
    return falloff;
}
float computeDirectionalLightFalloff_Physical(vec3 lightDirection, vec3 directionToLightCenterW, float cosHalfAngle) {
    const float kMinusLog2ConeAngleIntensityRatio = 6.64385618977;
    float concentrationKappa = kMinusLog2ConeAngleIntensityRatio / (1.0 - cosHalfAngle);
    vec4 lightDirectionSpreadSG = vec4(-lightDirection * concentrationKappa, -concentrationKappa);
    float falloff = exp2(dot(vec4(directionToLightCenterW, 1.0), lightDirectionSpreadSG));
    return falloff;
}
float computeDirectionalLightFalloff_GLTF(vec3 lightDirection, vec3 directionToLightCenterW, float lightAngleScale, float lightAngleOffset) {
    float cd = dot(-lightDirection, directionToLightCenterW);
    float falloff = saturate(cd * lightAngleScale + lightAngleOffset);
    falloff *= falloff;
    return falloff;
}
float computeDirectionalLightFalloff(vec3 lightDirection, vec3 directionToLightCenterW, float cosHalfAngle, float exponent, float lightAngleScale, float lightAngleOffset) {
    return computeDirectionalLightFalloff_Physical(lightDirection, directionToLightCenterW, cosHalfAngle);
}
#define FRESNEL_MAXIMUM_ON_ROUGH 0.25
vec3 getEnergyConservationFactor(const vec3 specularEnvironmentR0, const vec3 environmentBrdf) {
    return 1.0 + specularEnvironmentR0 * (1.0 / environmentBrdf.y - 1.0);
}
vec3 getBRDFLookup(float NdotV, float perceptualRoughness) {
    vec2 UV = vec2(NdotV, perceptualRoughness);
    vec4 brdfLookup = texture2D(environmentBrdfSampler, UV);
    return brdfLookup.rgb;
}
vec3 getReflectanceFromBRDFLookup(const vec3 specularEnvironmentR0, const vec3 specularEnvironmentR90, const vec3 environmentBrdf) {
    vec3 reflectance = (specularEnvironmentR90 - specularEnvironmentR0) * environmentBrdf.x + specularEnvironmentR0 * environmentBrdf.y;
    return reflectance;
}
vec3 getReflectanceFromBRDFLookup(const vec3 specularEnvironmentR0, const vec3 environmentBrdf) {
    vec3 reflectance = mix(environmentBrdf.xxx, environmentBrdf.yyy, specularEnvironmentR0);
    return reflectance;
}
vec3 fresnelSchlickGGX(float VdotH, vec3 reflectance0, vec3 reflectance90) {
    return reflectance0 + (reflectance90 - reflectance0) * pow5(1.0 - VdotH);
}
float fresnelSchlickGGX(float VdotH, float reflectance0, float reflectance90) {
    return reflectance0 + (reflectance90 - reflectance0) * pow5(1.0 - VdotH);
}
float normalDistributionFunction_TrowbridgeReitzGGX(float NdotH, float alphaG) {
    float a2 = square(alphaG);
    float d = NdotH * NdotH * (a2 - 1.0) + 1.0;
    return a2 / (PI * d * d);
}
float smithVisibility_GGXCorrelated(float NdotL, float NdotV, float alphaG) {
    float a2 = alphaG * alphaG;
    float GGXV = NdotL * sqrt(NdotV * (NdotV - a2 * NdotV) + a2);
    float GGXL = NdotV * sqrt(NdotL * (NdotL - a2 * NdotL) + a2);
    return 0.5 / (GGXV + GGXL);
}
float diffuseBRDF_Burley(float NdotL, float NdotV, float VdotH, float roughness) {
    float diffuseFresnelNV = pow5(saturateEps(1.0 - NdotL));
    float diffuseFresnelNL = pow5(saturateEps(1.0 - NdotV));
    float diffuseFresnel90 = 0.5 + 2.0 * VdotH * VdotH * roughness;
    float fresnel = (1.0 + (diffuseFresnel90 - 1.0) * diffuseFresnelNL) *
        (1.0 + (diffuseFresnel90 - 1.0) * diffuseFresnelNV);
    return fresnel / PI;
}
#define CLEARCOATREFLECTANCE90 1.0
struct lightingInfo {
    vec3 diffuse;
};
float adjustRoughnessFromLightProperties(float roughness, float lightRadius, float lightDistance) {
    float lightRoughness = lightRadius / lightDistance;
    float totalRoughness = saturate(lightRoughness + roughness);
    return totalRoughness;
}
vec3 computeHemisphericDiffuseLighting(preLightingInfo info, vec3 lightColor, vec3 groundColor) {
    return mix(groundColor, lightColor, info.NdotL);
}
vec3 computeDiffuseLighting(preLightingInfo info, vec3 lightColor) {
    float diffuseTerm = diffuseBRDF_Burley(info.NdotL, info.NdotV, info.VdotH, info.roughness);
    return diffuseTerm * info.attenuation * info.NdotL * lightColor;
}
#define inline
vec3 computeProjectionTextureDiffuseLighting(sampler2D projectionLightSampler, mat4 textureProjectionMatrix) {
    vec4 strq = textureProjectionMatrix * vec4(vPositionW, 1.0);
    strq /= strq.w;
    vec3 textureColor = texture2D(projectionLightSampler, strq.xy).rgb;
    return toLinearSpace(textureColor);
}
float getLodFromAlphaG(float cubeMapDimensionPixels, float microsurfaceAverageSlope) {
    float microsurfaceAverageSlopeTexels = cubeMapDimensionPixels * microsurfaceAverageSlope;
    float lod = log2(microsurfaceAverageSlopeTexels);
    return lod;
}
float getLinearLodFromRoughness(float cubeMapDimensionPixels, float roughness) {
    float lod = log2(cubeMapDimensionPixels) * roughness;
    return lod;
}
float environmentRadianceOcclusion(float ambientOcclusion, float NdotVUnclamped) {
    float temp = NdotVUnclamped + ambientOcclusion;
    return saturate(square(temp) - 1.0 + ambientOcclusion);
}
float environmentHorizonOcclusion(vec3 view, vec3 normal, vec3 geometricNormal) {
    vec3 reflection = reflect(view, normal);
    float temp = saturate(1.0 + 1.1 * dot(reflection, geometricNormal));
    return square(temp);
}
vec3 computeFixedEquirectangularCoords(vec4 worldPos, vec3 worldNormal, vec3 direction) {
    float lon = atan(direction.z, direction.x);
    float lat = acos(direction.y);
    vec2 sphereCoords = vec2(lon, lat) * RECIPROCAL_PI2 * 2.0;
    float s = sphereCoords.x * 0.5 + 0.5;
    float t = sphereCoords.y;
    return vec3(s, t, 0);
}
vec3 computeMirroredFixedEquirectangularCoords(vec4 worldPos, vec3 worldNormal, vec3 direction) {
    float lon = atan(direction.z, direction.x);
    float lat = acos(direction.y);
    vec2 sphereCoords = vec2(lon, lat) * RECIPROCAL_PI2 * 2.0;
    float s = sphereCoords.x * 0.5 + 0.5;
    float t = sphereCoords.y;
    return vec3(1.0 - s, t, 0);
}
vec3 computeEquirectangularCoords(vec4 worldPos, vec3 worldNormal, vec3 eyePosition, mat4 reflectionMatrix) {
    vec3 cameraToVertex = normalize(worldPos.xyz - eyePosition);
    vec3 r = normalize(reflect(cameraToVertex, worldNormal));
    r = vec3(reflectionMatrix * vec4(r, 0));
    float lon = atan(r.z, r.x);
    float lat = acos(r.y);
    vec2 sphereCoords = vec2(lon, lat) * RECIPROCAL_PI2 * 2.0;
    float s = sphereCoords.x * 0.5 + 0.5;
    float t = sphereCoords.y;
    return vec3(s, t, 0);
}
vec3 computeSphericalCoords(vec4 worldPos, vec3 worldNormal, mat4 view, mat4 reflectionMatrix) {
    vec3 viewDir = normalize(vec3(view * worldPos));
    vec3 viewNormal = normalize(vec3(view * vec4(worldNormal, 0.0)));
    vec3 r = reflect(viewDir, viewNormal);
    r = vec3(reflectionMatrix * vec4(r, 0));
    r.z = r.z - 1.0;
    float m = 2.0 * length(r);
    return vec3(r.x / m + 0.5, 1.0 - r.y / m - 0.5, 0);
}
vec3 computePlanarCoords(vec4 worldPos, vec3 worldNormal, vec3 eyePosition, mat4 reflectionMatrix) {
    vec3 viewDir = worldPos.xyz - eyePosition;
    vec3 coords = normalize(reflect(viewDir, worldNormal));
    return vec3(reflectionMatrix * vec4(coords, 1));
}
vec3 computeCubicCoords(vec4 worldPos, vec3 worldNormal, vec3 eyePosition, mat4 reflectionMatrix) {
    vec3 viewDir = normalize(worldPos.xyz - eyePosition);
    vec3 coords = reflect(viewDir, worldNormal);
    coords = vec3(reflectionMatrix * vec4(coords, 0));
    return coords;
}
vec3 computeCubicLocalCoords(vec4 worldPos, vec3 worldNormal, vec3 eyePosition, mat4 reflectionMatrix, vec3 reflectionSize, vec3 reflectionPosition) {
    vec3 viewDir = normalize(worldPos.xyz - eyePosition);
    vec3 coords = reflect(viewDir, worldNormal);
    coords = parallaxCorrectNormal(worldPos.xyz, coords, reflectionSize, reflectionPosition);
    coords = vec3(reflectionMatrix * vec4(coords, 0));
    return coords;
}
vec3 computeProjectionCoords(vec4 worldPos, mat4 view, mat4 reflectionMatrix) {
    return vec3(reflectionMatrix * (view * worldPos));
}
vec3 computeSkyBoxCoords(vec3 positionW, mat4 reflectionMatrix) {
    return vec3(reflectionMatrix * vec4(positionW, 1.));
}
vec3 computeReflectionCoords(vec4 worldPos, vec3 worldNormal) {
    return computeCubicCoords(worldPos, worldNormal, vEyePosition.xyz, reflectionMatrix);
}
#define CUSTOM_FRAGMENT_DEFINITIONS
struct albedoOpacityOutParams {
    vec3 surfaceAlbedo;
    float alpha;
};
#define pbr_inline
void albedoOpacityBlock(const in vec4 vAlbedoColor, out albedoOpacityOutParams outParams) {
    vec3 surfaceAlbedo = vAlbedoColor.rgb;
    float alpha = vAlbedoColor.a;
    #define CUSTOM_FRAGMENT_UPDATE_ALBEDO
    outParams.surfaceAlbedo = surfaceAlbedo;
    outParams.alpha = alpha;
}
struct reflectivityOutParams {
    float microSurface;
    float roughness;
    vec3 surfaceReflectivityColor;
    vec3 surfaceAlbedo;
};
#define pbr_inline
void reflectivityBlock(const in vec4 vReflectivityColor, const in vec3 surfaceAlbedo, const in vec4 metallicReflectanceFactors, const in vec3 reflectivityInfos, const in vec4 surfaceMetallicOrReflectivityColorMap, out reflectivityOutParams outParams) {
    float microSurface = vReflectivityColor.a;
    vec3 surfaceReflectivityColor = vReflectivityColor.rgb;
    vec2 metallicRoughness = surfaceReflectivityColor.rg;
    metallicRoughness.r *= surfaceMetallicOrReflectivityColorMap.b;
    metallicRoughness.g *= surfaceMetallicOrReflectivityColorMap.g;
    #define CUSTOM_FRAGMENT_UPDATE_METALLICROUGHNESS
    microSurface = 1.0 - metallicRoughness.g;
    vec3 baseColor = surfaceAlbedo;
    vec3 metallicF0 = metallicReflectanceFactors.rgb;
    outParams.surfaceAlbedo = mix(baseColor.rgb * (1.0 - metallicF0), vec3(0., 0., 0.), metallicRoughness.r);
    surfaceReflectivityColor = mix(metallicF0, baseColor, metallicRoughness.r);
    microSurface = saturate(microSurface);
    float roughness = 1. - microSurface;
    outParams.microSurface = microSurface;
    outParams.roughness = roughness;
    outParams.surfaceReflectivityColor = surfaceReflectivityColor;
}
struct ambientOcclusionOutParams {
    vec3 ambientOcclusionColor;
};
#define pbr_inline
void ambientOcclusionBlock(out ambientOcclusionOutParams outParams) {
    vec3 ambientOcclusionColor = vec3(1., 1., 1.);
    outParams.ambientOcclusionColor = ambientOcclusionColor;
}
struct reflectionOutParams {
    vec4 environmentRadiance;
    vec3 environmentIrradiance;
    vec3 reflectionCoords;
};
#define pbr_inline
void createReflectionCoords(const in vec3 vPositionW, const in vec3 normalW, out vec3 reflectionCoords) {
    vec3 reflectionVector = computeReflectionCoords(vec4(vPositionW, 1.0), normalW);
    reflectionCoords = reflectionVector;
}
#define pbr_inline
#define inline
void sampleReflectionTexture(const in float alphaG, const in vec3 vReflectionMicrosurfaceInfos, const in vec2 vReflectionInfos, const in vec3 vReflectionColor, const in samplerCube reflectionSampler, const vec3 reflectionCoords, out vec4 environmentRadiance) {
    float reflectionLOD = getLodFromAlphaG(vReflectionMicrosurfaceInfos.x, alphaG);
    reflectionLOD = reflectionLOD * vReflectionMicrosurfaceInfos.y + vReflectionMicrosurfaceInfos.z;
    float requestedReflectionLOD = reflectionLOD;
    environmentRadiance = sampleReflectionLod(reflectionSampler, reflectionCoords, reflectionLOD);
    environmentRadiance.rgb *= vReflectionInfos.x;
    environmentRadiance.rgb *= vReflectionColor.rgb;
}
#define pbr_inline
#define inline
void reflectionBlock(const in vec3 vPositionW, const in vec3 normalW, const in float alphaG, const in vec3 vReflectionMicrosurfaceInfos, const in vec2 vReflectionInfos, const in vec3 vReflectionColor, const in samplerCube reflectionSampler, const in vec3 vEnvironmentIrradiance, out reflectionOutParams outParams) {
    vec4 environmentRadiance = vec4(0., 0., 0., 0.);
    vec3 reflectionCoords = vec3(0.);
    createReflectionCoords(vPositionW, normalW, reflectionCoords);
    sampleReflectionTexture(alphaG, vReflectionMicrosurfaceInfos, vReflectionInfos, vReflectionColor, reflectionSampler, reflectionCoords, environmentRadiance);
    vec3 environmentIrradiance = vec3(0., 0., 0.);
    environmentIrradiance = vEnvironmentIrradiance;
    environmentIrradiance *= vReflectionColor.rgb;
    outParams.environmentRadiance = environmentRadiance;
    outParams.environmentIrradiance = environmentIrradiance;
    outParams.reflectionCoords = reflectionCoords;
}
struct clearcoatOutParams {
    vec3 specularEnvironmentR0;
    float conservationFactor;
    vec3 clearCoatNormalW;
    vec2 clearCoatAARoughnessFactors;
    float clearCoatIntensity;
    float clearCoatRoughness;
    vec3 finalClearCoatRadianceScaled;
    vec3 energyConservationFactorClearCoat;
};
struct subSurfaceOutParams {
    vec3 specularEnvironmentReflectance;
};
void main(void) {
    #define CUSTOM_FRAGMENT_MAIN_BEGIN
    vec3 viewDirectionW = normalize(vEyePosition.xyz - vPositionW);
    vec3 normalW = normalize(vNormalW);
    vec3 geometricNormalW = normalW;
    vec2 uvOffset = vec2(0.0, 0.0);
    albedoOpacityOutParams albedoOpacityOut;
    albedoOpacityBlock(vAlbedoColor, albedoOpacityOut);
    vec3 surfaceAlbedo = albedoOpacityOut.surfaceAlbedo;
    float alpha = albedoOpacityOut.alpha;
    #define CUSTOM_FRAGMENT_UPDATE_ALPHA
    #define CUSTOM_FRAGMENT_BEFORE_LIGHTS
    ambientOcclusionOutParams aoOut;
    ambientOcclusionBlock(aoOut);
    vec3 baseColor = surfaceAlbedo;
    reflectivityOutParams reflectivityOut;
    vec4 surfaceMetallicOrReflectivityColorMap = texture2D(reflectivitySampler, vReflectivityUV + uvOffset);
    vec4 baseReflectivity = surfaceMetallicOrReflectivityColorMap;
    vec4 metallicReflectanceFactors = vMetallicReflectanceFactors;
    reflectivityBlock(vReflectivityColor, surfaceAlbedo, metallicReflectanceFactors, vReflectivityInfos, surfaceMetallicOrReflectivityColorMap, reflectivityOut);
    float microSurface = reflectivityOut.microSurface;
    float roughness = reflectivityOut.roughness;
    surfaceAlbedo = reflectivityOut.surfaceAlbedo;
    float NdotVUnclamped = dot(normalW, viewDirectionW);
    float NdotV = absEps(NdotVUnclamped);
    float alphaG = convertRoughnessToAverageSlope(roughness);
    vec2 AARoughnessFactors = getAARoughnessFactors(normalW.xyz);
    vec3 environmentBrdf = getBRDFLookup(NdotV, roughness);
    float ambientMonochrome = getLuminance(aoOut.ambientOcclusionColor);
    float seo = environmentRadianceOcclusion(ambientMonochrome, NdotVUnclamped);
    reflectionOutParams reflectionOut;
    reflectionBlock(vPositionW, normalW, alphaG, vReflectionMicrosurfaceInfos, vReflectionInfos, vReflectionColor, reflectionSampler, vEnvironmentIrradiance, reflectionOut);
    float reflectance = max(max(reflectivityOut.surfaceReflectivityColor.r, reflectivityOut.surfaceReflectivityColor.g), reflectivityOut.surfaceReflectivityColor.b);
    vec3 specularEnvironmentR0 = reflectivityOut.surfaceReflectivityColor.rgb;
    vec3 specularEnvironmentR90 = vec3(metallicReflectanceFactors.a);
    clearcoatOutParams clearcoatOut;
    clearcoatOut.specularEnvironmentR0 = specularEnvironmentR0;
    vec3 specularEnvironmentReflectance = getReflectanceFromBRDFLookup(clearcoatOut.specularEnvironmentR0, specularEnvironmentR90, environmentBrdf);
    specularEnvironmentReflectance *= seo;
    subSurfaceOutParams subSurfaceOut;
    subSurfaceOut.specularEnvironmentReflectance = specularEnvironmentReflectance;
    vec3 diffuseBase = vec3(0., 0., 0.);
    preLightingInfo preInfo;
    lightingInfo info;
    float shadow = 1.;
    vec3 energyConservationFactor = getEnergyConservationFactor(clearcoatOut.specularEnvironmentR0, environmentBrdf);
    vec3 finalIrradiance = reflectionOut.environmentIrradiance;
    finalIrradiance *= surfaceAlbedo.rgb;
    finalIrradiance *= vLightingIntensity.z;
    finalIrradiance *= aoOut.ambientOcclusionColor;
    vec3 finalRadiance = reflectionOut.environmentRadiance.rgb;
    finalRadiance *= subSurfaceOut.specularEnvironmentReflectance;
    vec3 finalRadianceScaled = finalRadiance * vLightingIntensity.z;
    finalRadianceScaled *= energyConservationFactor;
    vec3 finalDiffuse = diffuseBase;
    finalDiffuse *= surfaceAlbedo.rgb;
    finalDiffuse = max(finalDiffuse, 0.0);
    finalDiffuse *= vLightingIntensity.x;
    vec3 finalAmbient = vAmbientColor;
    finalAmbient *= surfaceAlbedo.rgb;
    vec3 finalEmissive = vEmissiveColor;
    finalEmissive *= vLightingIntensity.y;
    vec3 ambientOcclusionForDirectDiffuse = aoOut.ambientOcclusionColor;
    finalAmbient *= aoOut.ambientOcclusionColor;
    finalDiffuse *= ambientOcclusionForDirectDiffuse;
    #define CUSTOM_FRAGMENT_BEFORE_FINALCOLORCOMPOSITION
    vec4 finalColor = vec4(finalAmbient +
        finalDiffuse +
        finalIrradiance +
        finalRadianceScaled +
        finalEmissive, alpha);
    #define CUSTOM_FRAGMENT_BEFORE_FOG
    finalColor = max(finalColor, 0.0);
    finalColor = applyImageProcessing(finalColor);
    finalColor.a *= visibility;
    #define CUSTOM_FRAGMENT_BEFORE_FRAGCOLOR
    gl_FragColor = finalColor;
}
 Copy code 

copyright notice
author[Na Ming],Please bring the original link to reprint, thank you.
https://en.qdmana.com/2021/08/20210826004746885r.html

Random recommended