Files
engine/docs/zh/graphics/material/shaderLab/script.mdx
SwayYan 66116ba675 Refactor ShaderLab documention (#2611)
* refactor: shaderlab doc
2025-04-18 11:46:46 +08:00

138 lines
4.4 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
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>