浏览代码

Gradient block (no UI) #6012

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

+ 58 - 0
dist/preview release/babylon.d.ts

@@ -55365,6 +55365,64 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
+     * Class used to store a color step for the GradientBlock
+     */
+    export class GradientBlockColorStep {
+        /**
+         * Gets or sets a value indicating which step this color is associated with (between 0 and 1)
+         */
+        step: number;
+        /**
+         * Gets or sets the color associated with this step
+         */
+        color: Color3;
+        /**
+         * Creates a new GradientBlockColorStep
+         * @param step defines a value indicating which step this color is associated with (between 0 and 1)
+         * @param color defines the color associated with this step
+         */
+        constructor(
+        /**
+         * Gets or sets a value indicating which step this color is associated with (between 0 and 1)
+         */
+        step: number, 
+        /**
+         * Gets or sets the color associated with this step
+         */
+        color: Color3);
+    }
+    /**
+     * Block used to return a color from a gradient based on an input value between 0 and 1
+     */
+    export class GradientBlock extends NodeMaterialBlock {
+        colorSteps: GradientBlockColorStep[];
+        /**
+         * Creates a new GradientBlock
+         * @param name defines the block name
+         */
+        constructor(name: string);
+        /**
+         * Gets the current class name
+         * @returns the class name
+         */
+        getClassName(): string;
+        /**
+         * Gets the gradient input component
+         */
+        readonly gradient: NodeMaterialConnectionPoint;
+        /**
+         * Gets the output component
+         */
+        readonly output: NodeMaterialConnectionPoint;
+        private _writeColorConstant;
+        protected _buildBlock(state: NodeMaterialBuildState): this | undefined;
+        serialize(): any;
+        _deserialize(serializationObject: any, scene: Scene, rootUrl: string): void;
+        protected _dumpPropertiesCode(): string;
+    }
+}
+declare module BABYLON {
+    /**
      * Effect Render Options
      */
     export interface IEffectRendererOptions {

文件差异内容过多而无法显示
+ 2 - 2
dist/preview release/babylon.js


文件差异内容过多而无法显示
+ 181 - 18
dist/preview release/babylon.max.js


文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/babylon.max.js.map


+ 127 - 5
dist/preview release/babylon.module.d.ts

@@ -58116,6 +58116,74 @@ declare module "babylonjs/Materials/Node/Blocks/waveBlock" {
         _deserialize(serializationObject: any, scene: Scene, rootUrl: string): void;
     }
 }
+declare module "babylonjs/Maths/index" {
+    export * from "babylonjs/Maths/math.scalar";
+    export * from "babylonjs/Maths/math";
+    export * from "babylonjs/Maths/sphericalPolynomial";
+}
+declare module "babylonjs/Materials/Node/Blocks/gradientBlock" {
+    import { NodeMaterialBlock } from "babylonjs/Materials/Node/nodeMaterialBlock";
+    import { NodeMaterialBuildState } from "babylonjs/Materials/Node/nodeMaterialBuildState";
+    import { NodeMaterialConnectionPoint } from "babylonjs/Materials/Node/nodeMaterialBlockConnectionPoint";
+    import { Color3 } from "babylonjs/Maths/index";
+    import { Scene } from "babylonjs/scene";
+    /**
+     * Class used to store a color step for the GradientBlock
+     */
+    export class GradientBlockColorStep {
+        /**
+         * Gets or sets a value indicating which step this color is associated with (between 0 and 1)
+         */
+        step: number;
+        /**
+         * Gets or sets the color associated with this step
+         */
+        color: Color3;
+        /**
+         * Creates a new GradientBlockColorStep
+         * @param step defines a value indicating which step this color is associated with (between 0 and 1)
+         * @param color defines the color associated with this step
+         */
+        constructor(
+        /**
+         * Gets or sets a value indicating which step this color is associated with (between 0 and 1)
+         */
+        step: number, 
+        /**
+         * Gets or sets the color associated with this step
+         */
+        color: Color3);
+    }
+    /**
+     * Block used to return a color from a gradient based on an input value between 0 and 1
+     */
+    export class GradientBlock extends NodeMaterialBlock {
+        colorSteps: GradientBlockColorStep[];
+        /**
+         * Creates a new GradientBlock
+         * @param name defines the block name
+         */
+        constructor(name: string);
+        /**
+         * Gets the current class name
+         * @returns the class name
+         */
+        getClassName(): string;
+        /**
+         * Gets the gradient input component
+         */
+        readonly gradient: NodeMaterialConnectionPoint;
+        /**
+         * Gets the output component
+         */
+        readonly output: NodeMaterialConnectionPoint;
+        private _writeColorConstant;
+        protected _buildBlock(state: NodeMaterialBuildState): this | undefined;
+        serialize(): any;
+        _deserialize(serializationObject: any, scene: Scene, rootUrl: string): void;
+        protected _dumpPropertiesCode(): string;
+    }
+}
 declare module "babylonjs/Materials/Node/Blocks/index" {
     export * from "babylonjs/Materials/Node/Blocks/Vertex/index";
     export * from "babylonjs/Materials/Node/Blocks/Fragment/index";
@@ -58155,6 +58223,7 @@ declare module "babylonjs/Materials/Node/Blocks/index" {
     export * from "babylonjs/Materials/Node/Blocks/replaceColorBlock";
     export * from "babylonjs/Materials/Node/Blocks/posterizeBlock";
     export * from "babylonjs/Materials/Node/Blocks/waveBlock";
+    export * from "babylonjs/Materials/Node/Blocks/gradientBlock";
 }
 declare module "babylonjs/Materials/Node/Optimizers/index" {
     export * from "babylonjs/Materials/Node/Optimizers/nodeMaterialOptimizer";
@@ -58316,11 +58385,6 @@ declare module "babylonjs/Materials/index" {
     export * from "babylonjs/Materials/Node/index";
     export * from "babylonjs/Materials/effectRenderer";
 }
-declare module "babylonjs/Maths/index" {
-    export * from "babylonjs/Maths/math.scalar";
-    export * from "babylonjs/Maths/math";
-    export * from "babylonjs/Maths/sphericalPolynomial";
-}
 declare module "babylonjs/Misc/workerPool" {
     import { IDisposable } from "babylonjs/scene";
     /**
@@ -122005,6 +122069,64 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
+     * Class used to store a color step for the GradientBlock
+     */
+    export class GradientBlockColorStep {
+        /**
+         * Gets or sets a value indicating which step this color is associated with (between 0 and 1)
+         */
+        step: number;
+        /**
+         * Gets or sets the color associated with this step
+         */
+        color: Color3;
+        /**
+         * Creates a new GradientBlockColorStep
+         * @param step defines a value indicating which step this color is associated with (between 0 and 1)
+         * @param color defines the color associated with this step
+         */
+        constructor(
+        /**
+         * Gets or sets a value indicating which step this color is associated with (between 0 and 1)
+         */
+        step: number, 
+        /**
+         * Gets or sets the color associated with this step
+         */
+        color: Color3);
+    }
+    /**
+     * Block used to return a color from a gradient based on an input value between 0 and 1
+     */
+    export class GradientBlock extends NodeMaterialBlock {
+        colorSteps: GradientBlockColorStep[];
+        /**
+         * Creates a new GradientBlock
+         * @param name defines the block name
+         */
+        constructor(name: string);
+        /**
+         * Gets the current class name
+         * @returns the class name
+         */
+        getClassName(): string;
+        /**
+         * Gets the gradient input component
+         */
+        readonly gradient: NodeMaterialConnectionPoint;
+        /**
+         * Gets the output component
+         */
+        readonly output: NodeMaterialConnectionPoint;
+        private _writeColorConstant;
+        protected _buildBlock(state: NodeMaterialBuildState): this | undefined;
+        serialize(): any;
+        _deserialize(serializationObject: any, scene: Scene, rootUrl: string): void;
+        protected _dumpPropertiesCode(): string;
+    }
+}
+declare module BABYLON {
+    /**
      * Effect Render Options
      */
     export interface IEffectRendererOptions {

+ 4 - 1
nodeEditor/src/blockTools.ts

@@ -49,6 +49,7 @@ import { ReplaceColorBlock } from 'babylonjs/Materials/Node/Blocks/replaceColorB
 import { PosterizeBlock } from 'babylonjs/Materials/Node/Blocks/posterizeBlock';
 import { ArcTan2Block } from 'babylonjs/Materials/Node/Blocks/arcTan2Block';
 import { ReciprocalBlock } from 'babylonjs/Materials/Node/Blocks/reciprocalBlock';
+import { GradientBlock } from 'babylonjs/Materials/Node/Blocks/gradientBlock';
 import { WaveBlock, WaveBlockKind } from 'babylonjs/Materials/Node/Blocks/waveBlock';
 
 export class BlockTools {
@@ -147,7 +148,9 @@ export class BlockTools {
             case "PosterizeBlock":                                          
                 return new PosterizeBlock("Posterize");                              
             case "ArcTan2Block":                                          
-                return new ArcTan2Block("ArcTan2");          
+                return new ArcTan2Block("ArcTan2");                            
+            case "GradientBlock":                                          
+                return new GradientBlock("Gradient");            
             case "CosBlock": {
                 let cosBlock = new TrigonometryBlock("Cos");
                 cosBlock.operation = TrigonometryBlockOperations.Cos;

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

@@ -27,7 +27,7 @@ export class NodeListComponent extends React.Component<INodeListComponentProps,
         const allBlocks = {
             Animation: ["BonesBlock", "MorphTargetsBlock"],
             Basic_Math: ["AddBlock",  "DivideBlock", "MultiplyBlock", "ScaleBlock", "SubtractBlock", "OneMinusBlock", "MaxBlock", "MinBlock", "LengthBlock", "DistanceBlock", "NegateBlock", "RandomNumberBlock", "ReciprocalBlock"],
-            Color_Management: ["ReplaceColorBlock", "PosterizeBlock"],
+            Color_Management: ["ReplaceColorBlock", "PosterizeBlock", "GradientBlock"],
             Conversion_Blocks: ["ColorMergerBlock", "ColorSplitterBlock", "VectorMergerBlock", "VectorSplitterBlock"],
             Inputs: ["Float", "Vector2", "Vector3", "Vector4", "Color3", "Color4", "TextureBlock", "TimeBlock", "DeltaTimeBlock"],
             Interpolation: ["LerpBlock", "SmoothStepBlock"],

+ 130 - 0
src/Materials/Node/Blocks/gradientBlock.ts

@@ -0,0 +1,130 @@
+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';
+import { Color3 } from '../../../Maths/math.color';
+import { Scene } from '../../../scene';
+
+/**
+ * Class used to store a color step for the GradientBlock
+ */
+export class GradientBlockColorStep {
+    /**
+     * Creates a new GradientBlockColorStep
+     * @param step defines a value indicating which step this color is associated with (between 0 and 1)
+     * @param color defines the color associated with this step
+     */
+    public constructor(
+        /**
+         * Gets or sets a value indicating which step this color is associated with (between 0 and 1)
+         */     
+        public step: number,
+        /**
+         * Gets or sets the color associated with this step
+         */
+        public color: Color3) {
+    }
+}
+
+/**
+ * Block used to return a color from a gradient based on an input value between 0 and 1
+ */
+export class GradientBlock extends NodeMaterialBlock {
+
+    public colorSteps: GradientBlockColorStep[] = [
+        new GradientBlockColorStep(0, Color3.Red()),
+        new GradientBlockColorStep(0.5, Color3.Teal()),
+        new GradientBlockColorStep(1.0, Color3.Red())
+    ];
+
+    /**
+     * Creates a new GradientBlock
+     * @param name defines the block name
+     */
+    public constructor(name: string) {
+        super(name, NodeMaterialBlockTargets.Neutral);
+
+        this.registerInput("gradient", NodeMaterialBlockConnectionPointTypes.Float);
+        this.registerOutput("output", NodeMaterialBlockConnectionPointTypes.Color3);
+    }
+
+    /**
+     * Gets the current class name
+     * @returns the class name
+     */
+    public getClassName() {
+        return "GradientBlock";
+    }
+
+    /**
+     * Gets the gradient input component
+     */
+    public get gradient(): NodeMaterialConnectionPoint {
+        return this._inputs[0];
+    }
+
+    /**
+     * Gets the output component
+     */
+    public get output(): NodeMaterialConnectionPoint {
+        return this._outputs[0];
+    }
+
+    private _writeColorConstant(index: number) {
+        let step = this.colorSteps[index];
+        return `vec3(${step.color.r}, ${step.color.g}, ${step.color.b})`;
+    }
+
+    protected _buildBlock(state: NodeMaterialBuildState) {
+        super._buildBlock(state);
+
+        if (!this.colorSteps.length) {
+            return;
+        }
+
+        let output = this._outputs[0];
+        let tempColor = state._getFreeVariableName("gradientTempColor");
+        let tempPosition = state._getFreeVariableName("gradientTempPosition");
+        
+        state.compilationString += `vec3 ${tempColor} = ${this._writeColorConstant(0)};\r\n`;        
+        state.compilationString += `float ${tempPosition};\r\n`;
+
+        for (var index = 1; index < this.colorSteps.length; index++) {
+            let step = this.colorSteps[index];
+            let previousStep = this.colorSteps[index - 1];
+            state.compilationString += `${tempPosition} = clamp((${this.gradient.associatedVariableName} - ${state._emitFloat(previousStep.step)}) / (${state._emitFloat(step.step)} -  ${state._emitFloat(previousStep.step)}), 0.0, 1.0) * step(${state._emitFloat(index)}, ${state._emitFloat(this.colorSteps.length - 1)});\r\n`;
+            state.compilationString += `${tempColor} = mix(${tempColor}, ${this._writeColorConstant(index)}, ${tempPosition});\r\n`;
+        }
+        state.compilationString += this._declareOutput(output, state) + ` = ${tempColor};\r\n`;
+
+        return this;
+    }
+
+    public serialize(): any {
+        let serializationObject = super.serialize();
+
+        serializationObject.colorSteps = this.colorSteps;
+
+        return serializationObject;
+    }
+
+    public _deserialize(serializationObject: any, scene: Scene, rootUrl: string) {
+        super._deserialize(serializationObject, scene, rootUrl);
+
+        this.colorSteps = serializationObject.colorSteps;
+    }
+
+    protected _dumpPropertiesCode() {
+        var codeString = "";
+
+        for (var colorStep of this.colorSteps) {
+            codeString += `${this._codeVariableName}.colorSteps.push(new BABYLON.GradientBlockColorStep(${colorStep.step}, new BABYLON.Color3(${colorStep.color.r}, ${colorStep.color.g}, ${colorStep.color.b})));\r\n`;
+        }
+
+        return codeString;
+    }    
+}
+
+_TypeStore.RegisteredTypes["BABYLON.GradientBlock"] = GradientBlock;

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

@@ -35,4 +35,5 @@ export * from "./smoothStepBlock";
 export * from "./reciprocalBlock";
 export * from "./replaceColorBlock";
 export * from "./posterizeBlock";
-export * from "./waveBlock";
+export * from "./waveBlock";
+export * from "./gradientBlock";

+ 9 - 0
src/Materials/Node/nodeMaterialBuildState.ts

@@ -351,4 +351,13 @@ export class NodeMaterialBuildState {
             this._uniformDeclaration += `#endif\r\n`;
         }
     }
+
+    /** @hidden */
+    public _emitFloat(value: number) {
+        if (value.toString() === value.toFixed(0)) {
+            return `${value}.0`;
+        }
+
+        return value.toString();
+    }
 }