Skip to content

Commit

Permalink
refactor: pbr shader clean up
Browse files Browse the repository at this point in the history
  • Loading branch information
shensi.zxd committed Sep 17, 2021
1 parent 8e2e9e7 commit 8e6636b
Show file tree
Hide file tree
Showing 11 changed files with 182 additions and 240 deletions.
2 changes: 1 addition & 1 deletion packages/core/src/material/PBRSpecularMaterial.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { PBRBaseMaterial } from "./PBRBaseMaterial";
*/
export class PBRSpecularMaterial extends PBRBaseMaterial {
private static _specularColorProp = Shader.getPropertyByName("u_specularColor");
private static _glossinessProp = Shader.getPropertyByName("u_glossinessFactor");
private static _glossinessProp = Shader.getPropertyByName("u_glossiness");
private static _specularGlossinessTextureProp = Shader.getPropertyByName("u_specularGlossinessSampler");

/**
Expand Down
1 change: 0 additions & 1 deletion packages/core/src/shaderlib/extra/pbr-specular.fs.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@

#include <pbr_frag_define>
#include <pbr_helper>
#include <normal_get>

void main() {
#include <pbr_frag>
Expand Down
1 change: 0 additions & 1 deletion packages/core/src/shaderlib/extra/pbr.fs.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@

#include <pbr_frag_define>
#include <pbr_helper>
#include <normal_get>

void main() {
#include <pbr_frag>
Expand Down
16 changes: 8 additions & 8 deletions packages/core/src/shaderlib/pbr/brdf.glsl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
vec3 F_Schlick( const in vec3 specularColor, const in float dotLH ) {
vec3 F_Schlick(vec3 specularColor, float dotLH ) {

// Original approximation by Christophe Schlick '94
// float fresnel = pow( 1.0 - dotLH, 5.0 );
Expand All @@ -9,11 +9,11 @@ vec3 F_Schlick( const in vec3 specularColor, const in float dotLH ) {

return ( 1.0 - specularColor ) * fresnel + specularColor;

} // validated
}

// Moving Frostbite to Physically Based Rendering 3.0 - page 12, listing 2
// https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf
float G_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {
float G_GGX_SmithCorrelated(float alpha, float dotNL, float dotNV ) {

float a2 = pow2( alpha );

Expand All @@ -28,7 +28,7 @@ float G_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const i
// Microfacet Models for Refraction through Rough Surfaces - equation (33)
// http://graphicrants.blogspot.com/2013/08/specular-brdf-reference.html
// alpha is "roughness squared" in Disney’s reparameterization
float D_GGX( const in float alpha, const in float dotNH ) {
float D_GGX(float alpha, float dotNH ) {

float a2 = pow2( alpha );

Expand All @@ -39,16 +39,16 @@ float D_GGX( const in float alpha, const in float dotNH ) {
}

// GGX Distribution, Schlick Fresnel, GGX-Smith Visibility
vec3 BRDF_Specular_GGX( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float roughness ) {
vec3 BRDF_Specular_GGX(vec3 incidentDirection, GeometricContext geometry, vec3 specularColor, float roughness ) {

float alpha = pow2( roughness ); // UE4's roughness

vec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );
vec3 halfDir = normalize( incidentDirection + geometry.viewDir );

float dotNL = saturate( dot( geometry.normal, incidentLight.direction ) );
float dotNL = saturate( dot( geometry.normal, incidentDirection ) );
float dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );
float dotNH = saturate( dot( geometry.normal, halfDir ) );
float dotLH = saturate( dot( incidentLight.direction, halfDir ) );
float dotLH = saturate( dot( incidentDirection, halfDir ) );

vec3 F = F_Schlick( specularColor, dotLH );

Expand Down
55 changes: 0 additions & 55 deletions packages/core/src/shaderlib/pbr/direct_irradiance_frag.glsl

This file was deleted.

94 changes: 73 additions & 21 deletions packages/core/src/shaderlib/pbr/direct_irradiance_frag_define.glsl
Original file line number Diff line number Diff line change
@@ -1,69 +1,121 @@
void RE_Direct_Physical( const in IncidentLight directLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {
void addDirectRadiance(vec3 incidentDirection, vec3 color, GeometricContext geometry, PhysicalMaterial material, inout ReflectedLight reflectedLight) {
float dotNL = saturate( dot( geometry.normal, incidentDirection ) );

float dotNL = saturate( dot( geometry.normal, directLight.direction ) );

vec3 irradiance = dotNL * directLight.color;
vec3 irradiance = dotNL * color;

#ifndef PHYSICALLY_CORRECT_LIGHTS

irradiance *= PI; // punctual light
irradiance *= PI;

#endif



reflectedLight.directSpecular += irradiance * BRDF_Specular_GGX( directLight, geometry, material.specularColor, material.specularRoughness );
reflectedLight.directSpecular += irradiance * BRDF_Specular_GGX( incidentDirection, geometry, material.specularColor, material.roughness);

reflectedLight.directDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );

}

#ifdef O3_DIRECT_LIGHT_COUNT

void addDirectionalDirectLightRadiance(DirectLight directionalLight, GeometricContext geometry, PhysicalMaterial material, inout ReflectedLight reflectedLight) {
vec3 color = directionalLight.color;
vec3 direction = -directionalLight.direction;

#ifdef O3_DIRECT_LIGHT_COUNT
addDirectRadiance( direction, color, geometry, material, reflectedLight );

void getDirectionalDirectLightIrradiance( const in DirectLight directionalLight, const in GeometricContext geometry, out IncidentLight directLight ) {
directLight.color = directionalLight.color;
directLight.direction = -directionalLight.direction;
}

#endif

#ifdef O3_POINT_LIGHT_COUNT

// directLight is an out parameter as having it as a return value caused compiler errors on some devices
void getPointDirectLightIrradiance( const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight directLight ) {
void addPointDirectLightRadiance(PointLight pointLight, GeometricContext geometry, PhysicalMaterial material, inout ReflectedLight reflectedLight) {

vec3 lVector = pointLight.position - geometry.position;
directLight.direction = normalize( lVector );
vec3 direction = normalize( lVector );

float lightDistance = length( lVector );

directLight.color = pointLight.color;
directLight.color *= clamp(1.0 - pow(lightDistance/pointLight.distance, 4.0), 0.0, 1.0);
vec3 color = pointLight.color;
color *= clamp(1.0 - pow(lightDistance/pointLight.distance, 4.0), 0.0, 1.0);

addDirectRadiance( direction, color, geometry, material, reflectedLight );

}

#endif

#ifdef O3_SPOT_LIGHT_COUNT

// directLight is an out parameter as having it as a return value caused compiler errors on some devices
void getSpotDirectLightIrradiance( const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight directLight ) {
void addSpotDirectLightRadiance(SpotLight spotLight, GeometricContext geometry, PhysicalMaterial material, inout ReflectedLight reflectedLight) {

vec3 lVector = spotLight.position - geometry.position;
directLight.direction = normalize( lVector );
vec3 direction = normalize( lVector );

float lightDistance = length( lVector );
float angleCos = dot( directLight.direction, -spotLight.direction );
float angleCos = dot( direction, -spotLight.direction );

float spotEffect = smoothstep( spotLight.penumbraCos, spotLight.angleCos, angleCos );
float decayEffect = clamp(1.0 - pow(lightDistance/spotLight.distance, 4.0), 0.0, 1.0);

directLight.color = spotLight.color;
directLight.color *= spotEffect * decayEffect;
vec3 color = spotLight.color;
color *= spotEffect * decayEffect;

addDirectRadiance( direction, color, geometry, material, reflectedLight );

}


#endif

void addTotalDirectRadiance(GeometricContext geometry, PhysicalMaterial material, inout ReflectedLight reflectedLight){
#ifdef O3_DIRECT_LIGHT_COUNT

DirectLight directionalLight;

for ( int i = 0; i < O3_DIRECT_LIGHT_COUNT; i ++ ) {

directionalLight.color = u_directLightColor[i];
directionalLight.direction = u_directLightDirection[i];

addDirectionalDirectLightRadiance( directionalLight, geometry, material, reflectedLight );
}

#endif

#ifdef O3_POINT_LIGHT_COUNT

PointLight pointLight;

for ( int i = 0; i < O3_POINT_LIGHT_COUNT; i ++ ) {

pointLight.color = u_pointLightColor[i];
pointLight.position = u_pointLightPosition[i];
pointLight.distance = u_pointLightDistance[i];

addPointDirectLightRadiance( pointLight, geometry, material, reflectedLight );
}

#endif

#ifdef O3_SPOT_LIGHT_COUNT

SpotLight spotLight;

for ( int i = 0; i < O3_SPOT_LIGHT_COUNT; i ++ ) {

spotLight.color = u_spotLightColor[i];
spotLight.position = u_spotLightPosition[i];
spotLight.direction = u_spotLightDirection[i];
spotLight.distance = u_spotLightDistance[i];
spotLight.angleCos = u_spotLightAngleCos[i];
spotLight.penumbraCos = u_spotLightPenumbraCos[i];

addSpotDirectLightRadiance( spotLight, geometry, material, reflectedLight );
}

#endif

}
43 changes: 11 additions & 32 deletions packages/core/src/shaderlib/pbr/ibl_frag_define.glsl
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
// ------------Diffuse------------
void RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {

reflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );

}

// ------------------------Diffuse------------------------

// sh need be pre-scaled in CPU.
vec3 getLightProbeIrradiance(vec3 sh[9], vec3 normal){
Expand All @@ -24,17 +18,15 @@ vec3 getLightProbeIrradiance(vec3 sh[9], vec3 normal){

}

// ------------Specular------------
// ------------------------Specular------------------------

// source: http://simonstechblog.blogspot.ca/2011/12/microfacet-brdf.html
float GGXRoughnessToBlinnExponent( const in float ggxRoughness ) {
float GGXRoughnessToBlinnExponent(float ggxRoughness ) {
return ( 2.0 / pow2( ggxRoughness + 0.0001 ) - 2.0 );
}

// ref: https://www.unrealengine.com/blog/physically-based-shading-on-mobile - environmentBRDF for GGX on mobile
vec3 BRDF_Specular_GGX_Environment( const in GeometricContext geometry, const in vec3 specularColor, const in float roughness ) {

float dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );
vec3 envBRDFApprox(vec3 specularColor,float roughness, float dotNV ) {

const vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 );

Expand All @@ -52,11 +44,7 @@ vec3 BRDF_Specular_GGX_Environment( const in GeometricContext geometry, const in


// taken from here: http://casual-effects.blogspot.ca/2011/08/plausible-environment-lighting-in-two.html
float getSpecularMIPLevel( const in float blinnShininessExponent, const in int maxMIPLevel ) {

//float envMapWidth = pow( 2.0, maxMIPLevelScalar );
//float desiredMIPLevel = log2( envMapWidth * sqrt( 3.0 ) ) - 0.5 * log2( pow2( blinnShininessExponent ) + 1.0 );

float getSpecularMIPLevel(float blinnShininessExponent, int maxMIPLevel ) {
float maxMIPLevelScalar = float( maxMIPLevel );
float desiredMIPLevel = maxMIPLevelScalar + 0.79248 - 0.5 * log2( pow2( blinnShininessExponent ) + 1.0 );

Expand All @@ -65,37 +53,28 @@ float getSpecularMIPLevel( const in float blinnShininessExponent, const in int m

}

vec3 getLightProbeIndirectRadiance( /*const in SpecularLightProbe specularLightProbe,*/ const in GeometricContext geometry, const in float blinnShininessExponent, const in int maxMIPLevel ) {
vec3 getLightProbeRadiance(GeometricContext geometry, float roughness, int maxMIPLevel, float specularIntensity) {

#ifndef O3_USE_SPECULAR_ENV

return vec3(0.0);
return vec3(0);

#else

vec3 reflectVec = reflect( -geometry.viewDir, geometry.normal );

float specularMIPLevel = getSpecularMIPLevel( blinnShininessExponent, maxMIPLevel );
float specularMIPLevel = getSpecularMIPLevel( GGXRoughnessToBlinnExponent( roughness ), maxMIPLevel );

#ifdef HAS_TEX_LOD
vec4 envMapColor = textureCubeLodEXT( u_env_specularSampler, reflectVec, specularMIPLevel );
#else
vec4 envMapColor = textureCube( u_env_specularSampler, reflectVec, specularMIPLevel );
#endif

envMapColor.rgb = SRGBtoLINEAR( envMapColor * u_envMapLight.specularIntensity).rgb;
envMapColor.rgb *= specularIntensity;

return envMapColor.rgb;

#endif

}

void RE_IndirectSpecular_Physical( const in vec3 radiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {

float dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );
float dotNL = dotNV;

reflectedLight.indirectSpecular += radiance * BRDF_Specular_GGX_Environment( geometry, material.specularColor, material.specularRoughness );

}
}
4 changes: 1 addition & 3 deletions packages/core/src/shaderlib/pbr/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import brdf from "./brdf.glsl";
import direct_irradiance_frag_define from "./direct_irradiance_frag_define.glsl";
import ibl_frag_define from "./ibl_frag_define.glsl";

import direct_irradiance_frag from "./direct_irradiance_frag.glsl";
import pbr_frag from "./pbr_frag.glsl";

export default {
Expand All @@ -17,6 +16,5 @@ export default {
direct_irradiance_frag_define,
ibl_frag_define,

pbr_frag,
direct_irradiance_frag
pbr_frag
};
Loading

0 comments on commit 8e6636b

Please sign in to comment.