From b8f6aec772d78e82246858c2c61fbc7d17b3c796 Mon Sep 17 00:00:00 2001 From: "shensi.zxd" Date: Tue, 1 Mar 2022 17:28:46 +0800 Subject: [PATCH 01/16] feat: support clearcoat --- packages/controls/src/OrbitControl.ts | 2 +- packages/core/src/material/PBRMaterial.ts | 94 ++++++++++++++++++- packages/core/src/shaderlib/common.glsl | 4 + packages/core/src/shaderlib/normal_get.glsl | 48 ++++++++++ packages/core/src/shaderlib/pbr/brdf.glsl | 14 ++- .../pbr/direct_irradiance_frag_define.glsl | 15 ++- .../src/shaderlib/pbr/ibl_frag_define.glsl | 4 +- packages/core/src/shaderlib/pbr/pbr_frag.glsl | 30 +++++- .../src/shaderlib/pbr/pbr_frag_define.glsl | 29 ++++++ .../core/src/shaderlib/pbr/pbr_helper.glsl | 27 ++++-- .../extensions/KHR_materials_clearcoat.ts | 36 +++++++ .../loader/src/gltf/parser/MaterialParser.ts | 6 +- 12 files changed, 281 insertions(+), 28 deletions(-) diff --git a/packages/controls/src/OrbitControl.ts b/packages/controls/src/OrbitControl.ts index e68e0fe2aa..b3ede278c4 100644 --- a/packages/controls/src/OrbitControl.ts +++ b/packages/controls/src/OrbitControl.ts @@ -400,7 +400,7 @@ export class OrbitControl extends Script { */ pan(deltaX: number, deltaY: number) { // perspective only - const position: Vector3 = this.camera.position; + const position: Vector3 = this.camera.transform.position; position.cloneTo(this._vPan); this._vPan.subtract(this.target); let targetDistance = this._vPan.length(); diff --git a/packages/core/src/material/PBRMaterial.ts b/packages/core/src/material/PBRMaterial.ts index 3074529797..a35652dc2b 100644 --- a/packages/core/src/material/PBRMaterial.ts +++ b/packages/core/src/material/PBRMaterial.ts @@ -10,9 +10,14 @@ export class PBRMaterial extends PBRBaseMaterial { private static _metallicProp = Shader.getPropertyByName("u_metal"); private static _roughnessProp = Shader.getPropertyByName("u_roughness"); private static _metallicRoughnessTextureProp = Shader.getPropertyByName("u_metallicRoughnessSampler"); + private static _clearcoatProp = Shader.getPropertyByName("u_clearcoat"); + private static _clearcoatTextureProp = Shader.getPropertyByName("u_clearcoatTexture"); + private static _clearcoatRoughnessProp = Shader.getPropertyByName("u_clearcoatRoughness"); + private static _clearcoatRoughnessTextureProp = Shader.getPropertyByName("u_clearcoatRoughnessTexture"); + private static _clearcoatNormalTextureProp = Shader.getPropertyByName("u_clearcoatNormalTexture"); /** - * Metallic. + * Metallic, default 1. */ get metallic(): number { return this.shaderData.getFloat(PBRMaterial._metallicProp); @@ -23,7 +28,7 @@ export class PBRMaterial extends PBRBaseMaterial { } /** - * Roughness. + * Roughness, default 1. */ get roughness(): number { return this.shaderData.getFloat(PBRMaterial._roughnessProp); @@ -50,14 +55,95 @@ export class PBRMaterial extends PBRBaseMaterial { } } + /** + * The clearcoat layer intensity, default 0. + */ + get clearcoat(): number { + return this.shaderData.getFloat(PBRMaterial._clearcoatProp); + } + + set clearcoat(value: number) { + this.shaderData.setFloat(PBRMaterial._clearcoatProp, value); + + if (value === 0) { + this.shaderData.disableMacro("CLEARCOAT"); + } else { + this.shaderData.enableMacro("CLEARCOAT"); + } + } + + /** + * The clearcoat layer intensity texture. + */ + get clearcoatTexture(): Texture2D { + return this.shaderData.getTexture(PBRMaterial._clearcoatTextureProp); + } + + set clearcoatTexture(value: Texture2D) { + this.shaderData.setTexture(PBRMaterial._clearcoatTextureProp, value); + + if (value) { + this.shaderData.enableMacro("HAS_CLEARCOATTEXTURE"); + } else { + this.shaderData.disableMacro("HAS_CLEARCOATTEXTURE"); + } + } + + /** + * The clearcoat layer roughness, default 0. + */ + get clearcoatRoughness(): number { + return this.shaderData.getFloat(PBRMaterial._clearcoatRoughnessProp); + } + + set clearcoatRoughness(value: number) { + this.shaderData.setFloat(PBRMaterial._clearcoatRoughnessProp, value); + } + + /** + * The clearcoat layer roughness texture. + */ + get clearcoatRoughnessTexture(): Texture2D { + return this.shaderData.getTexture(PBRMaterial._clearcoatRoughnessTextureProp); + } + + set clearcoatRoughnessTexture(value: Texture2D) { + this.shaderData.setTexture(PBRMaterial._clearcoatRoughnessTextureProp, value); + + if (value) { + this.shaderData.enableMacro("HAS_CLEARCOATROUGHNESSTEXTURE"); + } else { + this.shaderData.disableMacro("HAS_CLEARCOATROUGHNESSTEXTURE"); + } + } + + /** + * The clearcoat normal map texture. + */ + get clearcoatNormalTexture(): Texture2D { + return this.shaderData.getTexture(PBRMaterial._clearcoatNormalTextureProp); + } + + set clearcoatNormalTexture(value: Texture2D) { + this.shaderData.setTexture(PBRMaterial._clearcoatNormalTextureProp, value); + + if (value) { + this.shaderData.enableMacro("HAS_CLEARCOATNORMALTEXTURE"); + } else { + this.shaderData.disableMacro("HAS_CLEARCOATNORMALTEXTURE"); + } + } + /** * Create a pbr metallic-roughness workflow material instance. * @param engine - Engine to which the material belongs */ constructor(engine: Engine) { super(engine, Shader.find("pbr")); - this.shaderData.setFloat(PBRMaterial._metallicProp, 1.0); - this.shaderData.setFloat(PBRMaterial._roughnessProp, 1.0); + this.shaderData.setFloat(PBRMaterial._metallicProp, 1); + this.shaderData.setFloat(PBRMaterial._roughnessProp, 1); + this.shaderData.setFloat(PBRMaterial._clearcoatProp, 0); + this.shaderData.setFloat(PBRMaterial._clearcoatRoughnessProp, 0); } /** diff --git a/packages/core/src/shaderlib/common.glsl b/packages/core/src/shaderlib/common.glsl index 026ff80b34..615638debf 100644 --- a/packages/core/src/shaderlib/common.glsl +++ b/packages/core/src/shaderlib/common.glsl @@ -6,6 +6,10 @@ #define saturate( a ) clamp( a, 0.0, 1.0 ) #define whiteCompliment(a) ( 1.0 - saturate( a ) ) +float pow2(float x ) { + return x * x; +} + vec4 RGBMToLinear(vec4 value, float maxRange ) { return vec4( value.rgb * value.a * maxRange, 1.0 ); } diff --git a/packages/core/src/shaderlib/normal_get.glsl b/packages/core/src/shaderlib/normal_get.glsl index b7b2223d71..69424b350e 100644 --- a/packages/core/src/shaderlib/normal_get.glsl +++ b/packages/core/src/shaderlib/normal_get.glsl @@ -45,3 +45,51 @@ vec3 getNormal() return n; } + +vec3 getClearcoatNormal() +{ + #ifdef HAS_CLEARCOATNORMALTEXTURE + #ifndef O3_HAS_TANGENT + #ifdef HAS_DERIVATIVES + vec3 pos_dx = dFdx(v_pos); + vec3 pos_dy = dFdy(v_pos); + vec3 tex_dx = dFdx(vec3(v_uv, 0.0)); + vec3 tex_dy = dFdy(vec3(v_uv, 0.0)); + vec3 t = (tex_dy.t * pos_dx - tex_dx.t * pos_dy) / (tex_dx.s * tex_dy.t - tex_dy.s * tex_dx.t); + #ifdef O3_HAS_NORMAL + vec3 ng = normalize(v_normal); + #else + vec3 ng = normalize( cross(pos_dx, pos_dy) ); + #endif + t = normalize(t - ng * dot(ng, t)); + vec3 b = normalize(cross(ng, t)); + mat3 tbn = mat3(t, b, ng); + #else + #ifdef O3_HAS_NORMAL + vec3 ng = normalize(v_normal); + #else + vec3 ng = vec3(0.0, 0.0, 1.0); + #endif + mat3 tbn = mat3(vec3(0.0), vec3(0.0), ng); + #endif + #else + mat3 tbn = v_TBN; + #endif + vec3 n = texture2D(u_clearcoatNormalTexture, v_uv ).rgb; + n = normalize(tbn * ((2.0 * n - 1.0) * vec3(u_normalIntensity, u_normalIntensity, 1.0))); + #else + #ifdef O3_HAS_NORMAL + vec3 n = normalize(v_normal); + #elif defined(HAS_DERIVATIVES) + vec3 pos_dx = dFdx(v_pos); + vec3 pos_dy = dFdy(v_pos); + vec3 n = normalize( cross(pos_dx, pos_dy) ); + #else + vec3 n= vec3(0.0,0.0,1.0); + #endif + #endif + + n *= float( gl_FrontFacing ) * 2.0 - 1.0; + + return n; +} \ No newline at end of file diff --git a/packages/core/src/shaderlib/pbr/brdf.glsl b/packages/core/src/shaderlib/pbr/brdf.glsl index 4026207888..1a87d0047f 100644 --- a/packages/core/src/shaderlib/pbr/brdf.glsl +++ b/packages/core/src/shaderlib/pbr/brdf.glsl @@ -39,15 +39,15 @@ float D_GGX(float alpha, float dotNH ) { } // GGX Distribution, Schlick Fresnel, GGX-Smith Visibility -vec3 BRDF_Specular_GGX(vec3 incidentDirection, GeometricContext geometry, vec3 specularColor, float roughness ) { +vec3 BRDF_Specular_GGX(vec3 incidentDirection, vec3 viewDir, vec3 normal, vec3 specularColor, float roughness ) { float alpha = pow2( roughness ); // UE4's roughness - vec3 halfDir = normalize( incidentDirection + geometry.viewDir ); + vec3 halfDir = normalize( incidentDirection + viewDir ); - float dotNL = saturate( dot( geometry.normal, incidentDirection ) ); - float dotNV = saturate( dot( geometry.normal, geometry.viewDir ) ); - float dotNH = saturate( dot( geometry.normal, halfDir ) ); + float dotNL = saturate( dot( normal, incidentDirection ) ); + float dotNV = saturate( dot( normal, viewDir ) ); + float dotNH = saturate( dot( normal, halfDir ) ); float dotLH = saturate( dot( incidentDirection, halfDir ) ); vec3 F = F_Schlick( specularColor, dotLH ); @@ -59,3 +59,7 @@ vec3 BRDF_Specular_GGX(vec3 incidentDirection, GeometricContext geometry, vec3 s return F * ( G * D ); } + +vec3 BRDF_Diffuse_Lambert(vec3 diffuseColor ) { + return RECIPROCAL_PI * diffuseColor; +} 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 152150dd30..883556d70d 100644 --- a/packages/core/src/shaderlib/pbr/direct_irradiance_frag_define.glsl +++ b/packages/core/src/shaderlib/pbr/direct_irradiance_frag_define.glsl @@ -4,9 +4,18 @@ void addDirectRadiance(vec3 incidentDirection, vec3 color, GeometricContext geom vec3 irradiance = dotNL * color; irradiance *= PI; - reflectedLight.directSpecular += irradiance * BRDF_Specular_GGX( incidentDirection, geometry, material.specularColor, material.roughness); - - reflectedLight.directDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor ); + #ifdef CLEARCOAT + float ccDotNL = saturate( dot( geometry.clearcoatNormal, incidentDirection ) ); + vec3 ccIrradiance = ccDotNL * color; + float clearcoatDHR = material.clearcoat * clearcoatDHRApprox( material.clearcoatRoughness, ccDotNL ); + reflectedLight.directSpecular += ccIrradiance * material.clearcoat * BRDF_Specular_GGX( incidentDirection, geometry.viewDir, geometry.clearcoatNormal, vec3( 0.04 ), material.clearcoatRoughness ); + #else + float clearcoatDHR = 0.0; + #endif + + reflectedLight.directSpecular += ( 1.0 - clearcoatDHR ) * irradiance * BRDF_Specular_GGX( incidentDirection, geometry.viewDir, geometry.normal, material.specularColor, material.roughness); + + reflectedLight.directDiffuse += ( 1.0 - clearcoatDHR ) * irradiance * BRDF_Diffuse_Lambert( material.diffuseColor ); } diff --git a/packages/core/src/shaderlib/pbr/ibl_frag_define.glsl b/packages/core/src/shaderlib/pbr/ibl_frag_define.glsl index 1a4a3ff8ff..2b523ceefa 100644 --- a/packages/core/src/shaderlib/pbr/ibl_frag_define.glsl +++ b/packages/core/src/shaderlib/pbr/ibl_frag_define.glsl @@ -42,7 +42,7 @@ float getSpecularMIPLevel(float roughness, int maxMIPLevel ) { return roughness * float(maxMIPLevel); } -vec3 getLightProbeRadiance(GeometricContext geometry, float roughness, int maxMIPLevel, float specularIntensity) { +vec3 getLightProbeRadiance(vec3 viewDir, vec3 normal, float roughness, int maxMIPLevel, float specularIntensity) { #ifndef O3_USE_SPECULAR_ENV @@ -50,7 +50,7 @@ vec3 getLightProbeRadiance(GeometricContext geometry, float roughness, int maxMI #else - vec3 reflectVec = reflect( -geometry.viewDir, geometry.normal ); + vec3 reflectVec = reflect( -viewDir, normal ); float specularMIPLevel = getSpecularMIPLevel(roughness, maxMIPLevel ); diff --git a/packages/core/src/shaderlib/pbr/pbr_frag.glsl b/packages/core/src/shaderlib/pbr/pbr_frag.glsl index be129ebba1..ead29a58d4 100644 --- a/packages/core/src/shaderlib/pbr/pbr_frag.glsl +++ b/packages/core/src/shaderlib/pbr/pbr_frag.glsl @@ -1,4 +1,11 @@ -GeometricContext geometry = GeometricContext(v_pos, getNormal(), normalize(u_cameraPos - v_pos)); +GeometricContext geometry; +geometry.position = v_pos; +geometry.normal = getNormal(); +geometry.viewDir = normalize(u_cameraPos - v_pos); +#ifdef CLEARCOAT + geometry.clearcoatNormal = getClearcoatNormal(); +#endif + 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 ) ); @@ -21,8 +28,25 @@ addTotalDirectRadiance(geometry, material, reflectedLight); reflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor ); // IBL specular -vec3 radiance = getLightProbeRadiance( geometry, material.roughness, int(u_envMapLight.mipMapLevel), u_envMapLight.specularIntensity); -reflectedLight.indirectSpecular += radiance * envBRDFApprox(material.specularColor, material.roughness, dotNV ); +vec3 radiance = getLightProbeRadiance(geometry.viewDir, geometry.normal, material.roughness, int(u_envMapLight.mipMapLevel), u_envMapLight.specularIntensity); +vec3 clearcoatRadiance = vec3(0); + +#ifdef CLEARCOAT + clearcoatRadiance = getLightProbeRadiance( geometry.viewDir, geometry.clearcoatNormal, material.clearcoatRoughness, int(u_envMapLight.mipMapLevel), u_envMapLight.specularIntensity ); +#endif + +#ifdef CLEARCOAT + float ccDotNV = saturate( dot( geometry.clearcoatNormal, geometry.viewDir ) ); + reflectedLight.indirectSpecular += clearcoatRadiance * material.clearcoat * envBRDFApprox(vec3( 0.04 ), material.clearcoatRoughness, dotNV); + float ccDotNL = ccDotNV; + float clearcoatDHR = material.clearcoat * clearcoatDHRApprox( material.clearcoatRoughness, ccDotNL ); +#else + float clearcoatDHR = 0.0; +#endif + +float clearcoatInv = 1.0 - clearcoatDHR; +reflectedLight.indirectSpecular += clearcoatInv * radiance * envBRDFApprox(material.specularColor, material.roughness, dotNV ); + // Occlusion #ifdef HAS_OCCLUSIONMAP diff --git a/packages/core/src/shaderlib/pbr/pbr_frag_define.glsl b/packages/core/src/shaderlib/pbr/pbr_frag_define.glsl index 6ddb7d742c..9e1bd900ad 100644 --- a/packages/core/src/shaderlib/pbr/pbr_frag_define.glsl +++ b/packages/core/src/shaderlib/pbr/pbr_frag_define.glsl @@ -7,6 +7,11 @@ uniform vec3 u_specularColor; uniform float u_glossiness; uniform vec3 u_emissiveColor; +#ifdef CLEARCOAT + uniform float u_clearcoat; + uniform float u_clearcoatRoughness; +#endif + uniform float u_normalIntensity; uniform float u_occlusionStrength; @@ -36,6 +41,19 @@ uniform float u_occlusionStrength; uniform sampler2D u_occlusionSampler; #endif +#ifdef HAS_CLEARCOATTEXTURE + uniform sampler2D u_clearcoatTexture; +#endif + +#ifdef HAS_CLEARCOATROUGHNESSTEXTURE + uniform sampler2D u_clearcoatRoughnessTexture; +#endif + +#ifdef HAS_CLEARCOATNORMALTEXTURE + uniform sampler2D u_clearcoatNormalTexture; +#endif + + struct ReflectedLight { vec3 directDiffuse; @@ -43,14 +61,25 @@ struct ReflectedLight { vec3 indirectDiffuse; vec3 indirectSpecular; }; + struct GeometricContext { vec3 position; vec3 normal; vec3 viewDir; + #ifdef CLEARCOAT + vec3 clearcoatNormal; + #endif + }; + struct PhysicalMaterial { vec3 diffuseColor; float roughness; vec3 specularColor; float opacity; + #ifdef CLEARCOAT + float clearcoat; + float clearcoatRoughness; + #endif + }; diff --git a/packages/core/src/shaderlib/pbr/pbr_helper.glsl b/packages/core/src/shaderlib/pbr/pbr_helper.glsl index 5d626fbc8f..0aca1c0aa5 100644 --- a/packages/core/src/shaderlib/pbr/pbr_helper.glsl +++ b/packages/core/src/shaderlib/pbr/pbr_helper.glsl @@ -1,19 +1,14 @@ #include -float pow2(float x ) { - return x * x; -} - -vec3 BRDF_Diffuse_Lambert(vec3 diffuseColor ) { - return RECIPROCAL_PI * diffuseColor; -} - - float computeSpecularOcclusion(float ambientOcclusion, float roughness, float dotNV ) { return saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion ); } +float clearcoatDHRApprox(float roughness, float dotNL) { + return 0.04 + 0.96 * ( pow( 1.0 - dotNL, 5.0 ) * pow( 1.0 - roughness, 2.0 ) ); +} + PhysicalMaterial getPhysicalMaterial( vec4 diffuseColor, float metal, @@ -67,6 +62,20 @@ PhysicalMaterial getPhysicalMaterial( material.roughness = clamp( 1.0 - glossiness, 0.04, 1.0 ); #endif + #ifdef CLEARCOAT + material.clearcoat = u_clearcoat; + material.clearcoatRoughness = u_clearcoatRoughness; + #ifdef HAS_CLEARCOATTEXTURE + material.clearcoat *= texture2D( u_clearcoatTexture, v_uv ).r; + #endif + #ifdef HAS_CLEARCOATROUGHNESSTEXTURE + material.clearcoatRoughness *= texture2D( u_clearcoatRoughnessTexture, v_uv ).g; + #endif + material.clearcoat = saturate( material.clearcoat ); + material.clearcoatRoughness = clamp( material.clearcoatRoughness, 0.005, 1.0 ); + #endif + + material.opacity = diffuseColor.a; return material; diff --git a/packages/loader/src/gltf/extensions/KHR_materials_clearcoat.ts b/packages/loader/src/gltf/extensions/KHR_materials_clearcoat.ts index e69de29bb2..4d92337e6c 100644 --- a/packages/loader/src/gltf/extensions/KHR_materials_clearcoat.ts +++ b/packages/loader/src/gltf/extensions/KHR_materials_clearcoat.ts @@ -0,0 +1,36 @@ +import { PBRMaterial } from "@oasis-engine/core"; +import { GLTFResource } from "../GLTFResource"; +import { MaterialParser } from "../parser/MaterialParser"; +import { registerExtension } from "../parser/Parser"; +import { ExtensionParser } from "./ExtensionParser"; +import { IKHRMaterialsClearcoat } from "./Schema"; + +@registerExtension("KHR_materials_clearcoat") +class KHR_materials_clearcoat extends ExtensionParser { + parseEngineResource(schema: IKHRMaterialsClearcoat, material: PBRMaterial, context: GLTFResource): void { + const { textures } = context; + const { + clearcoatFactor = 0, + clearcoatTexture, + clearcoatRoughnessFactor = 0, + clearcoatRoughnessTexture, + clearcoatNormalTexture + } = schema; + + material.clearcoat = clearcoatFactor; + material.clearcoatRoughness = clearcoatRoughnessFactor; + + if (clearcoatTexture) { + material.clearcoatTexture = textures[clearcoatTexture.index]; + MaterialParser._parseTextureTransform(material, clearcoatTexture.extensions, context); + } + if (clearcoatRoughnessTexture) { + material.clearcoatRoughnessTexture = textures[clearcoatRoughnessTexture.index]; + MaterialParser._parseTextureTransform(material, clearcoatRoughnessTexture.extensions, context); + } + if (clearcoatNormalTexture) { + material.clearcoatNormalTexture = textures[clearcoatNormalTexture.index]; + MaterialParser._parseTextureTransform(material, clearcoatNormalTexture.extensions, context); + } + } +} diff --git a/packages/loader/src/gltf/parser/MaterialParser.ts b/packages/loader/src/gltf/parser/MaterialParser.ts index 6ab5d02737..9b8a6a4011 100644 --- a/packages/loader/src/gltf/parser/MaterialParser.ts +++ b/packages/loader/src/gltf/parser/MaterialParser.ts @@ -33,7 +33,7 @@ export class MaterialParser extends Parser { name = "" } = gltf.materials[i]; - const { KHR_materials_unlit, KHR_materials_pbrSpecularGlossiness } = extensions; + const { KHR_materials_unlit, KHR_materials_pbrSpecularGlossiness, KHR_materials_clearcoat } = extensions; let material: UnlitMaterial | PBRMaterial | PBRSpecularMaterial = null; @@ -53,6 +53,10 @@ export class MaterialParser extends Parser { material.name = name; + if (KHR_materials_clearcoat) { + Parser.parseEngineResource("KHR_materials_clearcoat", KHR_materials_clearcoat, material, context); + } + if (pbrMetallicRoughness) { const { baseColorFactor, baseColorTexture, metallicFactor, roughnessFactor, metallicRoughnessTexture } = pbrMetallicRoughness; From 9147bd1e3215c314d3149813f36b3043ed8523a5 Mon Sep 17 00:00:00 2001 From: "shensi.zxd" Date: Wed, 2 Mar 2022 18:28:41 +0800 Subject: [PATCH 02/16] refactor: code prettier --- .../pbr/direct_irradiance_frag_define.glsl | 10 ++-- packages/core/src/shaderlib/pbr/pbr_frag.glsl | 21 ++++----- .../src/shaderlib/pbr/pbr_frag_define.glsl | 9 ++-- .../core/src/shaderlib/pbr/pbr_helper.glsl | 47 +++++++++++-------- 4 files changed, 46 insertions(+), 41 deletions(-) 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 883556d70d..df73112e6f 100644 --- a/packages/core/src/shaderlib/pbr/direct_irradiance_frag_define.glsl +++ b/packages/core/src/shaderlib/pbr/direct_irradiance_frag_define.glsl @@ -1,4 +1,4 @@ -void addDirectRadiance(vec3 incidentDirection, vec3 color, GeometricContext geometry, PhysicalMaterial material, inout ReflectedLight reflectedLight) { +void addDirectRadiance(vec3 incidentDirection, vec3 color, Geometry geometry, Material material, inout ReflectedLight reflectedLight) { float dotNL = saturate( dot( geometry.normal, incidentDirection ) ); vec3 irradiance = dotNL * color; @@ -21,7 +21,7 @@ void addDirectRadiance(vec3 incidentDirection, vec3 color, GeometricContext geom #ifdef O3_DIRECT_LIGHT_COUNT - void addDirectionalDirectLightRadiance(DirectLight directionalLight, GeometricContext geometry, PhysicalMaterial material, inout ReflectedLight reflectedLight) { + void addDirectionalDirectLightRadiance(DirectLight directionalLight, Geometry geometry, Material material, inout ReflectedLight reflectedLight) { vec3 color = directionalLight.color; vec3 direction = -directionalLight.direction; @@ -33,7 +33,7 @@ void addDirectRadiance(vec3 incidentDirection, vec3 color, GeometricContext geom #ifdef O3_POINT_LIGHT_COUNT - void addPointDirectLightRadiance(PointLight pointLight, GeometricContext geometry, PhysicalMaterial material, inout ReflectedLight reflectedLight) { + void addPointDirectLightRadiance(PointLight pointLight, Geometry geometry, Material material, inout ReflectedLight reflectedLight) { vec3 lVector = pointLight.position - geometry.position; vec3 direction = normalize( lVector ); @@ -51,7 +51,7 @@ void addDirectRadiance(vec3 incidentDirection, vec3 color, GeometricContext geom #ifdef O3_SPOT_LIGHT_COUNT - void addSpotDirectLightRadiance(SpotLight spotLight, GeometricContext geometry, PhysicalMaterial material, inout ReflectedLight reflectedLight) { + void addSpotDirectLightRadiance(SpotLight spotLight, Geometry geometry, Material material, inout ReflectedLight reflectedLight) { vec3 lVector = spotLight.position - geometry.position; vec3 direction = normalize( lVector ); @@ -72,7 +72,7 @@ void addDirectRadiance(vec3 incidentDirection, vec3 color, GeometricContext geom #endif -void addTotalDirectRadiance(GeometricContext geometry, PhysicalMaterial material, inout ReflectedLight reflectedLight){ +void addTotalDirectRadiance(Geometry geometry, Material material, inout ReflectedLight reflectedLight){ #ifdef O3_DIRECT_LIGHT_COUNT DirectLight directionalLight; diff --git a/packages/core/src/shaderlib/pbr/pbr_frag.glsl b/packages/core/src/shaderlib/pbr/pbr_frag.glsl index ead29a58d4..47232a8117 100644 --- a/packages/core/src/shaderlib/pbr/pbr_frag.glsl +++ b/packages/core/src/shaderlib/pbr/pbr_frag.glsl @@ -1,14 +1,9 @@ -GeometricContext geometry; -geometry.position = v_pos; -geometry.normal = getNormal(); -geometry.viewDir = normalize(u_cameraPos - v_pos); -#ifdef CLEARCOAT - geometry.clearcoatNormal = getClearcoatNormal(); -#endif +Geometry geometry; +Material material; +ReflectedLight reflectedLight; -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 ) ); +initGeometry(geometry); +initMaterial(material); // Direct Light addTotalDirectRadiance(geometry, material, reflectedLight); @@ -37,7 +32,7 @@ vec3 clearcoatRadiance = vec3(0); #ifdef CLEARCOAT float ccDotNV = saturate( dot( geometry.clearcoatNormal, geometry.viewDir ) ); - reflectedLight.indirectSpecular += clearcoatRadiance * material.clearcoat * envBRDFApprox(vec3( 0.04 ), material.clearcoatRoughness, dotNV); + reflectedLight.indirectSpecular += clearcoatRadiance * material.clearcoat * envBRDFApprox(vec3( 0.04 ), material.clearcoatRoughness, geometry.dotNV); float ccDotNL = ccDotNV; float clearcoatDHR = material.clearcoat * clearcoatDHRApprox( material.clearcoatRoughness, ccDotNL ); #else @@ -45,7 +40,7 @@ vec3 clearcoatRadiance = vec3(0); #endif float clearcoatInv = 1.0 - clearcoatDHR; -reflectedLight.indirectSpecular += clearcoatInv * radiance * envBRDFApprox(material.specularColor, material.roughness, dotNV ); +reflectedLight.indirectSpecular += clearcoatInv * radiance * envBRDFApprox(material.specularColor, material.roughness, geometry.dotNV ); // Occlusion @@ -53,7 +48,7 @@ reflectedLight.indirectSpecular += clearcoatInv * radiance * envBRDFApprox(mater float ambientOcclusion = (texture2D(u_occlusionSampler, v_uv).r - 1.0) * u_occlusionStrength + 1.0; reflectedLight.indirectDiffuse *= ambientOcclusion; #ifdef O3_USE_SPECULAR_ENV - reflectedLight.indirectSpecular *= computeSpecularOcclusion(ambientOcclusion, material.roughness, dotNV); + reflectedLight.indirectSpecular *= computeSpecularOcclusion(ambientOcclusion, material.roughness, geometry.dotNV); #endif #endif diff --git a/packages/core/src/shaderlib/pbr/pbr_frag_define.glsl b/packages/core/src/shaderlib/pbr/pbr_frag_define.glsl index 9e1bd900ad..d37023a220 100644 --- a/packages/core/src/shaderlib/pbr/pbr_frag_define.glsl +++ b/packages/core/src/shaderlib/pbr/pbr_frag_define.glsl @@ -1,5 +1,4 @@ uniform float u_alphaCutoff; - uniform vec4 u_baseColor; uniform float u_metal; uniform float u_roughness; @@ -16,6 +15,7 @@ uniform float u_normalIntensity; uniform float u_occlusionStrength; +// Texture #ifdef HAS_BASECOLORMAP uniform sampler2D u_baseColorSampler; #endif @@ -55,6 +55,7 @@ uniform float u_occlusionStrength; +// Runtime struct ReflectedLight { vec3 directDiffuse; vec3 directSpecular; @@ -62,17 +63,19 @@ struct ReflectedLight { vec3 indirectSpecular; }; -struct GeometricContext { +struct Geometry { vec3 position; vec3 normal; vec3 viewDir; + float dotNV; + #ifdef CLEARCOAT vec3 clearcoatNormal; #endif }; -struct PhysicalMaterial { +struct Material { 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 0aca1c0aa5..267c10e8ee 100644 --- a/packages/core/src/shaderlib/pbr/pbr_helper.glsl +++ b/packages/core/src/shaderlib/pbr/pbr_helper.glsl @@ -9,31 +9,40 @@ float clearcoatDHRApprox(float roughness, float dotNL) { return 0.04 + 0.96 * ( pow( 1.0 - dotNL, 5.0 ) * pow( 1.0 - roughness, 2.0 ) ); } -PhysicalMaterial getPhysicalMaterial( - vec4 diffuseColor, - float metal, - float roughness, - vec3 specularColor, - float glossiness, - float alphaCutoff - ){ - PhysicalMaterial material; +void initGeometry(out Geometry geometry){ + geometry.position = v_pos; + geometry.normal = getNormal(); + geometry.viewDir = normalize(u_cameraPos - v_pos); + geometry.dotNV = saturate( dot(geometry.normal, geometry.viewDir) ); + + #ifdef CLEARCOAT + geometry.clearcoatNormal = getClearcoatNormal(); + #endif +} + +void initMaterial(out Material material){ + vec4 baseColor = u_baseColor; + float metal = u_metal; + float roughness = u_roughness; + vec3 specularColor = u_specularColor; + float glossiness = u_glossiness; + float alphaCutoff = u_alphaCutoff; #ifdef HAS_BASECOLORMAP - vec4 baseColor = texture2D(u_baseColorSampler, v_uv); + vec4 baseTextureColor = texture2D(u_baseColorSampler, v_uv); #ifndef OASIS_COLORSPACE_GAMMA - baseColor = gammaToLinear(baseColor); + baseTextureColor = gammaToLinear(baseTextureColor); #endif - diffuseColor *= baseColor; + baseColor *= baseTextureColor; #endif #ifdef O3_HAS_VERTEXCOLOR - diffuseColor *= v_color; + baseColor *= v_color; #endif #ifdef ALPHA_CUTOFF - if( diffuseColor.a < alphaCutoff ) { + if( baseColor.a < alphaCutoff ) { discard; } #endif @@ -52,12 +61,12 @@ PhysicalMaterial getPhysicalMaterial( #ifdef IS_METALLIC_WORKFLOW - material.diffuseColor = diffuseColor.rgb * ( 1.0 - metal ); - material.specularColor = mix( vec3( 0.04), diffuseColor.rgb, metal ); + material.diffuseColor = baseColor.rgb * ( 1.0 - metal ); + material.specularColor = mix( vec3( 0.04), baseColor.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.diffuseColor = baseColor.rgb * ( 1.0 - specularStrength ); material.specularColor = specularColor; material.roughness = clamp( 1.0 - glossiness, 0.04, 1.0 ); #endif @@ -76,9 +85,7 @@ PhysicalMaterial getPhysicalMaterial( #endif - material.opacity = diffuseColor.a; - return material; - + material.opacity = baseColor.a; } // direct + indirect From a970dc68b4cfcdf425c63aaaf52c969393b7a284 Mon Sep 17 00:00:00 2001 From: "shensi.zxd" Date: Thu, 3 Mar 2022 14:22:28 +0800 Subject: [PATCH 03/16] perf: normal function override --- .../core/src/shaderlib/begin_normal_vert.glsl | 12 ++- .../src/shaderlib/mobile_blinnphong_frag.glsl | 7 +- packages/core/src/shaderlib/normal_get.glsl | 78 ++++--------------- packages/core/src/shaderlib/normal_share.glsl | 19 ++--- packages/core/src/shaderlib/normal_vert.glsl | 17 ++-- .../core/src/shaderlib/pbr/pbr_helper.glsl | 18 ++++- 6 files changed, 57 insertions(+), 94 deletions(-) diff --git a/packages/core/src/shaderlib/begin_normal_vert.glsl b/packages/core/src/shaderlib/begin_normal_vert.glsl index 1f0b8d165b..c7d1a3553b 100644 --- a/packages/core/src/shaderlib/begin_normal_vert.glsl +++ b/packages/core/src/shaderlib/begin_normal_vert.glsl @@ -1,11 +1,9 @@ +#ifndef OMIT_NORMAL #ifdef O3_HAS_NORMAL + vec3 normal = vec3( NORMAL ); + #endif - vec3 normal = vec3( NORMAL ); - - #if defined( O3_HAS_TANGENT ) && defined( O3_NORMAL_TEXTURE ) - + #ifdef O3_HAS_TANGENT vec4 tangent = vec4( TANGENT ); - - #endif - #endif +#endif \ No newline at end of file diff --git a/packages/core/src/shaderlib/mobile_blinnphong_frag.glsl b/packages/core/src/shaderlib/mobile_blinnphong_frag.glsl index 3b2b08c78f..d0d9de454b 100644 --- a/packages/core/src/shaderlib/mobile_blinnphong_frag.glsl +++ b/packages/core/src/shaderlib/mobile_blinnphong_frag.glsl @@ -1,4 +1,9 @@ - vec3 N = getNormal(); + vec3 N = getNormal( + #ifdef O3_NORMAL_TEXTURE + u_normalTexture, + u_normalIntensity + #endif + ); vec3 lightDiffuse = vec3( 0.0, 0.0, 0.0 ); vec3 lightSpecular = vec3( 0.0, 0.0, 0.0 ); diff --git a/packages/core/src/shaderlib/normal_get.glsl b/packages/core/src/shaderlib/normal_get.glsl index 69424b350e..e6fe635d07 100644 --- a/packages/core/src/shaderlib/normal_get.glsl +++ b/packages/core/src/shaderlib/normal_get.glsl @@ -1,55 +1,24 @@ -vec3 getNormal() -{ - #ifdef O3_NORMAL_TEXTURE - #ifndef O3_HAS_TANGENT - #ifdef HAS_DERIVATIVES - vec3 pos_dx = dFdx(v_pos); - vec3 pos_dy = dFdy(v_pos); - vec3 tex_dx = dFdx(vec3(v_uv, 0.0)); - vec3 tex_dy = dFdy(vec3(v_uv, 0.0)); - vec3 t = (tex_dy.t * pos_dx - tex_dx.t * pos_dy) / (tex_dx.s * tex_dy.t - tex_dy.s * tex_dx.t); - #ifdef O3_HAS_NORMAL - vec3 ng = normalize(v_normal); - #else - vec3 ng = normalize( cross(pos_dx, pos_dy) ); - #endif - t = normalize(t - ng * dot(ng, t)); - vec3 b = normalize(cross(ng, t)); - mat3 tbn = mat3(t, b, ng); - #else - #ifdef O3_HAS_NORMAL - vec3 ng = normalize(v_normal); - #else - vec3 ng = vec3(0.0, 0.0, 1.0); - #endif - mat3 tbn = mat3(vec3(0.0), vec3(0.0), ng); - #endif - #else - mat3 tbn = v_TBN; - #endif - vec3 n = texture2D(u_normalTexture, v_uv ).rgb; - n = normalize(tbn * ((2.0 * n - 1.0) * vec3(u_normalIntensity, u_normalIntensity, 1.0))); - #else +vec3 getNormal(){ + vec3 normal = vec3(0, 0, 1); + #ifdef O3_HAS_NORMAL - vec3 n = normalize(v_normal); + normal = normalize(v_normal); #elif defined(HAS_DERIVATIVES) vec3 pos_dx = dFdx(v_pos); vec3 pos_dy = dFdy(v_pos); - vec3 n = normalize( cross(pos_dx, pos_dy) ); - #else - vec3 n= vec3(0.0,0.0,1.0); + normal = normalize( cross(pos_dx, pos_dy) ); #endif - #endif - n *= float( gl_FrontFacing ) * 2.0 - 1.0; - - return n; + normal *= float( gl_FrontFacing ) * 2.0 - 1.0; + return normal; } -vec3 getClearcoatNormal() +vec3 getNormal(sampler2D normalTexture, float normalIntensity) { - #ifdef HAS_CLEARCOATNORMALTEXTURE - #ifndef O3_HAS_TANGENT + + #if defined(O3_HAS_NORMAL) && defined(O3_HAS_TANGENT) && defined( O3_NORMAL_TEXTURE ) + mat3 tbn = v_TBN; + #else #ifdef HAS_DERIVATIVES vec3 pos_dx = dFdx(v_pos); vec3 pos_dy = dFdy(v_pos); @@ -72,24 +41,11 @@ vec3 getClearcoatNormal() #endif mat3 tbn = mat3(vec3(0.0), vec3(0.0), ng); #endif - #else - mat3 tbn = v_TBN; - #endif - vec3 n = texture2D(u_clearcoatNormalTexture, v_uv ).rgb; - n = normalize(tbn * ((2.0 * n - 1.0) * vec3(u_normalIntensity, u_normalIntensity, 1.0))); - #else - #ifdef O3_HAS_NORMAL - vec3 n = normalize(v_normal); - #elif defined(HAS_DERIVATIVES) - vec3 pos_dx = dFdx(v_pos); - vec3 pos_dy = dFdy(v_pos); - vec3 n = normalize( cross(pos_dx, pos_dy) ); - #else - vec3 n= vec3(0.0,0.0,1.0); #endif - #endif - n *= float( gl_FrontFacing ) * 2.0 - 1.0; + vec3 normal = texture2D(normalTexture, v_uv ).rgb; + normal = normalize(tbn * ((2.0 * normal - 1.0) * vec3(normalIntensity, normalIntensity, 1.0))); + normal *= float( gl_FrontFacing ) * 2.0 - 1.0; - return n; -} \ No newline at end of file + return normal; +} diff --git a/packages/core/src/shaderlib/normal_share.glsl b/packages/core/src/shaderlib/normal_share.glsl index d21d9322bc..094be54d11 100644 --- a/packages/core/src/shaderlib/normal_share.glsl +++ b/packages/core/src/shaderlib/normal_share.glsl @@ -1,13 +1,8 @@ -#ifdef O3_HAS_NORMAL - - #if defined( O3_HAS_TANGENT ) && defined( O3_NORMAL_TEXTURE ) - - varying mat3 v_TBN; - - #else - - varying vec3 v_normal; - +#ifndef OMIT_NORMAL + #ifdef O3_HAS_NORMAL + varying vec3 v_normal; + #if defined( O3_HAS_TANGENT ) && defined( O3_NORMAL_TEXTURE ) + varying mat3 v_TBN; + #endif #endif - -#endif +#endif \ No newline at end of file diff --git a/packages/core/src/shaderlib/normal_vert.glsl b/packages/core/src/shaderlib/normal_vert.glsl index 938ce04cac..03a42c72dc 100644 --- a/packages/core/src/shaderlib/normal_vert.glsl +++ b/packages/core/src/shaderlib/normal_vert.glsl @@ -1,16 +1,13 @@ +#ifndef OMIT_NORMAL #ifdef O3_HAS_NORMAL + v_normal = normalize( mat3(u_normalMat) * normal ); #if defined( O3_HAS_TANGENT ) && defined( O3_NORMAL_TEXTURE ) + vec3 normalW = normalize( mat3(u_normalMat) * normal.xyz ); + vec3 tangentW = normalize( mat3(u_normalMat) * tangent.xyz ); + vec3 bitangentW = cross( normalW, tangentW ) * tangent.w; - vec3 normalW = normalize( mat3(u_normalMat) * normal.xyz ); - vec3 tangentW = normalize( mat3(u_normalMat) * tangent.xyz ); - vec3 bitangentW = cross( normalW, tangentW ) * tangent.w; - v_TBN = mat3( tangentW, bitangentW, normalW ); - - #else - - v_normal = normalize( mat3(u_normalMat) * normal ); - + v_TBN = mat3( tangentW, bitangentW, normalW ); #endif - #endif +#endif \ No newline at end of file diff --git a/packages/core/src/shaderlib/pbr/pbr_helper.glsl b/packages/core/src/shaderlib/pbr/pbr_helper.glsl index 267c10e8ee..e0fc9fb32e 100644 --- a/packages/core/src/shaderlib/pbr/pbr_helper.glsl +++ b/packages/core/src/shaderlib/pbr/pbr_helper.glsl @@ -11,13 +11,25 @@ float clearcoatDHRApprox(float roughness, float dotNL) { void initGeometry(out Geometry geometry){ geometry.position = v_pos; - geometry.normal = getNormal(); geometry.viewDir = normalize(u_cameraPos - v_pos); - geometry.dotNV = saturate( dot(geometry.normal, geometry.viewDir) ); + + geometry.normal = getNormal( + #ifdef O3_NORMAL_TEXTURE + u_normalTexture, + u_normalIntensity + #endif + ); #ifdef CLEARCOAT - geometry.clearcoatNormal = getClearcoatNormal(); + geometry.clearcoatNormal = getNormal( + #ifdef HAS_CLEARCOATNORMALTEXTURE + u_clearcoatNormalTexture, + u_normalIntensity + #endif + ); #endif + + geometry.dotNV = saturate( dot(geometry.normal, geometry.viewDir) ); } void initMaterial(out Material material){ From c3a9dc81f2bac5ad8a82e9d695a285be8b8f1f87 Mon Sep 17 00:00:00 2001 From: "shensi.zxd" Date: Thu, 3 Mar 2022 16:56:16 +0800 Subject: [PATCH 04/16] perf: code format --- packages/core/src/shaderlib/pbr/pbr_frag.glsl | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/core/src/shaderlib/pbr/pbr_frag.glsl b/packages/core/src/shaderlib/pbr/pbr_frag.glsl index 47232a8117..499d4e3bb9 100644 --- a/packages/core/src/shaderlib/pbr/pbr_frag.glsl +++ b/packages/core/src/shaderlib/pbr/pbr_frag.glsl @@ -24,13 +24,10 @@ reflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.di // IBL specular vec3 radiance = getLightProbeRadiance(geometry.viewDir, geometry.normal, material.roughness, int(u_envMapLight.mipMapLevel), u_envMapLight.specularIntensity); -vec3 clearcoatRadiance = vec3(0); #ifdef CLEARCOAT - clearcoatRadiance = getLightProbeRadiance( geometry.viewDir, geometry.clearcoatNormal, material.clearcoatRoughness, int(u_envMapLight.mipMapLevel), u_envMapLight.specularIntensity ); -#endif + vec3 clearcoatRadiance = getLightProbeRadiance( geometry.viewDir, geometry.clearcoatNormal, material.clearcoatRoughness, int(u_envMapLight.mipMapLevel), u_envMapLight.specularIntensity ); -#ifdef CLEARCOAT float ccDotNV = saturate( dot( geometry.clearcoatNormal, geometry.viewDir ) ); reflectedLight.indirectSpecular += clearcoatRadiance * material.clearcoat * envBRDFApprox(vec3( 0.04 ), material.clearcoatRoughness, geometry.dotNV); float ccDotNL = ccDotNV; From 3b833e895c088dcf30e86a140ac495755fd9e7f1 Mon Sep 17 00:00:00 2001 From: "shensi.zxd" Date: Thu, 3 Mar 2022 19:58:52 +0800 Subject: [PATCH 05/16] fix: use linear color space in gltf --- packages/core/src/shaderlib/pbr/pbr_helper.glsl | 3 +++ .../KHR_materials_pbrSpecularGlossiness.ts | 13 +++++++++++-- packages/loader/src/gltf/parser/MaterialParser.ts | 13 +++++++++++-- 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/packages/core/src/shaderlib/pbr/pbr_helper.glsl b/packages/core/src/shaderlib/pbr/pbr_helper.glsl index e0fc9fb32e..9a92b3ae6b 100644 --- a/packages/core/src/shaderlib/pbr/pbr_helper.glsl +++ b/packages/core/src/shaderlib/pbr/pbr_helper.glsl @@ -67,6 +67,9 @@ void initMaterial(out Material material){ #ifdef HAS_SPECULARGLOSSINESSMAP vec4 specularGlossinessColor = texture2D(u_specularGlossinessSampler, v_uv ); + #ifndef OASIS_COLORSPACE_GAMMA + specularGlossinessColor = gammaToLinear(specularGlossinessColor); + #endif specularColor *= specularGlossinessColor.rgb; glossiness *= specularGlossinessColor.a; #endif diff --git a/packages/loader/src/gltf/extensions/KHR_materials_pbrSpecularGlossiness.ts b/packages/loader/src/gltf/extensions/KHR_materials_pbrSpecularGlossiness.ts index fd78e27579..6faeef7983 100644 --- a/packages/loader/src/gltf/extensions/KHR_materials_pbrSpecularGlossiness.ts +++ b/packages/loader/src/gltf/extensions/KHR_materials_pbrSpecularGlossiness.ts @@ -14,7 +14,12 @@ class KHR_materials_pbrSpecularGlossiness extends ExtensionParser { const { diffuseFactor, diffuseTexture, specularFactor, glossinessFactor, specularGlossinessTexture } = schema; if (diffuseFactor) { - material.baseColor = new Color(...diffuseFactor); + material.baseColor = new Color( + Color.linearToGammaSpace(diffuseFactor[0]), + Color.linearToGammaSpace(diffuseFactor[1]), + Color.linearToGammaSpace(diffuseFactor[2]), + diffuseFactor[3] + ); } if (diffuseTexture) { @@ -23,7 +28,11 @@ class KHR_materials_pbrSpecularGlossiness extends ExtensionParser { } if (specularFactor) { - material.specularColor = new Color(...specularFactor); + material.specularColor = new Color( + Color.linearToGammaSpace(specularFactor[0]), + Color.linearToGammaSpace(specularFactor[1]), + Color.linearToGammaSpace(specularFactor[2]) + ); } if (glossinessFactor !== undefined) { diff --git a/packages/loader/src/gltf/parser/MaterialParser.ts b/packages/loader/src/gltf/parser/MaterialParser.ts index 9b8a6a4011..e58f6a6d7c 100644 --- a/packages/loader/src/gltf/parser/MaterialParser.ts +++ b/packages/loader/src/gltf/parser/MaterialParser.ts @@ -62,7 +62,12 @@ export class MaterialParser extends Parser { pbrMetallicRoughness; if (baseColorFactor) { - material.baseColor = new Color(...baseColorFactor); + material.baseColor = new Color( + Color.linearToGammaSpace(baseColorFactor[0]), + Color.linearToGammaSpace(baseColorFactor[1]), + Color.linearToGammaSpace(baseColorFactor[2]), + baseColorFactor[3] + ); } if (baseColorTexture) { material.baseTexture = textures[baseColorTexture.index]; @@ -89,7 +94,11 @@ export class MaterialParser extends Parser { } if (emissiveFactor) { - m.emissiveColor = new Color(...emissiveFactor); + m.emissiveColor = new Color( + Color.linearToGammaSpace(emissiveFactor[0]), + Color.linearToGammaSpace(emissiveFactor[1]), + Color.linearToGammaSpace(emissiveFactor[2]) + ); } if (normalTexture) { From 3100e37da9fdc97bdb5e0d33bfc1b3fd744a3bca Mon Sep 17 00:00:00 2001 From: "shensi.zxd" Date: Fri, 4 Mar 2022 11:30:51 +0800 Subject: [PATCH 06/16] fix: use ccDotNV instead of dotNV --- packages/core/src/shaderlib/pbr/pbr_frag.glsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/shaderlib/pbr/pbr_frag.glsl b/packages/core/src/shaderlib/pbr/pbr_frag.glsl index 499d4e3bb9..0694aab615 100644 --- a/packages/core/src/shaderlib/pbr/pbr_frag.glsl +++ b/packages/core/src/shaderlib/pbr/pbr_frag.glsl @@ -29,7 +29,7 @@ vec3 radiance = getLightProbeRadiance(geometry.viewDir, geometry.normal, materia vec3 clearcoatRadiance = getLightProbeRadiance( geometry.viewDir, geometry.clearcoatNormal, material.clearcoatRoughness, int(u_envMapLight.mipMapLevel), u_envMapLight.specularIntensity ); float ccDotNV = saturate( dot( geometry.clearcoatNormal, geometry.viewDir ) ); - reflectedLight.indirectSpecular += clearcoatRadiance * material.clearcoat * envBRDFApprox(vec3( 0.04 ), material.clearcoatRoughness, geometry.dotNV); + reflectedLight.indirectSpecular += clearcoatRadiance * material.clearcoat * envBRDFApprox(vec3( 0.04 ), material.clearcoatRoughness, ccDotNV); float ccDotNL = ccDotNV; float clearcoatDHR = material.clearcoat * clearcoatDHRApprox( material.clearcoatRoughness, ccDotNL ); #else From b25780d0564c3ea2d47f42f15df33ea238087e9c Mon Sep 17 00:00:00 2001 From: "shensi.zxd" Date: Fri, 4 Mar 2022 16:40:37 +0800 Subject: [PATCH 07/16] refactor: use new clearcoat fresnel technique --- packages/core/src/shaderlib/pbr/brdf.glsl | 4 ++++ .../pbr/direct_irradiance_frag_define.glsl | 22 +++++++++---------- packages/core/src/shaderlib/pbr/pbr_frag.glsl | 12 ++++------ .../src/shaderlib/pbr/pbr_frag_define.glsl | 1 + .../core/src/shaderlib/pbr/pbr_helper.glsl | 5 +---- 5 files changed, 20 insertions(+), 24 deletions(-) diff --git a/packages/core/src/shaderlib/pbr/brdf.glsl b/packages/core/src/shaderlib/pbr/brdf.glsl index 1a87d0047f..e88bcfe381 100644 --- a/packages/core/src/shaderlib/pbr/brdf.glsl +++ b/packages/core/src/shaderlib/pbr/brdf.glsl @@ -1,3 +1,7 @@ +float F_Schlick(float dotLH) { + return 0.04 + 0.96 * (pow(1.0 - dotLH, 5.0)); +} + vec3 F_Schlick(vec3 specularColor, float dotLH ) { // Original approximation by Christophe Schlick '94 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 df73112e6f..27ff5bbaad 100644 --- a/packages/core/src/shaderlib/pbr/direct_irradiance_frag_define.glsl +++ b/packages/core/src/shaderlib/pbr/direct_irradiance_frag_define.glsl @@ -1,21 +1,19 @@ void addDirectRadiance(vec3 incidentDirection, vec3 color, Geometry geometry, Material material, inout ReflectedLight reflectedLight) { - float dotNL = saturate( dot( geometry.normal, incidentDirection ) ); + float attenuation = 1.0; - vec3 irradiance = dotNL * color; - irradiance *= PI; - #ifdef CLEARCOAT - float ccDotNL = saturate( dot( geometry.clearcoatNormal, incidentDirection ) ); - vec3 ccIrradiance = ccDotNL * color; - float clearcoatDHR = material.clearcoat * clearcoatDHRApprox( material.clearcoatRoughness, ccDotNL ); - reflectedLight.directSpecular += ccIrradiance * material.clearcoat * BRDF_Specular_GGX( incidentDirection, geometry.viewDir, geometry.clearcoatNormal, vec3( 0.04 ), material.clearcoatRoughness ); - #else - float clearcoatDHR = 0.0; + float clearcoatDotNL = saturate( dot( geometry.clearcoatNormal, incidentDirection ) ); + vec3 clearcoatIrradiance = clearcoatDotNL * color; + + reflectedLight.directSpecular += material.clearcoat * clearcoatIrradiance * BRDF_Specular_GGX( incidentDirection, geometry.viewDir, geometry.clearcoatNormal, vec3( 0.04 ), material.clearcoatRoughness ); + attenuation -= material.clearcoat * F_Schlick(geometry.clearcoatDotNV); #endif - reflectedLight.directSpecular += ( 1.0 - clearcoatDHR ) * irradiance * BRDF_Specular_GGX( incidentDirection, geometry.viewDir, geometry.normal, material.specularColor, material.roughness); + float dotNL = saturate( dot( geometry.normal, incidentDirection ) ); + vec3 irradiance = dotNL * color * PI; - reflectedLight.directDiffuse += ( 1.0 - clearcoatDHR ) * irradiance * BRDF_Diffuse_Lambert( material.diffuseColor ); + reflectedLight.directSpecular += attenuation * irradiance * BRDF_Specular_GGX( incidentDirection, geometry.viewDir, geometry.normal, material.specularColor, material.roughness); + reflectedLight.directDiffuse += attenuation * irradiance * BRDF_Diffuse_Lambert( material.diffuseColor ); } diff --git a/packages/core/src/shaderlib/pbr/pbr_frag.glsl b/packages/core/src/shaderlib/pbr/pbr_frag.glsl index 0694aab615..3ee86e5363 100644 --- a/packages/core/src/shaderlib/pbr/pbr_frag.glsl +++ b/packages/core/src/shaderlib/pbr/pbr_frag.glsl @@ -24,20 +24,16 @@ reflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.di // IBL specular vec3 radiance = getLightProbeRadiance(geometry.viewDir, geometry.normal, material.roughness, int(u_envMapLight.mipMapLevel), u_envMapLight.specularIntensity); +float radianceAttenuation = 1.0; #ifdef CLEARCOAT vec3 clearcoatRadiance = getLightProbeRadiance( geometry.viewDir, geometry.clearcoatNormal, material.clearcoatRoughness, int(u_envMapLight.mipMapLevel), u_envMapLight.specularIntensity ); - float ccDotNV = saturate( dot( geometry.clearcoatNormal, geometry.viewDir ) ); - reflectedLight.indirectSpecular += clearcoatRadiance * material.clearcoat * envBRDFApprox(vec3( 0.04 ), material.clearcoatRoughness, ccDotNV); - float ccDotNL = ccDotNV; - float clearcoatDHR = material.clearcoat * clearcoatDHRApprox( material.clearcoatRoughness, ccDotNL ); -#else - float clearcoatDHR = 0.0; + reflectedLight.indirectSpecular += clearcoatRadiance * material.clearcoat * envBRDFApprox(vec3( 0.04 ), material.clearcoatRoughness, geometry.clearcoatDotNV); + radianceAttenuation -= material.clearcoat * F_Schlick(geometry.clearcoatDotNV); #endif -float clearcoatInv = 1.0 - clearcoatDHR; -reflectedLight.indirectSpecular += clearcoatInv * radiance * envBRDFApprox(material.specularColor, material.roughness, geometry.dotNV ); +reflectedLight.indirectSpecular += radianceAttenuation * radiance * envBRDFApprox(material.specularColor, material.roughness, geometry.dotNV ); // Occlusion diff --git a/packages/core/src/shaderlib/pbr/pbr_frag_define.glsl b/packages/core/src/shaderlib/pbr/pbr_frag_define.glsl index d37023a220..249afe9977 100644 --- a/packages/core/src/shaderlib/pbr/pbr_frag_define.glsl +++ b/packages/core/src/shaderlib/pbr/pbr_frag_define.glsl @@ -71,6 +71,7 @@ struct Geometry { #ifdef CLEARCOAT vec3 clearcoatNormal; + float clearcoatDotNV; #endif }; diff --git a/packages/core/src/shaderlib/pbr/pbr_helper.glsl b/packages/core/src/shaderlib/pbr/pbr_helper.glsl index 9a92b3ae6b..80bf592ff7 100644 --- a/packages/core/src/shaderlib/pbr/pbr_helper.glsl +++ b/packages/core/src/shaderlib/pbr/pbr_helper.glsl @@ -5,10 +5,6 @@ float computeSpecularOcclusion(float ambientOcclusion, float roughness, float do return saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion ); } -float clearcoatDHRApprox(float roughness, float dotNL) { - return 0.04 + 0.96 * ( pow( 1.0 - dotNL, 5.0 ) * pow( 1.0 - roughness, 2.0 ) ); -} - void initGeometry(out Geometry geometry){ geometry.position = v_pos; geometry.viewDir = normalize(u_cameraPos - v_pos); @@ -27,6 +23,7 @@ void initGeometry(out Geometry geometry){ u_normalIntensity #endif ); + geometry.clearcoatDotNV = saturate( dot(geometry.clearcoatNormal, geometry.viewDir) ); #endif geometry.dotNV = saturate( dot(geometry.normal, geometry.viewDir) ); From 9eb8c1a96354ec5d710edb37ec202c45b23bb659 Mon Sep 17 00:00:00 2001 From: "shensi.zxd" Date: Fri, 4 Mar 2022 17:24:38 +0800 Subject: [PATCH 08/16] feat: add specular anti aliasing --- packages/core/src/shaderlib/pbr/pbr_frag.glsl | 2 +- .../core/src/shaderlib/pbr/pbr_helper.glsl | 38 ++++++++++++------- 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/packages/core/src/shaderlib/pbr/pbr_frag.glsl b/packages/core/src/shaderlib/pbr/pbr_frag.glsl index 3ee86e5363..2b1409c3f4 100644 --- a/packages/core/src/shaderlib/pbr/pbr_frag.glsl +++ b/packages/core/src/shaderlib/pbr/pbr_frag.glsl @@ -3,7 +3,7 @@ Material material; ReflectedLight reflectedLight; initGeometry(geometry); -initMaterial(material); +initMaterial(material, geometry); // Direct Light addTotalDirectRadiance(geometry, material, reflectedLight); diff --git a/packages/core/src/shaderlib/pbr/pbr_helper.glsl b/packages/core/src/shaderlib/pbr/pbr_helper.glsl index 80bf592ff7..1374290eee 100644 --- a/packages/core/src/shaderlib/pbr/pbr_helper.glsl +++ b/packages/core/src/shaderlib/pbr/pbr_helper.glsl @@ -5,6 +5,15 @@ float computeSpecularOcclusion(float ambientOcclusion, float roughness, float do return saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion ); } +float getAARoughnessFactor(vec3 normal) { + #ifdef HAS_DERIVATIVES + vec3 dxy = max( abs(dFdx(normal)), abs(dFdy(normal)) ); + return max( max(dxy.x, dxy.y), dxy.z ); + #else + return 0.0; + #endif +} + void initGeometry(out Geometry geometry){ geometry.position = v_pos; geometry.viewDir = normalize(u_cameraPos - v_pos); @@ -29,7 +38,7 @@ void initGeometry(out Geometry geometry){ geometry.dotNV = saturate( dot(geometry.normal, geometry.viewDir) ); } -void initMaterial(out Material material){ +void initMaterial(out Material material, const in Geometry geometry){ vec4 baseColor = u_baseColor; float metal = u_metal; float roughness = u_roughness; @@ -75,28 +84,29 @@ void initMaterial(out Material material){ #ifdef IS_METALLIC_WORKFLOW material.diffuseColor = baseColor.rgb * ( 1.0 - metal ); material.specularColor = mix( vec3( 0.04), baseColor.rgb, metal ); - material.roughness = clamp( roughness, 0.04, 1.0 ); + material.roughness = roughness; #else float specularStrength = max( max( specularColor.r, specularColor.g ), specularColor.b ); material.diffuseColor = baseColor.rgb * ( 1.0 - specularStrength ); material.specularColor = specularColor; - material.roughness = clamp( 1.0 - glossiness, 0.04, 1.0 ); + material.roughness = 1.0 - glossiness; #endif + material.roughness = max(material.roughness, getAARoughnessFactor(geometry.normal)); + #ifdef CLEARCOAT - material.clearcoat = u_clearcoat; - material.clearcoatRoughness = u_clearcoatRoughness; - #ifdef HAS_CLEARCOATTEXTURE - material.clearcoat *= texture2D( u_clearcoatTexture, v_uv ).r; - #endif - #ifdef HAS_CLEARCOATROUGHNESSTEXTURE - material.clearcoatRoughness *= texture2D( u_clearcoatRoughnessTexture, v_uv ).g; - #endif - material.clearcoat = saturate( material.clearcoat ); - material.clearcoatRoughness = clamp( material.clearcoatRoughness, 0.005, 1.0 ); + material.clearcoat = u_clearcoat; + material.clearcoatRoughness = u_clearcoatRoughness; + #ifdef HAS_CLEARCOATTEXTURE + material.clearcoat *= texture2D( u_clearcoatTexture, v_uv ).r; + #endif + #ifdef HAS_CLEARCOATROUGHNESSTEXTURE + material.clearcoatRoughness *= texture2D( u_clearcoatRoughnessTexture, v_uv ).g; + #endif + material.clearcoat = saturate( material.clearcoat ); + material.clearcoatRoughness = max(material.clearcoatRoughness, getAARoughnessFactor(geometry.clearcoatNormal)); #endif - material.opacity = baseColor.a; } From e611a1bfb8bf8e5d528edfadc13dcd87ad3a4aae Mon Sep 17 00:00:00 2001 From: "shensi.zxd" Date: Fri, 4 Mar 2022 17:59:49 +0800 Subject: [PATCH 09/16] ci: build error --- packages/controls/src/FreeControl.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/controls/src/FreeControl.ts b/packages/controls/src/FreeControl.ts index 52d42353e3..53cab157cd 100644 --- a/packages/controls/src/FreeControl.ts +++ b/packages/controls/src/FreeControl.ts @@ -281,7 +281,7 @@ export class FreeControl extends Script { */ updateSpherical(): void { this._v3Cache.setValue(0, 0, -1); - Vector3.transformByQuat(this._v3Cache, this.camera.rotation, this._v3Cache); + Vector3.transformByQuat(this._v3Cache, this.camera.transform.rotationQuaternion, this._v3Cache); this._spherical.setFromVec3(this._v3Cache); this._theta = this._spherical.theta; this._phi = this._spherical.phi; From d5a51186cbe2cf83ae70ab75c9f78ce0d9a87485 Mon Sep 17 00:00:00 2001 From: "shensi.zxd" Date: Thu, 10 Mar 2022 15:01:53 +0800 Subject: [PATCH 10/16] refactor: implements clearcoat in pbr base material --- packages/core/src/material/PBRBaseMaterial.ts | 90 ++++++++++++++++++- packages/core/src/material/PBRMaterial.ts | 86 ------------------ 2 files changed, 89 insertions(+), 87 deletions(-) diff --git a/packages/core/src/material/PBRBaseMaterial.ts b/packages/core/src/material/PBRBaseMaterial.ts index f9a2a38848..848dacdd15 100644 --- a/packages/core/src/material/PBRBaseMaterial.ts +++ b/packages/core/src/material/PBRBaseMaterial.ts @@ -15,10 +15,15 @@ export abstract class PBRBaseMaterial extends BaseMaterial { private static _normalTextureProp = Shader.getPropertyByName("u_normalTexture"); private static _normalTextureIntensityProp = Shader.getPropertyByName("u_normalIntensity"); private static _occlusionTextureIntensityProp = Shader.getPropertyByName("u_occlusionStrength"); - private static _emissiveTextureProp = Shader.getPropertyByName("u_emissiveSampler"); private static _occlusionTextureProp = Shader.getPropertyByName("u_occlusionSampler"); + private static _clearcoatProp = Shader.getPropertyByName("u_clearcoat"); + private static _clearcoatTextureProp = Shader.getPropertyByName("u_clearcoatTexture"); + private static _clearcoatRoughnessProp = Shader.getPropertyByName("u_clearcoatRoughness"); + private static _clearcoatRoughnessTextureProp = Shader.getPropertyByName("u_clearcoatRoughnessTexture"); + private static _clearcoatNormalTextureProp = Shader.getPropertyByName("u_clearcoatNormalTexture"); + /** * Base color. */ @@ -148,6 +153,86 @@ export abstract class PBRBaseMaterial extends BaseMaterial { } } + + /** + * The clearcoat layer intensity, default 0. + */ + get clearcoat(): number { + return this.shaderData.getFloat(PBRBaseMaterial._clearcoatProp); + } + + set clearcoat(value: number) { + this.shaderData.setFloat(PBRBaseMaterial._clearcoatProp, value); + + if (value === 0) { + this.shaderData.disableMacro("CLEARCOAT"); + } else { + this.shaderData.enableMacro("CLEARCOAT"); + } + } + + /** + * The clearcoat layer intensity texture. + */ + get clearcoatTexture(): Texture2D { + return this.shaderData.getTexture(PBRBaseMaterial._clearcoatTextureProp); + } + + set clearcoatTexture(value: Texture2D) { + this.shaderData.setTexture(PBRBaseMaterial._clearcoatTextureProp, value); + + if (value) { + this.shaderData.enableMacro("HAS_CLEARCOATTEXTURE"); + } else { + this.shaderData.disableMacro("HAS_CLEARCOATTEXTURE"); + } + } + + /** + * The clearcoat layer roughness, default 0. + */ + get clearcoatRoughness(): number { + return this.shaderData.getFloat(PBRBaseMaterial._clearcoatRoughnessProp); + } + + set clearcoatRoughness(value: number) { + this.shaderData.setFloat(PBRBaseMaterial._clearcoatRoughnessProp, value); + } + + /** + * The clearcoat layer roughness texture. + */ + get clearcoatRoughnessTexture(): Texture2D { + return this.shaderData.getTexture(PBRBaseMaterial._clearcoatRoughnessTextureProp); + } + + set clearcoatRoughnessTexture(value: Texture2D) { + this.shaderData.setTexture(PBRBaseMaterial._clearcoatRoughnessTextureProp, value); + + if (value) { + this.shaderData.enableMacro("HAS_CLEARCOATROUGHNESSTEXTURE"); + } else { + this.shaderData.disableMacro("HAS_CLEARCOATROUGHNESSTEXTURE"); + } + } + + /** + * The clearcoat normal map texture. + */ + get clearcoatNormalTexture(): Texture2D { + return this.shaderData.getTexture(PBRBaseMaterial._clearcoatNormalTextureProp); + } + + set clearcoatNormalTexture(value: Texture2D) { + this.shaderData.setTexture(PBRBaseMaterial._clearcoatNormalTextureProp, value); + + if (value) { + this.shaderData.enableMacro("HAS_CLEARCOATNORMALTEXTURE"); + } else { + this.shaderData.disableMacro("HAS_CLEARCOATNORMALTEXTURE"); + } + } + /** * Create a pbr base material instance. * @param engine - Engine to which the material belongs @@ -167,5 +252,8 @@ export abstract class PBRBaseMaterial extends BaseMaterial { shaderData.setFloat(PBRBaseMaterial._normalTextureIntensityProp, 1); shaderData.setFloat(PBRBaseMaterial._occlusionTextureIntensityProp, 1); + + this.shaderData.setFloat(PBRBaseMaterial._clearcoatProp, 0); + this.shaderData.setFloat(PBRBaseMaterial._clearcoatRoughnessProp, 0); } } diff --git a/packages/core/src/material/PBRMaterial.ts b/packages/core/src/material/PBRMaterial.ts index a35652dc2b..f14c649779 100644 --- a/packages/core/src/material/PBRMaterial.ts +++ b/packages/core/src/material/PBRMaterial.ts @@ -10,11 +10,6 @@ export class PBRMaterial extends PBRBaseMaterial { private static _metallicProp = Shader.getPropertyByName("u_metal"); private static _roughnessProp = Shader.getPropertyByName("u_roughness"); private static _metallicRoughnessTextureProp = Shader.getPropertyByName("u_metallicRoughnessSampler"); - private static _clearcoatProp = Shader.getPropertyByName("u_clearcoat"); - private static _clearcoatTextureProp = Shader.getPropertyByName("u_clearcoatTexture"); - private static _clearcoatRoughnessProp = Shader.getPropertyByName("u_clearcoatRoughness"); - private static _clearcoatRoughnessTextureProp = Shader.getPropertyByName("u_clearcoatRoughnessTexture"); - private static _clearcoatNormalTextureProp = Shader.getPropertyByName("u_clearcoatNormalTexture"); /** * Metallic, default 1. @@ -55,85 +50,6 @@ export class PBRMaterial extends PBRBaseMaterial { } } - /** - * The clearcoat layer intensity, default 0. - */ - get clearcoat(): number { - return this.shaderData.getFloat(PBRMaterial._clearcoatProp); - } - - set clearcoat(value: number) { - this.shaderData.setFloat(PBRMaterial._clearcoatProp, value); - - if (value === 0) { - this.shaderData.disableMacro("CLEARCOAT"); - } else { - this.shaderData.enableMacro("CLEARCOAT"); - } - } - - /** - * The clearcoat layer intensity texture. - */ - get clearcoatTexture(): Texture2D { - return this.shaderData.getTexture(PBRMaterial._clearcoatTextureProp); - } - - set clearcoatTexture(value: Texture2D) { - this.shaderData.setTexture(PBRMaterial._clearcoatTextureProp, value); - - if (value) { - this.shaderData.enableMacro("HAS_CLEARCOATTEXTURE"); - } else { - this.shaderData.disableMacro("HAS_CLEARCOATTEXTURE"); - } - } - - /** - * The clearcoat layer roughness, default 0. - */ - get clearcoatRoughness(): number { - return this.shaderData.getFloat(PBRMaterial._clearcoatRoughnessProp); - } - - set clearcoatRoughness(value: number) { - this.shaderData.setFloat(PBRMaterial._clearcoatRoughnessProp, value); - } - - /** - * The clearcoat layer roughness texture. - */ - get clearcoatRoughnessTexture(): Texture2D { - return this.shaderData.getTexture(PBRMaterial._clearcoatRoughnessTextureProp); - } - - set clearcoatRoughnessTexture(value: Texture2D) { - this.shaderData.setTexture(PBRMaterial._clearcoatRoughnessTextureProp, value); - - if (value) { - this.shaderData.enableMacro("HAS_CLEARCOATROUGHNESSTEXTURE"); - } else { - this.shaderData.disableMacro("HAS_CLEARCOATROUGHNESSTEXTURE"); - } - } - - /** - * The clearcoat normal map texture. - */ - get clearcoatNormalTexture(): Texture2D { - return this.shaderData.getTexture(PBRMaterial._clearcoatNormalTextureProp); - } - - set clearcoatNormalTexture(value: Texture2D) { - this.shaderData.setTexture(PBRMaterial._clearcoatNormalTextureProp, value); - - if (value) { - this.shaderData.enableMacro("HAS_CLEARCOATNORMALTEXTURE"); - } else { - this.shaderData.disableMacro("HAS_CLEARCOATNORMALTEXTURE"); - } - } - /** * Create a pbr metallic-roughness workflow material instance. * @param engine - Engine to which the material belongs @@ -142,8 +58,6 @@ export class PBRMaterial extends PBRBaseMaterial { super(engine, Shader.find("pbr")); this.shaderData.setFloat(PBRMaterial._metallicProp, 1); this.shaderData.setFloat(PBRMaterial._roughnessProp, 1); - this.shaderData.setFloat(PBRMaterial._clearcoatProp, 0); - this.shaderData.setFloat(PBRMaterial._clearcoatRoughnessProp, 0); } /** From 448ce1a16e0a6a95366752cd8480125ca5347872 Mon Sep 17 00:00:00 2001 From: "shensi.zxd" Date: Thu, 10 Mar 2022 18:04:45 +0800 Subject: [PATCH 11/16] refactor: code format --- packages/core/src/material/PBRBaseMaterial.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/core/src/material/PBRBaseMaterial.ts b/packages/core/src/material/PBRBaseMaterial.ts index 848dacdd15..58a922cee6 100644 --- a/packages/core/src/material/PBRBaseMaterial.ts +++ b/packages/core/src/material/PBRBaseMaterial.ts @@ -153,11 +153,10 @@ export abstract class PBRBaseMaterial extends BaseMaterial { } } - /** * The clearcoat layer intensity, default 0. */ - get clearcoat(): number { + get clearcoat(): number { return this.shaderData.getFloat(PBRBaseMaterial._clearcoatProp); } @@ -253,7 +252,7 @@ export abstract class PBRBaseMaterial extends BaseMaterial { shaderData.setFloat(PBRBaseMaterial._normalTextureIntensityProp, 1); shaderData.setFloat(PBRBaseMaterial._occlusionTextureIntensityProp, 1); - this.shaderData.setFloat(PBRBaseMaterial._clearcoatProp, 0); - this.shaderData.setFloat(PBRBaseMaterial._clearcoatRoughnessProp, 0); + shaderData.setFloat(PBRBaseMaterial._clearcoatProp, 0); + shaderData.setFloat(PBRBaseMaterial._clearcoatRoughnessProp, 0); } } From e9fd4b8c0cdf52bc73f27b549fa6a5f3a286ae8e Mon Sep 17 00:00:00 2001 From: "shensi.zxd" Date: Mon, 11 Apr 2022 17:56:06 +0800 Subject: [PATCH 12/16] perf: opt TBN --- .../core/src/shaderlib/blendShape_vert.glsl | 2 +- .../src/shaderlib/mobile_blinnphong_frag.glsl | 5 +- packages/core/src/shaderlib/normal_get.glsl | 72 ++++++++++--------- packages/core/src/shaderlib/normal_share.glsl | 2 +- packages/core/src/shaderlib/normal_vert.glsl | 2 +- .../core/src/shaderlib/pbr/pbr_helper.glsl | 15 +++- .../core/src/shaderlib/skinning_vert.glsl | 2 +- 7 files changed, 58 insertions(+), 42 deletions(-) diff --git a/packages/core/src/shaderlib/blendShape_vert.glsl b/packages/core/src/shaderlib/blendShape_vert.glsl index 237371e07d..218977ae8b 100644 --- a/packages/core/src/shaderlib/blendShape_vert.glsl +++ b/packages/core/src/shaderlib/blendShape_vert.glsl @@ -15,7 +15,7 @@ normal.xyz += NORMAL_BS3 * u_blendShapeWeights[3]; #endif - #if defined( O3_HAS_TANGENT ) && defined( O3_NORMAL_TEXTURE ) && defined(OASIS_BLENDSHAPE_TANGENT) + #if defined( O3_HAS_TANGENT ) && defined(OASIS_BLENDSHAPE_TANGENT) && ( defined(O3_NORMAL_TEXTURE) || defined(HAS_CLEARCOATNORMALTEXTURE) ) tangent.xyz += TANGENT_BS0 * u_blendShapeWeights[0]; tangent.xyz += TANGENT_BS1 * u_blendShapeWeights[1]; tangent.xyz += TANGENT_BS2 * u_blendShapeWeights[2]; diff --git a/packages/core/src/shaderlib/mobile_blinnphong_frag.glsl b/packages/core/src/shaderlib/mobile_blinnphong_frag.glsl index d0d9de454b..3115c76117 100644 --- a/packages/core/src/shaderlib/mobile_blinnphong_frag.glsl +++ b/packages/core/src/shaderlib/mobile_blinnphong_frag.glsl @@ -1,7 +1,10 @@ + mat3 tbn = getTBN(); vec3 N = getNormal( #ifdef O3_NORMAL_TEXTURE + tbn, u_normalTexture, - u_normalIntensity + u_normalIntensity, + v_uv #endif ); vec3 lightDiffuse = vec3( 0.0, 0.0, 0.0 ); diff --git a/packages/core/src/shaderlib/normal_get.glsl b/packages/core/src/shaderlib/normal_get.glsl index e6fe635d07..966946a80d 100644 --- a/packages/core/src/shaderlib/normal_get.glsl +++ b/packages/core/src/shaderlib/normal_get.glsl @@ -1,51 +1,55 @@ vec3 getNormal(){ - vec3 normal = vec3(0, 0, 1); - #ifdef O3_HAS_NORMAL - normal = normalize(v_normal); + vec3 normal = v_normal; #elif defined(HAS_DERIVATIVES) vec3 pos_dx = dFdx(v_pos); vec3 pos_dy = dFdy(v_pos); - normal = normalize( cross(pos_dx, pos_dy) ); + vec3 normal = normalize( cross(pos_dx, pos_dy) ); + #else + vec3 normal = vec3(0, 0, 1); #endif normal *= float( gl_FrontFacing ) * 2.0 - 1.0; return normal; } -vec3 getNormal(sampler2D normalTexture, float normalIntensity) -{ - - #if defined(O3_HAS_NORMAL) && defined(O3_HAS_TANGENT) && defined( O3_NORMAL_TEXTURE ) +vec3 getNormal(mat3 tbn, sampler2D normalTexture, float normalIntensity, vec2 uv){ + vec3 normal = texture2D(normalTexture, uv).rgb; + normal = normalize(tbn * ((2.0 * normal - 1.0) * vec3(normalIntensity, normalIntensity, 1.0))); + normal *= float( gl_FrontFacing ) * 2.0 - 1.0; + + return normal; +} + +mat3 getTBN(){ + #if defined(O3_HAS_NORMAL) && defined(O3_HAS_TANGENT) && ( defined(O3_NORMAL_TEXTURE) || defined(HAS_CLEARCOATNORMALTEXTURE) ) mat3 tbn = v_TBN; #else + vec3 normal = getNormal(); + vec3 position = v_pos; + vec2 uv = gl_FrontFacing? v_uv: -v_uv; + #ifdef HAS_DERIVATIVES - vec3 pos_dx = dFdx(v_pos); - vec3 pos_dy = dFdy(v_pos); - vec3 tex_dx = dFdx(vec3(v_uv, 0.0)); - vec3 tex_dy = dFdy(vec3(v_uv, 0.0)); - vec3 t = (tex_dy.t * pos_dx - tex_dx.t * pos_dy) / (tex_dx.s * tex_dy.t - tex_dy.s * tex_dx.t); - #ifdef O3_HAS_NORMAL - vec3 ng = normalize(v_normal); - #else - vec3 ng = normalize( cross(pos_dx, pos_dy) ); - #endif - t = normalize(t - ng * dot(ng, t)); - vec3 b = normalize(cross(ng, t)); - mat3 tbn = mat3(t, b, ng); + // ref: http://www.thetenthplanet.de/archives/1180 + // get edge vectors of the pixel triangle + vec3 dp1 = dFdx(position); + vec3 dp2 = dFdy(position); + vec2 duv1 = dFdx(uv); + vec2 duv2 = dFdy(uv); + + // solve the linear system + vec3 dp2perp = cross(dp2, normal); + vec3 dp1perp = cross(normal, dp1); + vec3 tangent = dp2perp * duv1.x + dp1perp * duv2.x; + vec3 binormal = dp2perp * duv1.y + dp1perp * duv2.y; + + // construct a scale-invariant frame + float invmax = inversesqrt(max(dot(tangent, tangent), dot(binormal, binormal))); + mat3 tbn = mat3(tangent * invmax, binormal * invmax, normal); #else - #ifdef O3_HAS_NORMAL - vec3 ng = normalize(v_normal); - #else - vec3 ng = vec3(0.0, 0.0, 1.0); - #endif - mat3 tbn = mat3(vec3(0.0), vec3(0.0), ng); + mat3 tbn = mat3(vec3(0.0), vec3(0.0), normal); #endif #endif - - vec3 normal = texture2D(normalTexture, v_uv ).rgb; - normal = normalize(tbn * ((2.0 * normal - 1.0) * vec3(normalIntensity, normalIntensity, 1.0))); - normal *= float( gl_FrontFacing ) * 2.0 - 1.0; - - return normal; -} + + return tbn; +} \ No newline at end of file diff --git a/packages/core/src/shaderlib/normal_share.glsl b/packages/core/src/shaderlib/normal_share.glsl index 094be54d11..fa03d27571 100644 --- a/packages/core/src/shaderlib/normal_share.glsl +++ b/packages/core/src/shaderlib/normal_share.glsl @@ -1,7 +1,7 @@ #ifndef OMIT_NORMAL #ifdef O3_HAS_NORMAL varying vec3 v_normal; - #if defined( O3_HAS_TANGENT ) && defined( O3_NORMAL_TEXTURE ) + #if defined(O3_HAS_TANGENT) && ( defined(O3_NORMAL_TEXTURE) || defined(HAS_CLEARCOATNORMALTEXTURE) ) varying mat3 v_TBN; #endif #endif diff --git a/packages/core/src/shaderlib/normal_vert.glsl b/packages/core/src/shaderlib/normal_vert.glsl index 03a42c72dc..9c44a0b3a6 100644 --- a/packages/core/src/shaderlib/normal_vert.glsl +++ b/packages/core/src/shaderlib/normal_vert.glsl @@ -2,7 +2,7 @@ #ifdef O3_HAS_NORMAL v_normal = normalize( mat3(u_normalMat) * normal ); - #if defined( O3_HAS_TANGENT ) && defined( O3_NORMAL_TEXTURE ) + #if defined(O3_HAS_TANGENT) && ( defined(O3_NORMAL_TEXTURE) || defined(HAS_CLEARCOATNORMALTEXTURE) ) vec3 normalW = normalize( mat3(u_normalMat) * normal.xyz ); vec3 tangentW = normalize( mat3(u_normalMat) * tangent.xyz ); vec3 bitangentW = cross( normalW, tangentW ) * tangent.w; diff --git a/packages/core/src/shaderlib/pbr/pbr_helper.glsl b/packages/core/src/shaderlib/pbr/pbr_helper.glsl index 1374290eee..40d0edef02 100644 --- a/packages/core/src/shaderlib/pbr/pbr_helper.glsl +++ b/packages/core/src/shaderlib/pbr/pbr_helper.glsl @@ -18,24 +18,33 @@ void initGeometry(out Geometry geometry){ geometry.position = v_pos; geometry.viewDir = normalize(u_cameraPos - v_pos); + #if defined(O3_NORMAL_TEXTURE) || defined(HAS_CLEARCOATNORMALTEXTURE) + mat3 tbn = getTBN(); + #endif + geometry.normal = getNormal( #ifdef O3_NORMAL_TEXTURE + tbn, u_normalTexture, - u_normalIntensity + u_normalIntensity, + v_uv #endif ); + geometry.dotNV = saturate( dot(geometry.normal, geometry.viewDir) ); + #ifdef CLEARCOAT geometry.clearcoatNormal = getNormal( #ifdef HAS_CLEARCOATNORMALTEXTURE + tbn, u_clearcoatNormalTexture, - u_normalIntensity + u_normalIntensity, + v_uv #endif ); geometry.clearcoatDotNV = saturate( dot(geometry.clearcoatNormal, geometry.viewDir) ); #endif - geometry.dotNV = saturate( dot(geometry.normal, geometry.viewDir) ); } void initMaterial(out Material material, const in Geometry geometry){ diff --git a/packages/core/src/shaderlib/skinning_vert.glsl b/packages/core/src/shaderlib/skinning_vert.glsl index 0874956155..b0eba9a14e 100644 --- a/packages/core/src/shaderlib/skinning_vert.glsl +++ b/packages/core/src/shaderlib/skinning_vert.glsl @@ -19,7 +19,7 @@ #if defined(O3_HAS_NORMAL) && !defined(OMIT_NORMAL) normal = vec4( skinMatrix * vec4( normal, 0.0 ) ).xyz; - #if defined( O3_HAS_TANGENT ) && defined( O3_NORMAL_TEXTURE ) + #if defined(O3_HAS_TANGENT) && ( defined(O3_NORMAL_TEXTURE) || defined(HAS_CLEARCOATNORMALTEXTURE) ) tangent.xyz = vec4( skinMatrix * vec4( tangent.xyz, 0.0 ) ).xyz; #endif From 82c48bcac396db41f8d4c932647ef7e61347af4c Mon Sep 17 00:00:00 2001 From: "shensi.zxd" Date: Thu, 21 Apr 2022 12:50:17 +0800 Subject: [PATCH 13/16] perf: opt code --- packages/core/src/material/PBRBaseMaterial.ts | 13 +++++++------ packages/core/src/material/PBRMaterial.ts | 4 ++-- packages/core/src/shaderlib/pbr/pbr_helper.glsl | 2 +- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/packages/core/src/material/PBRBaseMaterial.ts b/packages/core/src/material/PBRBaseMaterial.ts index fbad8fcf8b..f2a7521890 100644 --- a/packages/core/src/material/PBRBaseMaterial.ts +++ b/packages/core/src/material/PBRBaseMaterial.ts @@ -178,13 +178,14 @@ export abstract class PBRBaseMaterial extends BaseMaterial { } set clearcoat(value: number) { - this.shaderData.setFloat(PBRBaseMaterial._clearcoatProp, value); - - if (value === 0) { - this.shaderData.disableMacro("CLEARCOAT"); - } else { - this.shaderData.enableMacro("CLEARCOAT"); + if (!!this.shaderData.getFloat(PBRBaseMaterial._clearcoatProp) !== !!value) { + if (value === 0) { + this.shaderData.disableMacro("CLEARCOAT"); + } else { + this.shaderData.enableMacro("CLEARCOAT"); + } } + this.shaderData.setFloat(PBRBaseMaterial._clearcoatProp, value); } /** diff --git a/packages/core/src/material/PBRMaterial.ts b/packages/core/src/material/PBRMaterial.ts index f14c649779..56666318e8 100644 --- a/packages/core/src/material/PBRMaterial.ts +++ b/packages/core/src/material/PBRMaterial.ts @@ -12,7 +12,7 @@ export class PBRMaterial extends PBRBaseMaterial { private static _metallicRoughnessTextureProp = Shader.getPropertyByName("u_metallicRoughnessSampler"); /** - * Metallic, default 1. + * Metallic, default 1.0. */ get metallic(): number { return this.shaderData.getFloat(PBRMaterial._metallicProp); @@ -23,7 +23,7 @@ export class PBRMaterial extends PBRBaseMaterial { } /** - * Roughness, default 1. + * Roughness, default 1.0. */ get roughness(): number { return this.shaderData.getFloat(PBRMaterial._roughnessProp); diff --git a/packages/core/src/shaderlib/pbr/pbr_helper.glsl b/packages/core/src/shaderlib/pbr/pbr_helper.glsl index 40d0edef02..50bc9c0cb3 100644 --- a/packages/core/src/shaderlib/pbr/pbr_helper.glsl +++ b/packages/core/src/shaderlib/pbr/pbr_helper.glsl @@ -10,7 +10,7 @@ float getAARoughnessFactor(vec3 normal) { vec3 dxy = max( abs(dFdx(normal)), abs(dFdy(normal)) ); return max( max(dxy.x, dxy.y), dxy.z ); #else - return 0.0; + return 0.04; #endif } From 8c2291da5f096243e38c479765856159784ad13f Mon Sep 17 00:00:00 2001 From: "shensi.zxd" Date: Thu, 21 Apr 2022 15:14:21 +0800 Subject: [PATCH 14/16] refactor: rename --- packages/core/src/material/PBRBaseMaterial.ts | 66 +++++++++---------- .../pbr/direct_irradiance_frag_define.glsl | 8 +-- packages/core/src/shaderlib/pbr/pbr_frag.glsl | 6 +- .../src/shaderlib/pbr/pbr_frag_define.glsl | 18 ++--- .../core/src/shaderlib/pbr/pbr_helper.glsl | 18 ++--- .../extensions/KHR_materials_clearcoat.ts | 10 +-- 6 files changed, 63 insertions(+), 63 deletions(-) diff --git a/packages/core/src/material/PBRBaseMaterial.ts b/packages/core/src/material/PBRBaseMaterial.ts index f2a7521890..c677160564 100644 --- a/packages/core/src/material/PBRBaseMaterial.ts +++ b/packages/core/src/material/PBRBaseMaterial.ts @@ -21,11 +21,11 @@ export abstract class PBRBaseMaterial extends BaseMaterial { private static _emissiveTextureProp = Shader.getPropertyByName("u_emissiveSampler"); private static _occlusionTextureProp = Shader.getPropertyByName("u_occlusionSampler"); - private static _clearcoatProp = Shader.getPropertyByName("u_clearcoat"); - private static _clearcoatTextureProp = Shader.getPropertyByName("u_clearcoatTexture"); - private static _clearcoatRoughnessProp = Shader.getPropertyByName("u_clearcoatRoughness"); - private static _clearcoatRoughnessTextureProp = Shader.getPropertyByName("u_clearcoatRoughnessTexture"); - private static _clearcoatNormalTextureProp = Shader.getPropertyByName("u_clearcoatNormalTexture"); + private static _clearCoatProp = Shader.getPropertyByName("u_clearCoat"); + private static _clearCoatTextureProp = Shader.getPropertyByName("u_clearCoatTexture"); + private static _clearCoatRoughnessProp = Shader.getPropertyByName("u_clearCoatRoughness"); + private static _clearCoatRoughnessTextureProp = Shader.getPropertyByName("u_clearCoatRoughnessTexture"); + private static _clearCoatNormalTextureProp = Shader.getPropertyByName("u_clearCoatNormalTexture"); /** * Base color. @@ -171,32 +171,32 @@ export abstract class PBRBaseMaterial extends BaseMaterial { } /** - * The clearcoat layer intensity, default 0. + * The clearCoat layer intensity, default 0. */ - get clearcoat(): number { - return this.shaderData.getFloat(PBRBaseMaterial._clearcoatProp); + get clearCoat(): number { + return this.shaderData.getFloat(PBRBaseMaterial._clearCoatProp); } - set clearcoat(value: number) { - if (!!this.shaderData.getFloat(PBRBaseMaterial._clearcoatProp) !== !!value) { + set clearCoat(value: number) { + if (!!this.shaderData.getFloat(PBRBaseMaterial._clearCoatProp) !== !!value) { if (value === 0) { this.shaderData.disableMacro("CLEARCOAT"); } else { this.shaderData.enableMacro("CLEARCOAT"); } } - this.shaderData.setFloat(PBRBaseMaterial._clearcoatProp, value); + this.shaderData.setFloat(PBRBaseMaterial._clearCoatProp, value); } /** - * The clearcoat layer intensity texture. + * The clearCoat layer intensity texture. */ - get clearcoatTexture(): Texture2D { - return this.shaderData.getTexture(PBRBaseMaterial._clearcoatTextureProp); + get clearCoatTexture(): Texture2D { + return this.shaderData.getTexture(PBRBaseMaterial._clearCoatTextureProp); } - set clearcoatTexture(value: Texture2D) { - this.shaderData.setTexture(PBRBaseMaterial._clearcoatTextureProp, value); + set clearCoatTexture(value: Texture2D) { + this.shaderData.setTexture(PBRBaseMaterial._clearCoatTextureProp, value); if (value) { this.shaderData.enableMacro("HAS_CLEARCOATTEXTURE"); @@ -206,25 +206,25 @@ export abstract class PBRBaseMaterial extends BaseMaterial { } /** - * The clearcoat layer roughness, default 0. + * The clearCoat layer roughness, default 0. */ - get clearcoatRoughness(): number { - return this.shaderData.getFloat(PBRBaseMaterial._clearcoatRoughnessProp); + get clearCoatRoughness(): number { + return this.shaderData.getFloat(PBRBaseMaterial._clearCoatRoughnessProp); } - set clearcoatRoughness(value: number) { - this.shaderData.setFloat(PBRBaseMaterial._clearcoatRoughnessProp, value); + set clearCoatRoughness(value: number) { + this.shaderData.setFloat(PBRBaseMaterial._clearCoatRoughnessProp, value); } /** - * The clearcoat layer roughness texture. + * The clearCoat layer roughness texture. */ - get clearcoatRoughnessTexture(): Texture2D { - return this.shaderData.getTexture(PBRBaseMaterial._clearcoatRoughnessTextureProp); + get clearCoatRoughnessTexture(): Texture2D { + return this.shaderData.getTexture(PBRBaseMaterial._clearCoatRoughnessTextureProp); } - set clearcoatRoughnessTexture(value: Texture2D) { - this.shaderData.setTexture(PBRBaseMaterial._clearcoatRoughnessTextureProp, value); + set clearCoatRoughnessTexture(value: Texture2D) { + this.shaderData.setTexture(PBRBaseMaterial._clearCoatRoughnessTextureProp, value); if (value) { this.shaderData.enableMacro("HAS_CLEARCOATROUGHNESSTEXTURE"); @@ -234,14 +234,14 @@ export abstract class PBRBaseMaterial extends BaseMaterial { } /** - * The clearcoat normal map texture. + * The clearCoat normal map texture. */ - get clearcoatNormalTexture(): Texture2D { - return this.shaderData.getTexture(PBRBaseMaterial._clearcoatNormalTextureProp); + get clearCoatNormalTexture(): Texture2D { + return this.shaderData.getTexture(PBRBaseMaterial._clearCoatNormalTextureProp); } - set clearcoatNormalTexture(value: Texture2D) { - this.shaderData.setTexture(PBRBaseMaterial._clearcoatNormalTextureProp, value); + set clearCoatNormalTexture(value: Texture2D) { + this.shaderData.setTexture(PBRBaseMaterial._clearCoatNormalTextureProp, value); if (value) { this.shaderData.enableMacro("HAS_CLEARCOATNORMALTEXTURE"); @@ -271,7 +271,7 @@ export abstract class PBRBaseMaterial extends BaseMaterial { shaderData.setFloat(PBRBaseMaterial._occlusionTextureIntensityProp, 1); shaderData.setFloat(PBRBaseMaterial._occlusionTextureCoordProp, TextureCoordinate.UV0); - shaderData.setFloat(PBRBaseMaterial._clearcoatProp, 0); - shaderData.setFloat(PBRBaseMaterial._clearcoatRoughnessProp, 0); + shaderData.setFloat(PBRBaseMaterial._clearCoatProp, 0); + shaderData.setFloat(PBRBaseMaterial._clearCoatRoughnessProp, 0); } } 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 27ff5bbaad..98bf83fd56 100644 --- a/packages/core/src/shaderlib/pbr/direct_irradiance_frag_define.glsl +++ b/packages/core/src/shaderlib/pbr/direct_irradiance_frag_define.glsl @@ -2,11 +2,11 @@ void addDirectRadiance(vec3 incidentDirection, vec3 color, Geometry geometry, Ma float attenuation = 1.0; #ifdef CLEARCOAT - float clearcoatDotNL = saturate( dot( geometry.clearcoatNormal, incidentDirection ) ); - vec3 clearcoatIrradiance = clearcoatDotNL * color; + float clearCoatDotNL = saturate( dot( geometry.clearCoatNormal, incidentDirection ) ); + vec3 clearCoatIrradiance = clearCoatDotNL * color; - reflectedLight.directSpecular += material.clearcoat * clearcoatIrradiance * BRDF_Specular_GGX( incidentDirection, geometry.viewDir, geometry.clearcoatNormal, vec3( 0.04 ), material.clearcoatRoughness ); - attenuation -= material.clearcoat * F_Schlick(geometry.clearcoatDotNV); + reflectedLight.directSpecular += material.clearCoat * clearCoatIrradiance * BRDF_Specular_GGX( incidentDirection, geometry.viewDir, geometry.clearCoatNormal, vec3( 0.04 ), material.clearCoatRoughness ); + attenuation -= material.clearCoat * F_Schlick(geometry.clearCoatDotNV); #endif float dotNL = saturate( dot( geometry.normal, incidentDirection ) ); diff --git a/packages/core/src/shaderlib/pbr/pbr_frag.glsl b/packages/core/src/shaderlib/pbr/pbr_frag.glsl index b2f39da8e8..abc3a6b15b 100644 --- a/packages/core/src/shaderlib/pbr/pbr_frag.glsl +++ b/packages/core/src/shaderlib/pbr/pbr_frag.glsl @@ -27,10 +27,10 @@ vec3 radiance = getLightProbeRadiance(geometry.viewDir, geometry.normal, materia float radianceAttenuation = 1.0; #ifdef CLEARCOAT - vec3 clearcoatRadiance = getLightProbeRadiance( geometry.viewDir, geometry.clearcoatNormal, material.clearcoatRoughness, int(u_envMapLight.mipMapLevel), u_envMapLight.specularIntensity ); + vec3 clearCoatRadiance = getLightProbeRadiance( geometry.viewDir, geometry.clearCoatNormal, material.clearCoatRoughness, int(u_envMapLight.mipMapLevel), u_envMapLight.specularIntensity ); - reflectedLight.indirectSpecular += clearcoatRadiance * material.clearcoat * envBRDFApprox(vec3( 0.04 ), material.clearcoatRoughness, geometry.clearcoatDotNV); - radianceAttenuation -= material.clearcoat * F_Schlick(geometry.clearcoatDotNV); + reflectedLight.indirectSpecular += clearCoatRadiance * material.clearCoat * envBRDFApprox(vec3( 0.04 ), material.clearCoatRoughness, geometry.clearCoatDotNV); + radianceAttenuation -= material.clearCoat * F_Schlick(geometry.clearCoatDotNV); #endif reflectedLight.indirectSpecular += radianceAttenuation * radiance * envBRDFApprox(material.specularColor, material.roughness, geometry.dotNV ); diff --git a/packages/core/src/shaderlib/pbr/pbr_frag_define.glsl b/packages/core/src/shaderlib/pbr/pbr_frag_define.glsl index 00a72ab743..928735fe78 100644 --- a/packages/core/src/shaderlib/pbr/pbr_frag_define.glsl +++ b/packages/core/src/shaderlib/pbr/pbr_frag_define.glsl @@ -7,8 +7,8 @@ uniform float u_glossiness; uniform vec3 u_emissiveColor; #ifdef CLEARCOAT - uniform float u_clearcoat; - uniform float u_clearcoatRoughness; + uniform float u_clearCoat; + uniform float u_clearCoatRoughness; #endif uniform float u_normalIntensity; @@ -42,15 +42,15 @@ uniform float u_occlusionTextureCoord; #endif #ifdef HAS_CLEARCOATTEXTURE - uniform sampler2D u_clearcoatTexture; + uniform sampler2D u_clearCoatTexture; #endif #ifdef HAS_CLEARCOATROUGHNESSTEXTURE - uniform sampler2D u_clearcoatRoughnessTexture; + uniform sampler2D u_clearCoatRoughnessTexture; #endif #ifdef HAS_CLEARCOATNORMALTEXTURE - uniform sampler2D u_clearcoatNormalTexture; + uniform sampler2D u_clearCoatNormalTexture; #endif @@ -70,8 +70,8 @@ struct Geometry { float dotNV; #ifdef CLEARCOAT - vec3 clearcoatNormal; - float clearcoatDotNV; + vec3 clearCoatNormal; + float clearCoatDotNV; #endif }; @@ -82,8 +82,8 @@ struct Material { vec3 specularColor; float opacity; #ifdef CLEARCOAT - float clearcoat; - float clearcoatRoughness; + float clearCoat; + float clearCoatRoughness; #endif }; diff --git a/packages/core/src/shaderlib/pbr/pbr_helper.glsl b/packages/core/src/shaderlib/pbr/pbr_helper.glsl index 50bc9c0cb3..b6bf76a359 100644 --- a/packages/core/src/shaderlib/pbr/pbr_helper.glsl +++ b/packages/core/src/shaderlib/pbr/pbr_helper.glsl @@ -34,15 +34,15 @@ void initGeometry(out Geometry geometry){ #ifdef CLEARCOAT - geometry.clearcoatNormal = getNormal( + geometry.clearCoatNormal = getNormal( #ifdef HAS_CLEARCOATNORMALTEXTURE tbn, - u_clearcoatNormalTexture, + u_clearCoatNormalTexture, u_normalIntensity, v_uv #endif ); - geometry.clearcoatDotNV = saturate( dot(geometry.clearcoatNormal, geometry.viewDir) ); + geometry.clearCoatDotNV = saturate( dot(geometry.clearCoatNormal, geometry.viewDir) ); #endif } @@ -104,16 +104,16 @@ void initMaterial(out Material material, const in Geometry geometry){ material.roughness = max(material.roughness, getAARoughnessFactor(geometry.normal)); #ifdef CLEARCOAT - material.clearcoat = u_clearcoat; - material.clearcoatRoughness = u_clearcoatRoughness; + material.clearCoat = u_clearCoat; + material.clearCoatRoughness = u_clearCoatRoughness; #ifdef HAS_CLEARCOATTEXTURE - material.clearcoat *= texture2D( u_clearcoatTexture, v_uv ).r; + material.clearCoat *= texture2D( u_clearCoatTexture, v_uv ).r; #endif #ifdef HAS_CLEARCOATROUGHNESSTEXTURE - material.clearcoatRoughness *= texture2D( u_clearcoatRoughnessTexture, v_uv ).g; + material.clearCoatRoughness *= texture2D( u_clearCoatRoughnessTexture, v_uv ).g; #endif - material.clearcoat = saturate( material.clearcoat ); - material.clearcoatRoughness = max(material.clearcoatRoughness, getAARoughnessFactor(geometry.clearcoatNormal)); + material.clearCoat = saturate( material.clearCoat ); + material.clearCoatRoughness = max(material.clearCoatRoughness, getAARoughnessFactor(geometry.clearCoatNormal)); #endif material.opacity = baseColor.a; diff --git a/packages/loader/src/gltf/extensions/KHR_materials_clearcoat.ts b/packages/loader/src/gltf/extensions/KHR_materials_clearcoat.ts index 4d92337e6c..1c204e4ae8 100644 --- a/packages/loader/src/gltf/extensions/KHR_materials_clearcoat.ts +++ b/packages/loader/src/gltf/extensions/KHR_materials_clearcoat.ts @@ -17,19 +17,19 @@ class KHR_materials_clearcoat extends ExtensionParser { clearcoatNormalTexture } = schema; - material.clearcoat = clearcoatFactor; - material.clearcoatRoughness = clearcoatRoughnessFactor; + material.clearCoat = clearcoatFactor; + material.clearCoatRoughness = clearcoatRoughnessFactor; if (clearcoatTexture) { - material.clearcoatTexture = textures[clearcoatTexture.index]; + material.clearCoatTexture = textures[clearcoatTexture.index]; MaterialParser._parseTextureTransform(material, clearcoatTexture.extensions, context); } if (clearcoatRoughnessTexture) { - material.clearcoatRoughnessTexture = textures[clearcoatRoughnessTexture.index]; + material.clearCoatRoughnessTexture = textures[clearcoatRoughnessTexture.index]; MaterialParser._parseTextureTransform(material, clearcoatRoughnessTexture.extensions, context); } if (clearcoatNormalTexture) { - material.clearcoatNormalTexture = textures[clearcoatNormalTexture.index]; + material.clearCoatNormalTexture = textures[clearcoatNormalTexture.index]; MaterialParser._parseTextureTransform(material, clearcoatNormalTexture.extensions, context); } } From c06f809c2c0e90d2930260e270b3a037610a4934 Mon Sep 17 00:00:00 2001 From: "shensi.zxd" Date: Thu, 21 Apr 2022 17:57:58 +0800 Subject: [PATCH 15/16] perf: opt code --- .../src/shaderlib/mobile_blinnphong_frag.glsl | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/packages/core/src/shaderlib/mobile_blinnphong_frag.glsl b/packages/core/src/shaderlib/mobile_blinnphong_frag.glsl index 3115c76117..40e22bfc71 100644 --- a/packages/core/src/shaderlib/mobile_blinnphong_frag.glsl +++ b/packages/core/src/shaderlib/mobile_blinnphong_frag.glsl @@ -1,12 +1,10 @@ - mat3 tbn = getTBN(); - vec3 N = getNormal( - #ifdef O3_NORMAL_TEXTURE - tbn, - u_normalTexture, - u_normalIntensity, - v_uv - #endif - ); + #ifdef O3_NORMAL_TEXTURE + mat3 tbn = getTBN(); + vec3 N = getNormal(tbn, u_normalTexture, u_normalIntensity, v_uv); + #else + vec3 N = getNormal(); + #endif + vec3 lightDiffuse = vec3( 0.0, 0.0, 0.0 ); vec3 lightSpecular = vec3( 0.0, 0.0, 0.0 ); From 09feead6c5ea5988de6be117cab469de6ec7c787 Mon Sep 17 00:00:00 2001 From: "shensi.zxd" Date: Thu, 21 Apr 2022 18:43:00 +0800 Subject: [PATCH 16/16] refactor: opt code --- .../src/shaderlib/mobile_blinnphong_frag.glsl | 2 +- packages/core/src/shaderlib/normal_get.glsl | 2 +- .../core/src/shaderlib/pbr/pbr_helper.glsl | 27 ++++++++----------- 3 files changed, 13 insertions(+), 18 deletions(-) diff --git a/packages/core/src/shaderlib/mobile_blinnphong_frag.glsl b/packages/core/src/shaderlib/mobile_blinnphong_frag.glsl index 40e22bfc71..0beae8db71 100644 --- a/packages/core/src/shaderlib/mobile_blinnphong_frag.glsl +++ b/packages/core/src/shaderlib/mobile_blinnphong_frag.glsl @@ -1,6 +1,6 @@ #ifdef O3_NORMAL_TEXTURE mat3 tbn = getTBN(); - vec3 N = getNormal(tbn, u_normalTexture, u_normalIntensity, v_uv); + vec3 N = getNormalByNormalTexture(tbn, u_normalTexture, u_normalIntensity, v_uv); #else vec3 N = getNormal(); #endif diff --git a/packages/core/src/shaderlib/normal_get.glsl b/packages/core/src/shaderlib/normal_get.glsl index 966946a80d..05db910870 100644 --- a/packages/core/src/shaderlib/normal_get.glsl +++ b/packages/core/src/shaderlib/normal_get.glsl @@ -13,7 +13,7 @@ vec3 getNormal(){ return normal; } -vec3 getNormal(mat3 tbn, sampler2D normalTexture, float normalIntensity, vec2 uv){ +vec3 getNormalByNormalTexture(mat3 tbn, sampler2D normalTexture, float normalIntensity, vec2 uv){ vec3 normal = texture2D(normalTexture, uv).rgb; normal = normalize(tbn * ((2.0 * normal - 1.0) * vec3(normalIntensity, normalIntensity, 1.0))); normal *= float( gl_FrontFacing ) * 2.0 - 1.0; diff --git a/packages/core/src/shaderlib/pbr/pbr_helper.glsl b/packages/core/src/shaderlib/pbr/pbr_helper.glsl index b6bf76a359..8b9b8d3ffd 100644 --- a/packages/core/src/shaderlib/pbr/pbr_helper.glsl +++ b/packages/core/src/shaderlib/pbr/pbr_helper.glsl @@ -22,26 +22,21 @@ void initGeometry(out Geometry geometry){ mat3 tbn = getTBN(); #endif - geometry.normal = getNormal( - #ifdef O3_NORMAL_TEXTURE - tbn, - u_normalTexture, - u_normalIntensity, - v_uv - #endif - ); + #ifdef O3_NORMAL_TEXTURE + geometry.normal = getNormalByNormalTexture(tbn, u_normalTexture, u_normalIntensity, v_uv); + #else + geometry.normal = getNormal(); + #endif + geometry.dotNV = saturate( dot(geometry.normal, geometry.viewDir) ); #ifdef CLEARCOAT - geometry.clearCoatNormal = getNormal( - #ifdef HAS_CLEARCOATNORMALTEXTURE - tbn, - u_clearCoatNormalTexture, - u_normalIntensity, - v_uv - #endif - ); + #ifdef HAS_CLEARCOATNORMALTEXTURE + geometry.clearCoatNormal = getNormalByNormalTexture(tbn, u_clearCoatNormalTexture, u_normalIntensity, v_uv); + #else + geometry.clearCoatNormal = getNormal(); + #endif geometry.clearCoatDotNV = saturate( dot(geometry.clearCoatNormal, geometry.viewDir) ); #endif