فهرست منبع

Add the FragCoord and ScreenSize blocks

Popov72 5 سال پیش
والد
کامیت
b650714948

+ 2 - 0
dist/preview release/what's new.md

@@ -45,6 +45,8 @@
 - Added a modulo block ([ageneau](https://github.com/ageneau))
 - Fix bug where frame port labels would be the names of incorrect nodes ([belfortk](https://github.com/belfortk))
 - Fix bug where long comments on collapsed frames broke port alignment ([belfortk](https://github.com/belfortk))
+- Add the `FragCoord` and `ScreenSize` blocks ([Popov72](https://github.com/Popov72))
+- Particle systems: add the `ParticlePositionWorld` block ([Popov72](https://github.com/Popov72))
 
 ### Inspector
 

+ 6 - 0
nodeEditor/src/blockTools.ts

@@ -77,6 +77,8 @@ import { ParticleTextureBlock } from 'babylonjs/Materials/Node/Blocks/Particle/p
 import { ParticleRampGradientBlock } from 'babylonjs/Materials/Node/Blocks/Particle/particleRampGradientBlock';
 import { ParticleBlendMultiplyBlock } from 'babylonjs/Materials/Node/Blocks/Particle/particleBlendMultiplyBlock';
 import { NodeMaterialModes } from 'babylonjs/Materials/Node/Enums/nodeMaterialModes';
+import { FragCoordBlock } from 'babylonjs/Materials/Node/Blocks/Fragment/fragCoordBlock';
+import { ScreenSizeBlock } from 'babylonjs/Materials/Node/Blocks/Fragment/screenSizeBlock';
 
 export class BlockTools {
     public static GetBlockFromString(data: string, scene: Scene, nodeMaterial: NodeMaterial) {
@@ -500,6 +502,10 @@ export class BlockTools {
                 return new ParticleRampGradientBlock("ParticleRampGradient");
             case "ParticleBlendMultiplyBlock":
                 return new ParticleBlendMultiplyBlock("ParticleBlendMultiply");
+            case "FragCoordBlock":
+                return new FragCoordBlock("FragCoord");
+            case "ScreenSizeBlock":
+                return new ScreenSizeBlock("ScreenSize");
         }
 
         return null;

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

@@ -141,6 +141,8 @@ export class NodeListComponent extends React.Component<INodeListComponentProps,
         "ParticleRampGradientBlock": "The particle ramp gradient block",
         "ParticleBlendMultiplyBlock": "The particle blend multiply block",
         "ParticlePositionWorldBlock": "The world position of the particle",
+        "FragCoordBlock": "The gl_FragCoord predefined variable that contains the window relative coordinate (x, y, z, 1/w)",
+        "ScreenSizeBlock": "The size (in pixels) of the screen window",
     };
 
     constructor(props: INodeListComponentProps) {
@@ -168,7 +170,7 @@ export class NodeListComponent extends React.Component<INodeListComponentProps,
             Animation: ["BonesBlock", "MorphTargetsBlock"],
             Color_Management: ["ReplaceColorBlock", "PosterizeBlock", "GradientBlock", "DesaturateBlock"],
             Conversion_Blocks: ["ColorMergerBlock", "ColorSplitterBlock", "VectorMergerBlock", "VectorSplitterBlock"],
-            Inputs: ["Float", "Vector2", "Vector3", "Vector4", "Color3", "Color4", "TextureBlock", "ReflectionTextureBlock", "TimeBlock", "DeltaTimeBlock"],
+            Inputs: ["Float", "Vector2", "Vector3", "Vector4", "Color3", "Color4", "TextureBlock", "ReflectionTextureBlock", "TimeBlock", "DeltaTimeBlock", "FragCoordBlock", "ScreenSizeBlock"],
             Interpolation: ["LerpBlock", "StepBlock", "SmoothStepBlock", "NLerpBlock"],
             Math__Standard: ["AddBlock", "DivideBlock", "MaxBlock", "MinBlock", "ModBlock", "MultiplyBlock", "NegateBlock", "OneMinusBlock", "ReciprocalBlock", "ScaleBlock", "SignBlock", "SqrtBlock", "SubtractBlock"],
             Math__Scientific: ["AbsBlock", "ArcCosBlock", "ArcSinBlock", "ArcTanBlock", "ArcTan2Block", "CosBlock", "DegreesToRadiansBlock", "ExpBlock", "Exp2Block", "FractBlock", "LogBlock", "PowBlock", "RadiansToDegreesBlock", "SawToothWaveBlock", "SinBlock", "SquareWaveBlock", "TanBlock", "TriangleWaveBlock"],

+ 110 - 0
src/Materials/Node/Blocks/Fragment/fragCoordBlock.ts

@@ -0,0 +1,110 @@
+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 make gl_FragCoord available
+ */
+export class FragCoordBlock extends NodeMaterialBlock {
+    /**
+     * Creates a new FragCoordBlock
+     * @param name defines the block name
+     */
+    public constructor(name: string) {
+        super(name, NodeMaterialBlockTargets.Fragment);
+
+        this.registerOutput("xy", NodeMaterialBlockConnectionPointTypes.Vector2, NodeMaterialBlockTargets.Fragment);
+        this.registerOutput("xyz", NodeMaterialBlockConnectionPointTypes.Vector3, NodeMaterialBlockTargets.Fragment);
+        this.registerOutput("xyzw", NodeMaterialBlockConnectionPointTypes.Vector4, NodeMaterialBlockTargets.Fragment);
+        this.registerOutput("x", NodeMaterialBlockConnectionPointTypes.Float, NodeMaterialBlockTargets.Fragment);
+        this.registerOutput("y", NodeMaterialBlockConnectionPointTypes.Float, NodeMaterialBlockTargets.Fragment);
+        this.registerOutput("z", NodeMaterialBlockConnectionPointTypes.Float, NodeMaterialBlockTargets.Fragment);
+        this.registerOutput("w", NodeMaterialBlockConnectionPointTypes.Float, NodeMaterialBlockTargets.Fragment);
+    }
+
+    /**
+     * Gets the current class name
+     * @returns the class name
+     */
+    public getClassName() {
+        return "FragCoordBlock";
+    }
+
+    /**
+     * Gets the xy component
+     */
+    public get xy(): NodeMaterialConnectionPoint {
+        return this._outputs[0];
+    }
+
+    /**
+     * Gets the xyz component
+     */
+    public get xyz(): NodeMaterialConnectionPoint {
+        return this._outputs[1];
+    }
+
+    /**
+     * Gets the xyzw component
+     */
+    public get xyzw(): NodeMaterialConnectionPoint {
+        return this._outputs[2];
+    }
+
+    /**
+     * Gets the x component
+     */
+    public get x(): NodeMaterialConnectionPoint {
+        return this._outputs[3];
+    }
+
+    /**
+     * Gets the y component
+     */
+    public get y(): NodeMaterialConnectionPoint {
+        return this._outputs[4];
+    }
+
+    /**
+     * Gets the z component
+     */
+    public get z(): NodeMaterialConnectionPoint {
+        return this._outputs[5];
+    }
+
+    /**
+     * Gets the w component
+     */
+    public get output(): NodeMaterialConnectionPoint {
+        return this._outputs[6];
+    }
+
+    protected writeOutputs(state: NodeMaterialBuildState): string {
+        let code = "";
+
+        for (var output of this._outputs) {
+            if (output.hasEndpoints) {
+                code += `${this._declareOutput(output, state)} = gl_FragCoord.${output.name};\r\n`;
+            }
+        }
+
+        return code;
+    }
+
+    protected _buildBlock(state: NodeMaterialBuildState) {
+        super._buildBlock(state);
+
+        if (state.target === NodeMaterialBlockTargets.Vertex) {
+            throw "FragCoordBlock must only be used in a fragment shader";
+        }
+
+        state.compilationString += this.writeOutputs(state);
+
+        return this;
+    }
+}
+
+_TypeStore.RegisteredTypes["BABYLON.FragCoordBlock"] = FragCoordBlock;

+ 2 - 0
src/Materials/Node/Blocks/Fragment/index.ts

@@ -5,3 +5,5 @@ export * from "./perturbNormalBlock";
 export * from "./discardBlock";
 export * from "./frontFacingBlock";
 export * from "./derivativeBlock";
+export * from "./fragCoordBlock";
+export * from "./screenSizeBlock";

+ 98 - 0
src/Materials/Node/Blocks/Fragment/screenSizeBlock.ts

@@ -0,0 +1,98 @@
+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 { Effect } from '../../../effect';
+import { NodeMaterial } from '../../nodeMaterial';
+import { Mesh } from '../../../../Meshes/mesh';
+import { Scene } from '../../../../scene';
+
+/**
+ * Block used to get the screen sizes
+ */
+export class ScreenSizeBlock extends NodeMaterialBlock {
+    private _varName: string;
+    private _scene: Scene;
+
+    /**
+     * Creates a new ScreenSizeBlock
+     * @param name defines the block name
+     */
+    public constructor(name: string) {
+        super(name, NodeMaterialBlockTargets.Fragment);
+
+        this.registerOutput("xy", NodeMaterialBlockConnectionPointTypes.Vector2, NodeMaterialBlockTargets.Fragment);
+        this.registerOutput("x", NodeMaterialBlockConnectionPointTypes.Float, NodeMaterialBlockTargets.Fragment);
+        this.registerOutput("y", NodeMaterialBlockConnectionPointTypes.Float, NodeMaterialBlockTargets.Fragment);
+    }
+
+    /**
+     * Gets the current class name
+     * @returns the class name
+     */
+    public getClassName() {
+        return "ScreenSizeBlock";
+    }
+
+    /**
+     * Gets the xy component
+     */
+    public get xy(): NodeMaterialConnectionPoint {
+        return this._outputs[0];
+    }
+
+    /**
+     * Gets the x component
+     */
+    public get x(): NodeMaterialConnectionPoint {
+        return this._outputs[1];
+    }
+
+    /**
+     * Gets the y component
+     */
+    public get y(): NodeMaterialConnectionPoint {
+        return this._outputs[2];
+    }
+
+    public bind(effect: Effect, nodeMaterial: NodeMaterial, mesh?: Mesh) {
+        const engine = this._scene.getEngine();
+
+        effect.setFloat2(this._varName, engine.getRenderWidth(), engine.getRenderWidth());
+    }
+
+    protected writeOutputs(state: NodeMaterialBuildState, varName: string): string {
+        let code = "";
+
+        for (var output of this._outputs) {
+            if (output.hasEndpoints) {
+                code += `${this._declareOutput(output, state)} = ${varName}.${output.name};\r\n`;
+            }
+        }
+
+        return code;
+    }
+
+    protected _buildBlock(state: NodeMaterialBuildState) {
+        super._buildBlock(state);
+
+        this._scene = state.sharedData.scene;
+
+        if (state.target === NodeMaterialBlockTargets.Vertex) {
+            throw "ScreenSizeBlock must only be used in a fragment shader";
+        }
+
+        state.sharedData.bindableBlocks.push(this);
+
+        this._varName = state._getFreeVariableName("screenSize");
+        state._emitUniformFromString(this._varName, "vec2");
+
+        state.compilationString += this.writeOutputs(state, this._varName);
+
+        return this;
+    }
+}
+
+_TypeStore.RegisteredTypes["BABYLON.ScreenSizeBlock"] = ScreenSizeBlock;