浏览代码

Allow overriding the effect when calling bindForSubMesh

Popov72 5 年之前
父节点
当前提交
17f807e5ac
共有 4 个文件被更改,包括 50 次插入41 次删除
  1. 3 2
      src/Materials/PBR/pbrBaseMaterial.ts
  2. 2 1
      src/Materials/material.ts
  3. 42 36
      src/Materials/shaderMaterial.ts
  4. 3 2
      src/Materials/standardMaterial.ts

+ 3 - 2
src/Materials/PBR/pbrBaseMaterial.ts

@@ -1596,8 +1596,9 @@ export abstract class PBRBaseMaterial extends PushMaterial {
      * @param world - The world matrix.
      * @param mesh - The BJS mesh.
      * @param subMesh - A submesh of the BJS mesh.
+     * @param effectOverride - If provided, use this effect instead of the submesh effect
      */
-    public bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void {
+    public bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh, effectOverride?: Nullable<Effect>): void {
         var scene = this.getScene();
 
         var defines = <PBRMaterialDefines>subMesh._materialDefines;
@@ -1605,7 +1606,7 @@ export abstract class PBRBaseMaterial extends PushMaterial {
             return;
         }
 
-        var effect = subMesh.effect;
+        var effect = effectOverride ?? subMesh.effect;
 
         if (!effect) {
             return;

+ 2 - 1
src/Materials/material.ts

@@ -857,8 +857,9 @@ export class Material implements IAnimatable {
      * @param world defines the world transformation matrix
      * @param mesh defines the mesh containing the submesh
      * @param subMesh defines the submesh to bind the material to
+     * @param effectOverride - If provided, use this effect instead of the submesh effect
      */
-    public bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void {
+    public bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh, effectOverride?: Nullable<Effect>): void {
     }
 
     /**

+ 42 - 36
src/Materials/shaderMaterial.ts

@@ -614,27 +614,29 @@ export class ShaderMaterial extends Material {
     /**
      * Binds the world matrix to the material
      * @param world defines the world transformation matrix
+     * @param effectOverride - If provided, use this effect instead of internal effect
      */
-    public bindOnlyWorldMatrix(world: Matrix): void {
+    public bindOnlyWorldMatrix(world: Matrix, effectOverride?: Nullable<Effect>): void {
         var scene = this.getScene();
 
-        if (!this._effect) {
+        const effect = effectOverride ?? this._effect;
+
+        if (!effect) {
             return;
         }
 
         if (this._options.uniforms.indexOf("world") !== -1) {
-            this._effect.setMatrix("world", world);
+            effect.setMatrix("world", world);
         }
 
         if (this._options.uniforms.indexOf("worldView") !== -1) {
             world.multiplyToRef(scene.getViewMatrix(), this._cachedWorldViewMatrix);
-            this._effect.setMatrix("worldView", this._cachedWorldViewMatrix);
+            effect.setMatrix("worldView", this._cachedWorldViewMatrix);
         }
 
         if (this._options.uniforms.indexOf("worldViewProjection") !== -1) {
             world.multiplyToRef(scene.getTransformMatrix(), this._cachedWorldViewProjectionMatrix);
-            this._effect.setMatrix("worldViewProjection", this._cachedWorldViewProjectionMatrix);
-
+            effect.setMatrix("worldViewProjection", this._cachedWorldViewProjectionMatrix);
         }
     }
 
@@ -643,138 +645,142 @@ export class ShaderMaterial extends Material {
      * @param world defines the world transformation matrix
      * @param mesh defines the mesh containing the submesh
      * @param subMesh defines the submesh to bind the material to
+     * @param effectOverride - If provided, use this effect instead of internal effect
      */
-    public bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void {
-        this.bind(world, mesh);
+    public bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh, effectOverride?: Nullable<Effect>): void {
+        this.bind(world, mesh, effectOverride);
     }
 
     /**
      * Binds the material to the mesh
      * @param world defines the world transformation matrix
      * @param mesh defines the mesh to bind the material to
+     * @param effectOverride - If provided, use this effect instead of internal effect
      */
-    public bind(world: Matrix, mesh?: Mesh): void {
+    public bind(world: Matrix, mesh?: Mesh, effectOverride?: Nullable<Effect>): void {
         // Std values
-        this.bindOnlyWorldMatrix(world);
+        this.bindOnlyWorldMatrix(world, effectOverride);
+
+        const effect = effectOverride ?? this._effect;
 
-        if (this._effect && this.getScene().getCachedMaterial() !== this) {
+        if (effect && this.getScene().getCachedMaterial() !== this) {
             if (this._options.uniforms.indexOf("view") !== -1) {
-                this._effect.setMatrix("view", this.getScene().getViewMatrix());
+                effect.setMatrix("view", this.getScene().getViewMatrix());
             }
 
             if (this._options.uniforms.indexOf("projection") !== -1) {
-                this._effect.setMatrix("projection", this.getScene().getProjectionMatrix());
+                effect.setMatrix("projection", this.getScene().getProjectionMatrix());
             }
 
             if (this._options.uniforms.indexOf("viewProjection") !== -1) {
-                this._effect.setMatrix("viewProjection", this.getScene().getTransformMatrix());
+                effect.setMatrix("viewProjection", this.getScene().getTransformMatrix());
                 if (this._multiview) {
-                    this._effect.setMatrix("viewProjectionR", this.getScene()._transformMatrixR);
+                    effect.setMatrix("viewProjectionR", this.getScene()._transformMatrixR);
                 }
             }
 
             if (this.getScene().activeCamera && this._options.uniforms.indexOf("cameraPosition") !== -1) {
-                this._effect.setVector3("cameraPosition", this.getScene().activeCamera!.globalPosition);
+                effect.setVector3("cameraPosition", this.getScene().activeCamera!.globalPosition);
             }
 
             // Bones
-            MaterialHelper.BindBonesParameters(mesh, this._effect);
+            MaterialHelper.BindBonesParameters(mesh, effect);
 
             var name: string;
             // Texture
             for (name in this._textures) {
-                this._effect.setTexture(name, this._textures[name]);
+                effect.setTexture(name, this._textures[name]);
             }
 
             // Texture arrays
             for (name in this._textureArrays) {
-                this._effect.setTextureArray(name, this._textureArrays[name]);
+                effect.setTextureArray(name, this._textureArrays[name]);
             }
 
             // Int
             for (name in this._ints) {
-                this._effect.setInt(name, this._ints[name]);
+                effect.setInt(name, this._ints[name]);
             }
 
             // Float
             for (name in this._floats) {
-                this._effect.setFloat(name, this._floats[name]);
+                effect.setFloat(name, this._floats[name]);
             }
 
             // Floats
             for (name in this._floatsArrays) {
-                this._effect.setArray(name, this._floatsArrays[name]);
+                effect.setArray(name, this._floatsArrays[name]);
             }
 
             // Color3
             for (name in this._colors3) {
-                this._effect.setColor3(name, this._colors3[name]);
+                effect.setColor3(name, this._colors3[name]);
             }
 
             // Color3Array
             for (name in this._colors3Arrays) {
-                this._effect.setArray3(name, this._colors3Arrays[name]);
+                effect.setArray3(name, this._colors3Arrays[name]);
             }
 
             // Color4
             for (name in this._colors4) {
                 var color = this._colors4[name];
-                this._effect.setFloat4(name, color.r, color.g, color.b, color.a);
+                effect.setFloat4(name, color.r, color.g, color.b, color.a);
             }
 
             // Color4Array
             for (name in this._colors4Arrays) {
-                this._effect.setArray4(name, this._colors4Arrays[name]);
+                effect.setArray4(name, this._colors4Arrays[name]);
             }
 
             // Vector2
             for (name in this._vectors2) {
-                this._effect.setVector2(name, this._vectors2[name]);
+                effect.setVector2(name, this._vectors2[name]);
             }
 
             // Vector3
             for (name in this._vectors3) {
-                this._effect.setVector3(name, this._vectors3[name]);
+                effect.setVector3(name, this._vectors3[name]);
             }
 
             // Vector4
             for (name in this._vectors4) {
-                this._effect.setVector4(name, this._vectors4[name]);
+                effect.setVector4(name, this._vectors4[name]);
             }
 
             // Matrix
             for (name in this._matrices) {
-                this._effect.setMatrix(name, this._matrices[name]);
+                effect.setMatrix(name, this._matrices[name]);
             }
 
             // MatrixArray
             for (name in this._matrixArrays) {
-                this._effect.setMatrices(name, this._matrixArrays[name]);
+                effect.setMatrices(name, this._matrixArrays[name]);
             }
 
             // Matrix 3x3
             for (name in this._matrices3x3) {
-                this._effect.setMatrix3x3(name, this._matrices3x3[name]);
+                effect.setMatrix3x3(name, this._matrices3x3[name]);
             }
 
             // Matrix 2x2
             for (name in this._matrices2x2) {
-                this._effect.setMatrix2x2(name, this._matrices2x2[name]);
+                effect.setMatrix2x2(name, this._matrices2x2[name]);
             }
 
             // Vector2Array
             for (name in this._vectors2Arrays) {
-                this._effect.setArray2(name, this._vectors2Arrays[name]);
+                effect.setArray2(name, this._vectors2Arrays[name]);
             }
 
             // Vector3Array
             for (name in this._vectors3Arrays) {
-                this._effect.setArray3(name, this._vectors3Arrays[name]);
+                effect.setArray3(name, this._vectors3Arrays[name]);
             }
 
             // Vector4Array
             for (name in this._vectors4Arrays) {
-                this._effect.setArray4(name, this._vectors4Arrays[name]);
+                effect.setArray4(name, this._vectors4Arrays[name]);
             }
         }
 

+ 3 - 2
src/Materials/standardMaterial.ts

@@ -1282,8 +1282,9 @@ export class StandardMaterial extends PushMaterial {
      * @param world defines the world transformation matrix
      * @param mesh defines the mesh containing the submesh
      * @param subMesh defines the submesh to bind the material to
+     * @param effectOverride - If provided, use this effect instead of the submesh effect
      */
-    public bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void {
+    public bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh, effectOverride?: Nullable<Effect>): void {
         var scene = this.getScene();
 
         var defines = <StandardMaterialDefines>subMesh._materialDefines;
@@ -1291,7 +1292,7 @@ export class StandardMaterial extends PushMaterial {
             return;
         }
 
-        var effect = subMesh.effect;
+        var effect = effectOverride ?? subMesh.effect;
         if (!effect) {
             return;
         }