mirror of
https://github.com/galacean/engine.git
synced 2026-05-07 06:30:25 +08:00
138 lines
4.4 KiB
Plaintext
138 lines
4.4 KiB
Plaintext
---
|
||
title: UIScript 的使用和绑定
|
||
---
|
||
|
||
开发者使用编辑器对自定义材质属性进行调节的同时,还可以通过 `UIScript` 指令指定数据变更的回调行为。通过 UIScript 暴露的 hook 函数,开发者可以实现属性联动,从而减少声明属性的数量,达到简化 Inspector 面板的目的。
|
||
|
||
### 在 ShaderLab 中绑定 `UIScript`:
|
||
|
||
```glsl showLineNumbers
|
||
Editor {
|
||
...
|
||
UIScript "/path/to/script";
|
||
...
|
||
}
|
||
```
|
||
|
||
绑定的`UIScript`脚本路径支持相对路径和绝对路径,以下图项目根目录为例,绝对路径为
|
||
`/PBRScript1.ts`,相对路径为`./PBRScript1.ts`
|
||
|
||
<Image
|
||
src="https://mdn.alipayobjects.com/huamei_aftkdx/afts/img/A*t4LFQ4KEL6kAAAAAAAAAAAAADteEAQ/fmt.webp"
|
||
width="70%"
|
||
/>
|
||
|
||
### UIScript 接口
|
||
|
||
编辑器通过内置 `ShaderUIScript` 类暴露相关 API,`ShaderUIScript` 的类型定义已经内嵌至 Galacean Web 端脚本编辑器中,完整定义如下:
|
||
|
||
```ts
|
||
import { Color, Material, Texture, Vector2, Vector3, Vector4 } from "@galacean/engine";
|
||
|
||
type ShaderPropertyValue = number | Vector2 | Vector3 | Vector4 | Color | Texture;
|
||
type ShaderMacroValue = number | Vector2 | Vector3 | Vector4 | Color;
|
||
|
||
/**
|
||
* Script for extending `Shader` UI logic.
|
||
*/
|
||
export abstract class ShaderUIScript {
|
||
/** @internal */
|
||
_propertyCallBacks: Map<string, (material: Material, value: ShaderPropertyValue) => void> = new Map();
|
||
|
||
/** @internal */
|
||
_macroCallBacks: Map<string, (material: Material, defined: boolean, value: ShaderMacroValue) => void> = new Map();
|
||
|
||
/**
|
||
* The method is called when then shader is switched.
|
||
* @param material - The material which the shader is bound to
|
||
*/
|
||
onMaterialShaderSwitched(material: Material): void {}
|
||
|
||
/**
|
||
* Register property change callback.
|
||
* @parma propertyName - Property name
|
||
* @parma onChanged - Fired on property changed
|
||
*/
|
||
protected onPropertyChanged(
|
||
propertyName: string,
|
||
onChanged: (material: Material, value: ShaderPropertyValue) => void
|
||
): void {
|
||
this._propertyCallBacks.set(propertyName, onChanged);
|
||
}
|
||
|
||
/**
|
||
* Register macro change callback.
|
||
* @parma macroName - Macro name
|
||
* @parma onChanged - Fired on macro changed
|
||
*/
|
||
protected onMacroChanged(
|
||
macroName: string,
|
||
onChanged: (material: Material, defined: boolean, value: ShaderMacroValue) => void
|
||
): void {
|
||
this._macroCallBacks.set(macroName, onChanged);
|
||
}
|
||
}
|
||
```
|
||
|
||
### UIScript 编写
|
||
|
||
1. 在编辑器中创建 UIScript 脚本
|
||
|
||
<Image
|
||
src="https://mdn.alipayobjects.com/huamei_aftkdx/afts/img/A*Qh4UTZgaY7MAAAAAAAAAAAAADteEAQ/fmt.webp"
|
||
width="60%"
|
||
figcaption="创建UIScript"
|
||
/>
|
||
|
||
2. 通过继承 ShaderUIScript 类指定属性变更回调。
|
||
|
||
```ts
|
||
import { Material, RenderQueueType, Vector3, BlendFactor, RenderFace, CullMode, BlendMode } from "@galacean/engine";
|
||
|
||
export default class extends ShaderUIScript {
|
||
constructor() {
|
||
super();
|
||
|
||
......
|
||
// 在构造函数中注册监听属性回调
|
||
this.onPropertyChanged("material_NormalTexture", (material: Material, value) => {
|
||
const shaderData = material.shaderData;
|
||
if (value) {
|
||
shaderData.enableMacro("MATERIAL_HAS_NORMALTEXTURE");
|
||
} else {
|
||
shaderData.disableMacro("MATERIAL_HAS_NORMALTEXTURE");
|
||
}
|
||
})
|
||
|
||
......
|
||
|
||
}
|
||
|
||
// 指定 shader 绑定的回调
|
||
override onMaterialShaderSwitched(material: Material) {
|
||
const shaderData = material.shaderData;
|
||
|
||
shaderData.disableMacro("MATERIAL_OMIT_NORMAL");
|
||
shaderData.enableMacro("MATERIAL_NEED_WORLD_POS");
|
||
shaderData.enableMacro("MATERIAL_NEED_TILING_OFFSET");
|
||
|
||
// default value
|
||
const anisotropyInfo = shaderData.getVector3("material_AnisotropyInfo");
|
||
|
||
if (!anisotropyInfo) {
|
||
shaderData.setVector3("material_AnisotropyInfo", new Vector3(1, 0, 0));
|
||
} else {
|
||
shaderData.setFloat("anisotropy", anisotropyInfo.z);
|
||
const PI2 = Math.PI * 2;
|
||
const rotationRad = (Math.atan2(anisotropyInfo.y, anisotropyInfo.x) + PI2 ) % PI2;
|
||
shaderData.setFloat("anisotropyRotation", rotationRad * (180 / Math.PI))
|
||
}
|
||
}
|
||
}
|
||
|
||
```
|
||
|
||
<Callout info="warning">
|
||
注意,当前版本 ShaderLab 材质属性模块只是定义了绑定该 Shader 的材质在编辑器中的 Inspector
|
||
UI面板,并不会替你在`ShaderPass`中声明对应的全局变量,如果`ShaderPass`代码中引用了该变量需在[全局变量](./shader/#全局变量)模块中明确声明补充。
|
||
</Callout> |