소스 검색

Sync pbr node blocks with latest reflectance changes

Popov72 5 년 전
부모
커밋
baaa13b6a4
2개의 변경된 파일61개의 추가작업 그리고 10개의 파일을 삭제
  1. 15 6
      src/Materials/Node/Blocks/PBR/pbrMetallicRoughnessBlock.ts
  2. 46 4
      src/Materials/Node/Blocks/PBR/reflectivityBlock.ts

+ 15 - 6
src/Materials/Node/Blocks/PBR/pbrMetallicRoughnessBlock.ts

@@ -913,9 +913,18 @@ export class PBRMetallicRoughnessBlock extends NodeMaterialBlock {
             #else\r\n`;
 
         // _____________________________ Reflectivity _______________________________
+        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;
+
+        if (reflectivityBlock) {
+            reflectivityBlock.indexOfRefractionConnectionPoint = refractionBlock?.indexOfRefraction ?? null;
+        }
+
         const aoIntensity = aoBlock?.intensity.isConnected ? aoBlock.intensity.associatedVariableName : "1.";
 
-        state.compilationString += (this.reflectivity.connectedPoint?.ownerBlock as Nullable<ReflectivityBlock>)?.getCode(aoIntensity) ?? "";
+        state.compilationString += reflectivityBlock?.getCode(state, aoIntensity) ?? "";
 
         // _____________________________ Geometry info _________________________________
         state.compilationString += state._emitCodeFromInclude("pbrBlockGeometryInfo", comments, {
@@ -953,8 +962,11 @@ export class PBRMetallicRoughnessBlock extends NodeMaterialBlock {
         });
 
         // ___________________ Compute Reflectance aka R0 F0 info _________________________
-        state.compilationString += state._emitCodeFromInclude("pbrBlockReflectance0", comments);
-
+        state.compilationString += state._emitCodeFromInclude("pbrBlockReflectance0", comments, {
+            replaceStrings: [
+                { search: /metallicReflectanceFactors/g, replace: reflectivityBlock?._vMetallicReflectanceFactorsName ?? "metallicReflectanceFactors" },
+            ]
+        });
         // ________________________________ Sheen ______________________________
         const sheenBlock = this.sheen.isConnected ? this.sheen.connectedPoint?.ownerBlock as SheenBlock : null;
 
@@ -1006,9 +1018,6 @@ export class PBRMetallicRoughnessBlock extends NodeMaterialBlock {
         });
 
         // ___________________________________ SubSurface ______________________________________
-        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;
-
         state.compilationString += SubSurfaceBlock.GetCode(state, subsurfaceBlock, reflectionBlock, worldPosVarName);
 
         state._emitFunctionFromInclude("pbrBlockSubSurface", comments, {

+ 46 - 4
src/Materials/Node/Blocks/PBR/reflectivityBlock.ts

@@ -9,12 +9,31 @@ 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.
      */
@@ -103,24 +122,46 @@ export class ReflectivityBlock extends NodeMaterialBlock {
         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(aoIntensityVarName: string): string {
+    public getCode(state: NodeMaterialBuildState, aoIntensityVarName: string): string {
         const metalRoughTexture = this.texture.isConnected ? this.texture.connectedPoint?.associatedVariableName : null;
 
-        // note: metallic F0 factor = 0.04
+        this._vMetallicReflectanceFactorsName = state._getFreeVariableName("vMetallicReflectanceFactors");
+
+        state._emitUniformFromString(this._vMetallicReflectanceFactorsName, "vec4");
+
+        // note: metallic F0 factor = 1
         let code = `vec3 baseColor = surfaceAlbedo;
-            vec4 metallicReflectanceFactors = vec4(1.);
             reflectivityOutParams reflectivityOut;
 
             reflectivityBlock(
                 vec4(${this.metallic.associatedVariableName}, ${this.roughness.associatedVariableName}, 0., 0.),
             #ifdef METALLICWORKFLOW
                 surfaceAlbedo,
-                metallicReflectanceFactors,
+                ${this._vMetallicReflectanceFactorsName},
             #endif
             #ifdef REFLECTIVITY
                 vec3(0., 0., ${aoIntensityVarName}),
@@ -161,6 +202,7 @@ export class ReflectivityBlock extends NodeMaterialBlock {
     protected _buildBlock(state: NodeMaterialBuildState) {
         if (state.target === NodeMaterialBlockTargets.Fragment) {
             state.sharedData.blocksWithDefines.push(this);
+            state.sharedData.bindableBlocks.push(this);
         }
 
         return this;