Browse Source

Make it work for the ShaderMaterial class

Popov72 5 năm trước cách đây
mục cha
commit
186ad7d796

+ 1 - 1
materialsLibrary/src/custom/customMaterial.ts

@@ -106,7 +106,7 @@ export class CustomMaterial extends StandardMaterial {
         return arr;
     }
 
-    public Builder(shaderName: string, uniforms: string[], uniformBuffers: string[], samplers: string[], defines: MaterialDefines, attributes?: string[]): string {
+    public Builder(shaderName: string, uniforms: string[], uniformBuffers: string[], samplers: string[], defines: MaterialDefines | string[], attributes?: string[]): string {
 
         if (attributes && this._customAttributes && this._customAttributes.length > 0) {
             attributes.push(...this._customAttributes);

+ 1 - 1
materialsLibrary/src/custom/pbrCustomMaterial.ts

@@ -102,7 +102,7 @@ export class PBRCustomMaterial extends PBRMaterial {
         return arr;
     }
 
-    public Builder(shaderName: string, uniforms: string[], uniformBuffers: string[], samplers: string[], defines: MaterialDefines, attributes?: string[]): string {
+    public Builder(shaderName: string, uniforms: string[], uniformBuffers: string[], samplers: string[], defines: MaterialDefines | string[], attributes?: string[]): string {
 
         if (attributes && this._customAttributes && this._customAttributes.length > 0) {
             attributes.push(...this._customAttributes);

+ 16 - 1
src/Lights/Shadows/shadowGenerator.ts

@@ -1018,6 +1018,17 @@ export class ShadowGenerator implements IShadowGenerator {
     }
 
     protected _bindCustomEffectForRenderSubMeshForShadowMap(subMesh: SubMesh, effect: Effect): void {
+        if (effect.getUniform("viewProjection")) {
+            effect.setMatrix("viewProjection", this.getTransformMatrix());
+        }
+
+        if (effect.getUniform("view")) {
+            effect.setMatrix("view", this._viewMatrix);
+        }
+
+        if (effect.getUniform("projection")) {
+            effect.setMatrix("projection", this._projectionMatrix);
+        }
     }
 
     protected _renderSubMeshForShadowMap(subMesh: SubMesh): void {
@@ -1052,7 +1063,11 @@ export class ShadowGenerator implements IShadowGenerator {
                 subMesh.switchToShadowDepthEffect();
             }
 
-            const effect = customShadowDepthMat ? subMesh.effect! : this._effect;
+            let effect = customShadowDepthMat ? subMesh.effect! : this._effect;
+
+            if (!effect && customShadowDepthMat) {
+                effect = customShadowDepthMat.getEffect()!; // ShaderMaterial case where the effect is not stored on the sub mesh
+            }
 
             engine.enableEffect(effect);
 

+ 22 - 12
src/Materials/material.shadowDepth.ts

@@ -20,7 +20,7 @@ declare module "../Materials/material" {
         /** @hidden */
         _customShadowDepthMaterial: Nullable<Material>;
         /** @hidden */
-        _customShadowDepthOldNameResolve: Nullable<(shaderName: string, uniforms: string[], uniformBuffers: string[], samplers: string[], defines: MaterialDefines, attributes?: string[]) => string>;
+        _customShadowDepthOldNameResolve: Nullable<(shaderName: string, uniforms: string[], uniformBuffers: string[], samplers: string[], defines: MaterialDefines | string[], attributes?: string[]) => string>;
         /** @hidden */
         _setupCustomShadowDepthMaterial: () => void;
         /** @hidden */
@@ -59,6 +59,10 @@ Object.defineProperty(Material.prototype, "customShadowDepthMaterial", {
     configurable: true
 });
 
+function isMaterialDefines(defines:  MaterialDefines | string[]): defines is MaterialDefines {
+    return (defines as any)._keys !== undefined;
+}
+
 Material.prototype._setupCustomShadowDepthMaterial = function() {
     const mat = this._customShadowDepthMaterial;
 
@@ -68,19 +72,25 @@ Material.prototype._setupCustomShadowDepthMaterial = function() {
 
     this._customShadowDepthOldNameResolve = mat.customShaderNameResolve?.bind(mat);
 
-    mat.customShaderNameResolve = (shaderName: string, uniforms: string[], uniformBuffers: string[], samplers: string[], defines: MaterialDefines, attributes?: string[]) => {
+    mat.customShaderNameResolve = (shaderName: string, uniforms: string[], uniformBuffers: string[], samplers: string[], defines: MaterialDefines | string[], attributes?: string[]) => {
         if (this._customShadowDepthDefines) {
-            for (let i = 0; i < this._customShadowDepthDefines.length; ++i) {
-                const define = this._customShadowDepthDefines[i],
-                        offset = 8,
-                        spacePos = define.indexOf(" ", offset),
-                        name = define.substring(offset, spacePos !== -1 ? spacePos : define.length),
-                        value = spacePos === -1 ? true : define.substring(spacePos + 1);
-
-                if (defines[name] === undefined) {
-                    (defines as any)._keys.push(name);
+            if (!isMaterialDefines(defines)) {
+                for (let i = 0; i < this._customShadowDepthDefines.length; ++i) {
+                    defines.push(this._customShadowDepthDefines[i]);
+                }
+            } else {
+                for (let i = 0; i < this._customShadowDepthDefines.length; ++i) {
+                    const define = this._customShadowDepthDefines[i],
+                            offset = 8,
+                            spacePos = define.indexOf(" ", offset),
+                            name = define.substring(offset, spacePos !== -1 ? spacePos : define.length),
+                            value = spacePos === -1 ? true : define.substring(spacePos + 1);
+
+                    if (defines[name] === undefined) {
+                        (defines as any)._keys.push(name);
+                    }
+                    defines[name] = value;
                 }
-                defines[name] = value;
             }
         }
 

+ 1 - 1
src/Materials/material.ts

@@ -146,7 +146,7 @@ export class Material implements IAnimatable {
     /**
      * Custom callback helping to override the default shader used in the material.
      */
-    public customShaderNameResolve: (shaderName: string, uniforms: string[], uniformBuffers: string[], samplers: string[], defines: MaterialDefines, attributes?: string[]) => string;
+    public customShaderNameResolve: (shaderName: string, uniforms: string[], uniformBuffers: string[], samplers: string[], defines: MaterialDefines | string[], attributes?: string[]) => string;
 
     /**
      * The ID of the material

+ 27 - 5
src/Materials/shaderMaterial.ts

@@ -3,7 +3,7 @@ import { Scene } from "../scene";
 import { Matrix, Vector3, Vector2, Vector4 } from "../Maths/math.vector";
 import { AbstractMesh } from "../Meshes/abstractMesh";
 import { Mesh } from "../Meshes/mesh";
-import { BaseSubMesh } from "../Meshes/subMesh";
+import { SubMesh, BaseSubMesh } from "../Meshes/subMesh";
 import { VertexBuffer } from "../Meshes/buffer";
 import { BaseTexture } from "../Materials/Textures/baseTexture";
 import { Texture } from "../Materials/Textures/texture";
@@ -571,14 +571,26 @@ export class ShaderMaterial extends Material {
             defines.push("#define ALPHATEST");
         }
 
+        let shaderName = this._shaderPath,
+            uniforms = this._options.uniforms,
+            uniformBuffers = this._options.uniformBuffers,
+            samplers = this._options.samplers;
+
+        if (this.customShaderNameResolve) {
+            uniforms = uniforms.slice();
+            uniformBuffers = uniformBuffers.slice();
+            samplers = samplers.slice();
+            shaderName = this.customShaderNameResolve(shaderName, uniforms, uniformBuffers, samplers, defines, attribs);
+        }
+
         var previousEffect = this._effect;
         var join = defines.join("\n");
 
-        this._effect = engine.createEffect(this._shaderPath, <IEffectCreationOptions>{
+        this._effect = engine.createEffect(shaderName, <IEffectCreationOptions>{
             attributes: attribs,
-            uniformsNames: this._options.uniforms,
-            uniformBuffersNames: this._options.uniformBuffers,
-            samplers: this._options.samplers,
+            uniformsNames: uniforms,
+            uniformBuffersNames: uniformBuffers,
+            samplers: samplers,
             defines: join,
             fallbacks: fallbacks,
             onCompiled: this.onCompiled,
@@ -627,6 +639,16 @@ export class ShaderMaterial extends Material {
     }
 
     /**
+     * Binds the submesh to this material by preparing the effect and shader to draw
+     * @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
+     */
+    public bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void {
+        this.bind(world, mesh);
+    }
+
+    /**
      * Binds the material to the mesh
      * @param world defines the world transformation matrix
      * @param mesh defines the mesh to bind the material to