Skip to content

Commit

Permalink
Simplify PBR lighting shaders
Browse files Browse the repository at this point in the history
  • Loading branch information
Jeshurun Hembd committed May 21, 2024
1 parent 8f21b06 commit c4da3f4
Show file tree
Hide file tree
Showing 9 changed files with 67 additions and 185 deletions.

This file was deleted.

41 changes: 18 additions & 23 deletions packages/engine/Source/Shaders/Builtin/Functions/pbrLighting.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ float smithVisibilityG1(float NdotV, float roughness)
return NdotV / (NdotV * (1.0 - k) + k);
}

/**
* geometric shadowing function
* TODO: explain
*/
float smithVisibilityGGX(float roughness, float NdotL, float NdotV)
{
return (
Expand All @@ -56,6 +60,10 @@ float smithVisibilityGGX(float roughness, float NdotL, float NdotV)
) / (4.0 * NdotL * NdotV);
}

/**
* microfacet distribution function
* TODO: explain
*/
float GGX(float roughness, float NdotH)
{
float roughnessSquared = roughness * roughness;
Expand All @@ -69,38 +77,25 @@ float GGX(float roughness, float NdotH)
* rendering. This function only handles direct lighting.
* <p>
* This function only handles the lighting calculations. Metallic/roughness
* and specular/glossy must be handled separately. See {@czm_pbrMetallicRoughnessMaterial}, {@czm_pbrSpecularGlossinessMaterial} and {@czm_defaultPbrMaterial}
* and specular/glossy must be handled separately. See {@MaterialStageFS}
* </p>
*
* @name czm_pbrlighting
* @name czm_pbrLighting
* @glslFunction
*
* @param {vec3} positionEC The position of the fragment in eye coordinates
* @param {vec3} normalEC The surface normal in eye coordinates
* @param {vec3} lightDirectionEC Unit vector pointing to the light source in eye coordinates.
* @param {vec3} lightColorHdr radiance of the light source. This is a HDR value.
* @param {czm_pbrParameters} The computed PBR parameters.
* @param {czm_modelMaterial} The material properties.
* @return {vec3} The computed HDR color
*
* @example
* czm_pbrParameters pbrParameters = czm_pbrMetallicRoughnessMaterial(
* baseColor,
* metallic,
* roughness
* );
* vec3 color = czm_pbrlighting(
* positionEC,
* normalEC,
* lightDirectionEC,
* lightColorHdr,
* pbrParameters);
*/
vec3 czm_pbrLighting(
vec3 positionEC,
vec3 normalEC,
vec3 lightDirectionEC,
vec3 lightColorHdr,
czm_pbrParameters pbrParameters
czm_modelMaterial material
)
{
vec3 v = -normalize(positionEC);
Expand All @@ -109,24 +104,24 @@ vec3 czm_pbrLighting(
vec3 n = normalEC;
float VdotH = clamp(dot(v, h), 0.0, 1.0);

vec3 f0 = pbrParameters.f0;
vec3 f0 = material.specular;
float reflectance = max(max(f0.r, f0.g), f0.b);
// Typical dielectrics will have reflectance 0.04, so f90 will be 1.0.
// In this case, at grazing angle, all incident energy is reflected.
vec3 f90 = vec3(clamp(reflectance * 25.0, 0.0, 1.0));
vec3 F = fresnelSchlick2(f0, f90, VdotH);

#if defined(USE_SPECULAR)
F *= pbrParameters.specularWeight;
F *= material.specularWeight;
#endif

float alpha = pbrParameters.roughness;
float alpha = material.roughness;
#ifdef USE_ANISOTROPY
mat3 tbn = mat3(pbrParameters.anisotropicT, pbrParameters.anisotropicB, n);
mat3 tbn = mat3(material.anisotropicT, material.anisotropicB, n);
vec3 lightDirection = l * tbn;
vec3 viewDirection = v * tbn;
vec3 halfwayDirection = h * tbn;
float anisotropyStrength = pbrParameters.anisotropyStrength;
float anisotropyStrength = material.anisotropyStrength;
float tangentialRoughness = mix(alpha, 1.0, anisotropyStrength * anisotropyStrength);
float G = smithVisibilityGGX_anisotropic(alpha, tangentialRoughness, lightDirection, viewDirection);
float D = GGX_anisotropic(alpha, tangentialRoughness, halfwayDirection);
Expand All @@ -141,7 +136,7 @@ vec3 czm_pbrLighting(

vec3 specularContribution = F * G * D;

vec3 diffuseColor = pbrParameters.diffuseColor;
vec3 diffuseColor = material.diffuse;
// F here represents the specular contribution
vec3 diffuseContribution = (1.0 - F) * lambertianDiffuse(diffuseColor);

Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
* @name czm_modelMaterial
* @glslStruct
*
* TODO: is this used externally? Can we rename diffuse and specular?
*
* @property {vec3} diffuse Incoming light that scatters evenly in all directions.
* @property {float} alpha Alpha of this material. 0.0 is completely transparent; 1.0 is completely opaque.
* @property {vec3} specular Color of reflected light at normal incidence in PBR materials. This is sometimes referred to as f0 in the literature.
Expand Down
24 changes: 0 additions & 24 deletions packages/engine/Source/Shaders/Builtin/Structs/pbrParameters.glsl

This file was deleted.

40 changes: 20 additions & 20 deletions packages/engine/Source/Shaders/Model/ImageBasedLightingStageFS.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ vec3 proceduralIBL(
vec3 normalEC,
vec3 lightDirectionEC,
vec3 lightColorHdr,
czm_pbrParameters pbrParameters
czm_modelMaterial material
) {
vec3 v = -normalize(positionEC);
vec3 positionWC = vec3(czm_inverseView * vec4(positionEC, 1.0));
Expand All @@ -24,9 +24,9 @@ vec3 proceduralIBL(
r = -normalize(czm_temeToPseudoFixed * r);
r.x = -r.x;

vec3 diffuseColor = pbrParameters.diffuseColor;
float roughness = pbrParameters.roughness;
vec3 f0 = pbrParameters.f0;
vec3 diffuseColor = material.diffuse;
float roughness = material.roughness;
vec3 f0 = material.specular;

float inverseRoughness = 1.04 - roughness;
inverseRoughness *= inverseRoughness;
Expand Down Expand Up @@ -71,7 +71,7 @@ vec3 proceduralIBL(
vec3 specularColor = czm_srgbToLinear(f0 * brdfLut.x + brdfLut.y);
vec3 specularContribution = specularIrradiance * specularColor * model_iblFactor.y;
#ifdef USE_SPECULAR
specularContribution *= pbrParameters.specularWeight;
specularContribution *= material.specularWeight;
#endif
vec3 diffuseContribution = diffuseIrradiance * diffuseColor * model_iblFactor.x;
vec3 iblColor = specularContribution + diffuseContribution;
Expand All @@ -87,14 +87,14 @@ vec3 proceduralIBL(
}

#ifdef DIFFUSE_IBL
vec3 computeDiffuseIBL(czm_pbrParameters pbrParameters, vec3 cubeDir)
vec3 computeDiffuseIBL(czm_modelMaterial material, vec3 cubeDir)
{
#ifdef CUSTOM_SPHERICAL_HARMONICS
vec3 diffuseIrradiance = czm_sphericalHarmonics(cubeDir, model_sphericalHarmonicCoefficients);
#else
vec3 diffuseIrradiance = czm_sphericalHarmonics(cubeDir, czm_sphericalHarmonicCoefficients);
#endif
return diffuseIrradiance * pbrParameters.diffuseColor;
return diffuseIrradiance * material.diffuse;
}
#endif

Expand All @@ -111,10 +111,10 @@ vec3 sampleSpecularEnvironment(vec3 cubeDir, float roughness)
return czm_sampleOctahedralProjection(czm_specularEnvironmentMaps, czm_specularEnvironmentMapSize, cubeDir, lod, maxLod);
#endif
}
vec3 computeSpecularIBL(czm_pbrParameters pbrParameters, vec3 cubeDir, float NdotV, float VdotH)
vec3 computeSpecularIBL(czm_modelMaterial material, vec3 cubeDir, float NdotV, float VdotH)
{
float roughness = pbrParameters.roughness;
vec3 f0 = pbrParameters.f0;
float roughness = material.roughness;
vec3 f0 = material.specular;

float reflectance = max(max(f0.r, f0.g), f0.b);
vec3 f90 = vec3(clamp(reflectance * 25.0, 0.0, 1.0));
Expand All @@ -125,7 +125,7 @@ vec3 computeSpecularIBL(czm_pbrParameters pbrParameters, vec3 cubeDir, float Ndo
specularIBL *= F * brdfLut.x + brdfLut.y;

#ifdef USE_SPECULAR
specularIBL *= pbrParameters.specularWeight;
specularIBL *= material.specularWeight;
#endif

return f0 * specularIBL;
Expand All @@ -137,7 +137,7 @@ vec3 textureIBL(
vec3 positionEC,
vec3 normalEC,
vec3 lightDirectionEC,
czm_pbrParameters pbrParameters
czm_modelMaterial material
) {
vec3 v = -normalize(positionEC);
vec3 n = normalEC;
Expand All @@ -157,16 +157,16 @@ vec3 textureIBL(
vec3 cubeDir = normalize(cubeDirTransform * normalize(reflect(-v, n)));

#ifdef DIFFUSE_IBL
vec3 diffuseContribution = computeDiffuseIBL(pbrParameters, cubeDir);
vec3 diffuseContribution = computeDiffuseIBL(material, cubeDir);
#else
vec3 diffuseContribution = vec3(0.0);
#endif

#ifdef USE_ANISOTROPY
// Update environment map sampling direction to account for anisotropic distortion of specular reflection
float roughness = pbrParameters.roughness;
vec3 anisotropyDirection = pbrParameters.anisotropicB;
float anisotropyStrength = pbrParameters.anisotropyStrength;
float roughness = material.roughness;
vec3 anisotropyDirection = material.anisotropicB;
float anisotropyStrength = material.anisotropyStrength;

vec3 anisotropicTangent = cross(anisotropyDirection, v);
vec3 anisotropicNormal = cross(anisotropicTangent, anisotropyDirection);
Expand All @@ -177,7 +177,7 @@ vec3 textureIBL(
#endif

#ifdef SPECULAR_IBL
vec3 specularContribution = computeSpecularIBL(pbrParameters, cubeDir, NdotV, VdotH);
vec3 specularContribution = computeSpecularIBL(material, cubeDir, NdotV, VdotH);
#else
vec3 specularContribution = vec3(0.0);
#endif
Expand All @@ -191,15 +191,15 @@ vec3 imageBasedLightingStage(
vec3 normalEC,
vec3 lightDirectionEC,
vec3 lightColorHdr,
czm_pbrParameters pbrParameters
czm_modelMaterial material
) {
#if defined(DIFFUSE_IBL) || defined(SPECULAR_IBL)
// Environment maps were provided, use them for IBL
return textureIBL(
positionEC,
normalEC,
lightDirectionEC,
pbrParameters
material
);
#else
// Use the procedural IBL if there are no environment maps
Expand All @@ -208,7 +208,7 @@ vec3 imageBasedLightingStage(
normalEC,
lightDirectionEC,
lightColorHdr,
pbrParameters
material
);
#endif
}
Loading

0 comments on commit c4da3f4

Please sign in to comment.