Forráskód Böngészése

Multiple updates to the PBR NME blocks

Popov72 4 éve
szülő
commit
23b3e299d1

+ 0 - 6
nodeEditor/src/blockTools.ts

@@ -65,8 +65,6 @@ import { ReflectBlock } from 'babylonjs/Materials/Node/Blocks/reflectBlock';
 import { DesaturateBlock } from 'babylonjs/Materials/Node/Blocks/desaturateBlock';
 import { PBRMetallicRoughnessBlock } from 'babylonjs/Materials/Node/Blocks/PBR/pbrMetallicRoughnessBlock';
 import { SheenBlock } from 'babylonjs/Materials/Node/Blocks/PBR/sheenBlock';
-import { AmbientOcclusionBlock } from 'babylonjs/Materials/Node/Blocks/PBR/ambientOcclusionBlock';
-import { ReflectivityBlock } from 'babylonjs/Materials/Node/Blocks/PBR/reflectivityBlock';
 import { AnisotropyBlock } from 'babylonjs/Materials/Node/Blocks/PBR/anisotropyBlock';
 import { ReflectionBlock } from 'babylonjs/Materials/Node/Blocks/PBR/reflectionBlock';
 import { ClearCoatBlock } from 'babylonjs/Materials/Node/Blocks/PBR/clearCoatBlock';
@@ -460,10 +458,6 @@ export class BlockTools {
                 return new PBRMetallicRoughnessBlock("PBRMetallicRoughness");
             case "SheenBlock":
                 return new SheenBlock("Sheen");
-            case "AmbientOcclusionBlock":
-                return new AmbientOcclusionBlock("AmbientOcclusion");
-            case "ReflectivityBlock":
-                return new ReflectivityBlock("Reflectivity");
             case "AnisotropyBlock":
                 return new AnisotropyBlock("Anisotropy");
             case "ReflectionBlock":

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

@@ -130,8 +130,6 @@ export class NodeListComponent extends React.Component<INodeListComponentProps,
         "Rotate2dBlock": "Rotates UV coordinates around the W axis.",
         "PBRMetallicRoughnessBlock": "PBR metallic/roughness material",
         "SheenBlock": "PBR Sheen block",
-        "AmbientOcclusionBlock": "PBR Ambient occlusion block",
-        "ReflectivityBlock": "PBR Reflectivity block",
         "AnisotropyBlock": "PBR Anisotropy block",
         "ReflectionBlock": "PBR Reflection block",
         "ClearCoatBlock": "PBR ClearCoat block",
@@ -238,7 +236,7 @@ export class NodeListComponent extends React.Component<INodeListComponentProps,
             Noises: ["RandomNumberBlock", "SimplexPerlin3DBlock", "WorleyNoise3DBlock"],
             Output_Nodes: ["VertexOutputBlock", "FragmentOutputBlock", "DiscardBlock"],
             Particle: ["ParticleBlendMultiplyBlock", "ParticleColorBlock", "ParticlePositionWorldBlock", "ParticleRampGradientBlock", "ParticleTextureBlock", "ParticleTextureMaskBlock", "ParticleUVBlock"],
-            PBR: ["PBRMetallicRoughnessBlock", "AmbientOcclusionBlock", "AnisotropyBlock", "ClearCoatBlock", "ReflectionBlock", "ReflectivityBlock", "RefractionBlock", "SheenBlock", "SubSurfaceBlock"],
+            PBR: ["PBRMetallicRoughnessBlock", "AnisotropyBlock", "ClearCoatBlock", "ReflectionBlock", "RefractionBlock", "SheenBlock", "SubSurfaceBlock"],
             PostProcess: ["ScreenPositionBlock", "CurrentScreenBlock"],
             Procedural__Texture: ["ScreenPositionBlock"],
             Range: ["ClampBlock", "RemapBlock", "NormalizeBlock"],

+ 1 - 0
nodeEditor/src/components/preview/previewManager.ts

@@ -99,6 +99,7 @@ export class PreviewManager {
         this._engine = new Engine(targetCanvas, true);
         this._scene = new Scene(this._engine);
         this._scene.clearColor = this._globalState.backgroundColor;
+        this._scene.ambientColor = new Color3(1, 1, 1);
         this._camera = new ArcRotateCamera("Camera", 0, 0.8, 4, Vector3.Zero(), this._scene);
 
         this._camera.lowerRadiusLimit = 3;

+ 1 - 1
src/Materials/Node/Blocks/Dual/reflectionTextureBaseBlock.ts

@@ -135,7 +135,7 @@ export abstract class ReflectionTextureBaseBlock extends NodeMaterialBlock {
             worldInput.output.connectTo(this.world);
         }
 
-        if (!this.view.isConnected) {
+        if (this.view && !this.view.isConnected) {
             let viewInput = material.getInputBlockByPredicate((b) => b.systemValue === NodeMaterialSystemValues.View);
 
             if (!viewInput) {

+ 0 - 146
src/Materials/Node/Blocks/PBR/ambientOcclusionBlock.ts

@@ -1,146 +0,0 @@
-import { NodeMaterialBlock } from '../../nodeMaterialBlock';
-import { NodeMaterialBlockConnectionPointTypes } from '../../Enums/nodeMaterialBlockConnectionPointTypes';
-import { NodeMaterialBuildState } from '../../nodeMaterialBuildState';
-import { NodeMaterialConnectionPoint, NodeMaterialConnectionPointDirection } from '../../nodeMaterialBlockConnectionPoint';
-import { NodeMaterialBlockTargets } from '../../Enums/nodeMaterialBlockTargets';
-import { NodeMaterial, NodeMaterialDefines } from '../../nodeMaterial';
-import { Nullable } from '../../../../types';
-import { editableInPropertyPage, PropertyTypeForEdition } from "../../nodeMaterialDecorator";
-import { _TypeStore } from '../../../../Misc/typeStore';
-import { AbstractMesh } from '../../../../Meshes/abstractMesh';
-import { NodeMaterialConnectionPointCustomObject } from "../../nodeMaterialConnectionPointCustomObject";
-import { Scene } from '../../../../scene';
-
-/**
- * Block used to implement the ambient occlusion module of the PBR material
- */
-export class AmbientOcclusionBlock extends NodeMaterialBlock {
-
-    /**
-     * Create a new AmbientOcclusionBlock
-     * @param name defines the block name
-     */
-    public constructor(name: string) {
-        super(name, NodeMaterialBlockTargets.Fragment);
-
-        this._isUnique = true;
-
-        this.registerInput("texture", NodeMaterialBlockConnectionPointTypes.Color3, true, NodeMaterialBlockTargets.Fragment);
-        this.registerInput("intensity", NodeMaterialBlockConnectionPointTypes.Float, true, NodeMaterialBlockTargets.Fragment);
-        this.registerInput("directLightIntensity", NodeMaterialBlockConnectionPointTypes.Float, true, NodeMaterialBlockTargets.Fragment);
-
-        this.registerOutput("ambientOcc", NodeMaterialBlockConnectionPointTypes.Object, NodeMaterialBlockTargets.Fragment,
-            new NodeMaterialConnectionPointCustomObject("ambientOcc", this, NodeMaterialConnectionPointDirection.Output, AmbientOcclusionBlock, "AOBlock", "ambientOcc"));
-    }
-
-    /**
-     * Specifies if the ambient texture contains the ambient occlusion information in its red channel only.
-     */
-    @editableInPropertyPage("Ambient in gray scale", PropertyTypeForEdition.Boolean, "AMBIENT", { "notifiers": { "update": true }})
-    public useAmbientInGrayScale: boolean = false;
-
-    /**
-     * Initialize the block and prepare the context for build
-     * @param state defines the state that will be used for the build
-     */
-    public initialize(state: NodeMaterialBuildState) {
-        state._excludeVariableName("aoOut");
-    }
-
-    /**
-     * Gets the current class name
-     * @returns the class name
-     */
-    public getClassName() {
-        return "AmbientOcclusionBlock";
-    }
-
-    /**
-     * Gets the texture input component
-     */
-    public get texture(): NodeMaterialConnectionPoint {
-        return this._inputs[0];
-    }
-
-    /**
-     * Gets the texture intensity component
-     */
-    public get intensity(): NodeMaterialConnectionPoint {
-        return this._inputs[1];
-    }
-
-    /**
-     * Gets the direct light intensity input component
-     */
-    public get directLightIntensity(): NodeMaterialConnectionPoint {
-        return this._inputs[2];
-    }
-
-    /**
-     * Gets the ambient occlusion object output component
-     */
-    public get ambientOcc(): NodeMaterialConnectionPoint {
-        return this._outputs[0];
-    }
-
-    /**
-     * Gets the main code of the block (fragment side)
-     * @param block instance of an AmbientOcclusionBlock or null if the code must be generated without an active ambient occlusion module
-     * @returns the shader code
-     */
-    public static GetCode(block: Nullable<AmbientOcclusionBlock>): string {
-        let code = `ambientOcclusionOutParams aoOut;\r\n`;
-
-        const aoTexture = block?.texture.isConnected ? block.texture.associatedVariableName : "vec3(0.)";
-        const aoIntensity = block?.intensity.isConnected ? block.intensity.associatedVariableName : "1.";
-
-        code += `ambientOcclusionBlock(
-            #ifdef AMBIENT
-                ${aoTexture},
-                vec4(0., 1.0, ${aoIntensity}, 0.),
-            #endif
-                aoOut
-            );\r\n`;
-
-        return code;
-    }
-
-    public prepareDefines(mesh: AbstractMesh, nodeMaterial: NodeMaterial, defines: NodeMaterialDefines) {
-        super.prepareDefines(mesh, nodeMaterial, defines);
-
-        defines.setValue("AMBIENT", this.texture.isConnected, true);
-        defines.setValue("AMBIENTINGRAYSCALE", this.useAmbientInGrayScale, true);
-    }
-
-    protected _buildBlock(state: NodeMaterialBuildState) {
-        if (state.target === NodeMaterialBlockTargets.Fragment) {
-            state.sharedData.blocksWithDefines.push(this);
-        }
-
-        return this;
-    }
-
-    protected _dumpPropertiesCode() {
-        let codeString: string;
-
-        codeString = `${this._codeVariableName}.useAmbientInGrayScale = ${this.useAmbientInGrayScale};\r\n`;
-
-        return codeString;
-    }
-
-    public serialize(): any {
-        let serializationObject = super.serialize();
-
-        serializationObject.useAmbientInGrayScale = this.useAmbientInGrayScale;
-
-        return serializationObject;
-    }
-
-    public _deserialize(serializationObject: any, scene: Scene, rootUrl: string) {
-        super._deserialize(serializationObject, scene, rootUrl);
-
-        this.useAmbientInGrayScale = serializationObject.useAmbientInGrayScale;
-    }
-}
-
-_TypeStore.RegisteredTypes["BABYLON.AmbientOcclusionBlock"] = AmbientOcclusionBlock;

+ 4 - 13
src/Materials/Node/Blocks/PBR/anisotropyBlock.ts

@@ -35,7 +35,6 @@ export class AnisotropyBlock extends NodeMaterialBlock {
 
         this.registerInput("intensity", NodeMaterialBlockConnectionPointTypes.Float, true, NodeMaterialBlockTargets.Fragment);
         this.registerInput("direction", NodeMaterialBlockConnectionPointTypes.Vector2, true, NodeMaterialBlockTargets.Fragment);
-        this.registerInput("texture", NodeMaterialBlockConnectionPointTypes.Color3, true, NodeMaterialBlockTargets.Fragment);
         this.registerInput("uv", NodeMaterialBlockConnectionPointTypes.Vector2, true); // need this property and the next one in case there's no PerturbNormal block connected to the main PBR block
         this.registerInput("worldTangent", NodeMaterialBlockConnectionPointTypes.Vector4, true);
 
@@ -75,24 +74,17 @@ export class AnisotropyBlock extends NodeMaterialBlock {
     }
 
     /**
-     * Gets the texture input component
-     */
-    public get texture(): NodeMaterialConnectionPoint {
-        return this._inputs[2];
-    }
-
-    /**
      * Gets the uv input component
      */
     public get uv(): NodeMaterialConnectionPoint {
-        return this._inputs[3];
+        return this._inputs[2];
     }
 
     /**
      * Gets the worldTangent input component
      */
     public get worldTangent(): NodeMaterialConnectionPoint {
-        return this._inputs[4];
+        return this._inputs[3];
     }
 
     /**
@@ -160,13 +152,12 @@ export class AnisotropyBlock extends NodeMaterialBlock {
 
         const intensity = this.intensity.isConnected ? this.intensity.associatedVariableName : "1.0";
         const direction = this.direction.isConnected ? this.direction.associatedVariableName : "vec2(1., 0.)";
-        const texture = this.texture.isConnected ? this.texture.associatedVariableName : "vec3(0.)";
 
         code += `anisotropicOutParams anisotropicOut;
             anisotropicBlock(
                 vec3(${direction}, ${intensity}),
             #ifdef ANISOTROPIC_TEXTURE
-                ${texture},
+                vec3(0.),
             #endif
                 TBN,
                 normalW,
@@ -181,7 +172,7 @@ export class AnisotropyBlock extends NodeMaterialBlock {
         super.prepareDefines(mesh, nodeMaterial, defines);
 
         defines.setValue("ANISOTROPIC", true);
-        defines.setValue("ANISOTROPIC_TEXTURE", this.texture.isConnected, true);
+        defines.setValue("ANISOTROPIC_TEXTURE", false, true);
     }
 
     protected _buildBlock(state: NodeMaterialBuildState) {

+ 13 - 22
src/Materials/Node/Blocks/PBR/clearCoatBlock.ts

@@ -36,8 +36,7 @@ export class ClearCoatBlock extends NodeMaterialBlock {
         this.registerInput("intensity", NodeMaterialBlockConnectionPointTypes.Float, false, NodeMaterialBlockTargets.Fragment);
         this.registerInput("roughness", NodeMaterialBlockConnectionPointTypes.Float, true, NodeMaterialBlockTargets.Fragment);
         this.registerInput("ior", NodeMaterialBlockConnectionPointTypes.Float, true, NodeMaterialBlockTargets.Fragment);
-        this.registerInput("texture", NodeMaterialBlockConnectionPointTypes.Color3, true, NodeMaterialBlockTargets.Fragment);
-        this.registerInput("bumpTexture", NodeMaterialBlockConnectionPointTypes.Color4, true, NodeMaterialBlockTargets.Fragment);
+        this.registerInput("normalMapColor", NodeMaterialBlockConnectionPointTypes.Color3, true, NodeMaterialBlockTargets.Fragment);
         this.registerInput("uv", NodeMaterialBlockConnectionPointTypes.Vector2, true, NodeMaterialBlockTargets.Fragment);
         this.registerInput("tintColor", NodeMaterialBlockConnectionPointTypes.Color3, true, NodeMaterialBlockTargets.Fragment);
         this.registerInput("tintAtDistance", NodeMaterialBlockConnectionPointTypes.Float, true, NodeMaterialBlockTargets.Fragment);
@@ -90,52 +89,45 @@ export class ClearCoatBlock extends NodeMaterialBlock {
     }
 
     /**
-     * Gets the texture input component
-     */
-    public get texture(): NodeMaterialConnectionPoint {
-        return this._inputs[3];
-    }
-
-    /**
      * Gets the bump texture input component
      */
-    public get bumpTexture(): NodeMaterialConnectionPoint {
-        return this._inputs[4];
+    public get normalMapColor(): NodeMaterialConnectionPoint {
+        return this._inputs[3];
     }
 
     /**
      * Gets the uv input component
      */
     public get uv(): NodeMaterialConnectionPoint {
-        return this._inputs[5];
+        return this._inputs[4];
     }
 
     /**
      * Gets the tint color input component
      */
     public get tintColor(): NodeMaterialConnectionPoint {
-        return this._inputs[6];
+        return this._inputs[5];
     }
 
     /**
      * Gets the tint "at distance" input component
      */
     public get tintAtDistance(): NodeMaterialConnectionPoint {
-        return this._inputs[7];
+        return this._inputs[6];
     }
 
     /**
      * Gets the tint thickness input component
      */
     public get tintThickness(): NodeMaterialConnectionPoint {
-        return this._inputs[8];
+        return this._inputs[7];
     }
 
     /**
      * Gets the world tangent input component
      */
     public get worldTangent(): NodeMaterialConnectionPoint {
-        return this._inputs[9];
+        return this._inputs[8];
     }
 
     /**
@@ -157,10 +149,10 @@ export class ClearCoatBlock extends NodeMaterialBlock {
         super.prepareDefines(mesh, nodeMaterial, defines);
 
         defines.setValue("CLEARCOAT", true);
-        defines.setValue("CLEARCOAT_TEXTURE", this.texture.isConnected, true);
+        defines.setValue("CLEARCOAT_TEXTURE", false, true);
         defines.setValue("CLEARCOAT_USE_ROUGHNESS_FROM_MAINTEXTURE", true, true);
         defines.setValue("CLEARCOAT_TINT", this.tintColor.isConnected || this.tintThickness.isConnected || this.tintAtDistance.isConnected, true);
-        defines.setValue("CLEARCOAT_BUMP", this.bumpTexture.isConnected, true);
+        defines.setValue("CLEARCOAT_BUMP", this.normalMapColor.isConnected, true);
         defines.setValue("CLEARCOAT_DEFAULTIOR", this.ior.isConnected ? this.ior.connectInputBlock!.value === 1.5 : false, true);
     }
 
@@ -230,8 +222,7 @@ export class ClearCoatBlock extends NodeMaterialBlock {
 
         const intensity = ccBlock?.intensity.isConnected ? ccBlock.intensity.associatedVariableName : "1.";
         const roughness = ccBlock?.roughness.isConnected ? ccBlock.roughness.associatedVariableName : "0.";
-        const texture = ccBlock?.texture.isConnected ? ccBlock.texture.associatedVariableName : "vec2(0.)";
-        const bumpTexture = ccBlock?.bumpTexture.isConnected ? ccBlock.bumpTexture.associatedVariableName : "vec4(0.)";
+        const normalMapColor = ccBlock?.normalMapColor.isConnected ? ccBlock.normalMapColor.associatedVariableName : "vec3(0.)";
         const uv = ccBlock?.uv.isConnected ? ccBlock.uv.associatedVariableName : "vec2(0.)";
 
         const tintColor = ccBlock?.tintColor.isConnected ? ccBlock.tintColor.associatedVariableName : "vec3(1.)";
@@ -262,7 +253,7 @@ export class ClearCoatBlock extends NodeMaterialBlock {
                 vClearCoatParams,
                 specularEnvironmentR0,
             #ifdef CLEARCOAT_TEXTURE
-                ${texture}.rg,
+                vec2(0.),
             #endif
             #ifdef CLEARCOAT_TINT
                 vClearCoatTintParams,
@@ -274,7 +265,7 @@ export class ClearCoatBlock extends NodeMaterialBlock {
             #endif
             #ifdef CLEARCOAT_BUMP
                 vec2(0., 1.),
-                ${bumpTexture},
+                vec4(${normalMapColor}, 0.),
                 ${uv},
                 #if defined(${vTBNAvailable ? "TANGENT" : "IGNORE"}) && defined(NORMAL)
                     vTBN,

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

@@ -1,7 +1,5 @@
 export * from "./pbrMetallicRoughnessBlock";
 export * from "./sheenBlock";
-export * from "./ambientOcclusionBlock";
-export * from "./reflectivityBlock";
 export * from "./anisotropyBlock";
 export * from "./reflectionBlock";
 export * from "./clearCoatBlock";

+ 174 - 89
src/Materials/Node/Blocks/PBR/pbrMetallicRoughnessBlock.ts

@@ -17,9 +17,7 @@ import { PBRBaseMaterial } from '../../../PBR/pbrBaseMaterial';
 import { Scene } from '../../../../scene';
 import { editableInPropertyPage, PropertyTypeForEdition } from "../../nodeMaterialDecorator";
 import { NodeMaterialConnectionPointCustomObject } from "../../nodeMaterialConnectionPointCustomObject";
-import { AmbientOcclusionBlock } from './ambientOcclusionBlock';
 import { SheenBlock } from './sheenBlock';
-import { ReflectivityBlock } from './reflectivityBlock';
 import { BaseTexture } from '../../../Textures/baseTexture';
 import { BRDFTextureTools } from '../../../../Misc/brdfTextureTools';
 import { MaterialFlags } from '../../../materialFlags';
@@ -30,6 +28,7 @@ import { SubSurfaceBlock } from './subSurfaceBlock';
 import { RefractionBlock } from './refractionBlock';
 import { PerturbNormalBlock } from '../Fragment/perturbNormalBlock';
 import { Constants } from '../../../../Engines/constants';
+import { Color3, TmpColors } from '../../../../Maths/math.color';
 
 const mapOutputToVariable: { [name: string] : [string, string] } = {
     "ambient":      ["finalAmbient", ""],
@@ -62,6 +61,10 @@ export class PBRMetallicRoughnessBlock extends NodeMaterialBlock {
     private _environmentBrdfSamplerName: string;
     private _vNormalWName: string;
     private _invertNormalName: string;
+    private _indexOfRefractionConnectionPoint: Nullable<NodeMaterialConnectionPoint>;
+    private _metallicReflectanceColor: Color3 = Color3.White();
+    private _metallicF0Factor = 1;
+    private _vMetallicReflectanceFactorsName: string;
 
     /**
      * Create a new ReflectionBlock
@@ -74,15 +77,15 @@ export class PBRMetallicRoughnessBlock extends NodeMaterialBlock {
 
         this.registerInput("worldPosition", NodeMaterialBlockConnectionPointTypes.Vector4, false, NodeMaterialBlockTargets.Vertex);
         this.registerInput("worldNormal", NodeMaterialBlockConnectionPointTypes.Vector4, false, NodeMaterialBlockTargets.Fragment);
+        this.registerInput("view", NodeMaterialBlockConnectionPointTypes.Matrix, false);
         this.registerInput("perturbedNormal", NodeMaterialBlockConnectionPointTypes.Vector4, true, NodeMaterialBlockTargets.Fragment);
         this.registerInput("cameraPosition", NodeMaterialBlockConnectionPointTypes.Vector3, false, NodeMaterialBlockTargets.Fragment);
-        this.registerInput("baseColor", NodeMaterialBlockConnectionPointTypes.Color4, true, NodeMaterialBlockTargets.Fragment);
-        this.registerInput("opacityTexture", NodeMaterialBlockConnectionPointTypes.Color4, true, NodeMaterialBlockTargets.Fragment);
+        this.registerInput("baseColor", NodeMaterialBlockConnectionPointTypes.Color3, true, NodeMaterialBlockTargets.Fragment);
+        this.registerInput("metallic", NodeMaterialBlockConnectionPointTypes.Float, false, NodeMaterialBlockTargets.Fragment);
+        this.registerInput("roughness", NodeMaterialBlockConnectionPointTypes.Float, false, NodeMaterialBlockTargets.Fragment);
+        this.registerInput("ambientOcc", NodeMaterialBlockConnectionPointTypes.Float, true, NodeMaterialBlockTargets.Fragment);
+        this.registerInput("opacity", NodeMaterialBlockConnectionPointTypes.Float, true, NodeMaterialBlockTargets.Fragment);
         this.registerInput("ambientColor", NodeMaterialBlockConnectionPointTypes.Color3, true, NodeMaterialBlockTargets.Fragment);
-        this.registerInput("reflectivity", NodeMaterialBlockConnectionPointTypes.Object, false, NodeMaterialBlockTargets.Fragment,
-            new NodeMaterialConnectionPointCustomObject("reflectivity", this, NodeMaterialConnectionPointDirection.Input, ReflectivityBlock, "ReflectivityBlock"));
-        this.registerInput("ambientOcc", NodeMaterialBlockConnectionPointTypes.Object, true, NodeMaterialBlockTargets.Fragment,
-            new NodeMaterialConnectionPointCustomObject("ambientOcc", this, NodeMaterialConnectionPointDirection.Input, AmbientOcclusionBlock, "AOBlock"));
         this.registerInput("reflection", NodeMaterialBlockConnectionPointTypes.Object, true, NodeMaterialBlockTargets.Fragment,
             new NodeMaterialConnectionPointCustomObject("reflection", this, NodeMaterialConnectionPointDirection.Input, ReflectionBlock, "ReflectionBlock"));
         this.registerInput("sheen", NodeMaterialBlockConnectionPointTypes.Object, true, NodeMaterialBlockTargets.Fragment,
@@ -93,11 +96,10 @@ export class PBRMetallicRoughnessBlock extends NodeMaterialBlock {
             new NodeMaterialConnectionPointCustomObject("subsurface", this, NodeMaterialConnectionPointDirection.Input, SubSurfaceBlock, "SubSurfaceBlock"));
         this.registerInput("anisotropy", NodeMaterialBlockConnectionPointTypes.Object, true, NodeMaterialBlockTargets.Fragment,
             new NodeMaterialConnectionPointCustomObject("anisotropy", this, NodeMaterialConnectionPointDirection.Input, AnisotropyBlock, "AnisotropyBlock"));
-        this.registerInput("view", NodeMaterialBlockConnectionPointTypes.Matrix, true);
 
-        this.registerOutput("ambient", NodeMaterialBlockConnectionPointTypes.Color3, NodeMaterialBlockTargets.Fragment);
-        this.registerOutput("diffuse", NodeMaterialBlockConnectionPointTypes.Color3, NodeMaterialBlockTargets.Fragment);
-        this.registerOutput("specular", NodeMaterialBlockConnectionPointTypes.Color3, NodeMaterialBlockTargets.Fragment);
+        this.registerOutput("ambientClr", NodeMaterialBlockConnectionPointTypes.Color3, NodeMaterialBlockTargets.Fragment);
+        this.registerOutput("diffuseDir", NodeMaterialBlockConnectionPointTypes.Color3, NodeMaterialBlockTargets.Fragment);
+        this.registerOutput("specularDir", NodeMaterialBlockConnectionPointTypes.Color3, NodeMaterialBlockTargets.Fragment);
         this.registerOutput("sheenDir", NodeMaterialBlockConnectionPointTypes.Color3, NodeMaterialBlockTargets.Fragment);
         this.registerOutput("clearcoatDir", NodeMaterialBlockConnectionPointTypes.Color3, NodeMaterialBlockTargets.Fragment);
         this.registerOutput("diffuseInd", NodeMaterialBlockConnectionPointTypes.Color3, NodeMaterialBlockTargets.Fragment);
@@ -145,29 +147,22 @@ export class PBRMetallicRoughnessBlock extends NodeMaterialBlock {
     /**
      * Specifies that alpha test should be used
      */
-    @editableInPropertyPage("Alpha Testing", PropertyTypeForEdition.Boolean, "TRANSPARENCY")
+    @editableInPropertyPage("Alpha Testing", PropertyTypeForEdition.Boolean, "OPACITY")
     public useAlphaTest: boolean = false;
 
     /**
      * Defines the alpha limits in alpha test mode.
      */
-    @editableInPropertyPage("Alpha CutOff", PropertyTypeForEdition.Float, "TRANSPARENCY", { min: 0, max: 1, "notifiers": { "update": true }})
+    @editableInPropertyPage("Alpha CutOff", PropertyTypeForEdition.Float, "OPACITY", { min: 0, max: 1, "notifiers": { "update": true }})
     public alphaTestCutoff: number = 0.5;
 
     /**
      * Specifies that alpha blending should be used
      */
-    @editableInPropertyPage("Alpha blending", PropertyTypeForEdition.Boolean, "TRANSPARENCY")
+    @editableInPropertyPage("Alpha blending", PropertyTypeForEdition.Boolean, "OPACITY")
     public useAlphaBlending: boolean = false;
 
     /**
-     * Defines if the alpha value should be determined via the rgb values.
-     * If true the luminance of the pixel might be used to find the corresponding alpha value.
-     */
-    @editableInPropertyPage("Get alpha from opacity texture RGB", PropertyTypeForEdition.Boolean, "TRANSPARENCY", { "notifiers": { "update": true }})
-    public opacityRGB: boolean = false;
-
-    /**
      * Specifies that the material will keeps the reflection highlights over a transparent surface (only the most luminous ones).
      * A car glass is a good exemple of that. When the street lights reflects on it you can not see what is behind.
      */
@@ -258,18 +253,8 @@ export class PBRMetallicRoughnessBlock extends NodeMaterialBlock {
         { label: "Anisotropic Tangents", value: 12 },
         { label: "Anisotropic Bitangents", value: 13 },
         // Maps
-        { label: "Albedo Map", value: 20 },
-        { label: "Ambient Map", value: 21 },
-        { label: "Opacity Map", value: 22 },
         //{ label: "Emissive Map", value: 23 },
         //{ label: "Light Map", value: 24 },
-        { label: "Metallic Map", value: 25 },
-        { label: "Reflectivity Map", value: 26 },
-        { label: "ClearCoat Map", value: 27 },
-        { label: "ClearCoat Tint Map", value: 28 },
-        { label: "Sheen Map", value: 29 },
-        { label: "Anisotropic Map", value: 30 },
-        { label: "Thickness Map", value: 31 },
         // Env
         { label: "Env Refraction", value: 40 },
         { label: "Env Reflection", value: 41 },
@@ -336,6 +321,13 @@ export class PBRMetallicRoughnessBlock extends NodeMaterialBlock {
         state._excludeVariableName("surfaceAlbedo");
         state._excludeVariableName("alpha");
 
+        state._excludeVariableName("aoOut");
+
+        state._excludeVariableName("baseColor");
+        state._excludeVariableName("reflectivityOut");
+        state._excludeVariableName("microSurface");
+        state._excludeVariableName("roughness");
+
         state._excludeVariableName("NdotVUnclamped");
         state._excludeVariableName("NdotV");
         state._excludeVariableName("alphaG");
@@ -388,114 +380,121 @@ export class PBRMetallicRoughnessBlock extends NodeMaterialBlock {
     }
 
     /**
-     * Gets the perturbed normal input component
+     * Gets the view matrix parameter
      */
-    public get perturbedNormal(): NodeMaterialConnectionPoint {
+    public get view(): NodeMaterialConnectionPoint {
         return this._inputs[2];
     }
 
     /**
-     * Gets the camera position input component
+     * Gets the perturbed normal input component
      */
-    public get cameraPosition(): NodeMaterialConnectionPoint {
+    public get perturbedNormal(): NodeMaterialConnectionPoint {
         return this._inputs[3];
     }
 
     /**
-     * Gets the base color input component
+     * Gets the camera position input component
      */
-    public get baseColor(): NodeMaterialConnectionPoint {
+    public get cameraPosition(): NodeMaterialConnectionPoint {
         return this._inputs[4];
     }
 
     /**
-     * Gets the opacity texture input component
+     * Gets the base color input component
      */
-    public get opacityTexture(): NodeMaterialConnectionPoint {
+    public get baseColor(): NodeMaterialConnectionPoint {
         return this._inputs[5];
     }
 
     /**
-     * Gets the ambient color input component
+     * Gets the metallic input component
      */
-    public get ambientColor(): NodeMaterialConnectionPoint {
+    public get metallic(): NodeMaterialConnectionPoint {
         return this._inputs[6];
     }
 
     /**
-     * Gets the reflectivity object parameters
+     * Gets the roughness input component
      */
-    public get reflectivity(): NodeMaterialConnectionPoint {
+    public get roughness(): NodeMaterialConnectionPoint {
         return this._inputs[7];
     }
 
     /**
-     * Gets the ambient occlusion object parameters
+     * Gets the ambient occlusion input component
      */
     public get ambientOcc(): NodeMaterialConnectionPoint {
         return this._inputs[8];
     }
 
     /**
-     * Gets the reflection object parameters
+     * Gets the opacity input component
      */
-    public get reflection(): NodeMaterialConnectionPoint {
+    public get opacity(): NodeMaterialConnectionPoint {
         return this._inputs[9];
     }
 
     /**
-     * Gets the sheen object parameters
+     * Gets the ambient color input component
      */
-    public get sheen(): NodeMaterialConnectionPoint {
+    public get ambientColor(): NodeMaterialConnectionPoint {
         return this._inputs[10];
     }
 
     /**
-     * Gets the clear coat object parameters
+     * Gets the reflection object parameters
      */
-    public get clearcoat(): NodeMaterialConnectionPoint {
+    public get reflection(): NodeMaterialConnectionPoint {
         return this._inputs[11];
     }
 
     /**
-     * Gets the sub surface object parameters
+     * Gets the sheen object parameters
      */
-    public get subsurface(): NodeMaterialConnectionPoint {
+    public get sheen(): NodeMaterialConnectionPoint {
         return this._inputs[12];
     }
 
     /**
-     * Gets the anisotropy object parameters
+     * Gets the clear coat object parameters
      */
-    public get anisotropy(): NodeMaterialConnectionPoint {
+    public get clearcoat(): NodeMaterialConnectionPoint {
         return this._inputs[13];
     }
 
     /**
-     * Gets the view matrix parameter
+     * Gets the sub surface object parameters
      */
-    public get view(): NodeMaterialConnectionPoint {
+    public get subsurface(): NodeMaterialConnectionPoint {
         return this._inputs[14];
     }
 
     /**
+     * Gets the anisotropy object parameters
+     */
+    public get anisotropy(): NodeMaterialConnectionPoint {
+        return this._inputs[15];
+    }
+
+    /**
      * Gets the ambient output component
      */
-    public get ambient(): NodeMaterialConnectionPoint {
+    public get ambientClr(): NodeMaterialConnectionPoint {
         return this._outputs[0];
     }
 
     /**
      * Gets the diffuse output component
      */
-    public get diffuse(): NodeMaterialConnectionPoint {
+    public get diffuseDir(): NodeMaterialConnectionPoint {
         return this._outputs[1];
     }
 
     /**
      * Gets the specular output component
      */
-    public get specular(): NodeMaterialConnectionPoint {
+    public get specularDir(): NodeMaterialConnectionPoint {
         return this._outputs[2];
     }
 
@@ -579,6 +578,16 @@ export class PBRMetallicRoughnessBlock extends NodeMaterialBlock {
             }
             cameraPositionInput.output.connectTo(this.cameraPosition);
         }
+
+        if (!this.view.isConnected) {
+            let viewInput = material.getInputBlockByPredicate((b) => b.systemValue === NodeMaterialSystemValues.View);
+
+            if (!viewInput) {
+                viewInput = new InputBlock("view");
+                viewInput.setAsSystemValue(NodeMaterialSystemValues.View);
+            }
+            viewInput.output.connectTo(this.view);
+        }
     }
 
     public prepareDefines(mesh: AbstractMesh, nodeMaterial: NodeMaterial, defines: NodeMaterialDefines) {
@@ -591,7 +600,19 @@ export class PBRMetallicRoughnessBlock extends NodeMaterialBlock {
         defines.setValue("LODBASEDMICROSFURACE", this._scene.getEngine().getCaps().textureLOD);
 
         // Albedo & Opacity
-        defines.setValue("OPACITY", this.opacityTexture.isConnected, true);
+        defines.setValue("ALBEDO", false, true);
+        defines.setValue("OPACITY", this.opacity.isConnected, true);
+
+        // Ambient occlusion
+        defines.setValue("AMBIENT", true, true);
+        defines.setValue("AMBIENTINGRAYSCALE", false, true);
+
+        // Reflectivity
+        defines.setValue("REFLECTIVITY", false, true);
+        defines.setValue("AOSTOREINMETALMAPRED", false, true);
+        defines.setValue("METALLNESSSTOREINMETALMAPBLUE", false, true);
+        defines.setValue("ROUGHNESSSTOREINMETALMAPALPHA", false, true);
+        defines.setValue("ROUGHNESSSTOREINMETALMAPGREEN",  false, true);
 
         // Lighting & colors
         if (this.lightFalloff === PBRBaseMaterial.LIGHTFALLOFF_STANDARD) {
@@ -612,7 +633,7 @@ export class PBRMetallicRoughnessBlock extends NodeMaterialBlock {
         defines.setValue("ALPHAFROMALBEDO", false, true);
         defines.setValue("ALPHATEST", this.useAlphaTest, true);
         defines.setValue("ALPHATESTVALUE", alphaTestCutOffString.indexOf('.') < 0 ? alphaTestCutOffString + "." : alphaTestCutOffString, true);
-        defines.setValue("OPACITYRGB", this.opacityRGB, true);
+        defines.setValue("OPACITYRGB", false, true);
 
         // Rendering
         defines.setValue("RADIANCEOVERALPHA", this.useRadianceOverAlpha, true);
@@ -709,6 +730,21 @@ export class PBRMetallicRoughnessBlock extends NodeMaterialBlock {
         effect.setFloat(this._invertNormalName, invertNormal ? -1 : 1);
 
         effect.setFloat4("vLightingIntensity", this.directIntensity, 1, this.environmentIntensity * this._scene.environmentIntensity, this.specularIntensity);
+
+        // reflectivity bindings
+        const outside_ior = 1; // consider air as clear coat and other layers would remap in the shader.
+        const ior = this._indexOfRefractionConnectionPoint?.connectInputBlock?.value ?? 1.5;
+
+        // We are here deriving our default reflectance from a common value for none metallic surface.
+        // Based of the schlick fresnel approximation model
+        // for dielectrics.
+        const f0 = Math.pow((ior - outside_ior) / (ior + outside_ior), 2);
+
+        // Tweak the default F0 and F90 based on our given setup
+        this._metallicReflectanceColor.scaleToRef(f0 * this._metallicF0Factor, TmpColors.Color3[0]);
+        const metallicF90 = this._metallicF0Factor;
+
+        effect.setColor4(this._vMetallicReflectanceFactorsName, TmpColors.Color3[0], metallicF90);
     }
 
     private _injectVertexCode(state: NodeMaterialBuildState) {
@@ -740,6 +776,10 @@ export class PBRMetallicRoughnessBlock extends NodeMaterialBlock {
 
         const reflectionBlock = this.reflection.isConnected ? this.reflection.connectedPoint?.ownerBlock as ReflectionBlock : null;
 
+        if (reflectionBlock) {
+            reflectionBlock.viewConnectionPoint = this.view;
+        }
+
         state.compilationString += reflectionBlock?.handleVertexSide(state) ?? "";
 
         state._emitUniformFromString("vDebugMode", "vec2", "defined(IGNORE) || DEBUGMODE > 0");
@@ -769,24 +809,20 @@ export class PBRMetallicRoughnessBlock extends NodeMaterialBlock {
         }
     }
 
-    /**
-     * Gets the code corresponding to the albedo/opacity module
-     * @returns the shader code
-     */
-    public getAlbedoOpacityCode(): string {
+    private _getAlbedoOpacityCode(): string {
         let code = `albedoOpacityOutParams albedoOpacityOut;\r\n`;
 
-        const albedoColor = this.baseColor.isConnected ? this.baseColor.associatedVariableName : "vec4(1., 1., 1., 1.)";
-        const opacityTexture = this.opacityTexture.isConnected ? this.opacityTexture.associatedVariableName : "";
+        const albedoColor = this.baseColor.isConnected ? this.baseColor.associatedVariableName : "vec3(1.)";
+        const opacity = this.opacity.isConnected ? this.opacity.associatedVariableName : "1.";
 
         code += `albedoOpacityBlock(
-                ${albedoColor},
+                vec4(${albedoColor}, 1.),
             #ifdef ALBEDO
                 vec4(1.),
                 vec2(1., 1.),
             #endif
             #ifdef OPACITY
-                ${opacityTexture},
+                vec4(${opacity}),
                 vec2(1., 1.),
             #endif
                 albedoOpacityOut
@@ -798,6 +834,64 @@ export class PBRMetallicRoughnessBlock extends NodeMaterialBlock {
         return code;
     }
 
+    private _getAmbientOcclusionCode(): string {
+        let code = `ambientOcclusionOutParams aoOut;\r\n`;
+
+        const ao = this.ambientOcc.isConnected ? this.ambientOcc.associatedVariableName : "1.";
+
+        code += `ambientOcclusionBlock(
+            #ifdef AMBIENT
+                vec3(${ao}),
+                vec4(0., 1.0, 1.0, 0.),
+            #endif
+                aoOut
+            );\r\n`;
+
+        return code;
+    }
+
+    private _getReflectivityCode(state: NodeMaterialBuildState): string {
+        let code = `reflectivityOutParams reflectivityOut;\r\n`;
+
+        const aoIntensity = "1.";
+
+        this._vMetallicReflectanceFactorsName = state._getFreeVariableName("vMetallicReflectanceFactors");
+        state._emitUniformFromString(this._vMetallicReflectanceFactorsName, "vec4");
+
+        code += `vec3 baseColor = surfaceAlbedo;
+
+            reflectivityBlock(
+                vec4(${this.metallic.associatedVariableName}, ${this.roughness.associatedVariableName}, 0., 0.),
+            #ifdef METALLICWORKFLOW
+                surfaceAlbedo,
+                ${this._vMetallicReflectanceFactorsName},
+            #endif
+            #ifdef REFLECTIVITY
+                vec3(0., 0., ${aoIntensity}),
+                vec4(1.),
+            #endif
+            #if defined(METALLICWORKFLOW) && defined(REFLECTIVITY)  && defined(AOSTOREINMETALMAPRED)
+                aoOut.ambientOcclusionColor,
+            #endif
+            #ifdef MICROSURFACEMAP
+                microSurfaceTexel, <== not handled!
+            #endif
+                reflectivityOut
+            );
+
+            float microSurface = reflectivityOut.microSurface;
+            float roughness = reflectivityOut.roughness;
+
+            #ifdef METALLICWORKFLOW
+                surfaceAlbedo = reflectivityOut.surfaceAlbedo;
+            #endif
+            #if defined(METALLICWORKFLOW) && defined(REFLECTIVITY) && defined(AOSTOREINMETALMAPRED)
+                aoOut.ambientOcclusionColor = reflectivityOut.ambientOcclusionColor;
+            #endif\r\n`;
+
+        return code;
+    }
+
     protected _buildBlock(state: NodeMaterialBuildState) {
         super._buildBlock(state);
 
@@ -919,19 +1013,16 @@ export class PBRMetallicRoughnessBlock extends NodeMaterialBlock {
         });
 
         // _____________________________ Albedo & Opacity ______________________________
-        state.compilationString += this.getAlbedoOpacityCode();
+        state.compilationString += this._getAlbedoOpacityCode();
 
         state.compilationString += state._emitCodeFromInclude("depthPrePass", comments);
 
         // _____________________________ AO  _______________________________
-        const aoBlock = this.ambientOcc.connectedPoint?.ownerBlock as Nullable<AmbientOcclusionBlock>;
-
-        state.compilationString += AmbientOcclusionBlock.GetCode(aoBlock);
+        state.compilationString += this._getAmbientOcclusionCode();
 
         state.compilationString += state._emitCodeFromInclude("pbrBlockLightmapInit", comments);
 
         // _____________________________ UNLIT  _______________________________
-
         state.compilationString += `#ifdef UNLIT
                 vec3 diffuseBase = vec3(1., 1., 1.);
             #else\r\n`;
@@ -940,15 +1031,13 @@ export class PBRMetallicRoughnessBlock extends NodeMaterialBlock {
         const subsurfaceBlock = this.subsurface.isConnected ? this.subsurface.connectedPoint?.ownerBlock as SubSurfaceBlock : null;
         const refractionBlock = this.subsurface.isConnected ? (this.subsurface.connectedPoint?.ownerBlock as SubSurfaceBlock).refraction.connectedPoint?.ownerBlock as RefractionBlock : null;
 
-        const reflectivityBlock = this.reflectivity.connectedPoint?.ownerBlock as Nullable<ReflectivityBlock> ?? null;
+        this._indexOfRefractionConnectionPoint = refractionBlock?.indexOfRefraction ?? null;
 
-        if (reflectivityBlock) {
-            reflectivityBlock.indexOfRefractionConnectionPoint = refractionBlock?.indexOfRefraction ?? null;
+        if (refractionBlock) {
+            refractionBlock.viewConnectionPoint = this.view;
         }
 
-        const aoIntensity = aoBlock?.intensity.isConnected ? aoBlock.intensity.associatedVariableName : "1.";
-
-        state.compilationString += reflectivityBlock?.getCode(state, aoIntensity) ?? "";
+        state.compilationString += this._getReflectivityCode(state);
 
         // _____________________________ Geometry info _________________________________
         state.compilationString += state._emitCodeFromInclude("pbrBlockGeometryInfo", comments, {
@@ -989,7 +1078,7 @@ export class PBRMetallicRoughnessBlock extends NodeMaterialBlock {
         // ___________________ Compute Reflectance aka R0 F0 info _________________________
         state.compilationString += state._emitCodeFromInclude("pbrBlockReflectance0", comments, {
             replaceStrings: [
-                { search: /metallicReflectanceFactors/g, replace: reflectivityBlock?._vMetallicReflectanceFactorsName ?? "metallicReflectanceFactors" },
+                { search: /metallicReflectanceFactors/g, replace: this._vMetallicReflectanceFactorsName },
             ]
         });
         // ________________________________ Sheen ______________________________
@@ -1081,9 +1170,9 @@ export class PBRMetallicRoughnessBlock extends NodeMaterialBlock {
         // _____________________________ Compute Final Unlit Components ________________________
         const aoColor = this.ambientColor.isConnected ? this.ambientColor.associatedVariableName : "vec3(0., 0., 0.)";
 
-        let aoDirectLightIntensity = aoBlock?.directLightIntensity.isConnected ? aoBlock.directLightIntensity.associatedVariableName : PBRBaseMaterial.DEFAULT_AO_ON_ANALYTICAL_LIGHTS.toString();
+        let aoDirectLightIntensity = PBRBaseMaterial.DEFAULT_AO_ON_ANALYTICAL_LIGHTS.toString();
 
-        if (!aoBlock?.directLightIntensity.isConnected && aoDirectLightIntensity.indexOf('.') === -1) {
+        if (aoDirectLightIntensity.indexOf('.') === -1) {
             aoDirectLightIntensity += ".";
         }
 
@@ -1115,7 +1204,6 @@ export class PBRMetallicRoughnessBlock extends NodeMaterialBlock {
                 { search: /vNormalW/g, replace: this._vNormalWName },
                 { search: /vPositionW/g, replace: worldPosVarName },
                 { search: /albedoTexture\.rgb;/g, replace: "vec3(1.);\r\ngl_FragColor.rgb = toGammaSpace(gl_FragColor.rgb);\r\n" },
-                { search: /opacityMap/g, replace: this.opacityTexture.associatedVariableName },
             ]
         });
 
@@ -1150,7 +1238,6 @@ export class PBRMetallicRoughnessBlock extends NodeMaterialBlock {
         codeString += `${this._codeVariableName}.useAlphaTest = ${this.useAlphaTest};\r\n`;
         codeString += `${this._codeVariableName}.alphaTestCutoff = ${this.alphaTestCutoff};\r\n`;
         codeString += `${this._codeVariableName}.useAlphaBlending = ${this.useAlphaBlending};\r\n`;
-        codeString += `${this._codeVariableName}.opacityRGB = ${this.opacityRGB};\r\n`;
         codeString += `${this._codeVariableName}.useRadianceOverAlpha = ${this.useRadianceOverAlpha};\r\n`;
         codeString += `${this._codeVariableName}.useSpecularOverAlpha = ${this.useSpecularOverAlpha};\r\n`;
         codeString += `${this._codeVariableName}.enableSpecularAntiAliasing = ${this.enableSpecularAntiAliasing};\r\n`;
@@ -1179,7 +1266,6 @@ export class PBRMetallicRoughnessBlock extends NodeMaterialBlock {
         serializationObject.useAlphaTest = this.useAlphaTest;
         serializationObject.alphaTestCutoff = this.alphaTestCutoff;
         serializationObject.useAlphaBlending = this.useAlphaBlending;
-        serializationObject.opacityRGB = this.opacityRGB;
         serializationObject.useRadianceOverAlpha = this.useRadianceOverAlpha;
         serializationObject.useSpecularOverAlpha = this.useSpecularOverAlpha;
         serializationObject.enableSpecularAntiAliasing = this.enableSpecularAntiAliasing;
@@ -1208,7 +1294,6 @@ export class PBRMetallicRoughnessBlock extends NodeMaterialBlock {
         this.useAlphaTest = serializationObject.useAlphaTest;
         this.alphaTestCutoff = serializationObject.alphaTestCutoff;
         this.useAlphaBlending = serializationObject.useAlphaBlending;
-        this.opacityRGB = serializationObject.opacityRGB;
         this.useRadianceOverAlpha = serializationObject.useRadianceOverAlpha;
         this.useSpecularOverAlpha = serializationObject.useSpecularOverAlpha;
         this.enableSpecularAntiAliasing = serializationObject.enableSpecularAntiAliasing;

+ 5 - 4
src/Materials/Node/Blocks/PBR/reflectionBlock.ts

@@ -36,7 +36,7 @@ export class ReflectionBlock extends ReflectionTextureBaseBlock {
     private _scene: Scene;
 
     /**
-     * The three properties below are set by the main PBR block prior to calling methods of this class.
+     * The properties below are set by the main PBR block prior to calling methods of this class.
      * This is to avoid having to add them as inputs here whereas they are already inputs of the main block, so already known.
      * It's less burden on the user side in the editor part.
     */
@@ -47,6 +47,8 @@ export class ReflectionBlock extends ReflectionTextureBaseBlock {
     public worldNormalConnectionPoint: NodeMaterialConnectionPoint;
     /** @hidden */
     public cameraPositionConnectionPoint: NodeMaterialConnectionPoint;
+    /** @hidden */
+    public viewConnectionPoint: NodeMaterialConnectionPoint;
 
     /**
      * Defines if the material uses spherical harmonics vs spherical polynomials for the
@@ -72,7 +74,6 @@ export class ReflectionBlock extends ReflectionTextureBaseBlock {
 
         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.registerInput("color", NodeMaterialBlockConnectionPointTypes.Color3, true, NodeMaterialBlockTargets.Fragment);
 
         this.registerOutput("reflection", NodeMaterialBlockConnectionPointTypes.Object, NodeMaterialBlockTargets.Fragment,
@@ -126,14 +127,14 @@ export class ReflectionBlock extends ReflectionTextureBaseBlock {
      * Gets the view input component
      */
     public get view(): NodeMaterialConnectionPoint {
-        return this._inputs[2];
+        return this.viewConnectionPoint;
     }
 
     /**
      * Gets the color input component
      */
     public get color(): NodeMaterialConnectionPoint {
-        return this._inputs[3];
+        return this._inputs[2];
     }
 
     /**

+ 0 - 243
src/Materials/Node/Blocks/PBR/reflectivityBlock.ts

@@ -1,243 +0,0 @@
-import { NodeMaterial, NodeMaterialDefines } from '../../nodeMaterial';
-import { NodeMaterialBuildState } from '../../nodeMaterialBuildState';
-import { NodeMaterialBlock } from '../../nodeMaterialBlock';
-import { _TypeStore } from '../../../../Misc/typeStore';
-import { editableInPropertyPage, PropertyTypeForEdition } from "../../nodeMaterialDecorator";
-import { AbstractMesh } from '../../../../Meshes/abstractMesh';
-import { NodeMaterialBlockConnectionPointTypes } from '../../Enums/nodeMaterialBlockConnectionPointTypes';
-import { NodeMaterialBlockTargets } from '../../Enums/nodeMaterialBlockTargets';
-import { NodeMaterialConnectionPointCustomObject } from "../../nodeMaterialConnectionPointCustomObject";
-import { NodeMaterialConnectionPoint, NodeMaterialConnectionPointDirection } from '../../nodeMaterialBlockConnectionPoint';
-import { Scene } from '../../../../scene';
-import { Nullable } from '../../../../types';
-import { Color3 } from '../../../../Maths/math.color';
-import { TmpColors } from '../../../../Maths/math.color';
-import { Mesh } from '../../../../Meshes/mesh';
-import { SubMesh } from '../../../../Meshes/subMesh';
-import { Effect } from '../../../effect';
-
-/**
- * Block used to implement the reflectivity module of the PBR material
- */
-export class ReflectivityBlock extends NodeMaterialBlock {
-
-    private _metallicReflectanceColor: Color3 = Color3.White();
-    private _metallicF0Factor = 1;
-
-    /** @hidden */
-    public _vMetallicReflectanceFactorsName: string;
-
-    /**
-     * The property below is set by the main PBR block prior to calling methods of this class.
-    */
-
-    /** @hidden */
-    public indexOfRefractionConnectionPoint: Nullable<NodeMaterialConnectionPoint>;
-
-    /**
-     * Specifies if the metallic texture contains the ambient occlusion information in its red channel.
-     */
-    @editableInPropertyPage("AO from red channel", PropertyTypeForEdition.Boolean, "METALLIC WORKFLOW", { "notifiers": { "update": true }})
-    public useAmbientOcclusionFromMetallicTextureRed: boolean = false;
-
-    /**
-     * Specifies if the metallic texture contains the metallness information in its blue channel.
-     */
-    @editableInPropertyPage("Metallness from blue channel", PropertyTypeForEdition.Boolean, "METALLIC WORKFLOW", { "notifiers": { "update": true }})
-    public useMetallnessFromMetallicTextureBlue: boolean = true;
-
-    /**
-     * Specifies if the metallic texture contains the roughness information in its alpha channel.
-     */
-    @editableInPropertyPage("Roughness from alpha channel", PropertyTypeForEdition.Boolean, "METALLIC WORKFLOW", { "notifiers": { "update": true }})
-    public useRoughnessFromMetallicTextureAlpha: boolean = false;
-
-    /**
-     * Specifies if the metallic texture contains the roughness information in its green channel.
-     */
-    @editableInPropertyPage("Roughness from green channel", PropertyTypeForEdition.Boolean, "METALLIC WORKFLOW", { "notifiers": { "update": true }})
-    public useRoughnessFromMetallicTextureGreen: boolean = true;
-
-    /**
-     * Create a new ReflectivityBlock
-     * @param name defines the block name
-     */
-    public constructor(name: string) {
-        super(name, NodeMaterialBlockTargets.Fragment);
-
-        this._isUnique = true;
-
-        this.registerInput("metallic", NodeMaterialBlockConnectionPointTypes.Float, false, NodeMaterialBlockTargets.Fragment);
-        this.registerInput("roughness", NodeMaterialBlockConnectionPointTypes.Float, false, NodeMaterialBlockTargets.Fragment);
-        this.registerInput("texture", NodeMaterialBlockConnectionPointTypes.Color4, true, NodeMaterialBlockTargets.Fragment);
-
-        this.registerOutput("reflectivity", NodeMaterialBlockConnectionPointTypes.Object, NodeMaterialBlockTargets.Fragment,
-            new NodeMaterialConnectionPointCustomObject("reflectivity", this, NodeMaterialConnectionPointDirection.Output, ReflectivityBlock, "ReflectivityBlock"));
-    }
-
-    /**
-     * Initialize the block and prepare the context for build
-     * @param state defines the state that will be used for the build
-     */
-    public initialize(state: NodeMaterialBuildState) {
-        state._excludeVariableName("baseColor");
-        state._excludeVariableName("reflectivityOut");
-        state._excludeVariableName("microSurface");
-        state._excludeVariableName("roughness");
-    }
-
-    /**
-     * Gets the current class name
-     * @returns the class name
-     */
-    public getClassName() {
-        return "ReflectivityBlock";
-    }
-
-    /**
-     * Gets the metallic input component
-     */
-    public get metallic(): NodeMaterialConnectionPoint {
-        return this._inputs[0];
-    }
-
-    /**
-     * Gets the roughness input component
-     */
-    public get roughness(): NodeMaterialConnectionPoint {
-        return this._inputs[1];
-    }
-
-    /**
-     * Gets the texture input component
-     */
-    public get texture(): NodeMaterialConnectionPoint {
-        return this._inputs[2];
-    }
-
-    /**
-     * Gets the reflectivity object output component
-     */
-    public get reflectivity(): NodeMaterialConnectionPoint {
-        return this._outputs[0];
-    }
-
-    public bind(effect: Effect, nodeMaterial: NodeMaterial, mesh?: Mesh, subMesh?: SubMesh) {
-        super.bind(effect, nodeMaterial, mesh);
-
-        const outside_ior = 1; // consider air as clear coat and other layers would remap in the shader.
-        const ior = this.indexOfRefractionConnectionPoint?.connectInputBlock?.value ?? 1.5;
-
-        // We are here deriving our default reflectance from a common value for none metallic surface.
-        // Based of the schlick fresnel approximation model
-        // for dielectrics.
-        const f0 = Math.pow((ior - outside_ior) / (ior + outside_ior), 2);
-
-        // Tweak the default F0 and F90 based on our given setup
-        this._metallicReflectanceColor.scaleToRef(f0 * this._metallicF0Factor, TmpColors.Color3[0]);
-        const metallicF90 = this._metallicF0Factor;
-
-        effect.setColor4(this._vMetallicReflectanceFactorsName, TmpColors.Color3[0], metallicF90);
-    }
-
-    /**
-     * Gets the main code of the block (fragment side)
-     * @param state current state of the node material building
-     * @param aoIntensityVarName name of the variable with the ambient occlusion intensity
-     * @returns the shader code
-     */
-    public getCode(state: NodeMaterialBuildState, aoIntensityVarName: string): string {
-        const metalRoughTexture = this.texture.isConnected ? this.texture.connectedPoint?.associatedVariableName : null;
-
-        this._vMetallicReflectanceFactorsName = state._getFreeVariableName("vMetallicReflectanceFactors");
-
-        state._emitUniformFromString(this._vMetallicReflectanceFactorsName, "vec4");
-
-        // note: metallic F0 factor = 1
-        let code = `vec3 baseColor = surfaceAlbedo;
-            reflectivityOutParams reflectivityOut;
-
-            reflectivityBlock(
-                vec4(${this.metallic.associatedVariableName}, ${this.roughness.associatedVariableName}, 0., 0.),
-            #ifdef METALLICWORKFLOW
-                surfaceAlbedo,
-                ${this._vMetallicReflectanceFactorsName},
-            #endif
-            #ifdef REFLECTIVITY
-                vec3(0., 0., ${aoIntensityVarName}),
-                ${metalRoughTexture},
-            #endif
-            #if defined(METALLICWORKFLOW) && defined(REFLECTIVITY)  && defined(AOSTOREINMETALMAPRED)
-                aoOut.ambientOcclusionColor,
-            #endif
-            #ifdef MICROSURFACEMAP
-                microSurfaceTexel, <== not handled!
-            #endif
-                reflectivityOut
-            );
-
-            float microSurface = reflectivityOut.microSurface;
-            float roughness = reflectivityOut.roughness;
-
-            #ifdef METALLICWORKFLOW
-                surfaceAlbedo = reflectivityOut.surfaceAlbedo;
-            #endif
-            #if defined(METALLICWORKFLOW) && defined(REFLECTIVITY) && defined(AOSTOREINMETALMAPRED)
-                aoOut.ambientOcclusionColor = reflectivityOut.ambientOcclusionColor;
-            #endif\r\n`;
-
-        return code;
-    }
-
-    public prepareDefines(mesh: AbstractMesh, nodeMaterial: NodeMaterial, defines: NodeMaterialDefines) {
-        super.prepareDefines(mesh, nodeMaterial, defines);
-
-        defines.setValue("REFLECTIVITY", this.texture.isConnected, true);
-        defines.setValue("AOSTOREINMETALMAPRED", this.useAmbientOcclusionFromMetallicTextureRed, true);
-        defines.setValue("METALLNESSSTOREINMETALMAPBLUE", this.useMetallnessFromMetallicTextureBlue, true);
-        defines.setValue("ROUGHNESSSTOREINMETALMAPALPHA", this.useRoughnessFromMetallicTextureAlpha, true);
-        defines.setValue("ROUGHNESSSTOREINMETALMAPGREEN",  !this.useRoughnessFromMetallicTextureAlpha && this.useRoughnessFromMetallicTextureGreen, true);
-    }
-
-    protected _buildBlock(state: NodeMaterialBuildState) {
-        if (state.target === NodeMaterialBlockTargets.Fragment) {
-            state.sharedData.blocksWithDefines.push(this);
-            state.sharedData.bindableBlocks.push(this);
-        }
-
-        return this;
-    }
-
-    protected _dumpPropertiesCode() {
-        let codeString: string = "";
-
-        codeString += `${this._codeVariableName}.useAmbientOcclusionFromMetallicTextureRed = ${this.useAmbientOcclusionFromMetallicTextureRed};\r\n`;
-        codeString += `${this._codeVariableName}.useMetallnessFromMetallicTextureBlue = ${this.useMetallnessFromMetallicTextureBlue};\r\n`;
-        codeString += `${this._codeVariableName}.useRoughnessFromMetallicTextureAlpha = ${this.useRoughnessFromMetallicTextureAlpha};\r\n`;
-        codeString += `${this._codeVariableName}.useRoughnessFromMetallicTextureGreen = ${this.useRoughnessFromMetallicTextureGreen};\r\n`;
-
-        return codeString;
-    }
-
-    public serialize(): any {
-        let serializationObject = super.serialize();
-
-        serializationObject.useAmbientOcclusionFromMetallicTextureRed = this.useAmbientOcclusionFromMetallicTextureRed;
-        serializationObject.useMetallnessFromMetallicTextureBlue = this.useMetallnessFromMetallicTextureBlue;
-        serializationObject.useRoughnessFromMetallicTextureAlpha = this.useRoughnessFromMetallicTextureAlpha;
-        serializationObject.useRoughnessFromMetallicTextureGreen = this.useRoughnessFromMetallicTextureGreen;
-
-        return serializationObject;
-    }
-
-    public _deserialize(serializationObject: any, scene: Scene, rootUrl: string) {
-        super._deserialize(serializationObject, scene, rootUrl);
-
-        this.useAmbientOcclusionFromMetallicTextureRed = serializationObject.useAmbientOcclusionFromMetallicTextureRed;
-        this.useMetallnessFromMetallicTextureBlue = serializationObject.useMetallnessFromMetallicTextureBlue;
-        this.useRoughnessFromMetallicTextureAlpha = serializationObject.useRoughnessFromMetallicTextureAlpha;
-        this.useRoughnessFromMetallicTextureGreen = serializationObject.useRoughnessFromMetallicTextureGreen;
-    }
-}
-
-_TypeStore.RegisteredTypes["BABYLON.ReflectivityBlock"] = ReflectivityBlock;

+ 10 - 2
src/Materials/Node/Blocks/PBR/refractionBlock.ts

@@ -46,6 +46,15 @@ export class RefractionBlock extends NodeMaterialBlock {
     private _scene: Scene;
 
     /**
+     * The properties below are set by the main PBR block prior to calling methods of this class.
+     * This is to avoid having to add them as inputs here whereas they are already inputs of the main block, so already known.
+     * It's less burden on the user side in the editor part.
+    */
+
+    /** @hidden */
+    public viewConnectionPoint: NodeMaterialConnectionPoint;
+
+    /**
      * This parameters will make the material used its opacity to control how much it is refracting aginst not.
      * Materials half opaque for instance using refraction could benefit from this control.
      */
@@ -75,7 +84,6 @@ export class RefractionBlock extends NodeMaterialBlock {
         this.registerInput("intensity", NodeMaterialBlockConnectionPointTypes.Float, false, NodeMaterialBlockTargets.Fragment);
         this.registerInput("indexOfRefraction", NodeMaterialBlockConnectionPointTypes.Float, true, NodeMaterialBlockTargets.Fragment);
         this.registerInput("tintAtDistance", NodeMaterialBlockConnectionPointTypes.Float, true, NodeMaterialBlockTargets.Fragment);
-        this.registerInput("view", NodeMaterialBlockConnectionPointTypes.Matrix, false, NodeMaterialBlockTargets.Fragment);
 
         this.registerOutput("refraction", NodeMaterialBlockConnectionPointTypes.Object, NodeMaterialBlockTargets.Fragment,
             new NodeMaterialConnectionPointCustomObject("refraction", this, NodeMaterialConnectionPointDirection.Output, RefractionBlock, "RefractionBlock"));
@@ -114,7 +122,7 @@ export class RefractionBlock extends NodeMaterialBlock {
      * Gets the view input component
      */
     public get view(): NodeMaterialConnectionPoint {
-        return this._inputs[3];
+        return this.viewConnectionPoint;
     }
 
     /**

+ 20 - 48
src/Materials/Node/Blocks/PBR/subSurfaceBlock.ts

@@ -4,7 +4,6 @@ import { NodeMaterialBuildState } from '../../nodeMaterialBuildState';
 import { NodeMaterialConnectionPoint, NodeMaterialConnectionPointDirection } from '../../nodeMaterialBlockConnectionPoint';
 import { NodeMaterialBlockTargets } from '../../Enums/nodeMaterialBlockTargets';
 import { _TypeStore } from '../../../../Misc/typeStore';
-import { editableInPropertyPage, PropertyTypeForEdition } from "../../nodeMaterialDecorator";
 import { InputBlock } from '../Input/inputBlock';
 import { NodeMaterialConnectionPointCustomObject } from "../../nodeMaterialConnectionPointCustomObject";
 import { NodeMaterial, NodeMaterialDefines } from '../../nodeMaterial';
@@ -27,12 +26,10 @@ export class SubSurfaceBlock extends NodeMaterialBlock {
 
         this._isUnique = true;
 
-        this.registerInput("minThickness", NodeMaterialBlockConnectionPointTypes.Float, false, NodeMaterialBlockTargets.Fragment);
-        this.registerInput("maxThickness", NodeMaterialBlockConnectionPointTypes.Float, true, NodeMaterialBlockTargets.Fragment);
-        this.registerInput("thicknessTexture", NodeMaterialBlockConnectionPointTypes.Color4, true, NodeMaterialBlockTargets.Fragment);
+        this.registerInput("thickness", NodeMaterialBlockConnectionPointTypes.Float, false, NodeMaterialBlockTargets.Fragment);
         this.registerInput("tintColor", NodeMaterialBlockConnectionPointTypes.Color3, true, NodeMaterialBlockTargets.Fragment);
         this.registerInput("translucencyIntensity", NodeMaterialBlockConnectionPointTypes.Float, true, NodeMaterialBlockTargets.Fragment);
-        this.registerInput("translucencyDiffusionDistance", NodeMaterialBlockConnectionPointTypes.Color3, true, NodeMaterialBlockTargets.Fragment);
+        this.registerInput("translucencyDiffusionDist", NodeMaterialBlockConnectionPointTypes.Color3, true, NodeMaterialBlockTargets.Fragment);
         this.registerInput("refraction", NodeMaterialBlockConnectionPointTypes.Object, true, NodeMaterialBlockTargets.Fragment,
             new NodeMaterialConnectionPointCustomObject("refraction", this, NodeMaterialConnectionPointDirection.Input, RefractionBlock, "RefractionBlock"));
 
@@ -41,15 +38,6 @@ export class SubSurfaceBlock extends NodeMaterialBlock {
     }
 
     /**
-     * Stores the intensity of the different subsurface effects in the thickness texture.
-     * * the green channel is the translucency intensity.
-     * * the blue channel is the scattering intensity.
-     * * the alpha channel is the refraction intensity.
-     */
-    @editableInPropertyPage("Mask from thickness texture", PropertyTypeForEdition.Boolean, "PROPERTIES", { "notifiers": { "update": true }})
-    public useMaskFromThicknessTexture: boolean = false;
-
-    /**
      * Initialize the block and prepare the context for build
      * @param state defines the state that will be used for the build
      */
@@ -69,52 +57,38 @@ export class SubSurfaceBlock extends NodeMaterialBlock {
     }
 
     /**
-     * Gets the min thickness input component
+     * Gets the thickness component
      */
-    public get minThickness(): NodeMaterialConnectionPoint {
+    public get thickness(): NodeMaterialConnectionPoint {
         return this._inputs[0];
     }
 
     /**
-     * Gets the max thickness input component
-     */
-    public get maxThickness(): NodeMaterialConnectionPoint {
-        return this._inputs[1];
-    }
-
-    /**
-     * Gets the thickness texture component
-     */
-    public get thicknessTexture(): NodeMaterialConnectionPoint {
-        return this._inputs[2];
-    }
-
-    /**
      * Gets the tint color input component
      */
     public get tintColor(): NodeMaterialConnectionPoint {
-        return this._inputs[3];
+        return this._inputs[1];
     }
 
     /**
      * Gets the translucency intensity input component
      */
     public get translucencyIntensity(): NodeMaterialConnectionPoint {
-        return this._inputs[4];
+        return this._inputs[2];
     }
 
     /**
      * Gets the translucency diffusion distance input component
      */
-    public get translucencyDiffusionDistance(): NodeMaterialConnectionPoint {
-        return this._inputs[5];
+    public get translucencyDiffusionDist(): NodeMaterialConnectionPoint {
+        return this._inputs[3];
     }
 
     /**
      * Gets the refraction object parameters
      */
     public get refraction(): NodeMaterialConnectionPoint {
-        return this._inputs[6];
+        return this._inputs[4];
     }
 
     /**
@@ -125,22 +99,22 @@ export class SubSurfaceBlock extends NodeMaterialBlock {
     }
 
     public autoConfigure(material: NodeMaterial) {
-        if (!this.minThickness.isConnected) {
-            let minThicknessInput = new InputBlock("SubSurface min thickness", NodeMaterialBlockTargets.Fragment, NodeMaterialBlockConnectionPointTypes.Float);
-            minThicknessInput.value = 0;
-            minThicknessInput.output.connectTo(this.minThickness);
+        if (!this.thickness.isConnected) {
+            let thicknessInput = new InputBlock("SubSurface thickness", NodeMaterialBlockTargets.Fragment, NodeMaterialBlockConnectionPointTypes.Float);
+            thicknessInput.value = 0;
+            thicknessInput.output.connectTo(this.thickness);
         }
     }
 
     public prepareDefines(mesh: AbstractMesh, nodeMaterial: NodeMaterial, defines: NodeMaterialDefines) {
         super.prepareDefines(mesh, nodeMaterial, defines);
 
-        const translucencyEnabled = this.translucencyDiffusionDistance.isConnected || this.translucencyIntensity.isConnected;
+        const translucencyEnabled = this.translucencyDiffusionDist.isConnected || this.translucencyIntensity.isConnected;
 
         defines.setValue("SUBSURFACE", translucencyEnabled || this.refraction.isConnected, true);
         defines.setValue("SS_TRANSLUCENCY", translucencyEnabled, true);
-        defines.setValue("SS_THICKNESSANDMASK_TEXTURE", this.thicknessTexture.isConnected, true);
-        defines.setValue("SS_MASK_FROM_THICKNESS_TEXTURE", this.useMaskFromThicknessTexture, true);
+        defines.setValue("SS_THICKNESSANDMASK_TEXTURE", false, true);
+        defines.setValue("SS_MASK_FROM_THICKNESS_TEXTURE", false, true);
     }
 
     /**
@@ -154,12 +128,10 @@ export class SubSurfaceBlock extends NodeMaterialBlock {
     public static GetCode(state: NodeMaterialBuildState, ssBlock: Nullable<SubSurfaceBlock>, reflectionBlock: Nullable<ReflectionBlock>, worldPosVarName: string): string {
         let code = "";
 
-        const minThickness = ssBlock?.minThickness.isConnected ? ssBlock.minThickness.associatedVariableName : "0.";
-        const maxThickness = ssBlock?.maxThickness.isConnected ? ssBlock.maxThickness.associatedVariableName : "1.";
-        const thicknessTexture = ssBlock?.thicknessTexture.isConnected ? ssBlock.thicknessTexture.associatedVariableName : "vec4(0.)";
+        const thickness = ssBlock?.thickness.isConnected ? ssBlock.thickness.associatedVariableName : "0.";
         const tintColor = ssBlock?.tintColor.isConnected ? ssBlock.tintColor.associatedVariableName : "vec3(1.)";
         const translucencyIntensity = ssBlock?.translucencyIntensity.isConnected ? ssBlock?.translucencyIntensity.associatedVariableName : "1.";
-        const translucencyDiffusionDistance = ssBlock?.translucencyDiffusionDistance.isConnected ? ssBlock?.translucencyDiffusionDistance.associatedVariableName : "vec3(1.)";
+        const translucencyDiffusionDistance = ssBlock?.translucencyDiffusionDist.isConnected ? ssBlock?.translucencyDiffusionDist.associatedVariableName : "vec3(1.)";
 
         const refractionBlock: Nullable<RefractionBlock> = (ssBlock?.refraction.isConnected ? ssBlock?.refraction.connectedPoint?.ownerBlock : null) as Nullable<RefractionBlock>;
 
@@ -172,7 +144,7 @@ export class SubSurfaceBlock extends NodeMaterialBlock {
         code += `subSurfaceOutParams subSurfaceOut;
 
         #ifdef SUBSURFACE
-            vec2 vThicknessParam = vec2(${minThickness}, ${maxThickness} - ${minThickness});
+            vec2 vThicknessParam = vec2(0., ${thickness});
             vec4 vTintColor = vec4(${tintColor}, ${refractionTintAtDistance});
             vec3 vSubSurfaceIntensity = vec3(${refractionIntensity}, ${translucencyIntensity}, 0.);
 
@@ -183,7 +155,7 @@ export class SubSurfaceBlock extends NodeMaterialBlock {
                 normalW,
                 specularEnvironmentReflectance,
             #ifdef SS_THICKNESSANDMASK_TEXTURE
-                ${thicknessTexture},
+                vec4(0.),
             #endif
             #ifdef REFLECTION
                 #ifdef SS_TRANSLUCENCY