Skip to content

Commit afc9087

Browse files
authored
Merge pull request galacean#2448 from hhhhkrx/Sheen
feat: PBR support sheen
2 parents 0ae6eab + affd513 commit afc9087

File tree

2 files changed

+124
-2
lines changed

2 files changed

+124
-2
lines changed

packages/core/src/material/PBRMaterial.ts

+83-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { MathUtil, Vector2, Vector3, Vector4 } from "@galacean/engine-math";
1+
import { MathUtil, Vector2, Vector3, Vector4, Color } from "@galacean/engine-math";
22
import { Engine } from "../Engine";
33
import { ShaderProperty } from "../shader";
44
import { Shader } from "../shader/Shader";
@@ -25,6 +25,12 @@ export class PBRMaterial extends PBRBaseMaterial {
2525
private static _iridescenceTextureProp = ShaderProperty.getByName("material_IridescenceTexture");
2626
private _iridescenceRange = new Vector2(100, 400);
2727

28+
private _sheenEnabled = false;
29+
private static _sheenColorProp = ShaderProperty.getByName("material_SheenColor");
30+
private static _sheenRoughnessProp = ShaderProperty.getByName("material_SheenRoughness");
31+
private static _sheenTextureProp = ShaderProperty.getByName("material_SheenTexture");
32+
private static _sheenRoughnessTextureProp = ShaderProperty.getByName("material_SheenRoughnessTexture");
33+
2834
/**
2935
* Index Of Refraction.
3036
* @defaultValue `1.5`
@@ -190,7 +196,7 @@ export class PBRMaterial extends PBRBaseMaterial {
190196

191197
/**
192198
* The range of iridescence thickness, x is minimum, y is maximum.
193-
* @defaultValue `[100, 400]`.
199+
* @defaultValue `[100, 400]`
194200
*/
195201
get iridescenceThicknessRange(): Vector2 {
196202
return this._iridescenceRange;
@@ -222,6 +228,67 @@ export class PBRMaterial extends PBRBaseMaterial {
222228
}
223229
}
224230

231+
/**
232+
* Sheen color.
233+
* @defaultValue `[0,0,0]`
234+
*/
235+
get sheenColor(): Color {
236+
return this.shaderData.getColor(PBRMaterial._sheenColorProp);
237+
}
238+
239+
set sheenColor(value: Color) {
240+
const sheenColor = this.shaderData.getColor(PBRMaterial._sheenColorProp);
241+
if (value !== sheenColor) {
242+
sheenColor.copyFrom(value);
243+
}
244+
}
245+
246+
/**
247+
* Sheen roughness, from 0.0 to 1.0.
248+
* @defaultValue `0.0`
249+
*/
250+
get sheenRoughness(): number {
251+
return this.shaderData.getFloat(PBRMaterial._sheenRoughnessProp);
252+
}
253+
254+
set sheenRoughness(value: number) {
255+
value = Math.max(0, Math.min(1, value));
256+
this.shaderData.setFloat(PBRMaterial._sheenRoughnessProp, value);
257+
}
258+
259+
/**
260+
* Sheen color texture, multiply ‘sheenColor’.
261+
*/
262+
get sheenColorTexture(): Texture2D {
263+
return <Texture2D>this.shaderData.getTexture(PBRMaterial._sheenTextureProp);
264+
}
265+
266+
set sheenColorTexture(value: Texture2D) {
267+
this.shaderData.setTexture(PBRMaterial._sheenTextureProp, value);
268+
if (value) {
269+
this.shaderData.enableMacro("MATERIAL_HAS_SHEEN_TEXTURE");
270+
} else {
271+
this.shaderData.disableMacro("MATERIAL_HAS_SHEEN_TEXTURE");
272+
}
273+
}
274+
275+
/**
276+
* Sheen roughness texture.
277+
* @remarks Use alpha channel, and multiply 'sheenRoughness'.
278+
*/
279+
get sheenRoughnessTexture(): Texture2D {
280+
return <Texture2D>this.shaderData.getTexture(PBRMaterial._sheenRoughnessTextureProp);
281+
}
282+
283+
set sheenRoughnessTexture(value: Texture2D) {
284+
this.shaderData.setTexture(PBRMaterial._sheenRoughnessTextureProp, value);
285+
if (value) {
286+
this.shaderData.enableMacro("MATERIAL_HAS_SHEEN_ROUGHNESS_TEXTURE");
287+
} else {
288+
this.shaderData.disableMacro("MATERIAL_HAS_SHEEN_ROUGHNESS_TEXTURE");
289+
}
290+
}
291+
225292
/**
226293
* Create a pbr metallic-roughness workflow material instance.
227294
* @param engine - Engine to which the material belongs
@@ -235,8 +302,22 @@ export class PBRMaterial extends PBRBaseMaterial {
235302
shaderData.setFloat(PBRMaterial._iorProp, 1.5);
236303
shaderData.setVector3(PBRMaterial._anisotropyInfoProp, new Vector3(1, 0, 0));
237304
shaderData.setVector4(PBRMaterial._iridescenceInfoProp, new Vector4(0, 1.3, 100, 400));
305+
const sheenColor = new Color(0, 0, 0);
306+
shaderData.setColor(PBRMaterial._sheenColorProp, sheenColor);
238307
// @ts-ignore
239308
this._iridescenceRange._onValueChanged = this._onIridescenceRangeChanged.bind(this);
309+
// @ts-ignore
310+
sheenColor._onValueChanged = () => {
311+
const enableSheen = sheenColor.r + sheenColor.g + sheenColor.b > 0;
312+
if (enableSheen !== this._sheenEnabled) {
313+
this._sheenEnabled = enableSheen;
314+
if (enableSheen) {
315+
this.shaderData.enableMacro("MATERIAL_ENABLE_SHEEN");
316+
} else {
317+
this.shaderData.disableMacro("MATERIAL_ENABLE_SHEEN");
318+
}
319+
}
320+
};
240321
}
241322

242323
private _onIridescenceRangeChanged(): void {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { PBRMaterial, Texture2D } from "@galacean/engine-core";
2+
import { Color } from "@galacean/engine-math";
3+
import { GLTFMaterialParser } from "../parser/GLTFMaterialParser";
4+
import { registerGLTFExtension } from "../parser/GLTFParser";
5+
import { GLTFParserContext, GLTFParserType } from "../parser/GLTFParserContext";
6+
import { GLTFExtensionMode, GLTFExtensionParser } from "./GLTFExtensionParser";
7+
import { IKHRMaterialsSheen } from "./GLTFExtensionSchema";
8+
9+
@registerGLTFExtension("KHR_materials_sheen", GLTFExtensionMode.AdditiveParse)
10+
class KHR_materials_sheen extends GLTFExtensionParser {
11+
override additiveParse(context: GLTFParserContext, material: PBRMaterial, schema: IKHRMaterialsSheen): void {
12+
const { sheenColorFactor, sheenColorTexture, sheenRoughnessFactor = 0, sheenRoughnessTexture } = schema;
13+
14+
if (sheenColorFactor) {
15+
material.sheenColor.set(
16+
Color.linearToGammaSpace(sheenColorFactor[0]),
17+
Color.linearToGammaSpace(sheenColorFactor[1]),
18+
Color.linearToGammaSpace(sheenColorFactor[2]),
19+
undefined
20+
);
21+
}
22+
23+
material.sheenRoughness = sheenRoughnessFactor;
24+
25+
if (sheenColorTexture) {
26+
GLTFMaterialParser._checkOtherTextureTransform(sheenColorTexture, "Sheen texture");
27+
28+
context.get<Texture2D>(GLTFParserType.Texture, sheenColorTexture.index).then((texture) => {
29+
material.sheenColorTexture = texture;
30+
});
31+
}
32+
33+
if (sheenRoughnessTexture) {
34+
GLTFMaterialParser._checkOtherTextureTransform(sheenRoughnessTexture, "SheenRoughness texture");
35+
36+
context.get<Texture2D>(GLTFParserType.Texture, sheenRoughnessTexture.index).then((texture) => {
37+
material.sheenRoughnessTexture = texture;
38+
});
39+
}
40+
}
41+
}

0 commit comments

Comments
 (0)