Selaa lähdekoodia

InstancesBlock step1

David Catuhe 6 vuotta sitten
vanhempi
commit
4b5648ce9d

+ 3 - 4
src/Materials/Node/Blocks/Dual/fogBlock.ts

@@ -6,10 +6,9 @@ import { NodeMaterialBlockTargets } from '../../nodeMaterialBlockTargets';
 import { Mesh } from '../../../../Meshes/mesh';
 import { Effect } from '../../../effect';
 import { NodeMaterialConnectionPoint } from '../../nodeMaterialBlockConnectionPoint';
-import { MaterialDefines } from '../../../materialDefines';
 import { AbstractMesh } from '../../../../Meshes/abstractMesh';
 import { MaterialHelper } from '../../../materialHelper';
-import { NodeMaterial } from '../../nodeMaterial';
+import { NodeMaterial, NodeMaterialDefines } from '../../nodeMaterial';
 
 /**
  * Block used to add support for scene fog
@@ -85,9 +84,9 @@ export class FogBlock extends NodeMaterialBlock {
         return this._inputs[4];
     }
 
-    public prepareDefines(mesh: AbstractMesh, nodeMaterial: NodeMaterial, defines: MaterialDefines) {
+    public prepareDefines(mesh: AbstractMesh, nodeMaterial: NodeMaterial, defines: NodeMaterialDefines) {
         let scene = mesh.getScene();
-        defines["FOG"] = nodeMaterial.fogEnabled && MaterialHelper.GetFogState(mesh, scene);
+        defines.setValue("FOG", nodeMaterial.fogEnabled && MaterialHelper.GetFogState(mesh, scene));
     }
 
     public bind(effect: Effect, mesh?: Mesh) {

+ 26 - 12
src/Materials/Node/Blocks/Fragment/textureBlock.ts

@@ -5,8 +5,7 @@ import { NodeMaterialBlockTargets } from '../../nodeMaterialBlockTargets';
 import { NodeMaterialConnectionPoint } from '../../nodeMaterialBlockConnectionPoint';
 import { BaseTexture } from '../../../Textures/baseTexture';
 import { AbstractMesh } from '../../../../Meshes/abstractMesh';
-import { NodeMaterial } from '../../nodeMaterial';
-import { MaterialDefines } from '../../../materialDefines';
+import { NodeMaterial, NodeMaterialDefines } from '../../nodeMaterial';
 
 /**
  * Block used to read a texture from a sampler
@@ -101,17 +100,24 @@ export class TextureBlock extends NodeMaterialBlock {
         }
     }
 
-    public prepareDefines(mesh: AbstractMesh, nodeMaterial: NodeMaterial, defines: MaterialDefines) {
+    public prepareDefines(mesh: AbstractMesh, nodeMaterial: NodeMaterial, defines: NodeMaterialDefines) {
         if (!this.texture.value || !this.texture.value.getTextureMatrix) {
             return;
         }
 
+        let uvInput = this.uv;
+        let textureTransform = this.textureTransform;
+        let isTextureTransformConnected = textureTransform.connectedPoint != null || textureTransform.isUniform;
+
         const texture = this.texture.value as BaseTexture;
+        let mainUVName = ("vMain" + uvInput.associatedVariableName).toUpperCase();
 
-        if (!texture.getTextureMatrix().isIdentityAs3x2()) {
-            defines[this._defineName] = true;
+        if (isTextureTransformConnected && !texture.getTextureMatrix().isIdentityAs3x2()) {
+            defines.setValue(this._defineName, true);
+            defines.setValue(mainUVName, false);
         } else {
-            defines[this._defineName] = false;
+            defines.setValue(this._defineName, false);
+            defines.setValue(mainUVName, true);
         }
     }
 
@@ -122,22 +128,24 @@ export class TextureBlock extends NodeMaterialBlock {
         let isTextureTransformConnected = textureTransform.connectedPoint != null || textureTransform.isUniform;
 
         // Inject code in vertex
+        this._defineName = state._getFreeDefineName("UVTRANSFORM");
+        let mainUVName = "vMain" + uvInput.associatedVariableName;
+
         transformedUV.associatedVariableName = state._getFreeVariableName(transformedUV.name);
-        state._emitVaryings(transformedUV, true);
+        state._emitVaryings(transformedUV, this._defineName, true);
+        state._emitVaryings(transformedUV, mainUVName.toUpperCase(), true, false, mainUVName);
 
         textureTransform.associatedVariableName = state._getFreeVariableName(textureTransform.name);
-        state._emitUniformOrAttributes(textureTransform);
-
-        this._defineName = state._getFreeDefineName("UVTRANSFORM");
+        state._emitUniformOrAttributes(textureTransform, this._defineName);
 
         if (isTextureTransformConnected) {
             state.compilationString += `#ifdef ${this._defineName}\r\n`;
             state.compilationString += `${transformedUV.associatedVariableName} = vec2(${textureTransform.associatedVariableName} * vec4(${uvInput.associatedVariableName}, 1.0, 0.0));\r\n`;
             state.compilationString += `#else\r\n`;
-            state.compilationString += `${transformedUV.associatedVariableName} = ${uvInput.associatedVariableName};\r\n`;
+            state.compilationString += `${mainUVName} = ${uvInput.associatedVariableName};\r\n`;
             state.compilationString += `#endif\r\n`;
         } else {
-            state.compilationString += `${transformedUV.associatedVariableName} = ${uvInput.associatedVariableName};\r\n`;
+            state.compilationString += `${mainUVName} = ${uvInput.associatedVariableName};\r\n`;
         }
     }
 
@@ -150,6 +158,7 @@ export class TextureBlock extends NodeMaterialBlock {
         // Fragment
         state.sharedData.blocksWithDefines.push(this);
 
+        let uvInput = this.uv;
         let transformedUV = this.transformedUV;
         let textureInfo = this.textureInfo;
         let samplerInput = this.texture;
@@ -157,7 +166,12 @@ export class TextureBlock extends NodeMaterialBlock {
         let isTextureInfoConnected = textureInfo.connectedPoint != null || textureInfo.isUniform;
         const complement = isTextureInfoConnected ? ` * ${textureInfo.associatedVariableName}.y` : "";
 
+
+        state.compilationString += `#ifdef ${this._defineName}\r\n`;
         state.compilationString += `vec4 ${output.associatedVariableName} = texture2D(${samplerInput.associatedVariableName}, ${transformedUV.associatedVariableName})${complement};\r\n`;
+        state.compilationString += `#else\r\n`;
+        state.compilationString += `vec4 ${output.associatedVariableName} = texture2D(${samplerInput.associatedVariableName}, ${"vMain" + uvInput.associatedVariableName})${complement};\r\n`;
+        state.compilationString += `#endif\r\n`;
 
 
         return this;

+ 2 - 3
src/Materials/Node/Blocks/Vertex/bonesBlock.ts

@@ -8,8 +8,7 @@ import { Mesh } from '../../../../Meshes/mesh';
 import { Effect, EffectFallbacks } from '../../../effect';
 import { MaterialHelper } from '../../../materialHelper';
 import { NodeMaterialConnectionPoint } from '../../nodeMaterialBlockConnectionPoint';
-import { NodeMaterial } from '../../nodeMaterial';
-import { MaterialDefines } from '../../../materialDefines';
+import { NodeMaterial, NodeMaterialDefines } from '../../nodeMaterial';
 
 /**
  * Block used to add support for vertex skinning (bones)
@@ -102,7 +101,7 @@ export class BonesBlock extends NodeMaterialBlock {
         MaterialHelper.BindBonesParameters(mesh, effect);
     }
 
-    public prepareDefines(mesh: AbstractMesh, nodeMaterial: NodeMaterial, defines: MaterialDefines) {
+    public prepareDefines(mesh: AbstractMesh, nodeMaterial: NodeMaterial, defines: NodeMaterialDefines) {
         if (!defines._areAttributesDirty) {
             return;
         }

+ 2 - 1
src/Materials/Node/Blocks/Vertex/index.ts

@@ -1,2 +1,3 @@
 export * from "./vertexOutputBlock";
-export * from "./bonesBlock";
+export * from "./bonesBlock";
+export * from "./instancesBlock";

+ 65 - 0
src/Materials/Node/Blocks/Vertex/instancesBlock.ts

@@ -0,0 +1,65 @@
+import { NodeMaterialBlock } from '../../nodeMaterialBlock';
+import { NodeMaterialBlockTargets } from '../../nodeMaterialBlockTargets';
+import { NodeMaterialBlockConnectionPointTypes } from '../../nodeMaterialBlockConnectionPointTypes';
+import { NodeMaterialConnectionPoint } from '../../nodeMaterialBlockConnectionPoint';
+
+/**
+ * Block used to add support for instances
+ * @see https://doc.babylonjs.com/how_to/how_to_use_instances
+ */
+export class InstancesBlock extends NodeMaterialBlock {
+    /**
+     * Creates a new InstancesBlock
+     * @param name defines the block name
+     */
+    public constructor(name: string) {
+        super(name, NodeMaterialBlockTargets.Vertex);
+
+        this.registerInput("world0", NodeMaterialBlockConnectionPointTypes.Vector4);
+        this.registerInput("world1", NodeMaterialBlockConnectionPointTypes.Vector4);
+        this.registerInput("world2", NodeMaterialBlockConnectionPointTypes.Vector4);
+        this.registerInput("world3", NodeMaterialBlockConnectionPointTypes.Vector4);
+
+        // Auto-configuration
+        this.world0.setAsAttribute();
+        this.world1.setAsAttribute();
+        this.world2.setAsAttribute();
+        this.world3.setAsAttribute();
+    }
+
+    /**
+     * Gets the current class name
+     * @returns the class name
+     */
+    public getClassName() {
+        return "InstancesBlock";
+    }
+
+    /**
+     * Gets the first world row input component
+     */
+    public get world0(): NodeMaterialConnectionPoint {
+        return this._inputs[0];
+    }
+
+    /**
+     * Gets the second world row input component
+     */
+    public get world1(): NodeMaterialConnectionPoint {
+        return this._inputs[1];
+    }
+
+    /**
+     * Gets the third world row input component
+     */
+    public get world2(): NodeMaterialConnectionPoint {
+        return this._inputs[2];
+    }
+
+    /**
+     * Gets the forth world row input component
+     */
+    public get world3(): NodeMaterialConnectionPoint {
+        return this._inputs[3];
+    }
+}

+ 0 - 1
src/Materials/Node/Optimizers/index.ts

@@ -1,2 +1 @@
 export * from "./nodeMaterialOptimizer";
-export * from "./uvVaryingOptimizer";

+ 0 - 11
src/Materials/Node/Optimizers/uvVaryingOptimizer.ts

@@ -1,11 +0,0 @@
-import { NodeMaterialOptimizer } from './nodeMaterialOptimizer';
-import { NodeMaterialBlock } from '../nodeMaterialBlock';
-
-/**
- * Optimizer that will try to reuse uv varyings across the node graph
- */
-export class UVVaryingOptimizer extends NodeMaterialOptimizer {
-    public optimize(vertexOutputNodes: NodeMaterialBlock[], fragmentOutputNodes: NodeMaterialBlock[]) {
-
-    }
-}

+ 10 - 10
src/Materials/Node/nodeMaterial.ts

@@ -16,15 +16,10 @@ import { NodeMaterialBuildStateSharedData } from './NodeMaterialBuildStateShared
 import { SubMesh } from '../../Meshes/subMesh';
 import { MaterialDefines } from '../../Materials/materialDefines';
 import { NodeMaterialOptimizer } from './Optimizers/nodeMaterialOptimizer';
-import { UVVaryingOptimizer } from './Optimizers/uvVaryingOptimizer';
 
 /** @hidden */
 export class NodeMaterialDefines extends MaterialDefines {
-
-    /** MISC */
-    public FOG = false;
-
-    /** Bones */
+    /** BONES */
     public NUM_BONE_INFLUENCERS = 0;
     public BonesPerMesh = 0;
     public BONETEXTURE = false;
@@ -33,6 +28,14 @@ export class NodeMaterialDefines extends MaterialDefines {
         super();
         this.rebuild();
     }
+
+    public setValue(name: string, value: boolean) {
+        if (this[name] === undefined) {
+            this._keys.push(name);
+        }
+
+        this[name] = value;
+    }
 }
 
 /**
@@ -97,9 +100,6 @@ export class NodeMaterial extends PushMaterial {
             emitComments: false,
             ...options
         };
-
-        // Registers some optimizers
-        this.registerOptimizer(new UVVaryingOptimizer());
     }
 
     /**
@@ -388,7 +388,7 @@ export class NodeMaterial extends PushMaterial {
         }
 
         var scene = this.getScene();
-        var defines = subMesh._materialDefines;
+        var defines = <NodeMaterialDefines>subMesh._materialDefines;
         if (!this.checkReadyOnEveryCall && subMesh.effect) {
             if (defines._renderId === scene.getRenderId()) {
                 return true;

+ 6 - 4
src/Materials/Node/nodeMaterialBlock.ts

@@ -6,8 +6,7 @@ import { NodeMaterialBlockTargets } from './nodeMaterialBlockTargets';
 import { Effect, EffectFallbacks } from '../effect';
 import { AbstractMesh } from '../../Meshes/abstractMesh';
 import { Mesh } from '../../Meshes/mesh';
-import { MaterialDefines } from '../materialDefines';
-import { NodeMaterial } from './nodeMaterial';
+import { NodeMaterial, NodeMaterialDefines } from './nodeMaterial';
 
 /**
  * Defines a block that can be used inside a node based material
@@ -283,7 +282,7 @@ export class NodeMaterialBlock {
      * @param nodeMaterial defines the node material requesting the update
      * @param defines defines the material defines to update\
      */
-    public prepareDefines(mesh: AbstractMesh, nodeMaterial: NodeMaterial, defines: MaterialDefines) {
+    public prepareDefines(mesh: AbstractMesh, nodeMaterial: NodeMaterial, defines: NodeMaterialDefines) {
         // Do nothing
     }
 
@@ -331,7 +330,10 @@ export class NodeMaterialBlock {
 
         /** Prepare outputs */
         for (var output of this._outputs) {
-            if ((output.target & this.target!) === 0) {//} || output.associatedVariableName) {
+            if ((output.target & this.target!) === 0) {
+                continue;
+            }
+            if ((output.target & state.target!) === 0) {
                 continue;
             }
             output.associatedVariableName = state._getFreeVariableName(output.name);

+ 34 - 8
src/Materials/Node/nodeMaterialBuildState.ts

@@ -215,23 +215,37 @@ export class NodeMaterialBuildState {
     }
 
     /** @hidden */
-    public _emitVaryings(point: NodeMaterialConnectionPoint, force = false, fromFragment = false) {
+    public _emitVaryings(point: NodeMaterialConnectionPoint, define: string = "", force = false, fromFragment = false, replacementName: string = "") {
+        let name = replacementName || point.associatedVariableName;
         if (point.isVarying || force) {
-            if (this.sharedData.varyings.indexOf(point.associatedVariableName) !== -1) {
+            if (this.sharedData.varyings.indexOf(name) !== -1) {
                 return;
             }
 
-            this.sharedData.varyings.push(point.associatedVariableName);
-            this.sharedData.varyingDeclaration += `varying ${this._getGLType(point.type)} ${point.associatedVariableName};\r\n`;
+            this.sharedData.varyings.push(name);
+
+            if (define) {
+                this.sharedData.varyingDeclaration += `#ifdef ${define}\r\n`;
+            }
+            this.sharedData.varyingDeclaration += `varying ${this._getGLType(point.type)} ${name};\r\n`;
+            if (define) {
+                this.sharedData.varyingDeclaration += `#endif\r\n`;
+            }
 
             if (this.target === NodeMaterialBlockTargets.Vertex && fromFragment) {
-                this._varyingTransfer += `${point.associatedVariableName} = ${point.name};\r\n`;
+                if (define) {
+                    this.sharedData.varyingDeclaration += `#ifdef ${define}\r\n`;
+                }
+                this._varyingTransfer += `${name} = ${point.name};\r\n`;
+                if (define) {
+                    this.sharedData.varyingDeclaration += `#endif\r\n`;
+                }
             }
         }
     }
 
     /** @hidden */
-    public _emitUniformOrAttributes(point: NodeMaterialConnectionPoint) {
+    public _emitUniformOrAttributes(point: NodeMaterialConnectionPoint, define?: string) {
         // Samplers
         if (point.type === NodeMaterialBlockConnectionPointTypes.Texture) {
             point.name = this._getFreeVariableName(point.name);
@@ -242,7 +256,13 @@ export class NodeMaterialBuildState {
             }
 
             this.samplers.push(point.name);
+            if (define) {
+                this._uniformDeclaration += `#ifdef ${define}\r\n`;
+            }
             this._samplerDeclaration += `uniform ${this._getGLType(point.type)} ${point.name};\r\n`;
+            if (define) {
+                this._uniformDeclaration += `#endif\r\n`;
+            }
             this.sharedData.uniformConnectionPoints.push(point);
             return;
         }
@@ -262,7 +282,13 @@ export class NodeMaterialBuildState {
             }
 
             this.uniforms.push(point.associatedVariableName);
+            if (define) {
+                this._uniformDeclaration += `#ifdef ${define}\r\n`;
+            }
             this._uniformDeclaration += `uniform ${this._getGLType(point.type)} ${point.associatedVariableName};\r\n`;
+            if (define) {
+                this._uniformDeclaration += `#endif\r\n`;
+            }
 
             // well known
             let hints = this.sharedData.hints;
@@ -289,8 +315,8 @@ export class NodeMaterialBuildState {
                     return;
                 }
                 point.associatedVariableName = this._getFreeVariableName(point.name);
-                this._emitVaryings(point, true);
-                this._vertexState._emitVaryings(point, true, true);
+                this._emitVaryings(point, "", true);
+                this._vertexState._emitVaryings(point, "", true, true);
                 return;
             }
 

+ 2 - 1
src/Materials/materialDefines.ts

@@ -2,7 +2,8 @@
  * Manages the defines for the Material
  */
 export class MaterialDefines {
-    private _keys: string[];
+    /** @hidden */
+    protected _keys: string[];
     private _isDirty = true;
     /** @hidden */
     public _renderId: number;