Skip to content

Commit

Permalink
Merge pull request #13501 from sebavan/master
Browse files Browse the repository at this point in the history
Add Object Space mapping to NME PerturbNormal block
  • Loading branch information
sebavan authored Feb 6, 2023
2 parents effb011 + 94b3e05 commit 42a8bc6
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import "../../../../Shaders/ShadersInclude/bumpFragment";
export class PerturbNormalBlock extends NodeMaterialBlock {
private _tangentSpaceParameterName = "";
private _tangentCorrectionFactorName = "";
private _worldMatrixName = "";

/** 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 All @@ -36,6 +37,9 @@ export class PerturbNormalBlock extends NodeMaterialBlock {
/** Gets or sets a boolean indicating that parallax occlusion should be enabled */
@editableInPropertyPage("Use parallax occlusion", PropertyTypeForEdition.Boolean)
public useParallaxOcclusion = false;
/** Gets or sets a boolean indicating that sampling mode is in Object space */
@editableInPropertyPage("Object Space Mode", PropertyTypeForEdition.Boolean, "PROPERTIES", { notifiers: { update: false } })
public useObjectSpaceNormalMap = false;

/**
* Create a new PerturbNormalBlock
Expand Down Expand Up @@ -63,6 +67,7 @@ export class PerturbNormalBlock extends NodeMaterialBlock {
NodeMaterialBlockTargets.VertexAndFragment,
new NodeMaterialConnectionPointCustomObject("TBN", this, NodeMaterialConnectionPointDirection.Input, TBNBlock, "TBNBlock")
);
this.registerInput("world", NodeMaterialBlockConnectionPointTypes.Matrix, true);

// Fragment
this.registerOutput("output", NodeMaterialBlockConnectionPointTypes.Vector4);
Expand Down Expand Up @@ -148,6 +153,13 @@ export class PerturbNormalBlock extends NodeMaterialBlock {
return this._inputs[9];
}

/**
* Gets the World input component
*/
public get world(): NodeMaterialConnectionPoint {
return this._inputs[10];
}

/**
* Gets the output component
*/
Expand All @@ -169,6 +181,7 @@ export class PerturbNormalBlock extends NodeMaterialBlock {
defines.setValue("BUMP", true);
defines.setValue("PARALLAX", useParallax, true);
defines.setValue("PARALLAXOCCLUSION", this.useParallaxOcclusion, true);
defines.setValue("OBJECTSPACE_NORMALMAP", this.useObjectSpaceNormalMap, true);
}

public bind(effect: Effect, nodeMaterial: NodeMaterial, mesh?: Mesh) {
Expand All @@ -177,8 +190,14 @@ export class PerturbNormalBlock extends NodeMaterialBlock {
} 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);

if (this.useObjectSpaceNormalMap && !this.world.isConnected) {
// World default to the mesh world matrix
effect.setMatrix(this._worldMatrixName, mesh.getWorldMatrix());
}
}
}

Expand Down Expand Up @@ -220,6 +239,10 @@ export class PerturbNormalBlock extends NodeMaterialBlock {

state._emitUniformFromString(this._tangentCorrectionFactorName, "float");

this._worldMatrixName = state._getFreeDefineName("perturbNormalWorldMatrix");

state._emitUniformFromString(this._worldMatrixName, "mat4");

let normalSamplerName = null;
if (this.normalMapColor.connectedPoint) {
normalSamplerName = (this.normalMapColor.connectedPoint!._ownerBlock as TextureBlock).samplerName;
Expand All @@ -241,6 +264,7 @@ export class PerturbNormalBlock extends NodeMaterialBlock {

const tangentReplaceString = { search: /defined\(TANGENT\)/g, replace: worldTangent.isConnected ? "defined(TANGENT)" : "defined(IGNORE)" };
const tbnVarying = { search: /varying mat3 vTBN/g, replace: "" };
const normalMatrixReplaceString = { search: /uniform mat4 normalMatrix;/g, replace: "" };

const TBN = this.TBN;
if (TBN.isConnected) {
Expand All @@ -257,7 +281,7 @@ export class PerturbNormalBlock extends NodeMaterialBlock {
}

state._emitFunctionFromInclude("bumpFragmentMainFunctions", comments, {
replaceStrings: [tangentReplaceString, tbnVarying],
replaceStrings: [tangentReplaceString, tbnVarying, normalMatrixReplaceString],
});

state._emitFunctionFromInclude("bumpFragmentFunctions", comments, {
Expand All @@ -279,6 +303,11 @@ export class PerturbNormalBlock extends NodeMaterialBlock {
state.compilationString += this._declareOutput(this.output, state) + " = vec4(0.);\r\n";
state.compilationString += state._emitCodeFromInclude("bumpFragment", comments, {
replaceStrings: [
{ search: /texture2D\(bumpSampler,vBumpUV\)/g, replace: `${uvForPerturbNormal}` },
{
search: /#define CUSTOM_FRAGMENT_BUMP_FRAGMENT/g,
replace: `mat4 normalMatrix = toNormalMatrix(${this.world.isConnected ? this.world.associatedVariableName : this._worldMatrixName});`,
},
{ search: /perturbNormal\(TBN,texture2D\(bumpSampler,vBumpUV\+uvOffset\).xyz,vBumpInfos.y\)/g, replace: `perturbNormal(TBN, ${uvForPerturbNormal}, vBumpInfos.y)` },
{
search: /parallaxOcclusion\(invTBN\*-viewDirectionW,invTBN\*normalW,vBumpUV,vBumpInfos.z\)/g,
Expand Down Expand Up @@ -311,6 +340,7 @@ export class PerturbNormalBlock extends NodeMaterialBlock {

codeString += `${this._codeVariableName}.invertY = ${this.invertY};\r\n`;
codeString += `${this._codeVariableName}.useParallaxOcclusion = ${this.useParallaxOcclusion};\r\n`;
codeString += `${this._codeVariableName}.useObjectSpaceNormalMap = ${this.useObjectSpaceNormalMap};\r\n`;

return codeString;
}
Expand All @@ -321,6 +351,7 @@ export class PerturbNormalBlock extends NodeMaterialBlock {
serializationObject.invertX = this.invertX;
serializationObject.invertY = this.invertY;
serializationObject.useParallaxOcclusion = this.useParallaxOcclusion;
serializationObject.useObjectSpaceNormalMap = this.useObjectSpaceNormalMap;

return serializationObject;
}
Expand All @@ -331,6 +362,7 @@ export class PerturbNormalBlock extends NodeMaterialBlock {
this.invertX = serializationObject.invertX;
this.invertY = serializationObject.invertY;
this.useParallaxOcclusion = !!serializationObject.useParallaxOcclusion;
this.useObjectSpaceNormalMap = !!serializationObject.useObjectSpaceNormalMap;
}
}

Expand Down
3 changes: 3 additions & 0 deletions packages/dev/core/src/Shaders/ShadersInclude/bumpFragment.fx
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@

#ifdef BUMP
#ifdef OBJECTSPACE_NORMALMAP

#define CUSTOM_FRAGMENT_BUMP_FRAGMENT

normalW = normalize(texture2D(bumpSampler, vBumpUV).xyz * 2.0 - 1.0);
normalW = normalize(mat3(normalMatrix) * normalW);
#elif !defined(DETAIL)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,17 @@

#ifdef OBJECTSPACE_NORMALMAP
uniform mat4 normalMatrix;

mat4 toNormalMatrix(mat4 wMatrix)
{
mat4 ret = inverse(wMatrix);
ret = transpose(ret);
ret[0][3] = 0.;
ret[1][3] = 0.;
ret[2][3] = 0.;
ret[3] = vec4(0., 0., 0., 1.);
return ret;
}
#endif

vec3 perturbNormalBase(mat3 cotangentFrame, vec3 normal, float scale)
Expand Down
4 changes: 3 additions & 1 deletion packages/tools/tests/test/visualization/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
{
"title": "Iridescence NME",
"playgroundId": "#2FDQT5#1507",
"referenceImage": "iridescence_nme.png"
"referenceImage": "iridescence_nme.png",
"excludedEngines": ["webgl1"],
"excludeFromAutomaticTesting": true
},
{
"title": "Iridescence GLTF",
Expand Down

0 comments on commit 42a8bc6

Please sign in to comment.