Skip to content

Commit

Permalink
Merge pull request #13186 from Popov72/nme-fix-perturbnormal-tangent
Browse files Browse the repository at this point in the history
NME: fix wrong perturbed normals when using pre-existing tangents
Former-commit-id: 6237dadc8ddb225b63ebfcd16805af2c79b2ef40
  • Loading branch information
sebavan authored Oct 31, 2022
2 parents 8f38ce6 + 610c0dd commit f72f174
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand All @@ -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 } })
Expand Down Expand Up @@ -169,12 +171,15 @@ 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);
}
if (mesh) {
effect.setFloat(this._tangentCorrectionFactorName, mesh.getWorldMatrix().determinant() < 0 ? -1 : 1);
}
}

public autoConfigure(material: NodeMaterial) {
Expand Down Expand Up @@ -211,6 +216,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;
Expand Down Expand Up @@ -243,7 +252,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`;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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`;
}

Expand Down Expand Up @@ -202,9 +206,21 @@ export class AnisotropyBlock extends NodeMaterialBlock {
defines.setValue("ANISOTROPIC_TEXTURE", false, true);
}

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) {
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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import { TBNBlock } from "../Fragment/TBNBlock";
*/
export class ClearCoatBlock extends NodeMaterialBlock {
private _scene: Scene;
private _tangentCorrectionFactorName = "";

/**
* Create a new ClearCoatBlock
Expand Down Expand Up @@ -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) {
Expand All @@ -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`;
}

Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit f72f174

Please sign in to comment.