diff --git a/packages/core/src/material/PBRSpecularMaterial.ts b/packages/core/src/material/PBRSpecularMaterial.ts index bfed249e56..6f17babb73 100644 --- a/packages/core/src/material/PBRSpecularMaterial.ts +++ b/packages/core/src/material/PBRSpecularMaterial.ts @@ -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"); /** diff --git a/packages/core/src/shaderlib/extra/pbr-specular.fs.glsl b/packages/core/src/shaderlib/extra/pbr-specular.fs.glsl index 963f7b7d00..1448e6b5b2 100644 --- a/packages/core/src/shaderlib/extra/pbr-specular.fs.glsl +++ b/packages/core/src/shaderlib/extra/pbr-specular.fs.glsl @@ -13,7 +13,6 @@ #include #include -#include void main() { #include diff --git a/packages/core/src/shaderlib/extra/pbr.fs.glsl b/packages/core/src/shaderlib/extra/pbr.fs.glsl index 0a3535937a..aa88aab4e3 100644 --- a/packages/core/src/shaderlib/extra/pbr.fs.glsl +++ b/packages/core/src/shaderlib/extra/pbr.fs.glsl @@ -14,7 +14,6 @@ #include #include -#include void main() { #include diff --git a/packages/core/src/shaderlib/pbr/brdf.glsl b/packages/core/src/shaderlib/pbr/brdf.glsl index 0b0d65c219..4026207888 100644 --- a/packages/core/src/shaderlib/pbr/brdf.glsl +++ b/packages/core/src/shaderlib/pbr/brdf.glsl @@ -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 ); @@ -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 ); @@ -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 ); @@ -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 ); diff --git a/packages/core/src/shaderlib/pbr/direct_irradiance_frag.glsl b/packages/core/src/shaderlib/pbr/direct_irradiance_frag.glsl deleted file mode 100644 index d7c39344fa..0000000000 --- a/packages/core/src/shaderlib/pbr/direct_irradiance_frag.glsl +++ /dev/null @@ -1,55 +0,0 @@ - #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]; - - getDirectionalDirectLightIrradiance( directionalLight, geometry, directLight ); - - RE_Direct_Physical( directLight, 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]; - - getPointDirectLightIrradiance( pointLight, geometry, directLight ); - - RE_Direct_Physical( directLight, 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]; - - getSpotDirectLightIrradiance( spotLight, geometry, directLight ); - - RE_Direct_Physical( directLight, geometry, material, reflectedLight ); - - } - - #endif diff --git a/packages/core/src/shaderlib/pbr/direct_irradiance_frag_define.glsl b/packages/core/src/shaderlib/pbr/direct_irradiance_frag_define.glsl index f84b88cd5d..0d2a39c490 100644 --- a/packages/core/src/shaderlib/pbr/direct_irradiance_frag_define.glsl +++ b/packages/core/src/shaderlib/pbr/direct_irradiance_frag_define.glsl @@ -1,46 +1,47 @@ -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 ); } @@ -48,22 +49,73 @@ void RE_Direct_Physical( const in IncidentLight directLight, const in GeometricC #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 + +} \ No newline at end of file diff --git a/packages/core/src/shaderlib/pbr/ibl_frag_define.glsl b/packages/core/src/shaderlib/pbr/ibl_frag_define.glsl index d2f9a62ba3..0bd1f31f39 100644 --- a/packages/core/src/shaderlib/pbr/ibl_frag_define.glsl +++ b/packages/core/src/shaderlib/pbr/ibl_frag_define.glsl @@ -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){ @@ -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 ); @@ -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 ); @@ -65,17 +53,17 @@ 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 ); @@ -83,19 +71,10 @@ vec3 getLightProbeIndirectRadiance( /*const in SpecularLightProbe specularLightP 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 ); - -} +} \ No newline at end of file diff --git a/packages/core/src/shaderlib/pbr/index.ts b/packages/core/src/shaderlib/pbr/index.ts index 407e6e25d9..d5a0e3ba7f 100644 --- a/packages/core/src/shaderlib/pbr/index.ts +++ b/packages/core/src/shaderlib/pbr/index.ts @@ -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 { @@ -17,6 +16,5 @@ export default { direct_irradiance_frag_define, ibl_frag_define, - pbr_frag, - direct_irradiance_frag + pbr_frag }; diff --git a/packages/core/src/shaderlib/pbr/pbr_frag.glsl b/packages/core/src/shaderlib/pbr/pbr_frag.glsl index 1e0ea6c503..6f326c4d29 100644 --- a/packages/core/src/shaderlib/pbr/pbr_frag.glsl +++ b/packages/core/src/shaderlib/pbr/pbr_frag.glsl @@ -1,75 +1,14 @@ - vec3 normal = getNormal(); - vec4 diffuseColor = u_baseColor; - vec3 totalEmissiveRadiance = u_emissiveColor; - float metalnessFactor = u_metal; - float roughnessFactor = u_roughness; - vec3 specularFactor = u_specularColor; - float glossinessFactor = u_glossinessFactor; +GeometricContext geometry = GeometricContext(v_pos, getNormal(), normalize(u_cameraPos - v_pos)); +PhysicalMaterial material = getPhysicalMaterial(u_baseColor, u_metal, u_roughness, u_specularColor, u_glossiness, u_alphaCutoff); +ReflectedLight reflectedLight = ReflectedLight( vec3( 0 ), vec3( 0 ), vec3( 0 ), vec3( 0 ) ); +float dotNV = saturate( dot( geometry.normal, geometry.viewDir ) ); - ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) ); - PhysicalMaterial material; - GeometricContext geometry; - IncidentLight directLight; - - #ifdef HAS_BASECOLORMAP - - vec4 baseMapColor = texture2D( u_baseColorSampler, v_uv ); - baseMapColor = SRGBtoLINEAR( baseMapColor ); - diffuseColor *= baseMapColor; - - #endif - - #ifdef O3_HAS_VERTEXCOLOR - diffuseColor *= v_color; - #endif - - - #ifdef ALPHA_CUTOFF - - if( diffuseColor.a < u_alphaCutoff ) { - discard; - } - - #endif - - #ifdef HAS_METALROUGHNESSMAP - - vec4 metalRoughMapColor = texture2D( u_metallicRoughnessSampler, v_uv ); - roughnessFactor *= metalRoughMapColor.g; - metalnessFactor *= metalRoughMapColor.b; - - #endif - - #ifdef HAS_SPECULARGLOSSINESSMAP - - vec4 specularGlossinessColor = texture2D(u_specularGlossinessSampler, v_uv ); - specularFactor *= specularGlossinessColor.rgb; - glossinessFactor *= specularGlossinessColor.a; - - #endif - - - #ifdef IS_METALLIC_WORKFLOW - material.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor ); - material.specularRoughness = clamp( roughnessFactor, 0.04, 1.0 ); - material.specularColor = mix( vec3( 0.04), diffuseColor.rgb, metalnessFactor ); - #else - float specularStrength = max( max( specularFactor.r, specularFactor.g ), specularFactor.b ); - material.diffuseColor = diffuseColor.rgb * ( 1.0 - specularStrength ); - material.specularRoughness = clamp( 1.0 - glossinessFactor, 0.04, 1.0 ); - material.specularColor = specularFactor; - #endif - - geometry.position = v_pos; - geometry.normal = normal; - geometry.viewDir = normalize( u_cameraPos - v_pos ); - - -#include +// Direct Light +addTotalDirectRadiance(geometry, material, reflectedLight); // IBL diffuse #ifdef O3_USE_SH - vec3 irradiance = getLightProbeIrradiance(u_env_sh, normal) * u_envMapLight.diffuseIntensity; + vec3 irradiance = getLightProbeIrradiance(u_env_sh, geometry.normal) * u_envMapLight.diffuseIntensity; #else vec3 irradiance = u_envMapLight.diffuse * u_envMapLight.diffuseIntensity; #endif @@ -78,39 +17,32 @@ irradiance *= PI; #endif -RE_IndirectDiffuse_Physical( irradiance, geometry, material, reflectedLight ); - +reflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor ); // IBL specular -vec3 radiance = getLightProbeIndirectRadiance( geometry, GGXRoughnessToBlinnExponent( material.specularRoughness ), int(u_envMapLight.mipMapLevel) ); - -RE_IndirectSpecular_Physical( radiance, geometry, material, reflectedLight ); +vec3 radiance = getLightProbeRadiance( geometry, material.roughness, int(u_envMapLight.mipMapLevel), u_envMapLight.specularIntensity); +reflectedLight.indirectSpecular += radiance * envBRDFApprox(material.specularColor, material.roughness, dotNV ); - -// occlusion +// Occlusion #ifdef HAS_OCCLUSIONMAP - float ambientOcclusion = (texture2D(u_occlusionSampler, v_uv).r - 1.0) * u_occlusionStrength + 1.0; reflectedLight.indirectDiffuse *= ambientOcclusion; - - #if defined(O3_USE_SPECULAR_ENV) - - float dotNV = saturate(dot(geometry.normal, geometry.viewDir)); - reflectedLight.indirectSpecular *= computeSpecularOcclusion(dotNV, ambientOcclusion, material.specularRoughness); - + #ifdef O3_USE_SPECULAR_ENV + reflectedLight.indirectSpecular *= computeSpecularOcclusion(ambientOcclusion, material.roughness, dotNV); #endif - #endif -// emissive +// Emissive +vec3 emissiveRadiance = u_emissiveColor; #ifdef HAS_EMISSIVEMAP - - vec4 emissiveMapColor = texture2D(u_emissiveSampler, v_uv); - emissiveMapColor = SRGBtoLINEAR(emissiveMapColor); - totalEmissiveRadiance *= emissiveMapColor.rgb; - + emissiveRadiance *= texture2D(u_emissiveSampler, v_uv).rgb; #endif -vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance; -gl_FragColor = vec4(outgoingLight, diffuseColor.a); +// Total +vec3 totalRadiance = reflectedLight.directDiffuse + + reflectedLight.indirectDiffuse + + reflectedLight.directSpecular + + reflectedLight.indirectSpecular + + emissiveRadiance; +gl_FragColor = vec4(totalRadiance, u_baseColor.a); \ No newline at end of file diff --git a/packages/core/src/shaderlib/pbr/pbr_frag_define.glsl b/packages/core/src/shaderlib/pbr/pbr_frag_define.glsl index 9cf753901e..58f94996ff 100644 --- a/packages/core/src/shaderlib/pbr/pbr_frag_define.glsl +++ b/packages/core/src/shaderlib/pbr/pbr_frag_define.glsl @@ -4,7 +4,7 @@ uniform vec4 u_baseColor; uniform float u_metal; uniform float u_roughness; uniform vec3 u_specularColor; -uniform float u_glossinessFactor; +uniform float u_glossiness; uniform vec3 u_emissiveColor; uniform float u_normalIntensity; @@ -37,11 +37,6 @@ uniform float u_occlusionStrength; #endif - -struct IncidentLight { - vec3 color; - vec3 direction; -}; struct ReflectedLight { vec3 directDiffuse; vec3 directSpecular; @@ -49,12 +44,12 @@ struct ReflectedLight { vec3 indirectSpecular; }; struct GeometricContext { - vec3 position; - vec3 normal; - vec3 viewDir; + vec3 position; + vec3 normal; + vec3 viewDir; }; struct PhysicalMaterial { - vec3 diffuseColor; - float specularRoughness; - vec3 specularColor; + vec3 diffuseColor; + float roughness; + vec3 specularColor; }; diff --git a/packages/core/src/shaderlib/pbr/pbr_helper.glsl b/packages/core/src/shaderlib/pbr/pbr_helper.glsl index f1cc12eda2..71cfcd68d6 100644 --- a/packages/core/src/shaderlib/pbr/pbr_helper.glsl +++ b/packages/core/src/shaderlib/pbr/pbr_helper.glsl @@ -1,37 +1,80 @@ +#include + vec4 SRGBtoLINEAR(vec4 srgbIn) { - #ifdef MANUAL_SRGB - #ifdef SRGB_FAST_APPROXIMATION - vec3 linOut = pow(srgbIn.xyz, vec3(2.2)); - #else - vec3 bLess = step(vec3(0.04045), srgbIn.xyz); - vec3 linOut = mix(srgbIn.xyz/vec3(12.92), pow((srgbIn.xyz+vec3(0.055))/vec3(1.055), vec3(2.4)), bLess); - #endif - - return vec4(linOut, srgbIn.w);; - #else - return srgbIn; - #endif + return vec4( pow(srgbIn.xyz, vec3(2.2)), srgbIn.w);; } -float pow2( const in float x ) { +float pow2(float x ) { return x * x; } -vec3 BRDF_Diffuse_Lambert( const in vec3 diffuseColor ) { +vec3 BRDF_Diffuse_Lambert(vec3 diffuseColor ) { return RECIPROCAL_PI * diffuseColor; } -float computeSpecularOcclusion( const in float dotNV, const in float ambientOcclusion, const in float roughness ) { +float computeSpecularOcclusion(float ambientOcclusion, float roughness, float dotNV ) { return saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion ); } +PhysicalMaterial getPhysicalMaterial( + vec4 diffuseColor, + float metal, + float roughness, + vec3 specularColor, + float glossiness, + float alphaCutoff + ){ + PhysicalMaterial material; + + #ifdef HAS_BASECOLORMAP + diffuseColor *= texture2D( u_baseColorSampler, v_uv );; + #endif + + #ifdef O3_HAS_VERTEXCOLOR + diffuseColor *= v_color; + #endif + + + #ifdef ALPHA_CUTOFF + if( diffuseColor.a < alphaCutoff ) { + discard; + } + #endif + + #ifdef HAS_METALROUGHNESSMAP + vec4 metalRoughMapColor = texture2D( u_metallicRoughnessSampler, v_uv ); + roughness *= metalRoughMapColor.g; + metal *= metalRoughMapColor.b; + #endif + + #ifdef HAS_SPECULARGLOSSINESSMAP + vec4 specularGlossinessColor = texture2D(u_specularGlossinessSampler, v_uv ); + specularColor *= specularGlossinessColor.rgb; + glossiness *= specularGlossinessColor.a; + #endif + + + #ifdef IS_METALLIC_WORKFLOW + material.diffuseColor = diffuseColor.rgb * ( 1.0 - metal ); + material.specularColor = mix( vec3( 0.04), diffuseColor.rgb, metal ); + material.roughness = clamp( roughness, 0.04, 1.0 ); + #else + float specularStrength = max( max( specularColor.r, specularColor.g ), specularColor.b ); + material.diffuseColor = diffuseColor.rgb * ( 1.0 - specularStrength ); + material.specularColor = specularColor; + material.roughness = clamp( 1.0 - glossiness, 0.04, 1.0 ); + #endif + + return material; + +} // direct + indirect #include