Переглянути джерело

Merge pull request #8340 from BabylonJS/revert-8332-removeNativeShaderProcessor

Revert "Remove nativeShaderProcessor.ts"
Justin Murray 5 роки тому
батько
коміт
88c0d8d647
2 змінених файлів з 144 додано та 2 видалено
  1. 142 0
      src/Engines/Native/nativeShaderProcessor.ts
  2. 2 2
      src/Engines/nativeEngine.ts

+ 142 - 0
src/Engines/Native/nativeShaderProcessor.ts

@@ -0,0 +1,142 @@
+import { WebGL2ShaderProcessor } from "../WebGL/webGL2ShaderProcessors";
+import { VertexBuffer } from "../../Meshes/buffer";
+
+// These numbers must match the values for bgfx::Attrib::Enum
+const attributeLocations: { [kind: string]: number } = {
+    [VertexBuffer.PositionKind]: 0,
+    [VertexBuffer.NormalKind]: 1,
+    [VertexBuffer.TangentKind]: 2,
+    [VertexBuffer.UVKind]: 10,
+    [VertexBuffer.UV2Kind]: 11,
+    [VertexBuffer.UV3Kind]: 12,
+    [VertexBuffer.UV4Kind]: 13,
+    [VertexBuffer.ColorKind]: 4,
+    [VertexBuffer.MatricesIndicesKind]: 8,
+    [VertexBuffer.MatricesWeightsKind]: 9,
+};
+// Remap BJS names to bgfx names
+const attributeBGFXName: { [kind: string]: string } = {
+    [VertexBuffer.PositionKind]: "a_position",
+    [VertexBuffer.NormalKind]: "a_normal",
+    [VertexBuffer.TangentKind]: "a_tangent",
+    [VertexBuffer.UVKind]: "a_texcoord0",
+    [VertexBuffer.UV2Kind]: "a_texcoord1",
+    [VertexBuffer.UV3Kind]: "a_texcoord2",
+    [VertexBuffer.UV4Kind]: "a_texcoord3",
+    [VertexBuffer.ColorKind]: "a_color0",
+    [VertexBuffer.MatricesIndicesKind]: "a_indices",
+    [VertexBuffer.MatricesWeightsKind]: "a_weight",
+};
+
+// Must match bgfx::Attrib::TexCoord0
+const firstGenericAttributeLocation = 10;
+
+// Must match bgfx::Attrib::TexCoord7
+const lastGenericAttributeLocation = 17;
+
+/** @hidden */
+export class NativeShaderProcessor extends WebGL2ShaderProcessor {
+    private _genericAttributeLocation: number;
+    private _varyingLocationCount: number;
+    private _varyingLocationMap: { [name: string]: number };
+    private _replacements: Array<{ searchValue: RegExp, replaceValue: string }>;
+    private _textureCount: number;
+    private _uniforms: Array<string>;
+
+    public lineProcessor(line: string): string {
+        for (const replacement of this._replacements) {
+            line = line.replace(replacement.searchValue, replacement.replaceValue);
+        }
+
+        return line;
+    }
+
+    public attributeProcessor(attribute: string): string {
+        const match = attribute.match(/attribute\s+[^\s]+\s+([^\s]+)\s*(?:\[.+\])?\s*;/)!;
+        const name = match[1];
+
+        let location = attributeLocations[name];
+        if (location === undefined) {
+            location = this._genericAttributeLocation++;
+            if (location > lastGenericAttributeLocation) {
+                throw new Error("Exceeded maximum custom attributes");
+            }
+        }
+        let newName = attributeBGFXName[name];
+        if (newName === undefined) {
+            throw new Error("Can't find bgfx name mapping");
+        }
+        attribute = attribute.replace(name, newName);
+        this._replacements.push({ searchValue: new RegExp(`\\b${name}\\b`, 'g'), replaceValue: `${newName}` });
+        return `layout(location=${location}) ${super.attributeProcessor(attribute)}`;
+    }
+
+    public varyingProcessor(varying: string, isFragment: boolean): string {
+        let location: number;
+
+        if (isFragment) {
+            location = this._varyingLocationMap[varying];
+        }
+        else {
+            location = this._varyingLocationCount++;
+            this._varyingLocationMap[varying] = location;
+        }
+
+        return `layout(location=${location}) ${super.varyingProcessor(varying, isFragment)}`;
+    }
+
+    public uniformProcessor(uniform: string): string {
+        const match = uniform.match(/uniform\s+([^\s]+)\s+([^\s]+)\s*(?:\[.+\])?\s*;/)!;
+        const type = match[1];
+        const name = match[2];
+
+        switch (type) {
+            case "sampler2D":
+            case "samplerCube": {
+                const suffix = type.substr(7);
+                const binding = this._textureCount++;
+                this._replacements.push({ searchValue: new RegExp(`\\b${name}\\b`), replaceValue: `sampler${suffix}(${name}Texture, ${name})` });
+                return `layout(binding=${binding}) uniform texture${suffix} ${name}Texture;\nlayout(binding=${binding}) uniform sampler ${name};`;
+            }
+            case "float": {
+                this._replacements.push({ searchValue: new RegExp(`\\b${name}\\b`), replaceValue: `${name}.x` });
+                uniform = `uniform vec4 ${name};`;
+                break;
+            }
+            case "vec2": {
+                this._replacements.push({ searchValue: new RegExp(`\\b${name}\\b`), replaceValue: `${name}.xy` });
+                uniform = `uniform vec4 ${name};`;
+                break;
+            }
+            case "vec3": {
+                this._replacements.push({ searchValue: new RegExp(`\\b${name}\\b`), replaceValue: `${name}.xyz` });
+                uniform = `uniform vec4 ${name};`;
+                break;
+            }
+        }
+
+        this._uniforms.push(uniform);
+        return this._uniforms.length === 1 ? "<UNIFORM>" : "";
+    }
+
+    public preProcessor(code: string, defines: string[], isFragment: boolean): string {
+        this._genericAttributeLocation = firstGenericAttributeLocation;
+
+        if (!isFragment) {
+            this._varyingLocationCount = 0;
+            this._varyingLocationMap = {};
+        }
+
+        this._replacements = [];
+        this._textureCount = 0;
+        this._uniforms = [];
+        return code;
+    }
+
+    public postProcessor(code: string, defines: string[], isFragment: boolean): string {
+        code = super.postProcessor(code, defines, isFragment);
+        code = code.replace("<UNIFORM>", `layout(binding=0) uniform Frame {\n${this._uniforms.join("\n")}\n};`);
+        code = code.replace("out vec4 glFragColor", "layout(location=0) out vec4 glFragColor");
+        return code;
+    }
+}

+ 2 - 2
src/Engines/nativeEngine.ts

@@ -17,13 +17,13 @@ import { IColor4Like } from '../Maths/math.like';
 import { Scene } from "../scene";
 import { RenderTargetCreationOptions } from "../Materials/Textures/renderTargetCreationOptions";
 import { IPipelineContext } from './IPipelineContext';
+import { NativeShaderProcessor } from './Native/nativeShaderProcessor';
 import { Logger } from "../Misc/logger";
 import { Constants } from './constants';
 import { ThinEngine, ISceneLike } from './thinEngine';
 import { IWebRequest } from '../Misc/interfaces/iWebRequest';
 import { EngineStore } from './engineStore';
 import { ShaderCodeInliner } from "./Processors/shaderCodeInliner";
-import { WebGL2ShaderProcessor } from '../Engines/WebGL/webGL2ShaderProcessors';
 
 interface INativeEngine {
     dispose(): void;
@@ -270,7 +270,7 @@ export class NativeEngine extends Engine {
         }
 
         // Shader processor
-        this._shaderProcessor = new WebGL2ShaderProcessor();
+        this._shaderProcessor = new NativeShaderProcessor();
     }
 
     public dispose(): void {