Quellcode durchsuchen

Add the PBR reflection block (WIP)

Popov72 vor 5 Jahren
Ursprung
Commit
2ec5eb1cb8

+ 3 - 0
nodeEditor/src/blockTools.ts

@@ -67,6 +67,7 @@ import { SheenBlock } from 'babylonjs/Materials/Node/Blocks/Fragment/PBR/sheenBl
 import { AmbientOcclusionBlock } from 'babylonjs/Materials/Node/Blocks/Fragment/PBR/ambientOcclusionBlock';
 import { ReflectivityBlock } from 'babylonjs/Materials/Node/Blocks/Fragment/PBR/reflectivityBlock';
 import { AnisotropyBlock } from 'babylonjs/Materials/Node/Blocks/Fragment/PBR/anisotropyBlock';
+import { ReflectionBlock } from 'babylonjs/Materials/Node/Blocks/Fragment/PBR/reflectionBlock';
 
 export class BlockTools {
     public static GetBlockFromString(data: string, scene: Scene, nodeMaterial: NodeMaterial) {
@@ -447,6 +448,8 @@ export class BlockTools {
                 return new ReflectivityBlock("Reflectivity");
             case "AnisotropyBlock":
                 return new AnisotropyBlock("Anisotropy");
+            case "ReflectionBlock":
+                return new ReflectionBlock("Reflection");
         }
 
         return null;

+ 6 - 5
nodeEditor/src/components/nodeList/nodeListComponent.tsx

@@ -118,10 +118,11 @@ export class NodeListComponent extends React.Component<INodeListComponentProps,
         "RefractBlock": "Outputs a direction simulating a deflection of the input vector.",
         "Rotate2dBlock": "Rotates UV coordinates around the W axis.",
         "PBRMetallicRoughnessBlock": "PBR metallic/roughness material",
-        "SheenBlock": "Sheen block",
-        "AmbientOcclusionBlock": "Ambient occlusion block",
-        "ReflectivityBlock": "Reflectivity block",
-        "AnisotropyBlock": "Anisotropy block"
+        "SheenBlock": "PBR Sheen block",
+        "AmbientOcclusionBlock": "PBR Ambient occlusion block",
+        "ReflectivityBlock": "PBR Reflectivity block",
+        "AnisotropyBlock": "PBR Anisotropy block",
+        "ReflectionBlock": "PBR Reflection block"
     };
 
     constructor(props: INodeListComponentProps) {
@@ -150,7 +151,7 @@ export class NodeListComponent extends React.Component<INodeListComponentProps,
             Mesh: ["InstancesBlock", "PositionBlock", "UVBlock", "ColorBlock", "NormalBlock", "PerturbNormalBlock", "NormalBlendBlock" , "TangentBlock", "MatrixIndicesBlock", "MatrixWeightsBlock", "WorldPositionBlock", "WorldNormalBlock", "WorldTangentBlock", "FrontFacingBlock"],
             Noises: ["RandomNumberBlock", "SimplexPerlin3DBlock", "WorleyNoise3DBlock"],
             Output_Nodes: ["VertexOutputBlock", "FragmentOutputBlock", "DiscardBlock"],
-            PBR: ["PBRMetallicRoughnessBlock", "AmbientOcclusionBlock", "AnisotropyBlock", "ReflectivityBlock", "SheenBlock"],
+            PBR: ["PBRMetallicRoughnessBlock", "AmbientOcclusionBlock", "AnisotropyBlock", "ReflectionBlock", "ReflectivityBlock", "SheenBlock"],
             Range: ["ClampBlock", "RemapBlock", "NormalizeBlock"],
             Round: ["RoundBlock", "CeilingBlock", "FloorBlock"],
             Scene: ["FogBlock", "CameraPositionBlock", "FogColorBlock", "ImageProcessingBlock", "LightBlock", "LightInformationBlock", "ViewDirectionBlock"],

+ 1 - 0
nodeEditor/src/diagram/displayLedger.ts

@@ -20,5 +20,6 @@ DisplayLedger.RegisteredControls["RemapBlock"] = RemapDisplayManager;
 DisplayLedger.RegisteredControls["TrigonometryBlock"] = TrigonometryDisplayManager;
 DisplayLedger.RegisteredControls["TextureBlock"] = TextureDisplayManager;
 DisplayLedger.RegisteredControls["ReflectionTextureBlock"] = TextureDisplayManager;
+DisplayLedger.RegisteredControls["ReflectionBlock"] = TextureDisplayManager;
 DisplayLedger.RegisteredControls["MetallicRoughnessTextureBlock"] = TextureDisplayManager;
 DisplayLedger.RegisteredControls["DiscardBlock"] = DiscardDisplayManager;

+ 9 - 6
nodeEditor/src/diagram/properties/texturePropertyTabComponent.tsx

@@ -14,13 +14,16 @@ import { CubeTexture } from 'babylonjs/Materials/Textures/cubeTexture';
 import { OptionsLineComponent } from '../../sharedComponents/optionsLineComponent';
 import { IPropertyComponentProps } from './propertyComponentProps';
 import { ReflectionTextureBlock } from 'babylonjs/Materials/Node/Blocks/Dual/reflectionTextureBlock';
+import { ReflectionBlock } from 'babylonjs/Materials/Node/Blocks/Fragment/PBR/reflectionBlock';
 import { TextureBlock } from 'babylonjs/Materials/Node/Blocks/Dual/textureBlock';
 import { GeneralPropertyTabComponent, GenericPropertyTabComponent } from './genericNodePropertyComponent';
 
+type ReflectionTexture = ReflectionTextureBlock | ReflectionBlock;
+
 export class TexturePropertyTabComponent extends React.Component<IPropertyComponentProps, {isEmbedded: boolean, loadAsCubeTexture: boolean}> {
 
-    get textureBlock(): TextureBlock | ReflectionTextureBlock {
-        return this.props.block as TextureBlock | ReflectionTextureBlock;
+    get textureBlock(): TextureBlock | ReflectionTexture {
+        return this.props.block as TextureBlock | ReflectionTexture;
     }
 
     constructor(props: IPropertyComponentProps) {
@@ -33,7 +36,7 @@ export class TexturePropertyTabComponent extends React.Component<IPropertyCompon
 
     UNSAFE_componentWillUpdate(nextProps: IPropertyComponentProps, nextState: {isEmbedded: boolean, loadAsCubeTexture: boolean}) {
         if (nextProps.block !== this.props.block) {
-            let texture = (nextProps.block as TextureBlock | ReflectionTextureBlock).texture as BaseTexture;
+            let texture = (nextProps.block as TextureBlock | ReflectionTexture).texture as BaseTexture;
 
             nextState.isEmbedded = !texture || texture.name.substring(0, 4) === "data";
             nextState.loadAsCubeTexture = texture && texture.isCube;
@@ -76,7 +79,7 @@ export class TexturePropertyTabComponent extends React.Component<IPropertyCompon
 
         if (!texture) {
             if (!this.state.loadAsCubeTexture) {
-                this.textureBlock.texture = new Texture(null, this.props.globalState.nodeMaterial.getScene(), false, this.textureBlock instanceof ReflectionTextureBlock);
+                this.textureBlock.texture = new Texture(null, this.props.globalState.nodeMaterial.getScene(), false, this.textureBlock instanceof ReflectionTextureBlock || this.textureBlock instanceof ReflectionBlock);
                 texture = this.textureBlock.texture;
                 texture.coordinatesMode = Texture.EQUIRECTANGULAR_MODE;
             } else {
@@ -119,7 +122,7 @@ export class TexturePropertyTabComponent extends React.Component<IPropertyCompon
         this._prepareTexture();
 
         let texture = this.textureBlock.texture as BaseTexture;       
-        if (texture.isCube || this.textureBlock instanceof ReflectionTextureBlock) {
+        if (texture.isCube || this.textureBlock instanceof ReflectionTextureBlock || this.textureBlock instanceof ReflectionBlock) {
             let extension: string | undefined = undefined;
             if (url.toLowerCase().indexOf(".dds") > 0) {
                 extension = ".dds";
@@ -143,7 +146,7 @@ export class TexturePropertyTabComponent extends React.Component<IPropertyCompon
 
         url = url.replace(/\?nocache=\d+/, "");
 
-        let isInReflectionMode = this.textureBlock instanceof ReflectionTextureBlock;
+        let isInReflectionMode = this.textureBlock instanceof ReflectionTextureBlock || this.textureBlock instanceof ReflectionBlock;
 
         var reflectionModeOptions: {label: string, value: number}[] = [
             {

+ 1 - 0
nodeEditor/src/diagram/propertyLedger.ts

@@ -19,5 +19,6 @@ PropertyLedger.RegisteredControls["LightBlock"] = LightPropertyTabComponent;
 PropertyLedger.RegisteredControls["LightInformationBlock"] = LightInformationPropertyTabComponent;
 PropertyLedger.RegisteredControls["TextureBlock"] = TexturePropertyTabComponent;
 PropertyLedger.RegisteredControls["ReflectionTextureBlock"] = TexturePropertyTabComponent;
+PropertyLedger.RegisteredControls["ReflectionBlock"] = TexturePropertyTabComponent;
 PropertyLedger.RegisteredControls["MetallicRoughnessTextureBlock"] = TexturePropertyTabComponent;
 PropertyLedger.RegisteredControls["TrigonometryBlock"] = TrigonometryPropertyTabComponent;

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

@@ -3,3 +3,4 @@ export * from "./sheenBlock";
 export * from "./ambientOcclusionBlock";
 export * from "./reflectivityBlock";
 export * from "./anisotropyBlock";
+export * from "./reflectionBlock";

+ 33 - 20
src/Materials/Node/Blocks/Fragment/PBR/pbrMetallicRoughnessBlock.ts

@@ -25,6 +25,7 @@ import { Engine } from '../../../../../Engines/engine';
 import { BRDFTextureTools } from '../../../../../Misc/brdfTextureTools';
 import { MaterialFlags } from '../../../../materialFlags';
 import { AnisotropyBlock } from './anisotropyBlock';
+import { ReflectionBlock } from './reflectionBlock';
 
 export class PBRMetallicRoughnessBlock extends NodeMaterialBlock {
     private _lightId: number;
@@ -52,7 +53,7 @@ export class PBRMetallicRoughnessBlock extends NodeMaterialBlock {
         this.registerInput("reflectivity", NodeMaterialBlockConnectionPointTypes.Object, false, NodeMaterialBlockTargets.Fragment, new NodeMaterialConnectionPointCustomObject("reflectivity", this, NodeMaterialConnectionPointDirection.Input, ReflectivityBlock, "ReflectivityBlock"));
         this.registerInput("ambientColor", NodeMaterialBlockConnectionPointTypes.Color3, true, NodeMaterialBlockTargets.Fragment);
         this.registerInput("ambientOcclusion", NodeMaterialBlockConnectionPointTypes.Object, true, NodeMaterialBlockTargets.Fragment, new NodeMaterialConnectionPointCustomObject("ambientOcclusion", this, NodeMaterialConnectionPointDirection.Input, AmbientOcclusionBlock, "AOBlock"));
-        this.registerInput("reflection", NodeMaterialBlockConnectionPointTypes.Object, true, NodeMaterialBlockTargets.Fragment);
+        this.registerInput("reflection", NodeMaterialBlockConnectionPointTypes.Object, true, NodeMaterialBlockTargets.Fragment, new NodeMaterialConnectionPointCustomObject("reflection", this, NodeMaterialConnectionPointDirection.Input, ReflectionBlock, "ReflectionBlock"));
         this.registerInput("sheen", NodeMaterialBlockConnectionPointTypes.Object, true, NodeMaterialBlockTargets.Fragment, new NodeMaterialConnectionPointCustomObject("sheen", this, NodeMaterialConnectionPointDirection.Input, SheenBlock, "SheenBlock"));
         this.registerInput("clearCoat", NodeMaterialBlockConnectionPointTypes.Object, true, NodeMaterialBlockTargets.Fragment);
         this.registerInput("subSurface", NodeMaterialBlockConnectionPointTypes.Object, true, NodeMaterialBlockTargets.Fragment);
@@ -312,6 +313,11 @@ export class PBRMetallicRoughnessBlock extends NodeMaterialBlock {
 
         anisotropyBlock?.prepareDefines(mesh, nodeMaterial, defines);
 
+        // Reflection
+        const reflectionBlock = this.reflectionParams.isConnected ? this.reflectionParams.connectedPoint?.ownerBlock as ReflectionBlock : null;
+
+        reflectionBlock?.prepareDefines(mesh, nodeMaterial, defines);
+
         // Rendering
         defines.setValue("RADIANCEOVERALPHA", this.useRadianceOverAlpha);
         defines.setValue("SPECULAROVERALPHA", this.useSpecularOverAlpha);
@@ -376,11 +382,9 @@ export class PBRMetallicRoughnessBlock extends NodeMaterialBlock {
     }
 
     public isReady() {
-        /*if (this.texture && !this.texture.isReadyOrNotBlocking()) {
-            return false;
-        }*/
+        const reflectionBlock = this.reflectionParams.isConnected ? this.reflectionParams.connectedPoint?.ownerBlock as ReflectionBlock : null;
 
-        return true;
+        return reflectionBlock?.isReady() ?? true;
     }
 
     public bind(effect: Effect, nodeMaterial: NodeMaterial, mesh?: Mesh) {
@@ -388,6 +392,10 @@ export class PBRMetallicRoughnessBlock extends NodeMaterialBlock {
             return;
         }
 
+        const reflectionBlock = this.reflectionParams.isConnected ? this.reflectionParams.connectedPoint?.ownerBlock as ReflectionBlock : null;
+
+        reflectionBlock?.bind(effect, nodeMaterial, mesh);
+
         const scene = mesh.getScene();
 
         if (!this.light) {
@@ -397,18 +405,6 @@ export class PBRMetallicRoughnessBlock extends NodeMaterialBlock {
         }
 
         effect.setTexture(this._environmentBrdfSamplerName, this._environmentBRDFTexture);
-
-        /*if (!mesh || !this.texture) {
-            return;
-        }
-
-        effect.setMatrix(this._reflectionMatrixName, this.texture.getReflectionTextureMatrix());
-
-        if (this.texture.isCube) {
-            effect.setTexture(this._cubeSamplerName, this.texture);
-        } else {
-            effect.setTexture(this._2DSamplerName, this.texture);
-        }*/
     }
 
     private _injectVertexCode(state: NodeMaterialBuildState) {
@@ -438,6 +434,10 @@ export class PBRMetallicRoughnessBlock extends NodeMaterialBlock {
             state.compilationString += `${worldPosVaryingName} = ${worldPos.associatedVariableName};\r\n`;
         }
 
+        const reflectionBlock = this.reflectionParams.isConnected ? this.reflectionParams.connectedPoint?.ownerBlock as ReflectionBlock : null;
+
+        state.compilationString += reflectionBlock?.handleVertexSide(state) ?? "";
+
         if (this.light) {
             state.compilationString += state._emitCodeFromInclude("shadowsVertex", comments, {
                 replaceStrings: [
@@ -482,6 +482,14 @@ export class PBRMetallicRoughnessBlock extends NodeMaterialBlock {
     protected _buildBlock(state: NodeMaterialBuildState) {
         super._buildBlock(state);
 
+        const reflectionBlock = this.reflectionParams.isConnected ? this.reflectionParams.connectedPoint?.ownerBlock as ReflectionBlock : null;
+
+        if (reflectionBlock) {
+            reflectionBlock.worldPositionConnectionPoint = this.worldPosition;
+            reflectionBlock.worldNormalConnectionPoint = this.worldNormal;
+            reflectionBlock.cameraPositionConnectionPoint = this.cameraPosition;
+        }
+
         if (state.target !== NodeMaterialBlockTargets.Fragment) {
             // Vertex
             this._injectVertexCode(state);
@@ -591,9 +599,6 @@ export class PBRMetallicRoughnessBlock extends NodeMaterialBlock {
         // _____________________________ Geometry info _________________________________
         state.compilationString += state._emitCodeFromInclude("pbrBlockGeometryInfo", comments);
 
-        // _____________________________ Direct Lighting Info __________________________________
-        state.compilationString += state._emitCodeFromInclude("pbrBlockDirectLighting", comments);
-
         // _____________________________ Anisotropy _______________________________________
         const anisotropyBlock = this.anisotropyParams.isConnected ? this.anisotropyParams.connectedPoint?.ownerBlock as AnisotropyBlock : null;
 
@@ -601,6 +606,14 @@ export class PBRMetallicRoughnessBlock extends NodeMaterialBlock {
             state.compilationString += anisotropyBlock.getCode();
         }
 
+        // _____________________________ Reflection _______________________________________
+        reflectionBlock?.handleFragmentSideInits(state);
+
+        state.compilationString += reflectionBlock?.handleFragmentSideCodeReflectionCoords();
+
+        // _____________________________ Direct Lighting Info __________________________________
+        state.compilationString += state._emitCodeFromInclude("pbrBlockDirectLighting", comments);
+
         /*if (this.light) {
             state.compilationString += state._emitCodeFromInclude("lightFragment", comments, {
                 replaceStrings: [

+ 53 - 6
src/Materials/Node/Blocks/Fragment/PBR/reflectionBlock.ts

@@ -1,4 +1,4 @@
-import { NodeMaterialBlock } from '../../../nodeMaterialBlock';
+//import { NodeMaterialBlock } from '../../../nodeMaterialBlock';
 import { NodeMaterialBlockConnectionPointTypes } from '../../../Enums/nodeMaterialBlockConnectionPointTypes';
 import { NodeMaterialBuildState } from '../../../nodeMaterialBuildState';
 import { NodeMaterialConnectionPoint, NodeMaterialConnectionPointDirection } from '../../../nodeMaterialBlockConnectionPoint';
@@ -7,13 +7,20 @@ import { NodeMaterialBlockTargets } from '../../../Enums/nodeMaterialBlockTarget
 import { _TypeStore } from '../../../../../Misc/typeStore';
 //import { editableInPropertyPage } from "../../../nodeMaterialDecorator";
 import { NodeMaterialConnectionPointCustomObject } from "../../../nodeMaterialConnectionPointCustomObject";
+import { ReflectionTextureBaseBlock } from '../../Dual/reflectionTextureBaseBlock';
 
-export class ReflectionBlock extends NodeMaterialBlock {
+export class ReflectionBlock extends ReflectionTextureBaseBlock {
+
+    public worldPositionConnectionPoint: NodeMaterialConnectionPoint;
+    public worldNormalConnectionPoint: NodeMaterialConnectionPoint;
+    public cameraPositionConnectionPoint: NodeMaterialConnectionPoint;
 
     public constructor(name: string) {
-        super(name, NodeMaterialBlockTargets.Fragment);
+        super(name);
 
-        //this.registerInput("texture", NodeMaterialBlockConnectionPointTypes.Color4, true, NodeMaterialBlockTargets.Fragment);
+        this.registerInput("position", NodeMaterialBlockConnectionPointTypes.Vector3, false, NodeMaterialBlockTargets.Vertex);
+        this.registerInput("world", NodeMaterialBlockConnectionPointTypes.Matrix, false, NodeMaterialBlockTargets.Vertex);
+        this.registerInput("view", NodeMaterialBlockConnectionPointTypes.Matrix, false, NodeMaterialBlockTargets.Fragment);
 
         this.registerOutput("reflection", NodeMaterialBlockConnectionPointTypes.Object, NodeMaterialBlockTargets.Fragment, new NodeMaterialConnectionPointCustomObject("reflection", this, NodeMaterialConnectionPointDirection.Output, ReflectionBlock, "ReflectionBlock"));
     }
@@ -26,13 +33,53 @@ export class ReflectionBlock extends NodeMaterialBlock {
         return "ReflectionBlock";
     }
 
+    /**
+     * Gets the world position input component
+     */
+    public get position(): NodeMaterialConnectionPoint {
+        return this._inputs[0];
+    }
+
+    /**
+     * Gets the world position input component
+     */
+    public get worldPosition(): NodeMaterialConnectionPoint {
+        return this.worldPositionConnectionPoint;
+    }
+
+    /**
+     * Gets the world normal input component
+     */
+    public get worldNormal(): NodeMaterialConnectionPoint {
+        return this.worldNormalConnectionPoint;
+    }
+
+    /**
+     * Gets the world input component
+     */
+    public get world(): NodeMaterialConnectionPoint {
+        return this._inputs[1];
+    }
+
+    /**
+    * Gets the camera (or eye) position component
+    */
+    public get cameraPosition(): NodeMaterialConnectionPoint {
+        return this.cameraPositionConnectionPoint;
+    }
+
+    /**
+     * Gets the view input component
+     */
+    public get view(): NodeMaterialConnectionPoint {
+        return this._inputs[2];
+    }
+
     public get reflection(): NodeMaterialConnectionPoint {
         return this._outputs[0];
     }
 
     protected _buildBlock(state: NodeMaterialBuildState) {
-        super._buildBlock(state);
-
         return this;
     }
 }