浏览代码

- instancesBlock
- autoConfigure

David Catuhe 6 年之前
父节点
当前提交
9686890c3b

+ 13 - 6
src/Materials/Node/Blocks/Dual/fogBlock.ts

@@ -33,12 +33,6 @@ export class FogBlock extends NodeMaterialBlock {
         this.registerInput("fogParameters", NodeMaterialBlockConnectionPointTypes.Vector4, false, NodeMaterialBlockTargets.Fragment);
 
         this.registerOutput("output", NodeMaterialBlockConnectionPointTypes.Color3, NodeMaterialBlockTargets.Fragment);
-
-        // Auto configuration
-        this._inputs[1].setAsWellKnownValue(NodeMaterialWellKnownValues.View);
-        this._inputs[3].setAsWellKnownValue(NodeMaterialWellKnownValues.FogColor);
-        this._inputs[4].setAsWellKnownValue(NodeMaterialWellKnownValues.FogParameters);
-        this._outputs[0].isVarying = true;
     }
 
     /**
@@ -84,6 +78,19 @@ export class FogBlock extends NodeMaterialBlock {
         return this._inputs[4];
     }
 
+    public autoConfigure() {
+        if (!this.view.connectedPoint) {
+            this.view.setAsWellKnownValue(NodeMaterialWellKnownValues.View);
+        }
+        if (!this.fogColor.connectedPoint) {
+            this.fogColor.setAsWellKnownValue(NodeMaterialWellKnownValues.FogColor);
+        }
+        if (!this.fogParameters.connectedPoint) {
+            this.fogParameters.setAsWellKnownValue(NodeMaterialWellKnownValues.FogParameters);
+        }
+        this._outputs[0].isVarying = true;
+    }
+
     public prepareDefines(mesh: AbstractMesh, nodeMaterial: NodeMaterial, defines: NodeMaterialDefines) {
         let scene = mesh.getScene();
         defines.setValue("FOG", nodeMaterial.fogEnabled && MaterialHelper.GetFogState(mesh, scene));

+ 7 - 6
src/Materials/Node/Blocks/Fragment/textureBlock.ts

@@ -38,10 +38,6 @@ export class TextureBlock extends NodeMaterialBlock {
         this.registerInput("textureTransform", NodeMaterialBlockConnectionPointTypes.Matrix, true, NodeMaterialBlockTargets.Vertex);
 
         this.registerOutput("color", NodeMaterialBlockConnectionPointTypes.Color4);
-
-        // Auto configuration
-        this._inputs[0].setAsAttribute();
-        this._inputs[0].connectTo(this._inputs[2]);
     }
 
     /**
@@ -87,6 +83,13 @@ export class TextureBlock extends NodeMaterialBlock {
         return this._inputs[4];
     }
 
+    public autoConfigure() {
+        if (!this.uv.connectedPoint) {
+            this.uv.setAsAttribute();
+            this.uv.connectTo(this.transformedUV);
+        }
+    }
+
     public initialize(state: NodeMaterialBuildState) {
         if (this.texture.value && this.texture.value.getTextureMatrix) {
             const texture = this.texture.value as BaseTexture;
@@ -166,14 +169,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;
     }
 }

+ 18 - 7
src/Materials/Node/Blocks/Vertex/bonesBlock.ts

@@ -28,13 +28,6 @@ export class BonesBlock extends NodeMaterialBlock {
         this.registerInput("world", NodeMaterialBlockConnectionPointTypes.Matrix);
 
         this.registerOutput("output", NodeMaterialBlockConnectionPointTypes.Matrix);
-
-        // Auto configuration
-        this._inputs[0].setAsAttribute();
-        this._inputs[1].setAsAttribute();
-        this._inputs[2].setAsAttribute();
-        this._inputs[3].setAsAttribute();
-        this._inputs[4].setAsWellKnownValue(NodeMaterialWellKnownValues.World);
     }
 
     /**
@@ -91,6 +84,24 @@ export class BonesBlock extends NodeMaterialBlock {
         return this._inputs[4];
     }
 
+    public autoConfigure() {
+        if (!this.matricesIndices.connectedPoint) {
+            this.matricesIndices.setAsAttribute();
+        }
+        if (!this.matricesWeights.connectedPoint) {
+            this.matricesWeights.setAsAttribute();
+        }
+        if (!this.matricesIndicesExtra.connectedPoint) {
+            this.matricesIndicesExtra.setAsAttribute();
+        }
+        if (!this.matricesWeightsExtra.connectedPoint) {
+            this.matricesWeightsExtra.setAsAttribute();
+        }
+        if (!this.world.connectedPoint) {
+            this.world.setAsWellKnownValue(NodeMaterialWellKnownValues.World);
+        }
+    }
+
     public provideFallbacks(mesh: AbstractMesh, fallbacks: EffectFallbacks) {
         if (mesh && mesh.useBones && mesh.computeBonesUsingShaders && mesh.skeleton) {
             fallbacks.addCPUSkinningFallback(0, mesh);

+ 71 - 5
src/Materials/Node/Blocks/Vertex/instancesBlock.ts

@@ -2,6 +2,10 @@ import { NodeMaterialBlock } from '../../nodeMaterialBlock';
 import { NodeMaterialBlockTargets } from '../../nodeMaterialBlockTargets';
 import { NodeMaterialBlockConnectionPointTypes } from '../../nodeMaterialBlockConnectionPointTypes';
 import { NodeMaterialConnectionPoint } from '../../nodeMaterialBlockConnectionPoint';
+import { NodeMaterialBuildState } from '../../nodeMaterialBuildState';
+import { AbstractMesh } from '../../../../Meshes/abstractMesh';
+import { NodeMaterial, NodeMaterialDefines } from '../../nodeMaterial';
+import { NodeMaterialWellKnownValues } from '../../nodeMaterialWellKnownValues';
 
 /**
  * Block used to add support for instances
@@ -19,12 +23,9 @@ export class InstancesBlock extends NodeMaterialBlock {
         this.registerInput("world1", NodeMaterialBlockConnectionPointTypes.Vector4);
         this.registerInput("world2", NodeMaterialBlockConnectionPointTypes.Vector4);
         this.registerInput("world3", NodeMaterialBlockConnectionPointTypes.Vector4);
+        this.registerInput("world", NodeMaterialBlockConnectionPointTypes.Matrix, true);
 
-        // Auto-configuration
-        this.world0.setAsAttribute();
-        this.world1.setAsAttribute();
-        this.world2.setAsAttribute();
-        this.world3.setAsAttribute();
+        this.registerOutput("output", NodeMaterialBlockConnectionPointTypes.Matrix);
     }
 
     /**
@@ -62,4 +63,69 @@ export class InstancesBlock extends NodeMaterialBlock {
     public get world3(): NodeMaterialConnectionPoint {
         return this._inputs[3];
     }
+
+    /**
+     * Gets the world input component
+     */
+    public get world(): NodeMaterialConnectionPoint {
+        return this._inputs[4];
+    }
+
+    /**
+     * Gets the output component
+     */
+    public get output(): NodeMaterialConnectionPoint {
+        return this._outputs[0];
+    }
+
+    public autoConfigure() {
+        if (!this.world0.connectedPoint) {
+            this.world0.setAsAttribute();
+        }
+        if (!this.world1.connectedPoint) {
+            this.world1.setAsAttribute();
+        }
+        if (!this.world2.connectedPoint) {
+            this.world2.setAsAttribute();
+        }
+        if (!this.world3.connectedPoint) {
+            this.world3.setAsAttribute();
+        }
+        if (!this.world.connectedPoint) {
+            this.world.setAsWellKnownValue(NodeMaterialWellKnownValues.World);
+        }
+    }
+
+    public prepareDefines(mesh: AbstractMesh, nodeMaterial: NodeMaterial, defines: NodeMaterialDefines, useInstances: boolean = false) {
+        let changed = false;
+        if (defines["INSTANCES"] !== useInstances) {
+            defines.setValue("INSTANCES", useInstances);
+            changed = true;
+        }
+
+        if (changed) {
+            defines.markAsUnprocessed();
+        }
+    }
+
+    protected _buildBlock(state: NodeMaterialBuildState) {
+        super._buildBlock(state);
+
+        // Register for defines
+        state.sharedData.blocksWithDefines.push(this);
+
+        // Emit code
+        let output = this._outputs[0];
+        let world0 = this.world0;
+        let world1 = this.world1;
+        let world2 = this.world2;
+        let world3 = this.world3;
+
+        state.compilationString += `#ifdef INSTANCES\r\n`;
+        state.compilationString += this._declareOutput(output, state) + ` = mat4(${world0.associatedVariableName}, ${world1.associatedVariableName}, ${world2.associatedVariableName}, ${world3.associatedVariableName});\r\n`;
+        state.compilationString += `#else\r\n`;
+        state.compilationString += this._declareOutput(output, state) + ` = ${this.world.associatedVariableName};\r\n`;
+        state.compilationString += `#endif\r\n`;
+        return this;
+    }
 }

+ 2 - 2
src/Materials/Node/Optimizers/nodeMaterialOptimizer.ts

@@ -6,8 +6,8 @@ import { NodeMaterialBlock } from '../nodeMaterialBlock';
 export class NodeMaterialOptimizer {
     /**
      * Function used to optimize a NodeMaterial graph
-     * @param vertexShaderBuildState 
-     * @param fragmentShaderBuildState 
+     * @param vertexOutputNodes defines the list of output nodes for the vertex shader
+     * @param fragmentOutputNodes defines the list of output nodes for the fragment shader
      */
     public optimize(vertexOutputNodes: NodeMaterialBlock[], fragmentOutputNodes: NodeMaterialBlock[]) {
         // Do nothing by default

+ 2 - 1
src/Materials/Node/nodeMaterial.ts

@@ -248,6 +248,7 @@ export class NodeMaterial extends PushMaterial {
 
     private _initializeBlock(node: NodeMaterialBlock, state: NodeMaterialBuildState) {
         node.initialize(state);
+        node.autoConfigure();
 
         for (var inputs of node.inputs) {
             let connectedPoint = inputs.connectedPoint;
@@ -406,7 +407,7 @@ export class NodeMaterial extends PushMaterial {
 
         // Shared defines
         this._sharedData.blocksWithDefines.forEach((b) => {
-            b.prepareDefines(mesh, this, defines);
+            b.prepareDefines(mesh, this, defines, useInstances);
         });
 
         // Need to recompile?

+ 10 - 2
src/Materials/Node/nodeMaterialBlock.ts

@@ -280,9 +280,17 @@ export class NodeMaterialBlock {
      * Update defines for shader compilation
      * @param mesh defines the mesh to be rendered
      * @param nodeMaterial defines the node material requesting the update
-     * @param defines defines the material defines to update\
+     * @param defines defines the material defines to update
+     * @param useInstances specifies that instances should be used
      */
-    public prepareDefines(mesh: AbstractMesh, nodeMaterial: NodeMaterial, defines: NodeMaterialDefines) {
+    public prepareDefines(mesh: AbstractMesh, nodeMaterial: NodeMaterial, defines: NodeMaterialDefines, useInstances: boolean = false) {
+        // Do nothing
+    }
+
+    /**
+     * Lets the block try to connect some inputs automatically
+     */
+    public autoConfigure() {
         // Do nothing
     }