diff --git a/packages/core/src/material/BlinnPhongMaterial.ts b/packages/core/src/material/BlinnPhongMaterial.ts index 7c645d112d..8aa073132d 100644 --- a/packages/core/src/material/BlinnPhongMaterial.ts +++ b/packages/core/src/material/BlinnPhongMaterial.ts @@ -1,5 +1,6 @@ import { Color, Vector4 } from "@galacean/engine-math"; import { Engine } from "../Engine"; +import { ShaderUniformType, uniform } from "../shader"; import { Shader } from "../shader/Shader"; import { ShaderProperty } from "../shader/ShaderProperty"; import { Texture2D } from "../texture/Texture2D"; @@ -9,126 +10,78 @@ import { BaseMaterial } from "./BaseMaterial"; * Blinn-phong Material. */ export class BlinnPhongMaterial extends BaseMaterial { - private static _specularColorProp = ShaderProperty.getByName("material_SpecularColor"); private static _shininessProp = ShaderProperty.getByName("material_Shininess"); - private static _specularTextureProp = ShaderProperty.getByName("material_SpecularTexture"); /** * Base color. */ - get baseColor(): Color { - return this.shaderData.getColor(BlinnPhongMaterial._baseColorProp); - } - - set baseColor(value: Color) { - const baseColor = this.shaderData.getColor(BlinnPhongMaterial._baseColorProp); - if (value !== baseColor) { - baseColor.copyFrom(value); - } - } + @uniform(ShaderUniformType.Color, { + varName: "material_BaseColor", + keepRef: true + }) + baseColor: Color = new Color(1, 1, 1, 1); /** * Base texture. */ - get baseTexture(): Texture2D { - return this.shaderData.getTexture(BlinnPhongMaterial._baseTextureProp); - } - - set baseTexture(value: Texture2D) { - this.shaderData.setTexture(BlinnPhongMaterial._baseTextureProp, value); - if (value) { - this.shaderData.enableMacro(BlinnPhongMaterial._baseTextureMacro); - } else { - this.shaderData.disableMacro(BlinnPhongMaterial._baseTextureMacro); - } - } + @uniform(ShaderUniformType.Texture, { + varName: "material_BaseTexture", + macroName: "MATERIAL_HAS_BASETEXTURE" + }) + baseTexture: Texture2D; /** * Specular color. */ - get specularColor(): Color { - return this.shaderData.getColor(BlinnPhongMaterial._specularColorProp); - } - - set specularColor(value: Color) { - const specularColor = this.shaderData.getColor(BlinnPhongMaterial._specularColorProp); - if (value !== specularColor) { - specularColor.copyFrom(value); - } - } + @uniform(ShaderUniformType.Color, { + varName: "material_SpecularColor", + keepRef: true + }) + specularColor: Color = new Color(1, 1, 1, 1); /** * Specular texture. */ - get specularTexture(): Texture2D { - return this.shaderData.getTexture(BlinnPhongMaterial._specularTextureProp); - } - - set specularTexture(value: Texture2D) { - this.shaderData.setTexture(BlinnPhongMaterial._specularTextureProp, value); - if (value) { - this.shaderData.enableMacro("MATERIAL_HAS_SPECULAR_TEXTURE"); - } else { - this.shaderData.disableMacro("MATERIAL_HAS_SPECULAR_TEXTURE"); - } - } + @uniform(ShaderUniformType.Texture, { + varName: "material_SpecularTexture", + macroName: "MATERIAL_HAS_SPECULAR_TEXTURE" + }) + specularTexture: Texture2D; /** * Emissive color. */ - get emissiveColor(): Color { - return this.shaderData.getColor(BlinnPhongMaterial._emissiveColorProp); - } - - set emissiveColor(value: Color) { - const emissiveColor = this.shaderData.getColor(BlinnPhongMaterial._emissiveColorProp); - if (value !== emissiveColor) { - emissiveColor.copyFrom(value); - } - } + @uniform(ShaderUniformType.Color, { + varName: "material_EmissiveColor", + keepRef: true + }) + emissiveColor: Color = new Color(0, 0, 0, 1); /** * Emissive texture. */ - get emissiveTexture(): Texture2D { - return this.shaderData.getTexture(BlinnPhongMaterial._emissiveTextureProp); - } - - set emissiveTexture(value: Texture2D) { - this.shaderData.setTexture(BlinnPhongMaterial._emissiveTextureProp, value); - if (value) { - this.shaderData.enableMacro(BlinnPhongMaterial._emissiveTextureMacro); - } else { - this.shaderData.disableMacro(BlinnPhongMaterial._emissiveTextureMacro); - } - } + @uniform(ShaderUniformType.Texture, { + varName: "material_EmissiveTexture", + macroName: "MATERIAL_HAS_EMISSIVETEXTURE" + }) + emissiveTexture: Texture2D; /** * Normal texture. */ - get normalTexture(): Texture2D { - return this.shaderData.getTexture(BlinnPhongMaterial._normalTextureProp); - } - - set normalTexture(value: Texture2D) { - this.shaderData.setTexture(BlinnPhongMaterial._normalTextureProp, value); - if (value) { - this.shaderData.enableMacro(BlinnPhongMaterial._normalTextureMacro); - } else { - this.shaderData.disableMacro(BlinnPhongMaterial._normalTextureMacro); - } - } + @uniform(ShaderUniformType.Texture, { + varName: "material_NormalTexture", + macroName: "MATERIAL_HAS_NORMALTEXTURE" + }) + normalTexture: Texture2D; /** * Normal texture intensity. */ - get normalIntensity(): number { - return this.shaderData.getFloat(BlinnPhongMaterial._normalIntensityProp); - } - - set normalIntensity(value: number) { - this.shaderData.setFloat(BlinnPhongMaterial._normalIntensityProp, value); - } + @uniform(ShaderUniformType.Float, { + varName: "material_NormalIntensity" + }) + normalIntensity: number = 1; /** * Set the specular reflection coefficient, the larger the value, the more convergent the specular reflection effect. @@ -144,16 +97,11 @@ export class BlinnPhongMaterial extends BaseMaterial { /** * Tiling and offset of main textures. */ - get tilingOffset(): Vector4 { - return this.shaderData.getVector4(BlinnPhongMaterial._tilingOffsetProp); - } - - set tilingOffset(value: Vector4) { - const tilingOffset = this.shaderData.getVector4(BlinnPhongMaterial._tilingOffsetProp); - if (value !== tilingOffset) { - tilingOffset.copyFrom(value); - } - } + @uniform(ShaderUniformType.Vector4, { + varName: "material_TilingOffset", + keepRef: true + }) + tilingOffset: Vector4 = new Vector4(1, 1, 0, 0); /** * Create a BlinnPhong material instance. @@ -167,12 +115,7 @@ export class BlinnPhongMaterial extends BaseMaterial { shaderData.enableMacro("MATERIAL_NEED_WORLD_POS"); shaderData.enableMacro("MATERIAL_NEED_TILING_OFFSET"); - shaderData.setColor(BlinnPhongMaterial._baseColorProp, new Color(1, 1, 1, 1)); - shaderData.setColor(BlinnPhongMaterial._specularColorProp, new Color(1, 1, 1, 1)); - shaderData.setColor(BlinnPhongMaterial._emissiveColorProp, new Color(0, 0, 0, 1)); - shaderData.setVector4(BlinnPhongMaterial._tilingOffsetProp, new Vector4(1, 1, 0, 0)); shaderData.setFloat(BlinnPhongMaterial._shininessProp, 16); - shaderData.setFloat(BlinnPhongMaterial._normalIntensityProp, 1); } override clone(): BlinnPhongMaterial { diff --git a/packages/core/src/material/PBRBaseMaterial.ts b/packages/core/src/material/PBRBaseMaterial.ts index f421a92cb6..4217c49690 100644 --- a/packages/core/src/material/PBRBaseMaterial.ts +++ b/packages/core/src/material/PBRBaseMaterial.ts @@ -1,5 +1,5 @@ import { Color, Vector4 } from "@galacean/engine-math"; -import { Logger, ShaderProperty } from ".."; +import { Logger, ShaderProperty, ShaderUniformType, uniform } from ".."; import { Engine } from "../Engine"; import { Shader } from "../shader/Shader"; import { Texture2D } from "../texture/Texture2D"; @@ -10,129 +10,77 @@ import { TextureCoordinate } from "./enums/TextureCoordinate"; * PBR (Physically-Based Rendering) Material. */ export abstract class PBRBaseMaterial extends BaseMaterial { - private static _occlusionTextureIntensityProp = ShaderProperty.getByName("material_OcclusionIntensity"); private static _occlusionTextureCoordProp = ShaderProperty.getByName("material_OcclusionTextureCoord"); - private static _occlusionTextureProp = ShaderProperty.getByName("material_OcclusionTexture"); - - private static _clearCoatProp = ShaderProperty.getByName("material_ClearCoat"); - private static _clearCoatTextureProp = ShaderProperty.getByName("material_ClearCoatTexture"); - private static _clearCoatRoughnessProp = ShaderProperty.getByName("material_ClearCoatRoughness"); - private static _clearCoatRoughnessTextureProp = ShaderProperty.getByName("material_ClearCoatRoughnessTexture"); - private static _clearCoatNormalTextureProp = ShaderProperty.getByName("material_ClearCoatNormalTexture"); /** * Base color. */ - get baseColor(): Color { - return this.shaderData.getColor(PBRBaseMaterial._baseColorProp); - } - - set baseColor(value: Color) { - const baseColor = this.shaderData.getColor(PBRBaseMaterial._baseColorProp); - if (value !== baseColor) { - baseColor.copyFrom(value); - } - } + @uniform(ShaderUniformType.Color, { + varName: "material_BaseColor", + keepRef: true + }) + baseColor: Color = new Color(1, 1, 1, 1); /** * Base texture. */ - get baseTexture(): Texture2D { - return this.shaderData.getTexture(PBRBaseMaterial._baseTextureProp); - } - - set baseTexture(value: Texture2D) { - this.shaderData.setTexture(PBRBaseMaterial._baseTextureProp, value); - if (value) { - this.shaderData.enableMacro(PBRBaseMaterial._baseTextureMacro); - } else { - this.shaderData.disableMacro(PBRBaseMaterial._baseTextureMacro); - } - } + @uniform(ShaderUniformType.Texture, { + varName: "material_BaseTexture", + macroName: "MATERIAL_HAS_BASETEXTURE" + }) + baseTexture: Texture2D; /** * Normal texture. */ - get normalTexture(): Texture2D { - return this.shaderData.getTexture(PBRBaseMaterial._normalTextureProp); - } - - set normalTexture(value: Texture2D) { - this.shaderData.setTexture(PBRBaseMaterial._normalTextureProp, value); - if (value) { - this.shaderData.enableMacro(PBRBaseMaterial._normalTextureMacro); - } else { - this.shaderData.disableMacro(PBRBaseMaterial._normalTextureMacro); - } - } + @uniform(ShaderUniformType.Texture, { + varName: "material_NormalTexture", + macroName: "MATERIAL_HAS_NORMALTEXTURE" + }) + normalTexture: Texture2D; /** * Normal texture intensity. */ - get normalTextureIntensity(): number { - return this.shaderData.getFloat(PBRBaseMaterial._normalIntensityProp); - } - - set normalTextureIntensity(value: number) { - this.shaderData.setFloat(PBRBaseMaterial._normalIntensityProp, value); - } + @uniform(ShaderUniformType.Float, { + varName: "material_NormalIntensity" + }) + normalTextureIntensity: number = 1; /** * Emissive color. */ - get emissiveColor(): Color { - return this.shaderData.getColor(PBRBaseMaterial._emissiveColorProp); - } - - set emissiveColor(value: Color) { - const emissiveColor = this.shaderData.getColor(PBRBaseMaterial._emissiveColorProp); - if (value !== emissiveColor) { - emissiveColor.copyFrom(value); - } - } + @uniform(ShaderUniformType.Color, { + varName: "material_EmissiveColor", + keepRef: true + }) + emissiveColor: Color = new Color(0, 0, 0, 1); /** * Emissive texture. */ - get emissiveTexture(): Texture2D { - return this.shaderData.getTexture(PBRBaseMaterial._emissiveTextureProp); - } - - set emissiveTexture(value: Texture2D) { - this.shaderData.setTexture(PBRBaseMaterial._emissiveTextureProp, value); - if (value) { - this.shaderData.enableMacro(PBRBaseMaterial._emissiveTextureMacro); - } else { - this.shaderData.disableMacro(PBRBaseMaterial._emissiveTextureMacro); - } - } + @uniform(ShaderUniformType.Texture, { + varName: "material_EmissiveTexture", + macroName: "MATERIAL_HAS_EMISSIVETEXTURE" + }) + emissiveTexture: Texture2D; /** * Occlusion texture. */ - get occlusionTexture(): Texture2D { - return this.shaderData.getTexture(PBRBaseMaterial._occlusionTextureProp); - } - - set occlusionTexture(value: Texture2D) { - this.shaderData.setTexture(PBRBaseMaterial._occlusionTextureProp, value); - if (value) { - this.shaderData.enableMacro("MATERIAL_HAS_OCCLUSION_TEXTURE"); - } else { - this.shaderData.disableMacro("MATERIAL_HAS_OCCLUSION_TEXTURE"); - } - } + @uniform(ShaderUniformType.Texture, { + varName: "material_OcclusionTexture", + macroName: "MATERIAL_HAS_OCCLUSION_TEXTURE" + }) + occlusionTexture: Texture2D; /** * Occlusion texture intensity. */ - get occlusionTextureIntensity(): number { - return this.shaderData.getFloat(PBRBaseMaterial._occlusionTextureIntensityProp); - } - - set occlusionTextureIntensity(value: number) { - this.shaderData.setFloat(PBRBaseMaterial._occlusionTextureIntensityProp, value); - } + @uniform(ShaderUniformType.Float, { + varName: "material_OcclusionIntensity" + }) + occlusionTextureIntensity: number = 1; /** * Occlusion texture uv coordinate. @@ -152,96 +100,55 @@ export abstract class PBRBaseMaterial extends BaseMaterial { /** * Tiling and offset of main textures. */ - get tilingOffset(): Vector4 { - return this.shaderData.getVector4(PBRBaseMaterial._tilingOffsetProp); - } - - set tilingOffset(value: Vector4) { - const tilingOffset = this.shaderData.getVector4(PBRBaseMaterial._tilingOffsetProp); - if (value !== tilingOffset) { - tilingOffset.copyFrom(value); - } - } + @uniform(ShaderUniformType.Vector4, { + varName: "material_TilingOffset", + keepRef: true + }) + tilingOffset: Vector4 = new Vector4(1, 1, 0, 0); /** * The clearCoat layer intensity, default 0. */ - get clearCoat(): number { - return this.shaderData.getFloat(PBRBaseMaterial._clearCoatProp); - } - - set clearCoat(value: number) { - if (!!this.shaderData.getFloat(PBRBaseMaterial._clearCoatProp) !== !!value) { - if (value === 0) { - this.shaderData.disableMacro("MATERIAL_ENABLE_CLEAR_COAT"); - } else { - this.shaderData.enableMacro("MATERIAL_ENABLE_CLEAR_COAT"); - } - } - this.shaderData.setFloat(PBRBaseMaterial._clearCoatProp, value); - } + @uniform(ShaderUniformType.Float, { + varName: "material_ClearCoat", + macroName: "MATERIAL_ENABLE_CLEAR_COAT" + }) + clearCoat: number = 0; /** * 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("MATERIAL_HAS_CLEAR_COAT_TEXTURE"); - } else { - this.shaderData.disableMacro("MATERIAL_HAS_CLEAR_COAT_TEXTURE"); - } - } + @uniform(ShaderUniformType.Texture, { + varName: "material_ClearCoatTexture", + macroName: "MATERIAL_HAS_CLEAR_COAT_TEXTURE" + }) + clearCoatTexture: Texture2D; /** * 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); - } + @uniform(ShaderUniformType.Float, { + varName: "material_ClearCoatRoughness" + }) + clearCoatRoughness: number = 0; /** * 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("MATERIAL_HAS_CLEAR_COAT_ROUGHNESS_TEXTURE"); - } else { - this.shaderData.disableMacro("MATERIAL_HAS_CLEAR_COAT_ROUGHNESS_TEXTURE"); - } - } + @uniform(ShaderUniformType.Texture, { + varName: "material_ClearCoatRoughnessTexture", + macroName: "MATERIAL_HAS_CLEAR_COAT_ROUGHNESS_TEXTURE" + }) + clearCoatRoughnessTexture: Texture2D; /** * 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("MATERIAL_HAS_CLEAR_COAT_NORMAL_TEXTURE"); - } else { - this.shaderData.disableMacro("MATERIAL_HAS_CLEAR_COAT_NORMAL_TEXTURE"); - } - } + @uniform(ShaderUniformType.Texture, { + varName: "material_ClearCoatNormalTexture", + macroName: "MATERIAL_HAS_CLEAR_COAT_NORMAL_TEXTURE" + }) + clearCoatNormalTexture: Texture2D; /** * Create a pbr base material instance. @@ -255,16 +162,5 @@ export abstract class PBRBaseMaterial extends BaseMaterial { shaderData.enableMacro("MATERIAL_NEED_WORLD_POS"); shaderData.enableMacro("MATERIAL_NEED_TILING_OFFSET"); - - shaderData.setColor(PBRBaseMaterial._baseColorProp, new Color(1, 1, 1, 1)); - shaderData.setColor(PBRBaseMaterial._emissiveColorProp, new Color(0, 0, 0, 1)); - shaderData.setVector4(PBRBaseMaterial._tilingOffsetProp, new Vector4(1, 1, 0, 0)); - - shaderData.setFloat(PBRBaseMaterial._normalIntensityProp, 1); - shaderData.setFloat(PBRBaseMaterial._occlusionTextureIntensityProp, 1); - shaderData.setFloat(PBRBaseMaterial._occlusionTextureCoordProp, TextureCoordinate.UV0); - - shaderData.setFloat(PBRBaseMaterial._clearCoatProp, 0); - shaderData.setFloat(PBRBaseMaterial._clearCoatRoughnessProp, 0); } } diff --git a/packages/core/src/material/PBRMaterial.ts b/packages/core/src/material/PBRMaterial.ts index bc463e1d07..034bd7d8be 100644 --- a/packages/core/src/material/PBRMaterial.ts +++ b/packages/core/src/material/PBRMaterial.ts @@ -1,5 +1,5 @@ import { Engine } from "../Engine"; -import { ShaderProperty } from "../shader"; +import { ShaderProperty, ShaderUniformType, uniform } from "../shader"; import { Shader } from "../shader/Shader"; import { Texture2D } from "../texture/Texture2D"; import { PBRBaseMaterial } from "./PBRBaseMaterial"; @@ -8,11 +8,7 @@ import { PBRBaseMaterial } from "./PBRBaseMaterial"; * PBR (Metallic-Roughness Workflow) Material. */ export class PBRMaterial extends PBRBaseMaterial { - private static _metallicProp = ShaderProperty.getByName("material_Metal"); - private static _roughnessProp = ShaderProperty.getByName("material_Roughness"); - private static _roughnessMetallicTextureProp = ShaderProperty.getByName("material_RoughnessMetallicTexture"); - - private static _iorProp = Shader.getPropertyByName("material_IOR"); + private static _iorProp = ShaderProperty.getByName("material_IOR"); /** * Index Of Refraction. @@ -30,42 +26,29 @@ export class PBRMaterial extends PBRBaseMaterial { * Metallic. * @defaultValue `1.0` */ - get metallic(): number { - return this.shaderData.getFloat(PBRMaterial._metallicProp); - } - - set metallic(value: number) { - this.shaderData.setFloat(PBRMaterial._metallicProp, value); - } + @uniform(ShaderUniformType.Float, { + varName: "material_Metal" + }) + metallic = 1; /** * Roughness. default 1.0. * @defaultValue `1.0` */ - get roughness(): number { - return this.shaderData.getFloat(PBRMaterial._roughnessProp); - } - - set roughness(value: number) { - this.shaderData.setFloat(PBRMaterial._roughnessProp, value); - } + @uniform(ShaderUniformType.Float, { + varName: "material_Roughness" + }) + roughness = 1; /** * Roughness metallic texture. * @remarks G channel is roughness, B channel is metallic */ - get roughnessMetallicTexture(): Texture2D { - return this.shaderData.getTexture(PBRMaterial._roughnessMetallicTextureProp); - } - - set roughnessMetallicTexture(value: Texture2D) { - this.shaderData.setTexture(PBRMaterial._roughnessMetallicTextureProp, value); - if (value) { - this.shaderData.enableMacro("MATERIAL_HAS_ROUGHNESS_METALLIC_TEXTURE"); - } else { - this.shaderData.disableMacro("MATERIAL_HAS_ROUGHNESS_METALLIC_TEXTURE"); - } - } + @uniform(ShaderUniformType.Texture, { + varName: "material_RoughnessMetallicTexture", + macroName: "MATERIAL_HAS_ROUGHNESS_METALLIC_TEXTURE" + }) + roughnessMetallicTexture: Texture2D; /** * Create a pbr metallic-roughness workflow material instance. @@ -73,8 +56,6 @@ export class PBRMaterial extends PBRBaseMaterial { */ constructor(engine: Engine) { super(engine, Shader.find("pbr")); - this.shaderData.setFloat(PBRMaterial._metallicProp, 1); - this.shaderData.setFloat(PBRMaterial._roughnessProp, 1); this.shaderData.setFloat(PBRMaterial._iorProp, 1.5); } diff --git a/packages/core/src/material/PBRSpecularMaterial.ts b/packages/core/src/material/PBRSpecularMaterial.ts index 8eb54d0e68..e03097402b 100644 --- a/packages/core/src/material/PBRSpecularMaterial.ts +++ b/packages/core/src/material/PBRSpecularMaterial.ts @@ -1,8 +1,7 @@ import { Color } from "@galacean/engine-math"; +import { uniform, ShaderUniformType } from ".."; import { Engine } from "../Engine"; import { Shader } from "../shader/Shader"; -import { ShaderMacro } from "../shader/ShaderMacro"; -import { ShaderProperty } from "../shader/ShaderProperty"; import { Texture2D } from "../texture/Texture2D"; import { PBRBaseMaterial } from "./PBRBaseMaterial"; @@ -10,54 +9,32 @@ import { PBRBaseMaterial } from "./PBRBaseMaterial"; * PBR (Specular-Glossiness Workflow) Material. */ export class PBRSpecularMaterial extends PBRBaseMaterial { - private static _specularColorProp = ShaderProperty.getByName("material_PBRSpecularColor"); - private static _glossinessProp = ShaderProperty.getByName("material_Glossiness"); - private static _specularGlossinessTextureProp = ShaderProperty.getByName("material_SpecularGlossinessTexture"); - private static _specularGlossinessTextureMacro: ShaderMacro = ShaderMacro.getByName( - "MATERIAL_HAS_SPECULAR_GLOSSINESS_TEXTURE" - ); - /** * Specular color. */ - get specularColor(): Color { - return this.shaderData.getColor(PBRSpecularMaterial._specularColorProp); - } - - set specularColor(value: Color) { - const specularColor = this.shaderData.getColor(PBRSpecularMaterial._specularColorProp); - if (value !== specularColor) { - specularColor.copyFrom(value); - } - } + @uniform(ShaderUniformType.Color, { + varName: "material_PBRSpecularColor", + keepRef: true + }) + specularColor: Color = new Color(1, 1, 1, 1); /** * Glossiness. */ - get glossiness(): number { - return this.shaderData.getFloat(PBRSpecularMaterial._glossinessProp); - } - - set glossiness(value: number) { - this.shaderData.setFloat(PBRSpecularMaterial._glossinessProp, value); - } + @uniform(ShaderUniformType.Float, { + varName: "material_Glossiness" + }) + glossiness: number = 1; /** * Specular glossiness texture. * @remarks RGB is specular, A is glossiness */ - get specularGlossinessTexture(): Texture2D { - return this.shaderData.getTexture(PBRSpecularMaterial._specularGlossinessTextureProp); - } - - set specularGlossinessTexture(value: Texture2D) { - this.shaderData.setTexture(PBRSpecularMaterial._specularGlossinessTextureProp, value); - if (value) { - this.shaderData.enableMacro(PBRSpecularMaterial._specularGlossinessTextureMacro); - } else { - this.shaderData.disableMacro(PBRSpecularMaterial._specularGlossinessTextureMacro); - } - } + @uniform(ShaderUniformType.Texture, { + varName: "material_SpecularGlossinessTexture", + macroName: "MATERIAL_HAS_SPECULAR_GLOSSINESS_TEXTURE" + }) + specularGlossinessTexture: Texture2D; /** * Create a pbr specular-glossiness workflow material instance. @@ -65,9 +42,6 @@ export class PBRSpecularMaterial extends PBRBaseMaterial { */ constructor(engine: Engine) { super(engine, Shader.find("pbr-specular")); - - this.shaderData.setColor(PBRSpecularMaterial._specularColorProp, new Color(1, 1, 1, 1)); - this.shaderData.setFloat(PBRSpecularMaterial._glossinessProp, 1.0); } /** diff --git a/packages/core/src/material/UnlitMaterial.ts b/packages/core/src/material/UnlitMaterial.ts index 2e6684e0ab..7d5f076512 100644 --- a/packages/core/src/material/UnlitMaterial.ts +++ b/packages/core/src/material/UnlitMaterial.ts @@ -1,6 +1,8 @@ import { Color, Vector4 } from "@galacean/engine-math"; import { Engine } from "../Engine"; import { Shader } from "../shader/Shader"; +import { uniform } from "../shader/ShaderUniformDecorator"; +import { ShaderUniformType } from "../shader/ShaderUniformType"; import { Texture2D } from "../texture/Texture2D"; import { BaseMaterial } from "./BaseMaterial"; @@ -11,46 +13,29 @@ export class UnlitMaterial extends BaseMaterial { /** * Base color. */ - get baseColor(): Color { - return this.shaderData.getColor(UnlitMaterial._baseColorProp); - } - - set baseColor(value: Color) { - const baseColor = this.shaderData.getColor(UnlitMaterial._baseColorProp); - if (value !== baseColor) { - baseColor.copyFrom(value); - } - } + @uniform(ShaderUniformType.Color, { + varName: "material_BaseColor", + keepRef: true + }) + baseColor: Color = new Color(1, 1, 1, 1); /** * Base texture. */ - get baseTexture(): Texture2D { - return this.shaderData.getTexture(UnlitMaterial._baseTextureProp); - } - - set baseTexture(value: Texture2D) { - this.shaderData.setTexture(UnlitMaterial._baseTextureProp, value); - if (value) { - this.shaderData.enableMacro(UnlitMaterial._baseTextureMacro); - } else { - this.shaderData.disableMacro(UnlitMaterial._baseTextureMacro); - } - } + @uniform(ShaderUniformType.Texture, { + varName: "material_BaseTexture", + macroName: "MATERIAL_HAS_BASETEXTURE" + }) + baseTexture: Texture2D; /** * Tiling and offset of main textures. */ - get tilingOffset(): Vector4 { - return this.shaderData.getVector4(UnlitMaterial._tilingOffsetProp); - } - - set tilingOffset(value: Vector4) { - const tilingOffset = this.shaderData.getVector4(UnlitMaterial._tilingOffsetProp); - if (value !== tilingOffset) { - tilingOffset.copyFrom(value); - } - } + @uniform(ShaderUniformType.Vector4, { + varName: "material_TilingOffset", + keepRef: true + }) + tilingOffset: Vector4 = new Vector4(1, 1, 0, 0); /** * Create a unlit material instance. @@ -63,9 +48,6 @@ export class UnlitMaterial extends BaseMaterial { shaderData.enableMacro("MATERIAL_OMIT_NORMAL"); shaderData.enableMacro("MATERIAL_NEED_TILING_OFFSET"); - - shaderData.setColor(UnlitMaterial._baseColorProp, new Color(1, 1, 1, 1)); - shaderData.setVector4(UnlitMaterial._tilingOffsetProp, new Vector4(1, 1, 0, 0)); } /** diff --git a/packages/core/src/shader/ShaderUniformDecorator.ts b/packages/core/src/shader/ShaderUniformDecorator.ts new file mode 100644 index 0000000000..bad2874b8e --- /dev/null +++ b/packages/core/src/shader/ShaderUniformDecorator.ts @@ -0,0 +1,85 @@ +import { Material } from "../material/Material"; +import { ShaderProperty } from "./ShaderProperty"; +import { ShaderUniformType } from "./ShaderUniformType"; + +export type UniformOptions = { + varName?: string; // the variable name in glsl + macroName?: string; // whether enable or disable a macro in glsl depends on setting value + keepRef?: boolean; // whether setting a value to a property will change reference or just copy value. Only available for vector or matrix type +}; + +function handleMacro(value: any, macroName?: string) { + if (macroName) { + if (value !== undefined) { + this.shaderData.enableMacro(macroName); + } else { + this.shaderData.disableMacro(macroName); + } + } +} + +/** + * Shader uniform decorator. + */ +export function uniform(type: ShaderUniformType, options?: UniformOptions) { + return function (target: Material, propertyKey: string) { + const shaderProp = ShaderProperty.getByName(options?.varName || propertyKey); + const get = "get" + type; + const set = "set" + type; + + let setFunc: (value: any) => void; + if ( + type === ShaderUniformType.Float || + type === ShaderUniformType.Int || + type === ShaderUniformType.Texture || + type === ShaderUniformType.TextureArray + ) { + setFunc = function (value: any) { + this.shaderData[set](shaderProp, value); + handleMacro.call(this, value, options?.macroName); + }; + } else if (options?.keepRef) { + if (type === ShaderUniformType.FloatArray || type === ShaderUniformType.IntArray) { + setFunc = function (value: any) { + let data = this.shaderData[get](shaderProp); + if (!data) { + this.shaderData[set](shaderProp, value); + data = value; + } + data.set(value); + handleMacro.call(this, value, options?.macroName); + }; + } else if ( + type === ShaderUniformType.Vector2 || + type === ShaderUniformType.Vector3 || + type === ShaderUniformType.Vector4 || + type === ShaderUniformType.Matrix || + type === ShaderUniformType.Color + ) { + setFunc = function (value: any) { + let data = this.shaderData[get](shaderProp); + if (!data) { + this.shaderData[set](shaderProp, value); + data = value; + } + data.copyFrom(value); + handleMacro.call(this, value, options?.macroName); + }; + } + } else { + setFunc = function (value: any) { + this.shaderData[set](shaderProp, value); + handleMacro.call(this, value, options?.macroName); + }; + } + + Reflect.defineProperty(target, propertyKey, { + get: function () { + return this.shaderData[get](shaderProp); + }, + set: setFunc!, + enumerable: false, + configurable: true + }); + }; +} diff --git a/packages/core/src/shader/ShaderUniformType.ts b/packages/core/src/shader/ShaderUniformType.ts new file mode 100644 index 0000000000..94a36fd332 --- /dev/null +++ b/packages/core/src/shader/ShaderUniformType.ts @@ -0,0 +1,13 @@ +export enum ShaderUniformType { + Float = "Float", + Texture = "Texture", + Int = "Int", + FloatArray = "FloatArray", + IntArray = "IntArray", + TextureArray = "TextureArray", + Vector2 = "Vector2", + Vector3 = "Vector3", + Vector4 = "Vector4", + Color = "Color", + Matrix = "Matrix" +} diff --git a/packages/core/src/shader/index.ts b/packages/core/src/shader/index.ts index adc58156f3..9a7502ab1c 100644 --- a/packages/core/src/shader/index.ts +++ b/packages/core/src/shader/index.ts @@ -13,5 +13,7 @@ export { ShaderMacro } from "./ShaderMacro"; export { ShaderPass } from "./ShaderPass"; export { ShaderProperty } from "./ShaderProperty"; export { ShaderTagKey } from "./ShaderTagKey"; +export { ShaderUniformType } from "./ShaderUniformType"; export { SubShader } from "./SubShader"; +export { uniform } from "./ShaderUniformDecorator"; export * from "./state";