From 06a42424b92464a59773e7bf71a180018edcbf75 Mon Sep 17 00:00:00 2001 From: hhhhkrx Date: Tue, 3 Dec 2024 15:47:26 +0800 Subject: [PATCH 1/5] feat: pbr support sheen --- packages/core/src/material/PBRMaterial.ts | 87 ++++++++++++++++++- .../gltf/extensions/KHR_materials_sheen.ts | 41 +++++++++ 2 files changed, 127 insertions(+), 1 deletion(-) diff --git a/packages/core/src/material/PBRMaterial.ts b/packages/core/src/material/PBRMaterial.ts index 9b0d65ba30..c054c561f9 100644 --- a/packages/core/src/material/PBRMaterial.ts +++ b/packages/core/src/material/PBRMaterial.ts @@ -1,4 +1,4 @@ -import { MathUtil, Vector2, Vector3, Vector4 } from "@galacean/engine-math"; +import { MathUtil, Vector2, Vector3, Vector4, Color } from "@galacean/engine-math"; import { Engine } from "../Engine"; import { ShaderProperty } from "../shader"; import { Shader } from "../shader/Shader"; @@ -25,6 +25,12 @@ export class PBRMaterial extends PBRBaseMaterial { private static _iridescenceTextureProp = ShaderProperty.getByName("material_IridescenceTexture"); private _iridescenceRange = new Vector2(100, 400); + private static _sheenProp = ShaderProperty.getByName("material_Sheen"); + private static _sheenColorProp = ShaderProperty.getByName("material_SheenColor"); + private static _sheenRoughnessProp = ShaderProperty.getByName("material_SheenRoughness"); + private static _sheenTextureProp = ShaderProperty.getByName("material_SheenTexture"); + private static _sheenRoughnessTextureProp = ShaderProperty.getByName("material_SheenRoughnessTexture"); + /** * Index Of Refraction. * @defaultValue `1.5` @@ -222,6 +228,84 @@ export class PBRMaterial extends PBRBaseMaterial { } } + /** + * The sheen layer intensity, from 0.0 to 1.0. + * @defaultValue `0` + */ + get sheen(): number { + return this.shaderData.getFloat(PBRMaterial._sheenProp); + } + + set sheen(value: number) { + if (!!this.shaderData.getFloat(PBRMaterial._sheenProp) !== !!value) { + if (value === 0) { + this.shaderData.disableMacro("MATERIAL_ENABLE_SHEEN"); + } else { + this.shaderData.enableMacro("MATERIAL_ENABLE_SHEEN"); + } + } + this.shaderData.setFloat(PBRMaterial._sheenProp, value); + } + + /** + * Sheen color + * @defaultValue `[0,0,0]` + */ + get sheenColor(): Color { + return this.shaderData.getColor(PBRMaterial._sheenColorProp); + } + + set sheenColor(value: Color) { + const sheenColor = this.shaderData.getColor(PBRMaterial._sheenColorProp); + if (value !== sheenColor) { + sheenColor.copyFrom(value); + } + } + + /** + * Sheen roughness, from 0.0 to 1.0. + * @defaultValue `0.0` + */ + get sheenRoughness(): number { + return this.shaderData.getFloat(PBRMaterial._sheenRoughnessProp); + } + + set sheenRoughness(value: number) { + this.shaderData.setFloat(PBRMaterial._sheenRoughnessProp, value); + } + + /** + * Sheen color texture, multiply ‘sheencolor’. + */ + get sheenColorTexture(): Texture2D { + return this.shaderData.getTexture(PBRMaterial._sheenTextureProp); + } + + set sheenColorTexture(value: Texture2D) { + this.shaderData.setTexture(PBRMaterial._sheenTextureProp, value); + if (value) { + this.shaderData.enableMacro("MATERIAL_HAS_SHEEN_TEXTURE"); + } else { + this.shaderData.disableMacro("MATERIAL_HAS_SHEEN_TEXTURE"); + } + } + + /** + * Sheen roughness texture, multiply 'sheenRoughness'. + */ + get sheenRoughnessTexture(): Texture2D { + return this.shaderData.getTexture(PBRMaterial._sheenRoughnessTextureProp); + } + + set sheenRoughnessTexture(value: Texture2D) { + this.shaderData.setTexture(PBRMaterial._sheenRoughnessTextureProp, value); + if (value) { + this.shaderData.enableMacro("MATERIAL_HAS_SHEEN_ROUGHNESS_TEXTURE"); + } else { + this.shaderData.disableMacro("MATERIAL_HAS_SHEEN_ROUGHNESS_TEXTURE"); + } + } + /** * Create a pbr metallic-roughness workflow material instance. * @param engine - Engine to which the material belongs @@ -235,6 +319,7 @@ export class PBRMaterial extends PBRBaseMaterial { shaderData.setFloat(PBRMaterial._iorProp, 1.5); shaderData.setVector3(PBRMaterial._anisotropyInfoProp, new Vector3(1, 0, 0)); shaderData.setVector4(PBRMaterial._iridescenceInfoProp, new Vector4(0, 1.3, 100, 400)); + shaderData.setColor(PBRMaterial._sheenColorProp, new Color(1, 1, 1)); // @ts-ignore this._iridescenceRange._onValueChanged = this._onIridescenceRangeChanged.bind(this); } diff --git a/packages/loader/src/gltf/extensions/KHR_materials_sheen.ts b/packages/loader/src/gltf/extensions/KHR_materials_sheen.ts index e69de29bb2..6e1fa3fc7c 100644 --- a/packages/loader/src/gltf/extensions/KHR_materials_sheen.ts +++ b/packages/loader/src/gltf/extensions/KHR_materials_sheen.ts @@ -0,0 +1,41 @@ +import { PBRMaterial, Texture2D } from "@galacean/engine-core"; +import { Color } from "@galacean/engine-math"; +import { GLTFMaterialParser } from "../parser/GLTFMaterialParser"; +import { registerGLTFExtension } from "../parser/GLTFParser"; +import { GLTFParserContext, GLTFParserType } from "../parser/GLTFParserContext"; +import { GLTFExtensionMode, GLTFExtensionParser } from "./GLTFExtensionParser"; +import { IKHRMaterialsSheen } from "./GLTFExtensionSchema"; + +@registerGLTFExtension("KHR_materials_sheen", GLTFExtensionMode.AdditiveParse) +class KHR_materials_sheen extends GLTFExtensionParser { + override additiveParse(context: GLTFParserContext, material: PBRMaterial, schema: IKHRMaterialsSheen): void { + const { sheenColorFactor, sheenColorTexture, sheenRoughnessFactor, sheenRoughnessTexture } = schema; + + if (sheenColorFactor) { + material.sheenColor = new Color( + Color.linearToGammaSpace(sheenColorFactor[0]), + Color.linearToGammaSpace(sheenColorFactor[1]), + Color.linearToGammaSpace(sheenColorFactor[2]), + sheenColorFactor[3] + ); + } + + material.sheenRoughness = sheenRoughnessFactor; + + if (sheenColorTexture) { + GLTFMaterialParser._checkOtherTextureTransform(sheenColorTexture, "Sheen texture"); + + context.get(GLTFParserType.Texture, sheenColorTexture.index).then((texture) => { + material.sheenColorTexture = texture; + }); + } + + if (sheenRoughnessTexture) { + GLTFMaterialParser._checkOtherTextureTransform(sheenRoughnessTexture, "SheenRoughness texture"); + + context.get(GLTFParserType.Texture, sheenRoughnessTexture.index).then((texture) => { + material.sheenRoughnessTexture = texture; + }); + } + } +} From d1dda0c989fa5d7bc6f5c589e1583935948428b4 Mon Sep 17 00:00:00 2001 From: hhhhkrx Date: Tue, 10 Dec 2024 20:29:30 +0800 Subject: [PATCH 2/5] fix: sheen switch --- packages/core/src/material/PBRMaterial.ts | 46 +++++++++---------- .../gltf/extensions/KHR_materials_sheen.ts | 5 +- 2 files changed, 25 insertions(+), 26 deletions(-) diff --git a/packages/core/src/material/PBRMaterial.ts b/packages/core/src/material/PBRMaterial.ts index c054c561f9..0d69af328a 100644 --- a/packages/core/src/material/PBRMaterial.ts +++ b/packages/core/src/material/PBRMaterial.ts @@ -25,7 +25,7 @@ export class PBRMaterial extends PBRBaseMaterial { private static _iridescenceTextureProp = ShaderProperty.getByName("material_IridescenceTexture"); private _iridescenceRange = new Vector2(100, 400); - private static _sheenProp = ShaderProperty.getByName("material_Sheen"); + private _sheen: boolean = false; private static _sheenColorProp = ShaderProperty.getByName("material_SheenColor"); private static _sheenRoughnessProp = ShaderProperty.getByName("material_SheenRoughness"); private static _sheenTextureProp = ShaderProperty.getByName("material_SheenTexture"); @@ -228,25 +228,6 @@ export class PBRMaterial extends PBRBaseMaterial { } } - /** - * The sheen layer intensity, from 0.0 to 1.0. - * @defaultValue `0` - */ - get sheen(): number { - return this.shaderData.getFloat(PBRMaterial._sheenProp); - } - - set sheen(value: number) { - if (!!this.shaderData.getFloat(PBRMaterial._sheenProp) !== !!value) { - if (value === 0) { - this.shaderData.disableMacro("MATERIAL_ENABLE_SHEEN"); - } else { - this.shaderData.enableMacro("MATERIAL_ENABLE_SHEEN"); - } - } - this.shaderData.setFloat(PBRMaterial._sheenProp, value); - } - /** * Sheen color * @defaultValue `[0,0,0]` @@ -275,7 +256,7 @@ export class PBRMaterial extends PBRBaseMaterial { } /** - * Sheen color texture, multiply ‘sheencolor’. + * Sheencolor texture, multiply ‘sheencolor’. */ get sheenColorTexture(): Texture2D { return this.shaderData.getTexture(PBRMaterial._sheenTextureProp); @@ -291,7 +272,7 @@ export class PBRMaterial extends PBRBaseMaterial { } /** - * Sheen roughness texture, multiply 'sheenRoughness'. + * @remarks Use alpha channel, and multiply 'sheenRoughness'. */ get sheenRoughnessTexture(): Texture2D { return this.shaderData.getTexture(PBRMaterial._sheenRoughnessTextureProp); @@ -319,9 +300,28 @@ export class PBRMaterial extends PBRBaseMaterial { shaderData.setFloat(PBRMaterial._iorProp, 1.5); shaderData.setVector3(PBRMaterial._anisotropyInfoProp, new Vector3(1, 0, 0)); shaderData.setVector4(PBRMaterial._iridescenceInfoProp, new Vector4(0, 1.3, 100, 400)); - shaderData.setColor(PBRMaterial._sheenColorProp, new Color(1, 1, 1)); + shaderData.setColor(PBRMaterial._sheenColorProp, new Color(0, 0, 0, 0)); // @ts-ignore this._iridescenceRange._onValueChanged = this._onIridescenceRangeChanged.bind(this); + // @ts-ignore + this.sheenColor._onValueChanged = () => { + const r = this.sheenColor.r; + const g = this.sheenColor.g; + const b = this.sheenColor.b; + const a = this.sheenColor.a; + /** + * The sheen layer switch. + */ + const enableSheen = (r + g + b) * a > 0; + if (enableSheen !== this._sheen) { + this._sheen = enableSheen; + if (enableSheen) { + this.shaderData.enableMacro("MATERIAL_ENABLE_SHEEN"); + } else { + this.shaderData.disableMacro("MATERIAL_ENABLE_SHEEN"); + } + } + }; } private _onIridescenceRangeChanged(): void { diff --git a/packages/loader/src/gltf/extensions/KHR_materials_sheen.ts b/packages/loader/src/gltf/extensions/KHR_materials_sheen.ts index 6e1fa3fc7c..504d9cd157 100644 --- a/packages/loader/src/gltf/extensions/KHR_materials_sheen.ts +++ b/packages/loader/src/gltf/extensions/KHR_materials_sheen.ts @@ -12,11 +12,10 @@ class KHR_materials_sheen extends GLTFExtensionParser { const { sheenColorFactor, sheenColorTexture, sheenRoughnessFactor, sheenRoughnessTexture } = schema; if (sheenColorFactor) { - material.sheenColor = new Color( + material.sheenColor.set( Color.linearToGammaSpace(sheenColorFactor[0]), Color.linearToGammaSpace(sheenColorFactor[1]), - Color.linearToGammaSpace(sheenColorFactor[2]), - sheenColorFactor[3] + Color.linearToGammaSpace(sheenColorFactor[2]) ); } From 5604310bc6affa5b4ceb295ead810c6785c46718 Mon Sep 17 00:00:00 2001 From: hhhhkrx Date: Wed, 11 Dec 2024 14:52:46 +0800 Subject: [PATCH 3/5] fix: sheen --- packages/core/src/material/PBRMaterial.ts | 18 +++++++++--------- .../src/gltf/extensions/KHR_materials_sheen.ts | 3 ++- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/packages/core/src/material/PBRMaterial.ts b/packages/core/src/material/PBRMaterial.ts index 0d69af328a..9deca97db5 100644 --- a/packages/core/src/material/PBRMaterial.ts +++ b/packages/core/src/material/PBRMaterial.ts @@ -25,7 +25,7 @@ export class PBRMaterial extends PBRBaseMaterial { private static _iridescenceTextureProp = ShaderProperty.getByName("material_IridescenceTexture"); private _iridescenceRange = new Vector2(100, 400); - private _sheen: boolean = false; + private _sheenEnabled = false; private static _sheenColorProp = ShaderProperty.getByName("material_SheenColor"); private static _sheenRoughnessProp = ShaderProperty.getByName("material_SheenRoughness"); private static _sheenTextureProp = ShaderProperty.getByName("material_SheenTexture"); @@ -196,7 +196,7 @@ export class PBRMaterial extends PBRBaseMaterial { /** * The range of iridescence thickness, x is minimum, y is maximum. - * @defaultValue `[100, 400]`. + * @defaultValue `[100, 400]` */ get iridescenceThicknessRange(): Vector2 { return this._iridescenceRange; @@ -229,7 +229,7 @@ export class PBRMaterial extends PBRBaseMaterial { } /** - * Sheen color + * Sheen color. * @defaultValue `[0,0,0]` */ get sheenColor(): Color { @@ -256,7 +256,7 @@ export class PBRMaterial extends PBRBaseMaterial { } /** - * Sheencolor texture, multiply ‘sheencolor’. + * SheenColor texture, multiply ‘sheenColor’. */ get sheenColorTexture(): Texture2D { return this.shaderData.getTexture(PBRMaterial._sheenTextureProp); @@ -272,6 +272,7 @@ export class PBRMaterial extends PBRBaseMaterial { } /** + * SheenRoughness texture. * @remarks Use alpha channel, and multiply 'sheenRoughness'. */ get sheenRoughnessTexture(): Texture2D { @@ -300,7 +301,7 @@ export class PBRMaterial extends PBRBaseMaterial { shaderData.setFloat(PBRMaterial._iorProp, 1.5); shaderData.setVector3(PBRMaterial._anisotropyInfoProp, new Vector3(1, 0, 0)); shaderData.setVector4(PBRMaterial._iridescenceInfoProp, new Vector4(0, 1.3, 100, 400)); - shaderData.setColor(PBRMaterial._sheenColorProp, new Color(0, 0, 0, 0)); + shaderData.setColor(PBRMaterial._sheenColorProp, new Color(0, 0, 0)); // @ts-ignore this._iridescenceRange._onValueChanged = this._onIridescenceRangeChanged.bind(this); // @ts-ignore @@ -308,13 +309,12 @@ export class PBRMaterial extends PBRBaseMaterial { const r = this.sheenColor.r; const g = this.sheenColor.g; const b = this.sheenColor.b; - const a = this.sheenColor.a; /** * The sheen layer switch. */ - const enableSheen = (r + g + b) * a > 0; - if (enableSheen !== this._sheen) { - this._sheen = enableSheen; + const enableSheen = r + g + b > 0; + if (enableSheen !== this._sheenEnabled) { + this._sheenEnabled = enableSheen; if (enableSheen) { this.shaderData.enableMacro("MATERIAL_ENABLE_SHEEN"); } else { diff --git a/packages/loader/src/gltf/extensions/KHR_materials_sheen.ts b/packages/loader/src/gltf/extensions/KHR_materials_sheen.ts index 504d9cd157..585cdf3e95 100644 --- a/packages/loader/src/gltf/extensions/KHR_materials_sheen.ts +++ b/packages/loader/src/gltf/extensions/KHR_materials_sheen.ts @@ -15,7 +15,8 @@ class KHR_materials_sheen extends GLTFExtensionParser { material.sheenColor.set( Color.linearToGammaSpace(sheenColorFactor[0]), Color.linearToGammaSpace(sheenColorFactor[1]), - Color.linearToGammaSpace(sheenColorFactor[2]) + Color.linearToGammaSpace(sheenColorFactor[2]), + undefined ); } From 313db93b8101f6336abfdbfd453f2c9f5852ec4d Mon Sep 17 00:00:00 2001 From: hhhhkrx Date: Wed, 11 Dec 2024 15:10:08 +0800 Subject: [PATCH 4/5] fix: sheen --- packages/core/src/material/PBRMaterial.ts | 17 ++++++----------- .../src/gltf/extensions/KHR_materials_sheen.ts | 2 +- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/packages/core/src/material/PBRMaterial.ts b/packages/core/src/material/PBRMaterial.ts index 9deca97db5..51bc335f24 100644 --- a/packages/core/src/material/PBRMaterial.ts +++ b/packages/core/src/material/PBRMaterial.ts @@ -256,7 +256,7 @@ export class PBRMaterial extends PBRBaseMaterial { } /** - * SheenColor texture, multiply ‘sheenColor’. + * Sheen color texture, multiply ‘sheenColor’. */ get sheenColorTexture(): Texture2D { return this.shaderData.getTexture(PBRMaterial._sheenTextureProp); @@ -272,7 +272,7 @@ export class PBRMaterial extends PBRBaseMaterial { } /** - * SheenRoughness texture. + * Sheen roughness texture. * @remarks Use alpha channel, and multiply 'sheenRoughness'. */ get sheenRoughnessTexture(): Texture2D { @@ -301,18 +301,13 @@ export class PBRMaterial extends PBRBaseMaterial { shaderData.setFloat(PBRMaterial._iorProp, 1.5); shaderData.setVector3(PBRMaterial._anisotropyInfoProp, new Vector3(1, 0, 0)); shaderData.setVector4(PBRMaterial._iridescenceInfoProp, new Vector4(0, 1.3, 100, 400)); - shaderData.setColor(PBRMaterial._sheenColorProp, new Color(0, 0, 0)); + const sheenColor = new Color(0, 0, 0); + shaderData.setColor(PBRMaterial._sheenColorProp, sheenColor); // @ts-ignore this._iridescenceRange._onValueChanged = this._onIridescenceRangeChanged.bind(this); // @ts-ignore - this.sheenColor._onValueChanged = () => { - const r = this.sheenColor.r; - const g = this.sheenColor.g; - const b = this.sheenColor.b; - /** - * The sheen layer switch. - */ - const enableSheen = r + g + b > 0; + sheenColor._onValueChanged = () => { + const enableSheen = sheenColor.r + sheenColor.g + sheenColor.b > 0; if (enableSheen !== this._sheenEnabled) { this._sheenEnabled = enableSheen; if (enableSheen) { diff --git a/packages/loader/src/gltf/extensions/KHR_materials_sheen.ts b/packages/loader/src/gltf/extensions/KHR_materials_sheen.ts index 585cdf3e95..426f15820d 100644 --- a/packages/loader/src/gltf/extensions/KHR_materials_sheen.ts +++ b/packages/loader/src/gltf/extensions/KHR_materials_sheen.ts @@ -9,7 +9,7 @@ import { IKHRMaterialsSheen } from "./GLTFExtensionSchema"; @registerGLTFExtension("KHR_materials_sheen", GLTFExtensionMode.AdditiveParse) class KHR_materials_sheen extends GLTFExtensionParser { override additiveParse(context: GLTFParserContext, material: PBRMaterial, schema: IKHRMaterialsSheen): void { - const { sheenColorFactor, sheenColorTexture, sheenRoughnessFactor, sheenRoughnessTexture } = schema; + const { sheenColorFactor, sheenColorTexture, sheenRoughnessFactor = 0, sheenRoughnessTexture } = schema; if (sheenColorFactor) { material.sheenColor.set( From affd513ad68eb5610c690a5cba8d37518a721e92 Mon Sep 17 00:00:00 2001 From: hhhhkrx Date: Thu, 12 Dec 2024 14:11:50 +0800 Subject: [PATCH 5/5] fix: clamp sheen roughness --- packages/core/src/material/PBRMaterial.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/core/src/material/PBRMaterial.ts b/packages/core/src/material/PBRMaterial.ts index 51bc335f24..d711947aa9 100644 --- a/packages/core/src/material/PBRMaterial.ts +++ b/packages/core/src/material/PBRMaterial.ts @@ -252,6 +252,7 @@ export class PBRMaterial extends PBRBaseMaterial { } set sheenRoughness(value: number) { + value = Math.max(0, Math.min(1, value)); this.shaderData.setFloat(PBRMaterial._sheenRoughnessProp, value); }