Browse Source

Fix missing varyings in fragment shaders

Popov72 4 năm trước cách đây
mục cha
commit
00546fe2d2

+ 1 - 0
src/Engines/Processors/iShaderProcessor.ts

@@ -11,5 +11,6 @@ export interface IShaderProcessor {
     lineProcessor?: (line: string, isFragment: boolean, processingContext: Nullable<ShaderProcessingContext>) => string;
     preProcessor?: (code: string, defines: string[], isFragment: boolean, processingContext: Nullable<ShaderProcessingContext>) => string;
     postProcessor?: (code: string, defines: string[], isFragment: boolean, processingContext: Nullable<ShaderProcessingContext>) => string;
+    initializeShaders?: (processingContext: Nullable<ShaderProcessingContext>) => void;
     finalizeShaders?: (vertexCode: string, fragmentCode: string, processingContext: Nullable<ShaderProcessingContext>) => { vertexCode: string, fragmentCode: string };
 }

+ 6 - 0
src/Engines/Processors/shaderProcessor.ts

@@ -20,6 +20,12 @@ const regexSERevert = /defined\s*?\[(.+?)\]/g;
 
 /** @hidden */
 export class ShaderProcessor {
+    public static Initialize(options: ProcessingOptions): void {
+        if (options.processor && options.processor.initializeShaders) {
+            options.processor.initializeShaders(options.processingContext);
+        }
+    }
+
     public static Process(sourceCode: string, options: ProcessingOptions, callback: (migratedCode: string) => void) {
         this._ProcessIncludes(sourceCode, options, (codeWithIncludes) => {
             let migratedCode = this._ProcessShaderConversion(codeWithIncludes, options);

+ 18 - 1
src/Engines/WebGPU/webgpuShaderProcessors.ts

@@ -55,6 +55,12 @@ const _comparisonSamplerByWebGPUSamplerType: { [key: string]: boolean } = {
 /** @hidden */
 export class WebGPUShaderProcessor implements IShaderProcessor {
 
+    protected _missingVaryings: Array<string> = [];
+
+    public initializeShaders(processingContext: Nullable<ShaderProcessingContext>): void {
+        this._missingVaryings.length = 0;
+    }
+
     public varyingProcessor(varying: string, isFragment: boolean, processingContext: Nullable<ShaderProcessingContext>) {
         const webgpuProcessingContext = processingContext! as WebGPUShaderProcessingContext;
 
@@ -65,10 +71,12 @@ export class WebGPUShaderProcessor implements IShaderProcessor {
             let location: number;
             if (isFragment) {
                 location = webgpuProcessingContext.availableVaryings[name];
+                this._missingVaryings[location] = "";
             }
             else {
                 location = webgpuProcessingContext.varyingNextLocation++;
                 webgpuProcessingContext.availableVaryings[name] = location;
+                this._missingVaryings.push(`layout(location = ${location}) in ${match[1]} ${name};`);
             }
 
             varying = varying.replace(match[0], `layout(location = ${location}) ${isFragment ? "in" : "out"} ${match[1]} ${name};`);
@@ -257,8 +265,17 @@ export class WebGPUShaderProcessor implements IShaderProcessor {
     }
 
     public finalizeShaders(vertexCode: string, fragmentCode: string, processingContext: Nullable<ShaderProcessingContext>): { vertexCode: string, fragmentCode: string } {
-        // Builds the leftover UBOs.
         const webgpuProcessingContext = processingContext! as WebGPUShaderProcessingContext;
+
+        // inject the missing varying in the fragment shader
+        for (let i = 0; i < this._missingVaryings.length; ++i) {
+            const decl = this._missingVaryings[i];
+            if (decl.length > 0) {
+                fragmentCode = decl + "\n" + fragmentCode;
+            }
+        }
+
+        // Builds the leftover UBOs.
         if (webgpuProcessingContext.leftOverUniforms.length) {
             const name = "LeftOver";
             let availableUBO = webgpuProcessingContext.availableUBOs[name];

+ 1 - 0
src/Materials/effect.ts

@@ -332,6 +332,7 @@ export class Effect implements IDisposable {
 
         };
         this._loadShader(vertexSource, "Vertex", "", (vertexCode) => {
+            ShaderProcessor.Initialize(processorOptions);
             ShaderProcessor.Process(vertexCode, processorOptions, (migratedVertexCode) => {
                 this._rawVertexSourceCode = vertexCode;
                 if (processFinalCode) {