diff --git a/docs/en/graphics/shader/shaderLab/syntax/_meta.json b/docs/en/graphics/shader/shaderLab/syntax/_meta.json
index 5d5635b9f9..3ab58d91d4 100644
--- a/docs/en/graphics/shader/shaderLab/syntax/_meta.json
+++ b/docs/en/graphics/shader/shaderLab/syntax/_meta.json
@@ -1,7 +1,8 @@
{
"intro": "Introduction",
"shader": "Shader",
+ "editor": "Editor",
"subShader": "SubShader",
"pass": "Pass",
"macro": "Macro"
-}
\ No newline at end of file
+}
diff --git a/docs/en/graphics/shader/shaderLab/syntax/editor.mdx b/docs/en/graphics/shader/shaderLab/syntax/editor.mdx
new file mode 100644
index 0000000000..470a69b754
--- /dev/null
+++ b/docs/en/graphics/shader/shaderLab/syntax/editor.mdx
@@ -0,0 +1,256 @@
+import { Image } from "@/mdx";
+
+---
+
+# Editor
+
+```glsl
+Editor {
+ Properties {
+ material_BaseColor("Offset unit scale", Color) = (1,1,1,1);
+ ...
+ Header("Emissive")
+ {
+ material_EmissiveColor("Emissive color", Color) = (1,1,1,1);
+ ...
+ }
+ ...
+ }
+ ...
+ Macros {
+ [On] UV_OFFSET("UV Offset", Range(1,100)) = 10;
+ ...
+ Header("") {
+ SOME_MACRO("label", Int) = 1;
+ }
+ }
+ ...
+ // Specify the path of bound UIScript.
+ UIScript "./shaderScript.ts";
+}
+```
+
+## Properties
+
+It can be used to define properties bound to the Shader's custom material, allowing developers to adjust the defined properties through the custom material Inspector panel in the editor.
+
+
+
+### Property Definition
+
+```glsl
+/**
+ * @language zh
+ * Comments description
+ */
+
+/**
+ * @language en
+ * 注释描述
+ */
+propertyName("Description", EditType) = [DefaultValue];
+```
+
+
+
+1. You can use the `Header` directive to organize related properties, and the corresponding Inspector will have the appropriate hierarchical categorization.
+
+```
+Header("Emissive") {
+ material_EmissiveColor("Emissive color", Color) = (1,1,1,1);
+ ...
+}
+```
+
+2. Annotate Inspector Hover tooltip content through comments, supporting multilingual specification using the `@language` directive.
+
+
+
+The currently supported list of EditTypes is as follows::
+
+| EditType | Example |
+| :-: | :-- |
+| Bool | propertyName("Property Description", Boolean) = true; |
+| Int | propertyName("Property Description", Int) = 1;
propertyName("Property Description", Range(0,8)) = 1
propertyName("Property Description", Enum(Item1: 1, Item2: 2, Item3: 3)) = 1 // Enumeration |
+| Float | propertyName("Property Description", FLoat) = 0.5;
propertyName("Property Description", Range(0.0, 1.0)) = 0.5;
propertyName("Property Description", Enum(Item1: 1.0, Item2: 2.0, Item3: 3.0)) = 1.0; // Enumeration |
+| Texture2D | propertyName("Property Description", Texture2D); |
+| TextureCube | propertyName("Property Description", TextureCube); |
+| Color | propertyName("Property Description", Color) = (0.25, 0.5, 0.5, 1); |
+| Vector2 | propertyName("Property Description", Vector2) = (0.25, 0.5); |
+| Vector3 | propertyName("Property Description", Vector3) = (0.25, 0.5, 0.5); |
+| Vector4 | propertyName("Property Description", Vector4) = (0.25, 0.5, 0.5, 1.0); |
+
+#### Enumeration
+
+```glsl
+propertyName("Property Description", Enum(Item1: 1, Item2: 2, Item3: 3)) = 1;
+```
+
+
+ Currently, only Int and Float types support enumeration, and type mixing is not supported. For example, the following
+ enumeration mixes Float and Int, and will not be correctly parsed. ```glsl propertyName("Property Description",
+ Enum("Item1":1, "Item2":2.0, "Item3": 3)) = 2.0; ```
+
+
+## Macros
+
+It is used to reflect macros utilized in the Shader to the Inspector, allowing for flexible adjustments of the macros on which the Shader depends within the editor.
+
+```
+[On/Off]macroName("MacroLabel", EditType) = [DefaultValue];
+```
+
+Specify the default state of a macro using the [On/Off] directive. The types of macros currently supported by the editor are as follows:
+
+| Type | Example |
+| :-----: | :-------------------------------------------------------------------------------------------------------- |
+| | macroName("Macro Description"); |
+| Bool | macroName("Macro Description", Boolean) = true; |
+| Int | macroName("Macro Description", Int) = 1;
macroName("Macro Description", Range(0,8)) = 1; |
+| Float | macroName("Macro Description", FLoat) = 0.5;
macroName("Macro Description", Range(0.0, 1.0)) = 0.5; |
+| Color | macroName("Macro Description", Color) = (0.25, 0.5, 0.5, 1); |
+| Vector2 | macroName("Macro Description", Vector2) = (0.25, 0.5); |
+| Vector3 | macroName("Macro Description", Vector3) = (0.25, 0.5, 0.5); |
+| Vector4 | macroName("Macro Description", Vector4) = (0.25, 0.5, 0.5, 1.0); |
+
+## UIScript
+
+While developers adjust custom material properties using the editor, they can also specify data change callback behavior through `UIScript`.
+
+- Bind `UIScript` in ShaderLab:
+
+```
+Editor {
+ ...
+ UIScript "/path/to/script";
+ ...
+}
+```
+
+
+The bound UIScript script path supports both relative and absolute paths. Taking the project root directory in the above
+image as an example, the absolute path is `/PBRScript1.ts`, and the relative path is `./PBRScript1.ts`.
+
+### UIScript API
+
+The editor exposes relevant APIs through the built-in `ShaderUIScript` class.
+
+```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 void> = new Map();
+
+ /** @internal */
+ _macroCallBacks: Map 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);
+ }
+}
+```
+
+### Edit UIScript
+
+1. Create UIScript in Editor
+
+
+
+2. Specify property change callbacks by inheriting from the `ShaderUIScript` class.
+
+```ts
+import { Material, RenderQueueType, Vector3, BlendFactor, RenderFace, CullMode, BlendMode } from "@galacean/engine";
+
+export default class extends ShaderUIScript {
+ constructor() {
+ super();
+
+ ......
+ // Register change callbacks in constructor.
+ this.onPropertyChanged("material_NormalTexture", (material: Material, value) => {
+ const shaderData = material.shaderData;
+ if (value) {
+ shaderData.enableMacro("MATERIAL_HAS_NORMALTEXTURE");
+ } else {
+ shaderData.disableMacro("MATERIAL_HAS_NORMALTEXTURE");
+ }
+ })
+
+ ......
+
+ }
+
+ // Specify callback on shader switch.
+ 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))
+ }
+ }
+}
+
+```
+
+
+ Note that the current version of the ShaderLab material properties module only defines the Inspector UI panel for the
+ material bound to the Shader in the editor. It does not declare the corresponding global variables in the ShaderPass
+ for you. If the ShaderPass code references this variable, you must explicitly declare it in the Global Variables
+ module.
+
diff --git a/docs/en/graphics/shader/shaderLab/syntax/intro.mdx b/docs/en/graphics/shader/shaderLab/syntax/intro.mdx
index 31d30ce314..13fd9e211a 100644
--- a/docs/en/graphics/shader/shaderLab/syntax/intro.mdx
+++ b/docs/en/graphics/shader/shaderLab/syntax/intro.mdx
@@ -8,7 +8,10 @@ Double-click the shader asset we created in the previous step to jump to the cod
> A future version will release the Galacean VSCode plugin, which will provide syntax checking, auto-completion, and code synchronization features for `ShaderLab`. Stay tuned.
-
+
## Syntax Standard
@@ -17,6 +20,9 @@ The `ShaderLab` syntax framework is as follows:
```glsl
Shader "ShaderName" {
...
+ Editor {
+ ...
+ }
SubShader "SubShaderName" {
...
Pass "PassName" {
diff --git a/docs/en/graphics/shader/shaderLab/syntax/pass.mdx b/docs/en/graphics/shader/shaderLab/syntax/pass.mdx
index 7d35de7c52..d83e1f89df 100644
--- a/docs/en/graphics/shader/shaderLab/syntax/pass.mdx
+++ b/docs/en/graphics/shader/shaderLab/syntax/pass.mdx
@@ -98,3 +98,32 @@ material.renderQueueType = RenderQueueType.Opaque;
When render states and render queues are declared in ShaderLab, the corresponding settings in the material will be ignored."
```
+
+## MRT(Multiple Render Targets)
+
+ShaderLab is compatible with both GLSL 100 and GLSL 300 syntax, allowing you to specify MRT using either syntax.
+
+1. Specify MRT using `gl_FragData[i]`.
+
+```glsl
+void main(v2f input) {
+ gl_FragData[0] = vec4(1.,0.,0.,1.); // render target 0
+ gl_FragData[1] = vec4(1.,0.,0.,1.); // render target 1
+}
+```
+
+2. Specify by returning a struct from the entry function
+
+```glsl
+struct mrt {
+ layout(location = 0) vec4 fragColor0; // render target 0
+ layout(location = 1) vec4 fragColor1; // render target 1
+}
+
+mrt main(v2f input) {
+ mrt output;
+ output.fragColor0 = vec4(1.,0.,0.,1.);
+ output.fragColor1 = vec4(1.,0.,0.,1.);
+ return output;
+}
+```
diff --git a/docs/en/graphics/shader/shaderLab/syntax/shader.mdx b/docs/en/graphics/shader/shaderLab/syntax/shader.mdx
index 6483e22b11..f64b8d6c49 100644
--- a/docs/en/graphics/shader/shaderLab/syntax/shader.mdx
+++ b/docs/en/graphics/shader/shaderLab/syntax/shader.mdx
@@ -18,195 +18,115 @@ In ShaderLab, `Shader` is a collection of shader programs and other engine rende
## Material Property Definition
-```glsl
-// Uniform
-EditorProperties
-{
- material_BaseColor("Offset unit scale", Color) = (1,1,1,1);
- ...
+In ShaderLab, developers can customize the Inspector property panel for custom materials using this Shader through the [`Editor`](./editor/) directive.
- Header("Emissive")
- {
- material_EmissiveColor("Emissive color", Color) = (1,1,1,1);
- ...
+## Global Variables
+
+You can declare 4 types of global variables in ShaderLab: RenderState, Structs, Functions, and Single Variables.
+
+### RenderState
+
+Includes BlendState, DepthState, StencilState, RasterState
+
+- BlendState
+
+ ```glsl
+ BlendState {
+ Enabled[n]: bool;
+ ColorBlendOperation[n]: BlendOperation;
+ AlphaBlendOperation[n]: BlendOperation;
+ SourceColorBlendFactor[n]: BlendFactor;
+ SourceAlphaBlendFactor[n]: BlendFactor;
+ DestinationColorBlendFactor[n]: BlendFactor;
+ DestinationAlphaBlendFactor[n]: BlendFactor;
+ ColorWriteMask[n]: float // 0xffffffff
+ BlendColor: vec4;
+ AlphaToCoverage: bool;
}
- ...
-}
+ ```
-// Macro
-EditorMacros
-{
- [On] UV_OFFSET("UV Offset", Range(1,100)) = 10;
- ...
-}
-```
+ [n] can be omitted. When using MRT, [n] specifies a particular MRT render state. Omitting it sets all MRT states. BlendOperation and BlendFactor enums are the same as the engine API.
-This module is used to define the UI display of the material bound to the Shader in the editor's Inspector panel. ShaderLab material properties use `EditorProperties` and `EditorMacros` to separately declare macro properties and other Uniform properties. The declaration format is:
-
-1. Uniform Properties
-
- ```glsl
- EditorProperties {
- propertyName("label in Inspector", type) [= defaultValue];
- ...
- [ Header("blockName") {
- propertyName("label in Inspector", type) [= defaultValue];
- ...
- } ]
- }
- ```
-
- > Nested `Header` blocks can be used to hierarchically categorize material properties.
-
- Supported types are
-
- | Type | Example |
- | :-: | :-- |
- | Bool | propertyName("Property Description", Boolean) = true; |
- | Int | propertyName("Property Description", Int) = 1;
propertyName("Property Description", Range(0,8)) = 1 |
- | Float | propertyName("Property Description", Float) = 0.5;
propertyName("Property Description", Range(0.0, 1.0)) = 0.5; |
- | Texture2D | propertyName("Property Description", Texture2D); |
- | TextureCube | propertyName("Property Description", TextureCube); |
- | Color | propertyName("Property Description", Color) = (0.25, 0.5, 0.5, 1); |
- | Vector2 | propertyName("Property Description", Vector2) = (0.25, 0.5); |
- | Vector3 | propertyName("Property Description", Vector3) = (0.25, 0.5, 0.5); |
- | Vector4 | propertyName("Property Description", Vector4) = (0.25, 0.5, 0.5, 1.0); |
-
-2. Macro Properties
-
- ```glsl
- EditorMacros {
- [\[Off/On\]] propertyName("label in Inspector"[, type]) [= defaultValue];
- ...
- [ Header("blockName") {
- [\[Off/On\]] propertyName("label in Inspector"[, type]) [= defaultValue];
- ...
- } ]
- }
- ```
-
- All include enable and disable functions, initialized by the `[On/Off]` directive. The types include
-
- | Type | Example |
- | :-: | :-- |
- | None (Toggle Macro) | macroName("Macro Description"); |
- | Bool | macroName("Macro Description", Boolean) = true; |
- | Int | macroName("Macro Description", Int) = 1;
macroName("Macro Description", Range(0,8)) = 1; |
- | Float | macroName("Macro Description", Float) = 0.5;
macroName("Macro Description", Range(0.0, 1.0)) = 0.5; |
- | Color | macroName("Macro Description", Color) = (0.25, 0.5, 0.5, 1); |
- | Vector2 | macroName("Macro Description", Vector2) = (0.25, 0.5); |
- | Vector3 | macroName("Macro Description", Vector3) = (0.25, 0.5, 0.5); |
- | Vector4 | macroName("Macro Description", Vector4) = (0.25, 0.5, 0.5, 1.0); |
-
-> Note that the current version of the ShaderLab material property module only defines the Inspector UI panel for the material bound to this Shader in the editor. It does not declare the corresponding global variables for you in the `ShaderPass`. If the `ShaderPass` code references this variable, you need to explicitly declare it in the global variable module (see below).
+- DepthState
-## Global Variables
+ ```glsl
+ DepthState {
+ Enabled: bool;
+ WriteEnabled: bool;
+ CompareFunction: CompareFunction;
+ }
+ ```
-You can declare 4 types of global variables in ShaderLab: RenderState, Structs, Functions, and Single Variables.
+ CompareFunction enums are the same as the engine API.
-### RenderState
+- StencilState
+
+ ```glsl
+ StencilState {
+ Enabled: bool;
+ ReferenceValue: int;
+ Mask: float; // 0xffffffff
+ WriteMask: float; // 0xffffffff
+ CompareFunctionFront: CompareFunction;
+ CompareFunctionBack: CompareFunction;
+ PassOperationFront: StencilOperation;
+ PassOperationBack: StencilOperation;
+ FailOperationFront: StencilOperation;
+ FailOperationBack: StencilOperation;
+ ZFailOperationFront: StencilOperation;
+ ZFailOperationBack: StencilOperation;
+ }
+ ```
+
+ CompareFunction and StencilOperation enums are the same as the engine API.
- Includes BlendState, DepthState, StencilState, RasterState
-
- - BlendState
-
- ```glsl
- BlendState {
- Enabled[n]: bool;
- ColorBlendOperation[n]: BlendOperation;
- AlphaBlendOperation[n]: BlendOperation;
- SourceColorBlendFactor[n]: BlendFactor;
- SourceAlphaBlendFactor[n]: BlendFactor;
- DestinationColorBlendFactor[n]: BlendFactor;
- DestinationAlphaBlendFactor[n]: BlendFactor;
- ColorWriteMask[n]: float // 0xffffffff
- BlendColor: vec4;
- AlphaToCoverage: bool;
- }
- ```
-
- [n] can be omitted. When using MRT, [n] specifies a particular MRT render state. Omitting it sets all MRT states. BlendOperation and BlendFactor enums are the same as the engine API.
-
- - DepthState
-
- ```glsl
- DepthState {
- Enabled: bool;
- WriteEnabled: bool;
- CompareFunction: CompareFunction;
- }
- ```
-
- CompareFunction enums are the same as the engine API.
-
- - StencilState
-
- ```glsl
- StencilState {
- Enabled: bool;
- ReferenceValue: int;
- Mask: float; // 0xffffffff
- WriteMask: float; // 0xffffffff
- CompareFunctionFront: CompareFunction;
- CompareFunctionBack: CompareFunction;
- PassOperationFront: StencilOperation;
- PassOperationBack: StencilOperation;
- FailOperationFront: StencilOperation;
- FailOperationBack: StencilOperation;
- ZFailOperationFront: StencilOperation;
- ZFailOperationBack: StencilOperation;
- }
- ```
-
- CompareFunction and StencilOperation enums are the same as the engine API.
-
- - RasterState
-
- ```glsl
- RasterState {
- CullMode: CullMode;
- DepthBias: float;
- SlopeScaledDepthBias: float;
- }
- ```
-
- CullMode enums are the same as the engine API.
-
- Example of setting `BlendState` in `ShaderLab`:
+- RasterState
```glsl
- Shader "Demo" {
+ RasterState {
+ CullMode: CullMode;
+ DepthBias: float;
+ SlopeScaledDepthBias: float;
+ }
+ ```
+
+ CullMode enums are the same as the engine API.
+
+Example of setting `BlendState` in `ShaderLab`:
+
+```glsl
+Shader "Demo" {
+ ...
+ BlendState customBlendState
+ {
+ Enabled = true;
+ // Constant variable assignment
+ SourceColorBlendFactor = BlendFactor.SourceColor;
+ // Variable assignment
+ DestinationColorBlendFactor = material_DstBlend;
+ }
+ ...
+ Pass "0" {
...
- BlendState customBlendState
- {
- Enabled = true;
- // Constant variable assignment
- SourceColorBlendFactor = BlendFactor.SourceColor;
- // Variable assignment
- DestinationColorBlendFactor = material_DstBlend;
- }
+ BlendState = customBlendState;
...
- Pass "0" {
- ...
- BlendState = customBlendState;
- ...
- }
}
- ```
+}
+```
- The above example shows two ways of assigning values to BlendState properties: *constant assignment* and *variable assignment*:
+The above example shows two ways of assigning values to BlendState properties: _constant assignment_ and _variable assignment_:
- - Constant assignment means the right side of the assignment statement is a specified engine enum variable, e.g., BlendFactor.SourceColor.
- - Variable assignment means the right side of the assignment statement is any variable name. The specific value of the variable is specified by the user at runtime through the ShaderData.setInt("material_DstBlend", BlendFactor.SourceColor) API.
+- Constant assignment means the right side of the assignment statement is a specified engine enum variable, e.g., BlendFactor.SourceColor.
+- Variable assignment means the right side of the assignment statement is any variable name. The specific value of the variable is specified by the user at runtime through the ShaderData.setInt("material_DstBlend", BlendFactor.SourceColor) API.
### Structs, Functions
- Same as the syntax in GLSL.
+Same as the syntax in GLSL.
### Single Variables
- ```glsl
- [lowp/mediump/highp] variableType variableName;
- ```
+```glsl
+[lowp/mediump/highp] variableType variableName;
+```
Similar to other programming languages, global variables in ShaderLab also have scope and name overriding principles. In simple terms, the scope of global variables in ShaderLab is limited to the SubShader or Pass module in which they are declared. The name overriding principle means that if there are global variables with the same name within a Pass, the global variables within the Pass will override the global variables with the same name in the SubShader.
diff --git a/docs/zh/graphics/shader/shaderLab/syntax/_meta.json b/docs/zh/graphics/shader/shaderLab/syntax/_meta.json
index 73a312cdf1..58a527e0c5 100644
--- a/docs/zh/graphics/shader/shaderLab/syntax/_meta.json
+++ b/docs/zh/graphics/shader/shaderLab/syntax/_meta.json
@@ -1,7 +1,8 @@
{
"intro": "总览",
"shader": "Shader",
+ "editor": "Editor",
"subShader": "SubShader",
"pass": "Pass",
"macro": "宏"
-}
\ No newline at end of file
+}
diff --git a/docs/zh/graphics/shader/shaderLab/syntax/editor.mdx b/docs/zh/graphics/shader/shaderLab/syntax/editor.mdx
new file mode 100644
index 0000000000..d48c815d65
--- /dev/null
+++ b/docs/zh/graphics/shader/shaderLab/syntax/editor.mdx
@@ -0,0 +1,260 @@
+import { Image } from "@/mdx";
+
+---
+
+# Editor
+
+```glsl
+Editor {
+ Properties {
+ material_BaseColor("Offset unit scale", Color) = (1,1,1,1);
+ ...
+
+ Header("Emissive")
+ {
+ material_EmissiveColor("Emissive color", Color) = (1,1,1,1);
+ ...
+ }
+ ...
+ }
+
+ ...
+
+ Macros {
+ [On] UV_OFFSET("UV Offset", Range(1,100)) = 10;
+ ...
+
+ Header("") {
+ SOME_MACRO("label", Int) = 1;
+ }
+ }
+
+ ...
+
+ // 指定 Shader 绑定的 UIScript 编辑器项目路径。
+ UIScript "./shaderScript.ts";
+}
+```
+
+## Properties 属性
+
+可用于定义绑定了该 Shader 自定义材质的属性,在编辑器中开发者可以通过自定义材质 Inspector 面板对定义的属性进行调整。
+
+
+
+### 属性定义
+
+```glsl
+/**
+ * @language zh
+ * Comments description
+ */
+
+/**
+ * @language en
+ * 注释描述
+ */
+propertyName("Description", EditType) = [DefaultValue];
+```
+
+
+
+1. 可以使用 `Header` 指令将有关联的属性组织起来,Inspector 对应的面板中也会有相应的层级分类:
+
+```
+Header("Emissive") {
+ material_EmissiveColor("Emissive color", Color) = (1,1,1,1);
+ ...
+}
+```
+
+2. 通过注释标注 Inspector Hover 提示内容,支持使用 @language 指令进行多语言指定。
+
+
+
+当前支持的 EditType 列表如下:
+
+| EditType | Example |
+| :-: | :-- |
+| Bool | propertyName("Property Description", Boolean) = true; |
+| Int | propertyName("Property Description", Int) = 1;
propertyName("Property Description", Range(0,8)) = 1
propertyName("Property Description", Enum(Item1: 1, Item2: 2, Item3: 3)) = 1 // 枚举 |
+| Float | propertyName("Property Description", FLoat) = 0.5;
propertyName("Property Description", Range(0.0, 1.0)) = 0.5;
propertyName("Property Description", Enum(Item1: 1.0, Item2: 2.0, Item3: 3.0)) = 1.0; // 枚举 |
+| Texture2D | propertyName("Property Description", Texture2D); |
+| TextureCube | propertyName("Property Description", TextureCube); |
+| Color | propertyName("Property Description", Color) = (0.25, 0.5, 0.5, 1); |
+| Vector2 | propertyName("Property Description", Vector2) = (0.25, 0.5); |
+| Vector3 | propertyName("Property Description", Vector3) = (0.25, 0.5, 0.5); |
+| Vector4 | propertyName("Property Description", Vector4) = (0.25, 0.5, 0.5, 1.0); |
+
+#### 枚举类型
+
+```glsl
+propertyName("Property Description", Enum(Item1: 1, Item2: 2, Item3: 3)) = 1;
+```
+
+
+ 当前只有 Int 和 Float 类型支持枚举,且不支持类型混合,比如下面的枚举混合了Float和Int,将不会被正确解析 ```glsl
+ propertyName("Property Description", Enum("Item1":1, "Item2":2.0, "Item3": 3)) = 2.0; ```
+
+
+## Macros
+
+用于将 Shader 中用到的宏反射到 Inspector 中,从而在编辑器中对 Shader 依赖的宏进行灵活的调整。
+
+```
+// 开启/关闭
+[On/Off]macroName("MacroLabel", EditType) = [DefaultValue];
+```
+
+通过`[On/Off]`指令指定宏的默认开关,当前编辑器支持的宏类型如下:
+
+| Type | Example |
+| :-----: | :-------------------------------------------------------------------------------------------------------- |
+| 无值宏 | macroName("Macro Description"); |
+| Bool | macroName("Macro Description", Boolean) = true; |
+| Int | macroName("Macro Description", Int) = 1;
macroName("Macro Description", Range(0,8)) = 1; |
+| Float | macroName("Macro Description", FLoat) = 0.5;
macroName("Macro Description", Range(0.0, 1.0)) = 0.5; |
+| Color | macroName("Macro Description", Color) = (0.25, 0.5, 0.5, 1); |
+| Vector2 | macroName("Macro Description", Vector2) = (0.25, 0.5); |
+| Vector3 | macroName("Macro Description", Vector3) = (0.25, 0.5, 0.5); |
+| Vector4 | macroName("Macro Description", Vector4) = (0.25, 0.5, 0.5, 1.0); |
+
+## UIScript
+
+开发者使用编辑器对自定义材质属性进行调节的同时,还可以通过`UIScript`指定数据变更的回调行为。
+
+- 在 ShaderLab 中绑定 `UIScript`:
+
+```
+Editor {
+ ...
+ UIScript "/path/to/script";
+ ...
+}
+```
+
+
+绑定的`UIScript`脚本路径支持相对路径和绝对路径,以上图项目根目录为例,绝对路径为
+`/PBRScript1.ts`,相对路径为`./PBRScript1.ts`
+
+### UIScript API
+
+编辑器通过内置`ShaderUIScript`类暴露相关API
+
+```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 void> = new Map();
+
+ /** @internal */
+ _macroCallBacks: Map 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 脚本
+
+
+
+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))
+ }
+ }
+}
+
+```
+
+
+ 注意,当前版本 ShaderLab 材质属性模块只是定义了绑定该 Shader 的材质在编辑器中的 Inspector
+ UI面板,并不会替你在`ShaderPass`中声明对应的全局变量,如果`ShaderPass`代码中引用了该变量需在[全局变量](./shader/#全局变量)模块中明确声明补充。
+
diff --git a/docs/zh/graphics/shader/shaderLab/syntax/intro.mdx b/docs/zh/graphics/shader/shaderLab/syntax/intro.mdx
index e8b435db22..6bee935bb2 100644
--- a/docs/zh/graphics/shader/shaderLab/syntax/intro.mdx
+++ b/docs/zh/graphics/shader/shaderLab/syntax/intro.mdx
@@ -8,7 +8,10 @@ title: ShaderLab 语法标准
> 未来版本会推出 Galacean VSCode 插件,该插件会为`ShaderLab`提供语法检测和自动补全功能以及代码同步功能,敬请期待
-
+
## 语法标准
@@ -16,6 +19,10 @@ title: ShaderLab 语法标准
```glsl
Shader "ShaderName" {
+ ...
+ Editor {
+ ...
+ }
...
SubShader "SubShaderName" {
...
diff --git a/docs/zh/graphics/shader/shaderLab/syntax/pass.mdx b/docs/zh/graphics/shader/shaderLab/syntax/pass.mdx
index 2f851c61fd..556d409ada 100644
--- a/docs/zh/graphics/shader/shaderLab/syntax/pass.mdx
+++ b/docs/zh/graphics/shader/shaderLab/syntax/pass.mdx
@@ -94,8 +94,36 @@ material.renderQueueType = RenderQueueType.Opaque;
// 渲染状态设置 const renderState = material.renderState.depthState; depthState.writeEnabled = false;
-```
+````
当 ShaderLab 中声明了渲染状态和渲染队列,材质相应的设置会被忽略。
+
+## MRT(多目标渲染)
+
+ShaderLab 同时兼容 GLSL 100 和 GLSL 300 语法,因此你可以使用两种语法进行 MRT 指定。
+
+1. 通过 `gl_FragData[i]` 进行指定 MRT 指定
+```glsl
+void main(v2f input) {
+ gl_FragData[0] = vec4(1.,0.,0.,1.); // render target 0
+ gl_FragData[1] = vec4(1.,0.,0.,1.); // render target 1
+}
+```
+
+2. 通过入口函数返回结构体指定
+
+```glsl
+struct mrt {
+ layout(location = 0) vec4 fragColor0; // render target 0
+ layout(location = 1) vec4 fragColor1; // render target 1
+}
+
+mrt main(v2f input) {
+ mrt output;
+ output.fragColor0 = vec4(1.,0.,0.,1.);
+ output.fragColor1 = vec4(1.,0.,0.,1.);
+ return output;
+}
```
+````
diff --git a/docs/zh/graphics/shader/shaderLab/syntax/shader.mdx b/docs/zh/graphics/shader/shaderLab/syntax/shader.mdx
index 33dde649db..a96e6cf89e 100644
--- a/docs/zh/graphics/shader/shaderLab/syntax/shader.mdx
+++ b/docs/zh/graphics/shader/shaderLab/syntax/shader.mdx
@@ -18,87 +18,7 @@ ShaderLab 中的 `Shader` 是传统渲染管线中着色器程序和其他引擎
## 材质属性定义
-```glsl
-// Uniform
-EditorProperties
-{
- material_BaseColor("Offset unit scale", Color) = (1,1,1,1);
- ...
-
- Header("Emissive")
- {
- material_EmissiveColor("Emissive color", Color) = (1,1,1,1);
- ...
- }
- ...
-}
-
-// 宏
-EditorMacros
-{
- [On] UV_OFFSET("UV Offset", Range(1,100)) = 10;
- ...
-}
-```
-
-此模块用于定义绑定该 Shader 的材质在编辑器 Inspector 面板中的 UI 展示。ShaderLab 材质属性对宏属性和其它 Uniform 属性使用`EditorProperties`和`EditorMacros`进行分开声明,其声明格式为:
-
-1. Uniform 属性
-
- ```glsl
- EditorProperties {
- propertyName("label in Inspector", type) [= defaultValue];
- ...
- [ Header("blockName") {
- propertyName("label in Inspector", type) [= defaultValue];
- ...
- } ]
- }
- ```
-
- > 可以使用嵌套`Header`块对材质属性进行层级分类。
-
- 支持的类型有
-
- | Type | Example |
- | :-: | :-- |
- | Bool | propertyName("Property Description", Boolean) = true; |
- | Int | propertyName("Property Description", Int) = 1;
propertyName("Property Description", Range(0,8)) = 1 |
- | Float | propertyName("Property Description", FLoat) = 0.5;
propertyName("Property Description", Range(0.0, 1.0)) = 0.5; |
- | Texture2D | propertyName("Property Description", Texture2D); |
- | TextureCube | propertyName("Property Description", TextureCube); |
- | Color | propertyName("Property Description", Color) = (0.25, 0.5, 0.5, 1); |
- | Vector2 | propertyName("Property Description", Vector2) = (0.25, 0.5); |
- | Vector3 | propertyName("Property Description", Vector3) = (0.25, 0.5, 0.5); |
- | Vector4 | propertyName("Property Description", Vector4) = (0.25, 0.5, 0.5, 1.0); |
-
-2. 宏属性
-
- ```glsl
- EditorMacros {
- [\[Off/On\]] propertyName("label in Inspector"[, type]) [= defaultValue];
- ...
- [ Header("blockName") {
- [\[Off/On\]] propertyName("label in Inspector"[, type]) [= defaultValue];
- ...
- } ]
- }
- ```
-
- 均包含开启和禁用功能,初始化通过 `[On/Off]` 指令指定,其类型包含
-
- | Type | Example |
- | :-: | :-- |
- | 无(开关宏) | macroName("Macro Description"); |
- | Bool | macroName("Macro Description", Boolean) = true; |
- | Int | macroName("Macro Description", Int) = 1;
macroName("Macro Description", Range(0,8)) = 1; |
- | Float | macroName("Macro Description", FLoat) = 0.5;
macroName("Macro Description", Range(0.0, 1.0)) = 0.5; |
- | Color | macroName("Macro Description", Color) = (0.25, 0.5, 0.5, 1); |
- | Vector2 | macroName("Macro Description", Vector2) = (0.25, 0.5); |
- | Vector3 | macroName("Macro Description", Vector3) = (0.25, 0.5, 0.5); |
- | Vector4 | macroName("Macro Description", Vector4) = (0.25, 0.5, 0.5, 1.0); |
-
-> 注意,当前版本 ShaderLab 材质属性模块只是定义了绑定该 Shader 的材质在编辑器中的 Inspector UI 面板,并不会替你在`ShaderPass`中声明对应的全局变量,如果`ShaderPass`代码中引用了该变量需在全局变量模块(见下文)中明确声明补充。
+在 ShaderLab 中开发者可以通过 [`Editor`](./editor/) 指令为使用该 Shader 的自定义材质定制 Inspector 属性面板。
## 全局变量