Browse Source

Added ability to toggle matrix caching in effects and set NativeEngine to disable it. This is a stopgap measure until we decide what the right way/place to cache uniform values is. This problem arose because the old underlying native layer had different expectations/assumptions than the new, so we just need to reevaluate (and possibly implement) the contract.

syntheticmagus 6 years ago
parent
commit
baedfc7f2e
3 changed files with 40 additions and 4 deletions
  1. 1 1
      src/Engines/engine.ts
  2. 35 1
      src/Engines/nativeEngine.ts
  3. 4 2
      src/Materials/effect.ts

+ 1 - 1
src/Engines/engine.ts

@@ -858,7 +858,7 @@ export class Engine {
     protected _currentEffect: Nullable<Effect>;
     /** @hidden */
     protected _currentProgram: Nullable<WebGLProgram>;
-    private _compiledEffects: { [key: string]: Effect } = {};
+    protected _compiledEffects: { [key: string]: Effect } = {};
     private _vertexAttribArraysEnabled: boolean[] = [];
     /** @hidden */
     protected _cachedViewport: Nullable<Viewport>;

+ 35 - 1
src/Engines/nativeEngine.ts

@@ -7,7 +7,7 @@ import { Texture } from "../Materials/Textures/texture";
 import { BaseTexture } from "../Materials/Textures/baseTexture";
 import { VideoTexture } from "../Materials/Textures/videoTexture";
 import { RenderTargetTexture } from "../Materials/Textures/renderTargetTexture";
-import { Effect } from "../Materials/effect";
+import { Effect, EffectCreationOptions, EffectFallbacks } from "../Materials/effect";
 import { Tools } from "../Misc/tools";
 import { Observer } from "../Misc/observable";
 import { EnvironmentTextureTools, EnvironmentTextureSpecularInfoV1 } from "../Misc/environmentTextureTools";
@@ -409,6 +409,40 @@ export class NativeEngine extends Engine {
     }
 
     /**
+     * Create a new effect (used to store vertex/fragment shaders)
+     * @param baseName defines the base name of the effect (The name of file without .fragment.fx or .vertex.fx)
+     * @param attributesNamesOrOptions defines either a list of attribute names or an EffectCreationOptions object
+     * @param uniformsNamesOrEngine defines either a list of uniform names or the engine to use
+     * @param samplers defines an array of string used to represent textures
+     * @param defines defines the string containing the defines to use to compile the shaders
+     * @param fallbacks defines the list of potential fallbacks to use if shader conmpilation fails
+     * @param onCompiled defines a function to call when the effect creation is successful
+     * @param onError defines a function to call when the effect creation has failed
+     * @param indexParameters defines an object containing the index values to use to compile shaders (like the maximum number of simultaneous lights)
+     * @returns the new Effect
+     */
+    public createEffect(baseName: any, attributesNamesOrOptions: string[] | EffectCreationOptions, uniformsNamesOrEngine: string[] | Engine, samplers?: string[], defines?: string, fallbacks?: EffectFallbacks,
+        onCompiled?: (effect: Effect) => void, onError?: (effect: Effect, errors: string) => void, indexParameters?: any): Effect {
+        var vertex = baseName.vertexElement || baseName.vertex || baseName;
+        var fragment = baseName.fragmentElement || baseName.fragment || baseName;
+
+        var name = vertex + "+" + fragment + "@" + (defines ? defines : (<EffectCreationOptions>attributesNamesOrOptions).defines);
+        if (this._compiledEffects[name]) {
+            var compiledEffect = <Effect>this._compiledEffects[name];
+            if (onCompiled && compiledEffect.isReady()) {
+                onCompiled(compiledEffect);
+            }
+
+            return compiledEffect;
+        }
+        var effect = new Effect(baseName, attributesNamesOrOptions, uniformsNamesOrEngine, samplers, this, defines, fallbacks, onCompiled, onError, indexParameters, false);
+        effect._key = name;
+        this._compiledEffects[name] = effect;
+
+        return effect;
+    }
+
+    /**
      * Directly creates a webGL program
      * @param vertexCode defines the vertex shader code to use
      * @param fragmentCode defines the fragment shader code to use

+ 4 - 2
src/Materials/effect.ts

@@ -264,6 +264,7 @@ export class Effect {
      * @hidden
      */
     public _program: WebGLProgram;
+    private _enableMatrixCaching: boolean;
     private _valueCache: { [key: string]: any };
     private static _baseCache: { [key: number]: WebGLBuffer } = {};
 
@@ -282,8 +283,9 @@ export class Effect {
      * @param indexParameters Parameters to be used with Babylons include syntax to iterate over an array (eg. {lights: 10})
      */
     constructor(baseName: any, attributesNamesOrOptions: string[] | EffectCreationOptions, uniformsNamesOrEngine: string[] | Engine, samplers: Nullable<string[]> = null, engine?: Engine, defines: Nullable<string> = null,
-        fallbacks: Nullable<EffectFallbacks> = null, onCompiled: Nullable<(effect: Effect) => void> = null, onError: Nullable<(effect: Effect, errors: string) => void> = null, indexParameters?: any) {
+        fallbacks: Nullable<EffectFallbacks> = null, onCompiled: Nullable<(effect: Effect) => void> = null, onError: Nullable<(effect: Effect, errors: string) => void> = null, indexParameters?: any, enableMatrixCaching: boolean = true) {
         this.name = baseName;
+        this._enableMatrixCaching = enableMatrixCaching;
 
         if ((<EffectCreationOptions>attributesNamesOrOptions).attributes) {
             var options = <EffectCreationOptions>attributesNamesOrOptions;
@@ -1287,7 +1289,7 @@ export class Effect {
      * @returns this effect.
      */
     public setMatrix(uniformName: string, matrix: Matrix): Effect {
-        if (this._cacheMatrix(uniformName, matrix)) {
+        if (!this._enableMatrixCaching || this._cacheMatrix(uniformName, matrix)) {
             this._engine.setMatrix(this.getUniform(uniformName), matrix);
         }
         return this;