From 5a26f3d8ccd113853e2595cd4d5176eed9d2b971 Mon Sep 17 00:00:00 2001 From: SwayYan Date: Wed, 20 Sep 2023 12:06:40 +0800 Subject: [PATCH 01/15] fix(shader-lab): compatible with empty macro --- packages/shader-lab/src/RuntimeContext.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/shader-lab/src/RuntimeContext.ts b/packages/shader-lab/src/RuntimeContext.ts index 8624faf161..5b70213a89 100644 --- a/packages/shader-lab/src/RuntimeContext.ts +++ b/packages/shader-lab/src/RuntimeContext.ts @@ -270,7 +270,7 @@ export default class RuntimeContext { getMacroText(macros: (FnMacroAstNode | FnMacroConditionAstNode)[], needSort = false): string { const list = needSort ? macros.sort(AstNodeUtils.astSortAsc) : macros; - return list.map((item) => item.serialize(this)).join("\n"); + return list?.map((item) => item.serialize(this)).join("\n"); } getGlobalText(): string { From 0d45d9c77f9803f5d69d7f5e058289ff2821ae5b Mon Sep 17 00:00:00 2001 From: SwayYan Date: Thu, 21 Sep 2023 16:02:36 +0800 Subject: [PATCH 02/15] fix(shader-lab): add break and continue syntax --- packages/shader-lab/src/ShaderVisitor.ts | 20 ++++++++++++++++ packages/shader-lab/src/ast-node/AstNode.ts | 12 ++++++++++ .../shader-lab/src/parser/ShaderParser.ts | 12 ++++++++++ .../src/parser/tokens/GLSLKeywords.ts | 4 +++- packages/shader-lab/src/types.ts | 24 +++++++++++++++++++ 5 files changed, 71 insertions(+), 1 deletion(-) diff --git a/packages/shader-lab/src/ShaderVisitor.ts b/packages/shader-lab/src/ShaderVisitor.ts index c7ffa899e1..812e400f2e 100644 --- a/packages/shader-lab/src/ShaderVisitor.ts +++ b/packages/shader-lab/src/ShaderVisitor.ts @@ -9,8 +9,10 @@ import { BlendFactorAstNode, BlendOperationAstNode, BooleanAstNode, + BreakStatementAstNode, CompareFunctionAstNode, ConditionExprAstNode, + ContinueStatementAstNode, CullModeAstNode, DeclarationWithoutAssignAstNode, DiscardStatementAstNode, @@ -80,8 +82,10 @@ import { _ruleBlendStatePropertyDeclarationCstChildren, _ruleBlendStateValueCstChildren, _ruleBooleanCstChildren, + _ruleBreakStatementCstChildren, _ruleCompareFunctionCstChildren, _ruleConditionExprCstChildren, + _ruleContinueStatementCstChildren, _ruleCullModeCstChildren, _ruleDeclarationWithoutAssignCstChildren, _ruleDepthSatePropertyDeclarationCstChildren, @@ -417,6 +421,22 @@ export class ShaderVisitor extends ShaderVisitorConstructor implements Partial { diff --git a/packages/shader-lab/src/ast-node/AstNode.ts b/packages/shader-lab/src/ast-node/AstNode.ts index 0fe5a1aa92..75578f0044 100644 --- a/packages/shader-lab/src/ast-node/AstNode.ts +++ b/packages/shader-lab/src/ast-node/AstNode.ts @@ -272,6 +272,18 @@ export class DiscardStatementAstNode extends AstNode { } } +export class BreakStatementAstNode extends AstNode { + override _doSerialization(context?: RuntimeContext, args?: any): string { + return "break;"; + } +} + +export class ContinueStatementAstNode extends AstNode { + override _doSerialization(context?: RuntimeContext, args?: any): string { + return "continue;"; + } +} + export class FnParenthesisAtomicAstNode extends AstNode { override _doSerialization(context?: RuntimeContext, args?: any): string { let ret = `(${this.content.parenthesisNode.serialize(context)})`; diff --git a/packages/shader-lab/src/parser/ShaderParser.ts b/packages/shader-lab/src/parser/ShaderParser.ts index e1068c01c9..7540e501f9 100644 --- a/packages/shader-lab/src/parser/ShaderParser.ts +++ b/packages/shader-lab/src/parser/ShaderParser.ts @@ -334,6 +334,16 @@ export class ShaderParser extends CstParser { this.CONSUME(Symbols.Semicolon); }); + private _ruleBreakStatement = this.RULE("_ruleBreakStatement", () => { + this.CONSUME(GLKeywords.Break); + this.CONSUME(Symbols.Semicolon); + }); + + private _ruleContinueStatement = this.RULE("_ruleContinueStatement", () => { + this.CONSUME(GLKeywords.Continue); + this.CONSUME(Symbols.Semicolon); + }); + private _ruleFnStatement = this.RULE("_ruleFnStatement", () => { this.OR([ { ALT: () => this.SUBRULE(this._ruleFnCall) }, @@ -342,6 +352,8 @@ export class ShaderParser extends CstParser { { ALT: () => this.SUBRULE(this._ruleFnVariableDeclaration) }, { ALT: () => this.SUBRULE(this._ruleFnConditionStatement) }, { ALT: () => this.SUBRULE(this._ruleDiscardStatement) }, + { ALT: () => this.SUBRULE(this._ruleBreakStatement) }, + { ALT: () => this.SUBRULE(this._ruleContinueStatement) }, { ALT: () => this.SUBRULE(this._ruleForLoopStatement) }, { ALT: () => this.SUBRULE(this._ruleFn) } ]); diff --git a/packages/shader-lab/src/parser/tokens/GLSLKeywords.ts b/packages/shader-lab/src/parser/tokens/GLSLKeywords.ts index fdaffe3f6a..b05eab0913 100644 --- a/packages/shader-lab/src/parser/tokens/GLSLKeywords.ts +++ b/packages/shader-lab/src/parser/tokens/GLSLKeywords.ts @@ -23,6 +23,8 @@ export const Struct = TokenUtils.createKeywordToken("struct"); export const If = TokenUtils.createKeywordToken("if"); export const Else = TokenUtils.createKeywordToken("else"); export const Discard = TokenUtils.createKeywordToken("discard"); +export const Break = TokenUtils.createKeywordToken("break"); +export const Continue = TokenUtils.createKeywordToken("continue"); export const Void = TokenUtils.createKeywordToken("void"); export const Return = TokenUtils.createKeywordToken("return"); export const For = TokenUtils.createKeywordToken("for"); @@ -30,4 +32,4 @@ export const For = TokenUtils.createKeywordToken("for"); // export const variableTokenList = [GLPosition, GLFragColor]; export const funcTokenList = [Texture2D]; export const macroTokenList = [M_DEFINE, M_IFDEF, M_IFNDEF, M_IF, M_ELSE, M_ELIF, M_ENDIF, M_UNDEFINE, M_INCLUDE]; -export const otherTokenList = [Struct, If, Else, Discard, Void, Return, For]; +export const otherTokenList = [Struct, If, Else, Discard, Void, Return, For, Break, Continue]; diff --git a/packages/shader-lab/src/types.ts b/packages/shader-lab/src/types.ts index dd59e24365..afdfae48b3 100644 --- a/packages/shader-lab/src/types.ts +++ b/packages/shader-lab/src/types.ts @@ -481,6 +481,26 @@ export type _ruleDiscardStatementCstChildren = { Semicolon: IToken[]; }; +export interface _ruleBreakStatementCstNode extends CstNode { + name: "_ruleBreakStatement"; + children: _ruleBreakStatementCstChildren; +} + +export type _ruleBreakStatementCstChildren = { + break: IToken[]; + Semicolon: IToken[]; +}; + +export interface _ruleContinueStatementCstNode extends CstNode { + name: "_ruleContinueStatement"; + children: _ruleContinueStatementCstChildren; +} + +export type _ruleContinueStatementCstChildren = { + continue: IToken[]; + Semicolon: IToken[]; +}; + export interface _ruleFnStatementCstNode extends CstNode { name: "_ruleFnStatement"; children: _ruleFnStatementCstChildren; @@ -493,6 +513,8 @@ export type _ruleFnStatementCstChildren = { _ruleFnVariableDeclaration?: _ruleFnVariableDeclarationCstNode[]; _ruleFnConditionStatement?: _ruleFnConditionStatementCstNode[]; _ruleDiscardStatement?: _ruleDiscardStatementCstNode[]; + _ruleBreakStatement?: _ruleBreakStatementCstNode[]; + _ruleContinueStatement?: _ruleContinueStatementCstNode[]; _ruleForLoopStatement?: _ruleForLoopStatementCstNode[]; _ruleFn?: _ruleFnCstNode[]; }; @@ -1241,6 +1263,8 @@ export interface ICstNodeVisitor extends ICstVisitor { _ruleArrayIndex(children: _ruleArrayIndexCstChildren, param?: IN): OUT; _ruleMultiplicationOperator(children: _ruleMultiplicationOperatorCstChildren, param?: IN): OUT; _ruleDiscardStatement(children: _ruleDiscardStatementCstChildren, param?: IN): OUT; + _ruleBreakStatement(children: _ruleBreakStatementCstChildren, param?: IN): OUT; + _ruleContinueStatement(children: _ruleContinueStatementCstChildren, param?: IN): OUT; _ruleFnStatement(children: _ruleFnStatementCstChildren, param?: IN): OUT; _ruleFnAssignStatement(children: _ruleFnAssignStatementCstChildren, param?: IN): OUT; _ruleForLoopStatement(children: _ruleForLoopStatementCstChildren, param?: IN): OUT; From 8871d9b06712665c786b25c0423e8b8fac15fdc9 Mon Sep 17 00:00:00 2001 From: SwayYan Date: Wed, 11 Oct 2023 16:15:11 +0800 Subject: [PATCH 03/15] fix: typo --- packages/core/src/shader/Shader.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/shader/Shader.ts b/packages/core/src/shader/Shader.ts index a922c528c4..d0eb131856 100644 --- a/packages/core/src/shader/Shader.ts +++ b/packages/core/src/shader/Shader.ts @@ -38,7 +38,7 @@ export class Shader { * // Import shaderLab * import { ShaderLab } from "@galacean/engine-shader-lab"; * // Create engine with shaderLab - * const engine = await WebGLEngine.create({ canvas: "canvas", new ShaderLab() }); + * const engine = await WebGLEngine.create({ canvas: "canvas", shader: new ShaderLab() }); * ... * ``` * From f649a58c681862c5707e4602bb3d49e176bd0b19 Mon Sep 17 00:00:00 2001 From: Sway007 Date: Wed, 1 Nov 2023 12:04:29 +0800 Subject: [PATCH 04/15] fix(shader-lab): Make usepass compatible with buitin shader --- packages/shader-lab/package.json | 1 + packages/shader-lab/src/parser/tokens/Value.ts | 2 +- tests/src/shader-lab/shaders/demo.shader | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/shader-lab/package.json b/packages/shader-lab/package.json index 089fbb7e83..1bc62d74c6 100644 --- a/packages/shader-lab/package.json +++ b/packages/shader-lab/package.json @@ -8,6 +8,7 @@ "license": "MIT", "main": "dist/main.js", "module": "dist/module.js", + "browser": "dist/browser.js", "debug": "src/index.ts", "types": "types/index.d.ts", "scripts": { diff --git a/packages/shader-lab/src/parser/tokens/Value.ts b/packages/shader-lab/src/parser/tokens/Value.ts index 88f689a030..9505758125 100644 --- a/packages/shader-lab/src/parser/tokens/Value.ts +++ b/packages/shader-lab/src/parser/tokens/Value.ts @@ -4,7 +4,7 @@ export const ValueInt = createToken({ name: "ValueInt", pattern: /-?\d+/ }); export const ValueFloat = createToken({ name: "ValueFloat", pattern: /-?\d+\.\d+/ }); export const ValueString = createToken({ name: "ValueString", - pattern: /"[\w\s/\.]*"/ + pattern: /"[\w-\s/\.]*"/ }); export const ValueTrue = createToken({ name: "ValueTrue", pattern: /true/ }); export const ValueFalse = createToken({ name: "ValueFalse", pattern: /false/ }); diff --git a/tests/src/shader-lab/shaders/demo.shader b/tests/src/shader-lab/shaders/demo.shader index ccf3984092..ca29fe4be0 100644 --- a/tests/src/shader-lab/shaders/demo.shader +++ b/tests/src/shader-lab/shaders/demo.shader @@ -114,5 +114,6 @@ Shader "Water" { #endif } } + UsePass "blinn-phong/Default/Forward" } } \ No newline at end of file From e33a66f7ba008562fa9498a0db02b8f19facc5ef Mon Sep 17 00:00:00 2001 From: Sway007 Date: Thu, 2 Nov 2023 15:51:25 +0800 Subject: [PATCH 05/15] fix(shader-lab): compatible with no varying variable --- packages/shader-lab/src/Ast2GLSLUtils.ts | 22 +++++--------- tests/src/shader-lab/ShaderLab.test.ts | 5 ++++ .../src/shader-lab/shaders/noFragArgs.shader | 30 +++++++++++++++++++ 3 files changed, 43 insertions(+), 14 deletions(-) create mode 100644 tests/src/shader-lab/shaders/noFragArgs.shader diff --git a/packages/shader-lab/src/Ast2GLSLUtils.ts b/packages/shader-lab/src/Ast2GLSLUtils.ts index b3bf252e47..5d3c074676 100644 --- a/packages/shader-lab/src/Ast2GLSLUtils.ts +++ b/packages/shader-lab/src/Ast2GLSLUtils.ts @@ -24,20 +24,14 @@ export class Ast2GLSLUtils { // parse varying variables const varyingStructAstNode = context.findGlobal(vertFnAst.content.returnType.content.text)?.ast as StructAstNode; - if (!varyingStructAstNode) { - context.diagnostics.push({ - severity: DiagnosticSeverity.Error, - message: "no varying struct definition", - token: vertFnAst.content.returnType.position - }); - return ""; + if (varyingStructAstNode) { + context.varyingStructInfo.structAstNode = varyingStructAstNode; + context.varyingStructInfo.reference = varyingStructAstNode.content.variables.map((v) => ({ + referenced: false, + property: v, + text: `varying ${v.content.type.serialize(context)} ${v.content.variableNode.serialize(context)}` + })); } - context.varyingStructInfo.structAstNode = varyingStructAstNode; - context.varyingStructInfo.reference = varyingStructAstNode.content.variables.map((v) => ({ - referenced: false, - property: v, - text: `varying ${v.content.type.serialize(context)} ${v.content.variableNode.serialize(context)}` - })); // parsing attribute variables vertFnAst.content.args.forEach((arg) => { @@ -101,7 +95,7 @@ export class Ast2GLSLUtils { } context.setMainFnAst(fragFnAst); - context.varyingStructInfo.objectName = fragFnAst.content.args[0].content.name; + context.varyingStructInfo.objectName = fragFnAst.content.args?.[0].content.name; const fragmentFnStr = fragFnAst.serialize(context); // There may be global variable references in conditional macro statement, so it needs to be serialized first. diff --git a/tests/src/shader-lab/ShaderLab.test.ts b/tests/src/shader-lab/ShaderLab.test.ts index eaa6f66838..bc3baa55f3 100644 --- a/tests/src/shader-lab/ShaderLab.test.ts +++ b/tests/src/shader-lab/ShaderLab.test.ts @@ -200,4 +200,9 @@ describe("ShaderLab", () => { const demoShader = fs.readFileSync(path.join(__dirname, "shaders/triangle.shader")).toString(); glslValidate(demoShader, shaderLab); }); + + it("No frag shader args", () => { + const demoShader = fs.readFileSync(path.join(__dirname, "shaders/noFragArgs.shader")).toString(); + glslValidate(demoShader, shaderLab); + }); }); diff --git a/tests/src/shader-lab/shaders/noFragArgs.shader b/tests/src/shader-lab/shaders/noFragArgs.shader new file mode 100644 index 0000000000..f99b87871f --- /dev/null +++ b/tests/src/shader-lab/shaders/noFragArgs.shader @@ -0,0 +1,30 @@ +Shader "Test-Default" { + Tags { ReplaceTag = "transparent" } + SubShader "Default" { + Pass "test" { + Tags { ReplaceTag = "opaque" } + mat4 renderer_MVPMat; + + struct a2v { + vec4 POSITION; + } + + // struct v2f { + // vec2 uv; + // } + + VertexShader = vert; + FragmentShader = frag; + + v2f vert(a2v v) { + gl_Position = renderer_MVPMat * v.POSITION; + } + + void frag() { + vec3 grayColor = vec3(0.299, 0.587, 0.114); + float gray = dot(grayColor, gl_FragColor.rgb); + gl_FragColor = vec4(gray, gray, gray, gl_FragColor.a); + } + } + } +} \ No newline at end of file From 41ef06fc71c57a40a3976d4b479583eec8d285dc Mon Sep 17 00:00:00 2001 From: Sway007 Date: Mon, 6 Nov 2023 11:01:22 +0800 Subject: [PATCH 06/15] feat(shader-lab): detect mismatch return type --- packages/shader-lab/src/ast-node/AstNode.ts | 13 +++++++++++++ packages/shader-lab/src/ast-node/AstNodeContent.ts | 4 +++- tests/src/shader-lab/shaders/noFragArgs.shader | 2 +- tests/src/shader-lab/shaders/planarShadow.shader | 1 + 4 files changed, 18 insertions(+), 2 deletions(-) diff --git a/packages/shader-lab/src/ast-node/AstNode.ts b/packages/shader-lab/src/ast-node/AstNode.ts index 2e7da08a96..fd26a17b25 100644 --- a/packages/shader-lab/src/ast-node/AstNode.ts +++ b/packages/shader-lab/src/ast-node/AstNode.ts @@ -202,6 +202,18 @@ export class FnAstNode extends AstNode { } const body = this.content.body.serialize(context); + if ( + (this.content.returnType.content.text === "void" && this.content.returnStatement) || + (this.content.returnType.content.text !== "void" && !this.content.returnStatement) + ) { + context.diagnostics.push({ + severity: DiagnosticSeverity.Error, + message: "Mismatched return type", + token: this.position + }); + throw "Mismatched return type"; + } + context.functionAstStack.pop(); return `${returnType} ${fnName} (${args}) {\n${body}\n}`; } @@ -493,6 +505,7 @@ export class FnArrayVariableAstNode extends AstNode export class FnReturnStatementAstNode extends AstNode { override _doSerialization(context: RuntimeContext): string { + context.currentFunctionInfo.fnAst.content.returnStatement = this; if (context.currentFunctionInfo.fnAst === context.currentMainFnAst) { return ""; } diff --git a/packages/shader-lab/src/ast-node/AstNodeContent.ts b/packages/shader-lab/src/ast-node/AstNodeContent.ts index 39606d5ce8..3f837ff48c 100644 --- a/packages/shader-lab/src/ast-node/AstNodeContent.ts +++ b/packages/shader-lab/src/ast-node/AstNodeContent.ts @@ -42,7 +42,8 @@ import { FnVariableDeclareUnitAstNode, FnMacroUndefineAstNode, FnMacroConditionAstNode, - RenderQueueValueAstNode + RenderQueueValueAstNode, + FnReturnStatementAstNode } from "./AstNode"; export interface IShaderAstContent { @@ -111,6 +112,7 @@ export interface IFnAstContent { name: string; args: FnArgAstNode[]; body: AstNode; + returnStatement?: FnReturnStatementAstNode; } export interface IFnBodyAstContent { diff --git a/tests/src/shader-lab/shaders/noFragArgs.shader b/tests/src/shader-lab/shaders/noFragArgs.shader index f99b87871f..438888ced9 100644 --- a/tests/src/shader-lab/shaders/noFragArgs.shader +++ b/tests/src/shader-lab/shaders/noFragArgs.shader @@ -16,7 +16,7 @@ Shader "Test-Default" { VertexShader = vert; FragmentShader = frag; - v2f vert(a2v v) { + void vert(a2v v) { gl_Position = renderer_MVPMat * v.POSITION; } diff --git a/tests/src/shader-lab/shaders/planarShadow.shader b/tests/src/shader-lab/shaders/planarShadow.shader index 954033c5fe..eb0d494de3 100644 --- a/tests/src/shader-lab/shaders/planarShadow.shader +++ b/tests/src/shader-lab/shaders/planarShadow.shader @@ -123,6 +123,7 @@ Shader "PlanarShadow" { // shadow color o.color = u_planarShadowColor; o.color.a *= falloff; + return o; } VertexShader = vert; From b5214fc9c4167448195a966668aa7f9c9af013d8 Mon Sep 17 00:00:00 2001 From: Sway007 Date: Tue, 7 Nov 2023 16:13:35 +0800 Subject: [PATCH 07/15] fix(shader-lab): renderState assignment --- packages/shader-lab/src/RuntimeContext.ts | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/packages/shader-lab/src/RuntimeContext.ts b/packages/shader-lab/src/RuntimeContext.ts index 5b70213a89..1dd6083b45 100644 --- a/packages/shader-lab/src/RuntimeContext.ts +++ b/packages/shader-lab/src/RuntimeContext.ts @@ -205,17 +205,16 @@ export default class RuntimeContext { const [constantProps, variableProps] = ret.renderStates; this.payload = { parsingRenderState: true }; - const tmpRenderStates = ast.content.renderStates; + const tmpRenderStates = ast.content.renderStates ?? []; ast.content.properties.forEach((prop) => this._parsePassProperty(>ast, prop, ret, tmpRenderStates) ); - if (tmpRenderStates) { - for (const rs of tmpRenderStates) { - const [constP, variableP] = rs.getContentValue(this).properties; - Object.assign(constantProps, constP); - Object.assign(variableProps, variableP); - } + for (const rs of tmpRenderStates) { + const [constP, variableP] = rs.getContentValue(this).properties; + Object.assign(constantProps, constP); + Object.assign(variableProps, variableP); } + this.payload = undefined; const renderQueueNode = ast.content.renderQueue; From f36ce020b558f0b0f792565396c1c91cbff47b32 Mon Sep 17 00:00:00 2001 From: Sway007 Date: Mon, 13 Nov 2023 10:01:57 +0800 Subject: [PATCH 08/15] feat: extend material loader data type --- packages/loader/src/MaterialLoader.ts | 4 ++++ .../resource-deserialize/resources/schema/MaterialSchema.ts | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/loader/src/MaterialLoader.ts b/packages/loader/src/MaterialLoader.ts index 145f5c8780..a8bfd96884 100644 --- a/packages/loader/src/MaterialLoader.ts +++ b/packages/loader/src/MaterialLoader.ts @@ -74,6 +74,10 @@ class MaterialLoader extends Loader { }) ); break; + case "Boolean": + materialShaderData.setInt(key, value ? 1 : 0); + case "Integer": + materialShaderData.setInt(key, Number(value)); } } diff --git a/packages/loader/src/resource-deserialize/resources/schema/MaterialSchema.ts b/packages/loader/src/resource-deserialize/resources/schema/MaterialSchema.ts index 07410cec8e..377ea86126 100644 --- a/packages/loader/src/resource-deserialize/resources/schema/MaterialSchema.ts +++ b/packages/loader/src/resource-deserialize/resources/schema/MaterialSchema.ts @@ -90,7 +90,7 @@ export interface IMaterialSchema { shader: string; shaderData: { [key: string]: { - type: "Vector2" | "Vector3" | "Vector4" | "Color" | "Float" | "Texture"; + type: "Vector2" | "Vector3" | "Vector4" | "Color" | "Float" | "Texture" | "Boolean" | "Integer"; value: IVector3 | IVector2 | IColor | number | IAssetRef; }; }; From 634236f90337ca8e0a1643c933e7cb2caf54506d Mon Sep 17 00:00:00 2001 From: Sway007 Date: Mon, 13 Nov 2023 14:19:40 +0800 Subject: [PATCH 09/15] fix(shader-lab): glsl type pattern --- .../shader-lab/src/parser/tokens/GLSLTypes.ts | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/packages/shader-lab/src/parser/tokens/GLSLTypes.ts b/packages/shader-lab/src/parser/tokens/GLSLTypes.ts index 8f767dff0c..fda23bde90 100644 --- a/packages/shader-lab/src/parser/tokens/GLSLTypes.ts +++ b/packages/shader-lab/src/parser/tokens/GLSLTypes.ts @@ -1,26 +1,26 @@ import { createToken } from "chevrotain"; -export const glsl_mat2 = createToken({ name: "glsl_mat2", pattern: /mat2/ }); -export const glsl_mat3 = createToken({ name: "glsl_mat3", pattern: /mat3/ }); -export const glsl_mat4 = createToken({ name: "glsl_mat4", pattern: /mat4/ }); +export const glsl_mat2 = createToken({ name: "glsl_mat2", pattern: /mat2\s/ }); +export const glsl_mat3 = createToken({ name: "glsl_mat3", pattern: /mat3\s/ }); +export const glsl_mat4 = createToken({ name: "glsl_mat4", pattern: /mat4\s/ }); -export const glsl_vec2 = createToken({ name: "glsl_vec2", pattern: /vec2/ }); -export const glsl_vec3 = createToken({ name: "glsl_vec3", pattern: /vec3/ }); -export const glsl_vec4 = createToken({ name: "glsl_vec4", pattern: /vec4/ }); +export const glsl_vec2 = createToken({ name: "glsl_vec2", pattern: /vec2\s/ }); +export const glsl_vec3 = createToken({ name: "glsl_vec3", pattern: /vec3\s/ }); +export const glsl_vec4 = createToken({ name: "glsl_vec4", pattern: /vec4\s/ }); -export const glsl_ivec2 = createToken({ name: "glsl_ivec2", pattern: /ivec2/ }); -export const glsl_ivec3 = createToken({ name: "glsl_ivec3", pattern: /ivec3/ }); -export const glsl_ivec4 = createToken({ name: "glsl_ivec4", pattern: /ivec4/ }); +export const glsl_ivec2 = createToken({ name: "glsl_ivec2", pattern: /ivec2\s/ }); +export const glsl_ivec3 = createToken({ name: "glsl_ivec3", pattern: /ivec3\s/ }); +export const glsl_ivec4 = createToken({ name: "glsl_ivec4", pattern: /ivec4\s/ }); -export const glsl_float = createToken({ name: "glsl_float", pattern: /float/ }); -export const glsl_int = createToken({ name: "glsl_int", pattern: /int/ }); +export const glsl_float = createToken({ name: "glsl_float", pattern: /float\s/ }); +export const glsl_int = createToken({ name: "glsl_int", pattern: /int\s/ }); export const glsl_sampler2D = createToken({ name: "glsl_sampler2D", - pattern: /sampler2D/ + pattern: /sampler2D\s/ }); -export const glsl_sampler2DArray = createToken({ name: "sampler2DArray", pattern: /sampler2DArray/ }); +export const glsl_sampler2DArray = createToken({ name: "sampler2DArray", pattern: /sampler2DArray / }); export const tokenList = [ glsl_ivec2, From 91e6fa4aab6df2da732a7b53227cd61714505fab Mon Sep 17 00:00:00 2001 From: Sway007 Date: Mon, 13 Nov 2023 14:39:27 +0800 Subject: [PATCH 10/15] fix(shader-lab): glsl type pattern --- packages/shader-lab/package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/shader-lab/package.json b/packages/shader-lab/package.json index d79611f7e6..5bf22de905 100644 --- a/packages/shader-lab/package.json +++ b/packages/shader-lab/package.json @@ -8,7 +8,6 @@ "license": "MIT", "main": "dist/main.js", "module": "dist/module.js", - "browser": "dist/browser.js", "debug": "src/index.ts", "types": "types/index.d.ts", "scripts": { From 3932448c79d48428521e6c172c6352702a7cb838 Mon Sep 17 00:00:00 2001 From: Sway007 Date: Wed, 15 Nov 2023 14:27:54 +0800 Subject: [PATCH 11/15] fix: switch case break --- packages/loader/src/MaterialLoader.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/loader/src/MaterialLoader.ts b/packages/loader/src/MaterialLoader.ts index a8bfd96884..6048f24301 100644 --- a/packages/loader/src/MaterialLoader.ts +++ b/packages/loader/src/MaterialLoader.ts @@ -76,8 +76,10 @@ class MaterialLoader extends Loader { break; case "Boolean": materialShaderData.setInt(key, value ? 1 : 0); + break; case "Integer": materialShaderData.setInt(key, Number(value)); + break; } } From 671cace03db15504f45adad8614105a45a12fa1d Mon Sep 17 00:00:00 2001 From: Sway007 Date: Tue, 11 Jun 2024 11:20:20 +0800 Subject: [PATCH 12/15] fix: array index loss --- packages/shader-lab/src/ast-node/AstNode.ts | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/packages/shader-lab/src/ast-node/AstNode.ts b/packages/shader-lab/src/ast-node/AstNode.ts index 2dd987174f..f889655f4b 100644 --- a/packages/shader-lab/src/ast-node/AstNode.ts +++ b/packages/shader-lab/src/ast-node/AstNode.ts @@ -627,13 +627,19 @@ export class FnVariableAstNode extends AstNode { override _doSerialization(context: RuntimeContext): string { const objName = this.content.variable; const propName = this.content.properties?.[0].content; + + const propList = [...(this.content.properties ?? []), ...(this.content.indexes ?? [])] + .sort((a, b) => AstNodeUtils.astSortAsc(a.position, b.position)) + .map((item) => item.serialize(context)) + .join(""); + if (propName) { if (objName === context.varyingStructInfo.objectName) { const ref = context.varyingStructInfo.reference?.find( (ref) => ref.property.content.variableNode.content.variable === propName ); ref && (ref.referenced = true); - return this.content.properties.map((item) => item.content).join("."); + return propList; } else { const attribStruct = context.attributeStructListInfo.find((struct) => struct.objectName === objName); if (attribStruct) { @@ -641,7 +647,7 @@ export class FnVariableAstNode extends AstNode { (ref) => ref.property.content.variableNode.content.variable === propName ); ref && (ref.referenced = true); - return this.content.properties.map((item) => item.content).join("."); + return propList; } } } @@ -654,10 +660,7 @@ export class FnVariableAstNode extends AstNode { }); } } - const propList = [...(this.content.properties ?? []), ...(this.content.indexes ?? [])] - .sort((a, b) => AstNodeUtils.astSortAsc(a.position, b.position)) - .map((item) => item.serialize(context)) - .join(""); + return objName + propList; } } From 9226d388d701046813775ea0ba38efd691b9630e Mon Sep 17 00:00:00 2001 From: Sway007 Date: Tue, 11 Jun 2024 22:05:25 +0800 Subject: [PATCH 13/15] fix: test-case --- packages/shader-lab/src/ast-node/AstNode.ts | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/packages/shader-lab/src/ast-node/AstNode.ts b/packages/shader-lab/src/ast-node/AstNode.ts index f889655f4b..86285640cc 100644 --- a/packages/shader-lab/src/ast-node/AstNode.ts +++ b/packages/shader-lab/src/ast-node/AstNode.ts @@ -628,10 +628,9 @@ export class FnVariableAstNode extends AstNode { const objName = this.content.variable; const propName = this.content.properties?.[0].content; - const propList = [...(this.content.properties ?? []), ...(this.content.indexes ?? [])] - .sort((a, b) => AstNodeUtils.astSortAsc(a.position, b.position)) - .map((item) => item.serialize(context)) - .join(""); + const propList = [...(this.content.properties ?? []), ...(this.content.indexes ?? [])].sort((a, b) => + AstNodeUtils.astSortAsc(a.position, b.position) + ); if (propName) { if (objName === context.varyingStructInfo.objectName) { @@ -639,7 +638,7 @@ export class FnVariableAstNode extends AstNode { (ref) => ref.property.content.variableNode.content.variable === propName ); ref && (ref.referenced = true); - return propList; + return propList.map((item) => item.content).join("."); } else { const attribStruct = context.attributeStructListInfo.find((struct) => struct.objectName === objName); if (attribStruct) { @@ -647,7 +646,7 @@ export class FnVariableAstNode extends AstNode { (ref) => ref.property.content.variableNode.content.variable === propName ); ref && (ref.referenced = true); - return propList; + return propList.map((item) => item.content).join("."); } } } @@ -661,7 +660,7 @@ export class FnVariableAstNode extends AstNode { } } - return objName + propList; + return objName + propList.map((item) => item.serialize(context)).join(""); } } From ff6a69a3f69ddacc82f409bf55e8fb72cf322ceb Mon Sep 17 00:00:00 2001 From: Sway007 Date: Wed, 12 Jun 2024 10:09:07 +0800 Subject: [PATCH 14/15] fix: test-case --- packages/shader-lab/src/ast-node/AstNode.ts | 15 +++++++++------ tests/src/shader-lab/shaders/demo.shader | 2 ++ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/packages/shader-lab/src/ast-node/AstNode.ts b/packages/shader-lab/src/ast-node/AstNode.ts index 86285640cc..e18ee3662b 100644 --- a/packages/shader-lab/src/ast-node/AstNode.ts +++ b/packages/shader-lab/src/ast-node/AstNode.ts @@ -628,9 +628,10 @@ export class FnVariableAstNode extends AstNode { const objName = this.content.variable; const propName = this.content.properties?.[0].content; - const propList = [...(this.content.properties ?? []), ...(this.content.indexes ?? [])].sort((a, b) => - AstNodeUtils.astSortAsc(a.position, b.position) - ); + const propList = [...(this.content.properties ?? []), ...(this.content.indexes ?? [])] + .sort((a, b) => AstNodeUtils.astSortAsc(a.position, b.position)) + .map((item) => item.serialize(context)) + .join(""); if (propName) { if (objName === context.varyingStructInfo.objectName) { @@ -638,7 +639,8 @@ export class FnVariableAstNode extends AstNode { (ref) => ref.property.content.variableNode.content.variable === propName ); ref && (ref.referenced = true); - return propList.map((item) => item.content).join("."); + if (propList.startsWith(".")) return propList.slice(1); + return propList; } else { const attribStruct = context.attributeStructListInfo.find((struct) => struct.objectName === objName); if (attribStruct) { @@ -646,7 +648,8 @@ export class FnVariableAstNode extends AstNode { (ref) => ref.property.content.variableNode.content.variable === propName ); ref && (ref.referenced = true); - return propList.map((item) => item.content).join("."); + if (propList.startsWith(".")) return propList.slice(1); + return propList; } } } @@ -660,7 +663,7 @@ export class FnVariableAstNode extends AstNode { } } - return objName + propList.map((item) => item.serialize(context)).join(""); + return objName + propList; } } diff --git a/tests/src/shader-lab/shaders/demo.shader b/tests/src/shader-lab/shaders/demo.shader index a529185d3e..1148d96683 100644 --- a/tests/src/shader-lab/shaders/demo.shader +++ b/tests/src/shader-lab/shaders/demo.shader @@ -43,6 +43,7 @@ Shader "Water" { struct a2v { vec4 POSITION; vec2 TEXCOORD_0; + mat3 TBN; } struct v2f { @@ -88,6 +89,7 @@ Shader "Water" { vec4 tmp = renderer_MVMat * POSITION; o.v_position = tmp.xyz; gl_Position = renderer_MVPMat * v.POSITION; + vec3 tangentW = v.TBN[0]; return o; } From 865bb9ae8985ea70a85e0c87d9209a3232fb99fb Mon Sep 17 00:00:00 2001 From: Sway007 Date: Wed, 7 Aug 2024 11:51:56 +0800 Subject: [PATCH 15/15] feat: ignore editor script directive --- packages/shader-lab/src/preprocessor/PpParser.ts | 12 ++++++++++-- packages/shader-lab/src/preprocessor/constants.ts | 6 ++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/packages/shader-lab/src/preprocessor/PpParser.ts b/packages/shader-lab/src/preprocessor/PpParser.ts index 025d311cc0..5122a5b493 100644 --- a/packages/shader-lab/src/preprocessor/PpParser.ts +++ b/packages/shader-lab/src/preprocessor/PpParser.ts @@ -6,7 +6,7 @@ import PpSourceMap, { BlockInfo } from "./sourceMap"; // #endif import { BaseToken } from "../common/BaseToken"; import { ParserUtils } from "../Utils"; -import { EPpKeyword, EPpToken, PpConstant } from "./constants"; +import { EEditorKeywords, EPpKeyword, EPpToken, PpConstant } from "./constants"; import PpScanner from "./PpScanner"; import { PpUtils } from "./Utils"; import { ShaderLab } from "../ShaderLab"; @@ -622,7 +622,7 @@ export default class PpParser { } private static _skipEditorBlock(token: BaseToken, scanner: PpScanner) { - if (token.lexeme === "EditorProperties" || token.lexeme === "EditorMacros") { + if (token.lexeme === EEditorKeywords.Property || token.lexeme === EEditorKeywords.Macro) { const start = scanner.current - token.lexeme.length; scanner.scanPairedBlock("{", "}"); const end = scanner.current; @@ -630,6 +630,14 @@ export default class PpParser { const endPosition = ShaderLab.createPosition(end); const range = ShaderLab.createRange(startPosition, endPosition); this.expandSegments.push({ rangeInBlock: range, replace: "" }); + } else if (token.lexeme === EEditorKeywords.Script) { + const start = scanner.current - token.lexeme.length; + scanner.scanQuotedString(); + const end = scanner.current; + const startPosition = ShaderLab.createPosition(start); + const endPosition = ShaderLab.createPosition(end); + const range = ShaderLab.createRange(startPosition, endPosition); + this.expandSegments.push({ rangeInBlock: range, replace: "" }); } } diff --git a/packages/shader-lab/src/preprocessor/constants.ts b/packages/shader-lab/src/preprocessor/constants.ts index 98a8912213..fced1372bd 100644 --- a/packages/shader-lab/src/preprocessor/constants.ts +++ b/packages/shader-lab/src/preprocessor/constants.ts @@ -70,3 +70,9 @@ export const PpKeyword = new Map([ ]); export type PpConstant = boolean | number; + +export enum EEditorKeywords { + Property = "EditorProperties", + Macro = "EditorMacros", + Script = "EditorScript" +}