David Catuhe 5 年之前
父节点
当前提交
4c6b32ba83

+ 3 - 0
nodeEditor/src/blockTools.ts

@@ -56,10 +56,13 @@ import { WaveBlock, WaveBlockKind } from 'babylonjs/Materials/Node/Blocks/waveBl
 import { NodeMaterial } from 'babylonjs/Materials/Node/nodeMaterial';
 import { WorleyNoise3DBlock } from 'babylonjs/Materials/Node/Blocks/worleyNoise3DBlock';
 import { SimplexPerlin3DBlock } from 'babylonjs/Materials/Node/Blocks/simplexPerlin3DBlock';
+import { NormalBlendBlock } from 'babylonjs/Materials/Node/Blocks/normalBlendBlock';
 
 export class BlockTools {
     public static GetBlockFromString(data: string, scene: Scene, nodeMaterial: NodeMaterial) {
         switch (data) {
+            case "NormalBlendBlock":
+                return new NormalBlendBlock("NormalBlend");
             case "WorleyNoise3DBlock":
                 return new WorleyNoise3DBlock("WorleyNoise3D");
             case "SimplexPerlin3DBlock":

+ 1 - 1
nodeEditor/src/components/diagram/clamp/clampNodeWidget.tsx

@@ -43,7 +43,7 @@ export class ClampNodeWidget extends React.Component<ClampNodeWidgetProps> {
         let clampBlock = this.props.node!.block! as ClampBlock;
 
         return (
-            <div className={"diagramBlock remap"}>
+            <div className={"diagramBlock clamp"}>
                 <div className="header">
                     {clampBlock.name}
                 </div>

+ 13 - 0
nodeEditor/src/components/diagram/diagram.scss

@@ -104,6 +104,19 @@
         }        
     }
 
+    &.clamp {
+        color:white;
+        background: #4086BB;
+
+        .value {
+            grid-row: 2;
+        }
+
+        .outputs, .inputs {
+            transform: translateY(5px);
+        }        
+    }    
+
     &.gradient {
         .outputs, .inputs {
             transform: translateY(5px);

+ 1 - 1
nodeEditor/src/components/nodeList/nodeListComponent.tsx

@@ -37,7 +37,7 @@ export class NodeListComponent extends React.Component<INodeListComponentProps,
             Output_Blocks: ["VertexOutputBlock", "FragmentOutputBlock", "DiscardBlock"],
             Range: ["ClampBlock", "RemapBlock", "NormalizeBlock"],
             Round: ["StepBlock", "RoundBlock", "CeilingBlock", "FloorBlock"],
-            Scene: ["FogBlock", "CameraPositionBlock", "FogColorBlock", "ImageProcessingBlock", "LightBlock", "LightInformationBlock", "ViewDirectionBlock", "PerturbNormalBlock"],
+            Scene: ["FogBlock", "CameraPositionBlock", "FogColorBlock", "ImageProcessingBlock", "LightBlock", "LightInformationBlock", "ViewDirectionBlock", "PerturbNormalBlock", "NormalBlendBlock"],
             Trigonometry: ["CosBlock", "SinBlock", "AbsBlock", "ExpBlock", "Exp2Block", "SqrtBlock", "PowBlock", "LogBlock", "ArcCosBlock", "ArcSinBlock", "TanBlock", "ArcTanBlock", "FractBlock", "SignBlock", "ArcTan2Block", "DegreesToRadiansBlock", "RadiansToDegreesBlock", "SawToothWaveBlock", "TriangleWaveBlock", "SquareWaveBlock"],
             Vector_Math: ["CrossBlock", "DotBlock", "TransformBlock", "FresnelBlock"],
         }

+ 35 - 8
src/Materials/Node/Blocks/Dual/textureBlock.ts

@@ -21,6 +21,7 @@ import "../../../../Shaders/ShadersInclude/helperFunctions";
 export class TextureBlock extends NodeMaterialBlock {
     private _defineName: string;
     private _linearDefineName: string;
+    private _tempTextureRead: string;
     private _samplerName: string;
     private _transformedUVName: string;
     private _textureTransformName: string;
@@ -253,6 +254,8 @@ export class TextureBlock extends NodeMaterialBlock {
             return;
         }
 
+        this._writeTextureRead(state, true);
+
         for (var output of this._outputs) {
             if (output.hasEndpoints) {
                 this._writeOutput(state, output, output.name, true);
@@ -260,7 +263,7 @@ export class TextureBlock extends NodeMaterialBlock {
         }
     }
 
-    private _writeOutput(state: NodeMaterialBuildState, output: NodeMaterialConnectionPoint, swizzle: string, vertexMode = false) {
+    private _writeTextureRead(state: NodeMaterialBuildState, vertexMode = false) {
         let uvInput = this.uv;
 
         if (vertexMode) {
@@ -268,24 +271,42 @@ export class TextureBlock extends NodeMaterialBlock {
                 return;
             }
 
-            state.compilationString += `${this._declareOutput(output, state)} = texture2D(${this._samplerName}, ${uvInput.associatedVariableName}).${swizzle};\r\n`;
-
+            state.compilationString += `vec4 ${this._tempTextureRead} = texture2D(${this._samplerName}, ${uvInput.associatedVariableName});\r\n`;
             return;
         }
 
         if (this.uv.ownerBlock.target === NodeMaterialBlockTargets.Fragment) {
-            state.compilationString += `${this._declareOutput(output, state)} = texture2D(${this._samplerName}, ${uvInput.associatedVariableName}).${swizzle};\r\n`;
+            state.compilationString += `vec4 ${this._tempTextureRead} = texture2D(${this._samplerName}, ${uvInput.associatedVariableName});\r\n`;
             return;
         }
 
-        const complement = ` * ${this._textureInfoName}`;
-
         state.compilationString += `#ifdef ${this._defineName}\r\n`;
-        state.compilationString += `${this._declareOutput(output, state)} = texture2D(${this._samplerName}, ${this._transformedUVName}).${swizzle}${complement};\r\n`;
+        state.compilationString += `vec4 ${this._tempTextureRead} = texture2D(${this._samplerName}, ${this._transformedUVName});\r\n`;
         state.compilationString += `#endif\r\n`;
         state.compilationString += `#ifdef ${this._mainUVDefineName}\r\n`;
-        state.compilationString += `${this._declareOutput(output, state)} = texture2D(${this._samplerName}, ${this._mainUVName}).${swizzle}${complement};\r\n`;
+        state.compilationString += `vec4 ${this._tempTextureRead} = texture2D(${this._samplerName}, ${this._mainUVName});\r\n`;
         state.compilationString += `#endif\r\n`;
+    }
+
+    private _writeOutput(state: NodeMaterialBuildState, output: NodeMaterialConnectionPoint, swizzle: string, vertexMode = false) {
+        if (vertexMode) {
+            if (state.target === NodeMaterialBlockTargets.Fragment) {
+                return;
+            }
+
+            state.compilationString += `${this._declareOutput(output, state)} = ${this._tempTextureRead}.${swizzle};\r\n`;
+
+            return;
+        }
+
+        if (this.uv.ownerBlock.target === NodeMaterialBlockTargets.Fragment) {
+            state.compilationString += `${this._declareOutput(output, state)} = ${this._tempTextureRead}.${swizzle};\r\n`;
+            return;
+        }
+
+        const complement = ` * ${this._textureInfoName}`;
+
+        state.compilationString += `${this._declareOutput(output, state)} = ${this._tempTextureRead}.${swizzle}${complement};\r\n`;
 
         state.compilationString += `#ifdef ${this._linearDefineName}\r\n`;
         state.compilationString += `${output.associatedVariableName} = toGammaSpace(${output.associatedVariableName});\r\n`;
@@ -295,6 +316,10 @@ export class TextureBlock extends NodeMaterialBlock {
     protected _buildBlock(state: NodeMaterialBuildState) {
         super._buildBlock(state);
 
+        if (!this._tempTextureRead) {
+            this._tempTextureRead = state._getFreeVariableName("tempTextureRead");
+        }
+
         if (!this._isMixed && state.target === NodeMaterialBlockTargets.Fragment || this._isMixed && state.target === NodeMaterialBlockTargets.Vertex) {
             this._samplerName = state._getFreeVariableName(this.name + "Sampler");
 
@@ -332,6 +357,8 @@ export class TextureBlock extends NodeMaterialBlock {
             state._emitUniformFromString(this._textureInfoName, "float");
         }
 
+        this._writeTextureRead(state);
+
         for (var output of this._outputs) {
             if (output.hasEndpoints) {
                 this._writeOutput(state, output, output.name);

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

@@ -40,3 +40,4 @@ export * from "./gradientBlock";
 export * from "./nLerpBlock";
 export * from "./worleyNoise3DBlock";
 export * from "./simplexPerlin3DBlock";
+export * from "./normalBlendBlock";

+ 80 - 0
src/Materials/Node/Blocks/normalBlendBlock.ts

@@ -0,0 +1,80 @@
+import { NodeMaterialBlock } from '../nodeMaterialBlock';
+import { NodeMaterialBlockConnectionPointTypes } from '../Enums/nodeMaterialBlockConnectionPointTypes';
+import { NodeMaterialBuildState } from '../nodeMaterialBuildState';
+import { NodeMaterialConnectionPoint } from '../nodeMaterialBlockConnectionPoint';
+import { NodeMaterialBlockTargets } from '../Enums/nodeMaterialBlockTargets';
+import { _TypeStore } from '../../../Misc/typeStore';
+/**
+ * Block used to blend normals
+ */
+export class NormalBlendBlock extends NodeMaterialBlock {
+    /**
+     * Creates a new NormalBlendBlock
+     * @param name defines the block name
+     */
+    public constructor(name: string) {
+        super(name, NodeMaterialBlockTargets.Neutral);
+
+        this.registerInput("input0", NodeMaterialBlockConnectionPointTypes.Vector3);
+        this.registerInput("input1", NodeMaterialBlockConnectionPointTypes.Vector3);
+        this.registerOutput("output", NodeMaterialBlockConnectionPointTypes.Vector3);
+
+        this._inputs[0].acceptedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Color3);
+        this._inputs[0].acceptedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Color4);
+        this._inputs[0].acceptedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Vector4);
+
+        this._inputs[1].acceptedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Color3);
+        this._inputs[1].acceptedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Color4);
+        this._inputs[1].acceptedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Vector4);
+    }
+
+    /**
+     * Gets the current class name
+     * @returns the class name
+     */
+    public getClassName() {
+        return "NormalBlendBlock";
+    }
+
+    /**
+     * Gets the first input component
+     */
+    public get input0(): NodeMaterialConnectionPoint {
+        return this._inputs[0];
+    }
+
+    /**
+     * Gets the second input component
+     */
+    public get input1(): NodeMaterialConnectionPoint {
+        return this._inputs[1];
+    }
+
+    /**
+     * Gets the output component
+     */
+    public get output(): NodeMaterialConnectionPoint {
+        return this._outputs[0];
+    }
+
+    protected _buildBlock(state: NodeMaterialBuildState) {
+        super._buildBlock(state);
+
+        let output = this._outputs[0];
+        let input0 = this._inputs[0];
+        let input1 = this._inputs[1];
+        let stepR = state._getFreeVariableName("stepR");
+        let stepG = state._getFreeVariableName("stepG");
+
+        state.compilationString += `float ${stepR} = step(0.5, ${input0.associatedVariableName}.r);\r\n`;
+        state.compilationString += `float ${stepG} = step(0.5, ${input0.associatedVariableName}.g);\r\n`;
+        state.compilationString += this._declareOutput(output, state) + `;\r\n`;
+        state.compilationString += `${output.associatedVariableName}.r = (1.0 - ${stepR}) * ${input0.associatedVariableName}.r * ${input1.associatedVariableName}.r * 2.0 + ${stepR} * (1.0 - ${input0.associatedVariableName}.r) * (1.0 - ${input1.associatedVariableName}.r) * 2.0;\r\n`;
+        state.compilationString += `${output.associatedVariableName}.g = (1.0 - ${stepG}) * ${input0.associatedVariableName}.g * ${input1.associatedVariableName}.g * 2.0 + ${stepG} * (1.0 - ${input0.associatedVariableName}.g) * (1.0 - ${input1.associatedVariableName}.g) * 2.0;\r\n`;
+        state.compilationString += `${output.associatedVariableName}.b = ${input0.associatedVariableName}.b * ${input1.associatedVariableName}.b;\r\n`;
+
+        return this;
+    }
+}
+
+_TypeStore.RegisteredTypes["BABYLON.NormalBlendBlock"] = NormalBlendBlock;

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

@@ -525,7 +525,7 @@ export class NodeMaterial extends PushMaterial {
      * Build the material and generates the inner effect
      * @param verbose defines if the build should log activity
      */
-    public build(verbose: boolean = false) {
+    public build(verbose: boolean = true) {
         this._buildWasSuccessful = false;
         var engine = this.getScene().getEngine();