From 9291fb9e73537c3625945cec9ed8bba7ca68ae4d Mon Sep 17 00:00:00 2001 From: Evgeni Popov Date: Fri, 28 Oct 2022 21:21:18 +0200 Subject: [PATCH 1/3] Fix TBN computation when using preexisting tangents Former-commit-id: a9627fe11bb54876e785d39d3ef8df7fc9af978c --- .../Node/Blocks/Fragment/perturbNormalBlock.ts | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/packages/dev/core/src/Materials/Node/Blocks/Fragment/perturbNormalBlock.ts b/packages/dev/core/src/Materials/Node/Blocks/Fragment/perturbNormalBlock.ts index f44a20e6945..f762d883b62 100644 --- a/packages/dev/core/src/Materials/Node/Blocks/Fragment/perturbNormalBlock.ts +++ b/packages/dev/core/src/Materials/Node/Blocks/Fragment/perturbNormalBlock.ts @@ -7,6 +7,7 @@ import { NodeMaterialConnectionPointDirection } from "../../nodeMaterialBlockCon import { RegisterClass } from "../../../../Misc/typeStore"; import type { NodeMaterial, NodeMaterialDefines } from "../../nodeMaterial"; import type { AbstractMesh } from "../../../../Meshes/abstractMesh"; +import type { Mesh } from "../../../../Meshes/mesh"; import { InputBlock } from "../Input/inputBlock"; import type { Effect } from "../../../effect"; import type { Scene } from "../../../../scene"; @@ -24,6 +25,7 @@ import "../../../../Shaders/ShadersInclude/bumpFragment"; */ export class PerturbNormalBlock extends NodeMaterialBlock { private _tangentSpaceParameterName = ""; + private _tangentCorrectionFactorName = ""; /** Gets or sets a boolean indicating that normal should be inverted on X axis */ @editableInPropertyPage("Invert X axis", PropertyTypeForEdition.Boolean, "PROPERTIES", { notifiers: { update: false } }) @@ -169,12 +171,13 @@ export class PerturbNormalBlock extends NodeMaterialBlock { defines.setValue("PARALLAXOCCLUSION", this.useParallaxOcclusion, true); } - public bind(effect: Effect, nodeMaterial: NodeMaterial) { + public bind(effect: Effect, nodeMaterial: NodeMaterial, mesh: Mesh) { if (nodeMaterial.getScene()._mirroredCameraPosition) { effect.setFloat2(this._tangentSpaceParameterName, this.invertX ? 1.0 : -1.0, this.invertY ? 1.0 : -1.0); } else { effect.setFloat2(this._tangentSpaceParameterName, this.invertX ? -1.0 : 1.0, this.invertY ? -1.0 : 1.0); } + effect.setFloat(this._tangentCorrectionFactorName, mesh.getWorldMatrix().determinant() < 0 ? -1 : 1); } public autoConfigure(material: NodeMaterial) { @@ -211,6 +214,10 @@ export class PerturbNormalBlock extends NodeMaterialBlock { state._emitUniformFromString(this._tangentSpaceParameterName, "vec2"); + this._tangentCorrectionFactorName = state._getFreeDefineName("tangentCorrectionFactor"); + + state._emitUniformFromString(this._tangentCorrectionFactorName, "float"); + let normalSamplerName = null; if (this.normalMapColor.connectedPoint) { normalSamplerName = (this.normalMapColor.connectedPoint!._ownerBlock as TextureBlock).samplerName; @@ -243,7 +250,7 @@ export class PerturbNormalBlock extends NodeMaterialBlock { } else if (worldTangent.isConnected) { state.compilationString += `vec3 tbnNormal = normalize(${worldNormal.associatedVariableName}.xyz);\r\n`; state.compilationString += `vec3 tbnTangent = normalize(${worldTangent.associatedVariableName}.xyz);\r\n`; - state.compilationString += `vec3 tbnBitangent = cross(tbnNormal, tbnTangent);\r\n`; + state.compilationString += `vec3 tbnBitangent = cross(tbnNormal, tbnTangent) * ${this._tangentCorrectionFactorName};\r\n`; state.compilationString += `mat3 vTBN = mat3(tbnTangent, tbnBitangent, tbnNormal);\r\n`; } From e606f28e0719d1244995152c9d421f65c5b7314a Mon Sep 17 00:00:00 2001 From: Evgeni Popov Date: Mon, 31 Oct 2022 18:19:44 +0100 Subject: [PATCH 2/3] Fix anisotropy block Former-commit-id: 0970d63d43fce21a9d864dd9aafdcc82ae3204e8 --- .../Materials/Node/Blocks/PBR/anisotropyBlock.ts | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/packages/dev/core/src/Materials/Node/Blocks/PBR/anisotropyBlock.ts b/packages/dev/core/src/Materials/Node/Blocks/PBR/anisotropyBlock.ts index cce7daabb98..4a7e2f728fc 100644 --- a/packages/dev/core/src/Materials/Node/Blocks/PBR/anisotropyBlock.ts +++ b/packages/dev/core/src/Materials/Node/Blocks/PBR/anisotropyBlock.ts @@ -9,11 +9,15 @@ import { RegisterClass } from "../../../../Misc/typeStore"; import type { AbstractMesh } from "../../../../Meshes/abstractMesh"; import { NodeMaterialConnectionPointCustomObject } from "../../nodeMaterialConnectionPointCustomObject"; import { TBNBlock } from "../Fragment/TBNBlock"; +import type { Mesh } from "../../../../Meshes/mesh"; +import type { Effect } from "../../../effect"; /** * Block used to implement the anisotropy module of the PBR material */ export class AnisotropyBlock extends NodeMaterialBlock { + private _tangentCorrectionFactorName = ""; + /** * The two 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. @@ -144,7 +148,7 @@ export class AnisotropyBlock extends NodeMaterialBlock { } else if (worldTangent.isConnected) { code += `vec3 tbnNormal = normalize(${worldNormal.associatedVariableName}.xyz);\r\n`; code += `vec3 tbnTangent = normalize(${worldTangent.associatedVariableName}.xyz);\r\n`; - code += `vec3 tbnBitangent = cross(tbnNormal, tbnTangent);\r\n`; + code += `vec3 tbnBitangent = cross(tbnNormal, tbnTangent) * ${this._tangentCorrectionFactorName};\r\n`; code += `mat3 vTBN = mat3(tbnTangent, tbnBitangent, tbnNormal);\r\n`; } @@ -202,9 +206,17 @@ export class AnisotropyBlock extends NodeMaterialBlock { defines.setValue("ANISOTROPIC_TEXTURE", false, true); } + public bind(effect: Effect, nodeMaterial: NodeMaterial, mesh: Mesh) { + effect.setFloat(this._tangentCorrectionFactorName, mesh.getWorldMatrix().determinant() < 0 ? -1 : 1); + } + protected _buildBlock(state: NodeMaterialBuildState) { if (state.target === NodeMaterialBlockTargets.Fragment) { state.sharedData.blocksWithDefines.push(this); + state.sharedData.bindableBlocks.push(this); + + this._tangentCorrectionFactorName = state._getFreeDefineName("tangentCorrectionFactor"); + state._emitUniformFromString(this._tangentCorrectionFactorName, "float"); } return this; From 610c0dde5f455fae1db8c79b914a46e5104fb927 Mon Sep 17 00:00:00 2001 From: Evgeni Popov Date: Mon, 31 Oct 2022 20:11:48 +0100 Subject: [PATCH 3/3] Fix clearcoat block Former-commit-id: 2245e1b66a242b242ab39fba4d16dbae0be83809 --- .../Node/Blocks/Fragment/perturbNormalBlock.ts | 6 ++++-- .../src/Materials/Node/Blocks/PBR/anisotropyBlock.ts | 8 ++++++-- .../src/Materials/Node/Blocks/PBR/clearCoatBlock.ts | 10 +++++++++- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/packages/dev/core/src/Materials/Node/Blocks/Fragment/perturbNormalBlock.ts b/packages/dev/core/src/Materials/Node/Blocks/Fragment/perturbNormalBlock.ts index f762d883b62..d6c7bbadb77 100644 --- a/packages/dev/core/src/Materials/Node/Blocks/Fragment/perturbNormalBlock.ts +++ b/packages/dev/core/src/Materials/Node/Blocks/Fragment/perturbNormalBlock.ts @@ -171,13 +171,15 @@ export class PerturbNormalBlock extends NodeMaterialBlock { defines.setValue("PARALLAXOCCLUSION", this.useParallaxOcclusion, true); } - public bind(effect: Effect, nodeMaterial: NodeMaterial, mesh: Mesh) { + public bind(effect: Effect, nodeMaterial: NodeMaterial, mesh?: Mesh) { if (nodeMaterial.getScene()._mirroredCameraPosition) { effect.setFloat2(this._tangentSpaceParameterName, this.invertX ? 1.0 : -1.0, this.invertY ? 1.0 : -1.0); } else { effect.setFloat2(this._tangentSpaceParameterName, this.invertX ? -1.0 : 1.0, this.invertY ? -1.0 : 1.0); } - effect.setFloat(this._tangentCorrectionFactorName, mesh.getWorldMatrix().determinant() < 0 ? -1 : 1); + if (mesh) { + effect.setFloat(this._tangentCorrectionFactorName, mesh.getWorldMatrix().determinant() < 0 ? -1 : 1); + } } public autoConfigure(material: NodeMaterial) { diff --git a/packages/dev/core/src/Materials/Node/Blocks/PBR/anisotropyBlock.ts b/packages/dev/core/src/Materials/Node/Blocks/PBR/anisotropyBlock.ts index 4a7e2f728fc..e79a4ede231 100644 --- a/packages/dev/core/src/Materials/Node/Blocks/PBR/anisotropyBlock.ts +++ b/packages/dev/core/src/Materials/Node/Blocks/PBR/anisotropyBlock.ts @@ -206,8 +206,12 @@ export class AnisotropyBlock extends NodeMaterialBlock { defines.setValue("ANISOTROPIC_TEXTURE", false, true); } - public bind(effect: Effect, nodeMaterial: NodeMaterial, mesh: Mesh) { - effect.setFloat(this._tangentCorrectionFactorName, mesh.getWorldMatrix().determinant() < 0 ? -1 : 1); + public bind(effect: Effect, nodeMaterial: NodeMaterial, mesh?: Mesh) { + super.bind(effect, nodeMaterial, mesh); + + if (mesh) { + effect.setFloat(this._tangentCorrectionFactorName, mesh.getWorldMatrix().determinant() < 0 ? -1 : 1); + } } protected _buildBlock(state: NodeMaterialBuildState) { diff --git a/packages/dev/core/src/Materials/Node/Blocks/PBR/clearCoatBlock.ts b/packages/dev/core/src/Materials/Node/Blocks/PBR/clearCoatBlock.ts index 04173f84595..5228d850d2a 100644 --- a/packages/dev/core/src/Materials/Node/Blocks/PBR/clearCoatBlock.ts +++ b/packages/dev/core/src/Materials/Node/Blocks/PBR/clearCoatBlock.ts @@ -25,6 +25,7 @@ import { TBNBlock } from "../Fragment/TBNBlock"; */ export class ClearCoatBlock extends NodeMaterialBlock { private _scene: Scene; + private _tangentCorrectionFactorName = ""; /** * Create a new ClearCoatBlock @@ -220,6 +221,10 @@ export class ClearCoatBlock extends NodeMaterialBlock { } else { effect.setFloat2("vClearCoatTangentSpaceParams", perturbedNormalBlock?.invertX ? -1.0 : 1.0, perturbedNormalBlock?.invertY ? -1.0 : 1.0); } + + if (mesh) { + effect.setFloat(this._tangentCorrectionFactorName, mesh.getWorldMatrix().determinant() < 0 ? -1 : 1); + } } private _generateTBNSpace(state: NodeMaterialBuildState, worldPositionVarName: string, worldNormalVarName: string) { @@ -242,7 +247,7 @@ export class ClearCoatBlock extends NodeMaterialBlock { } else if (worldTangent.isConnected) { code += `vec3 tbnNormal = normalize(${worldNormalVarName}.xyz);\r\n`; code += `vec3 tbnTangent = normalize(${worldTangent.associatedVariableName}.xyz);\r\n`; - code += `vec3 tbnBitangent = cross(tbnNormal, tbnTangent);\r\n`; + code += `vec3 tbnBitangent = cross(tbnNormal, tbnTangent) * ${this._tangentCorrectionFactorName};\r\n`; code += `mat3 vTBN = mat3(tbnTangent, tbnBitangent, tbnNormal);\r\n`; } @@ -382,6 +387,9 @@ export class ClearCoatBlock extends NodeMaterialBlock { if (state.target === NodeMaterialBlockTargets.Fragment) { state.sharedData.bindableBlocks.push(this); state.sharedData.blocksWithDefines.push(this); + + this._tangentCorrectionFactorName = state._getFreeDefineName("tangentCorrectionFactor"); + state._emitUniformFromString(this._tangentCorrectionFactorName, "float"); } return this;