From 0c17e8db779a2df51f23718739bc700c4172b485 Mon Sep 17 00:00:00 2001 From: sebavan Date: Sat, 30 Apr 2022 02:21:52 +0200 Subject: [PATCH 1/9] Create a TBN NME node --- .../Materials/Node/Blocks/Dual/TBNBlock.ts | 171 ++++++++++++++++++ .../src/Materials/Node/Blocks/Dual/index.ts | 1 + .../Blocks/Fragment/perturbNormalBlock.ts | 28 ++- .../Materials/Node/Blocks/Input/inputBlock.ts | 2 +- .../Node/Blocks/PBR/anisotropyBlock.ts | 25 ++- .../Node/Blocks/PBR/clearCoatBlock.ts | 25 ++- packages/tools/nodeEditor/src/blockTools.ts | 3 + .../components/nodeList/nodeListComponent.tsx | 2 + .../properties/inputNodePropertyComponent.tsx | 2 +- 9 files changed, 253 insertions(+), 6 deletions(-) create mode 100644 packages/dev/core/src/Materials/Node/Blocks/Dual/TBNBlock.ts diff --git a/packages/dev/core/src/Materials/Node/Blocks/Dual/TBNBlock.ts b/packages/dev/core/src/Materials/Node/Blocks/Dual/TBNBlock.ts new file mode 100644 index 00000000000..ba1979bccc0 --- /dev/null +++ b/packages/dev/core/src/Materials/Node/Blocks/Dual/TBNBlock.ts @@ -0,0 +1,171 @@ +import { NodeMaterialBlock } from "../../nodeMaterialBlock"; +import { NodeMaterialBlockConnectionPointTypes } from "../../Enums/nodeMaterialBlockConnectionPointTypes"; +import type { NodeMaterialBuildState } from "../../nodeMaterialBuildState"; +import { NodeMaterialBlockTargets } from "../../Enums/nodeMaterialBlockTargets"; +import { NodeMaterialConnectionPoint, NodeMaterialConnectionPointDirection } from "../../nodeMaterialBlockConnectionPoint"; +import { RegisterClass } from "../../../../Misc/typeStore"; +import { NodeMaterialConnectionPointCustomObject } from "../../nodeMaterialConnectionPointCustomObject"; +import { NodeMaterial, NodeMaterialDefines } from "../../nodeMaterial"; +import { NodeMaterialSystemValues } from "../../Enums/nodeMaterialSystemValues"; +import { InputBlock } from "../Input/inputBlock"; +import { AbstractMesh } from "../../../../Meshes/abstractMesh"; + +/** + * Block used to implement TBN matrix + */ +export class TBNBlock extends NodeMaterialBlock { + /** + * Create a new TBNBlock + * @param name defines the block name + */ + public constructor(name: string) { + super(name, NodeMaterialBlockTargets.VertexAndFragment, true); + + this.registerInput("normal", NodeMaterialBlockConnectionPointTypes.Vector4, false); + this.normal.acceptedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Vector3); + this.registerInput("tangent", NodeMaterialBlockConnectionPointTypes.Vector4, false); + this.registerInput("world", NodeMaterialBlockConnectionPointTypes.Matrix, false); + + this.registerOutput( + "TBN", + NodeMaterialBlockConnectionPointTypes.Object, + NodeMaterialBlockTargets.Fragment, + new NodeMaterialConnectionPointCustomObject("TBN", this, NodeMaterialConnectionPointDirection.Output, TBNBlock, "TBNBlock") + ); + } + + /** + * Gets the current class name + * @returns the class name + */ + public getClassName() { + return "TBNBlock"; + } + + /** + * 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("tbnNormal"); + state._excludeVariableName("tbnTangent"); + state._excludeVariableName("tbnBitangent"); + } + + /** + * Gets the normal input component + */ + public get normal(): NodeMaterialConnectionPoint { + return this._inputs[0]; + } + + /** + * Gets the tangent input component + */ + public get tangent(): NodeMaterialConnectionPoint { + return this._inputs[1]; + } + + /** + * Gets the world matrix input component + */ + public get world(): NodeMaterialConnectionPoint { + return this._inputs[2]; + } + + /** + * Gets the TBN output component + */ + // eslint-disable-next-line @typescript-eslint/naming-convention + public get TBN(): NodeMaterialConnectionPoint { + return this._outputs[0]; + } + + public get target() { + return NodeMaterialBlockTargets.VertexAndFragment; + } + + public set target(value: NodeMaterialBlockTargets) {} + + public autoConfigure(material: NodeMaterial) { + if (!this.world.isConnected) { + let worldInput = material.getInputBlockByPredicate((b) => b.isSystemValue && b.systemValue === NodeMaterialSystemValues.World); + + if (!worldInput) { + worldInput = new InputBlock("world"); + worldInput.setAsSystemValue(NodeMaterialSystemValues.World); + } + worldInput.output.connectTo(this.world); + } + + if (!this.normal.isConnected) { + let normalInput = material.getInputBlockByPredicate((b) => b.isAttribute && b.name === "normal"); + + if (!normalInput) { + normalInput = new InputBlock("normal"); + normalInput.setAsAttribute("normal"); + } + normalInput.output.connectTo(this.normal); + } + + if (!this.tangent.isConnected) { + let tangentInput = material.getInputBlockByPredicate((b) => b.isAttribute && b.name === "tangent" && b.type === NodeMaterialBlockConnectionPointTypes.Vector4); + + if (!tangentInput) { + tangentInput = new InputBlock("tangent"); + tangentInput.setAsAttribute("tangent"); + } + tangentInput.output.connectTo(this.tangent); + } + } + + public prepareDefines(mesh: AbstractMesh, nodeMaterial: NodeMaterial, defines: NodeMaterialDefines) { + const normal = this.normal; + const tangent = this.tangent; + + let normalAvailable = normal.isConnected && normal.isConnectedToInputBlock; + if (normal.connectInputBlock?.isAttribute && !mesh.isVerticesDataPresent(normal.connectInputBlock?.name)) { + normalAvailable = false; + } + + let tangentAvailable = tangent.isConnected && tangent.isConnectedToInputBlock; + if (tangent.connectInputBlock?.isAttribute && !mesh.isVerticesDataPresent(tangent.connectInputBlock?.name)) { + tangentAvailable = false; + } + + const useTBNBlock = normalAvailable && tangentAvailable; + + defines.setValue("TBNBLOCK", useTBNBlock, true); + } + + protected _buildBlock(state: NodeMaterialBuildState) { + super._buildBlock(state); + + const normal = this.normal; + const tangent = this.tangent; + const world = this.world; + const TBN = this.TBN; + + if (state.target !== NodeMaterialBlockTargets.Fragment) { + // Vertex + state._emitVaryingFromString(TBN.associatedVariableName, "mat3"); + + state.compilationString += ` + // ${this.name} + vec3 tbnNormal = normalize(${normal.associatedVariableName}); + vec3 tbnTangent = normalize(${tangent.associatedVariableName}.xyz); + vec3 tbnBitangent = cross(tbnNormal, tbnTangent) * ${tangent.associatedVariableName}.w; + ${TBN.associatedVariableName} = mat3(${world.associatedVariableName}) * mat3(tbnTangent, tbnBitangent, tbnNormal); + `; + + return this; + } + + // Fragment + state.sharedData.blocksWithDefines.push(this); + + return this; + } +} + +RegisterClass("BABYLON.TBNBlock", TBNBlock); diff --git a/packages/dev/core/src/Materials/Node/Blocks/Dual/index.ts b/packages/dev/core/src/Materials/Node/Blocks/Dual/index.ts index 4c3239a8f59..365a6461410 100644 --- a/packages/dev/core/src/Materials/Node/Blocks/Dual/index.ts +++ b/packages/dev/core/src/Materials/Node/Blocks/Dual/index.ts @@ -6,3 +6,4 @@ export * from "./currentScreenBlock"; export * from "./sceneDepthBlock"; export * from "./imageSourceBlock"; export * from "./clipPlanesBlock"; +export * from "./TBNBlock"; 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 27a05d89727..889a681b2b3 100644 --- a/packages/dev/core/src/Materials/Node/Blocks/Fragment/perturbNormalBlock.ts +++ b/packages/dev/core/src/Materials/Node/Blocks/Fragment/perturbNormalBlock.ts @@ -2,7 +2,7 @@ import { NodeMaterialBlock } from "../../nodeMaterialBlock"; import { NodeMaterialBlockConnectionPointTypes } from "../../Enums/nodeMaterialBlockConnectionPointTypes"; import type { NodeMaterialBuildState } from "../../nodeMaterialBuildState"; import { NodeMaterialBlockTargets } from "../../Enums/nodeMaterialBlockTargets"; -import type { NodeMaterialConnectionPoint } from "../../nodeMaterialBlockConnectionPoint"; +import { NodeMaterialConnectionPoint, NodeMaterialConnectionPointDirection } from "../../nodeMaterialBlockConnectionPoint"; import { RegisterClass } from "../../../../Misc/typeStore"; import type { NodeMaterial, NodeMaterialDefines } from "../../nodeMaterial"; import type { AbstractMesh } from "../../../../Meshes/abstractMesh"; @@ -11,6 +11,8 @@ import type { Effect } from "../../../effect"; import type { Scene } from "../../../../scene"; import { editableInPropertyPage, PropertyTypeForEdition } from "../../nodeMaterialDecorator"; import type { TextureBlock } from "../Dual/textureBlock"; +import { NodeMaterialConnectionPointCustomObject } from "../../nodeMaterialConnectionPointCustomObject"; +import { TBNBlock } from "../Dual/TBNBlock"; import "../../../../Shaders/ShadersInclude/bumpFragmentMainFunctions"; import "../../../../Shaders/ShadersInclude/bumpFragmentFunctions"; @@ -51,6 +53,13 @@ export class PerturbNormalBlock extends NodeMaterialBlock { this.registerInput("viewDirection", NodeMaterialBlockConnectionPointTypes.Vector3, true); this.registerInput("parallaxScale", NodeMaterialBlockConnectionPointTypes.Float, true); this.registerInput("parallaxHeight", NodeMaterialBlockConnectionPointTypes.Float, true); + this.registerInput( + "TBN", + NodeMaterialBlockConnectionPointTypes.Object, + true, + NodeMaterialBlockTargets.VertexAndFragment, + new NodeMaterialConnectionPointCustomObject("TBN", this, NodeMaterialConnectionPointDirection.Input, TBNBlock, "TBNBlock") + ); // Fragment this.registerOutput("output", NodeMaterialBlockConnectionPointTypes.Vector4); @@ -128,6 +137,14 @@ export class PerturbNormalBlock extends NodeMaterialBlock { return this._inputs[8]; } + /** + * Gets the TBN input component + */ + // eslint-disable-next-line @typescript-eslint/naming-convention + public get TBN(): NodeMaterialConnectionPoint { + return this._inputs[9]; + } + /** * Gets the output component */ @@ -212,7 +229,14 @@ 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: "" }; - if (worldTangent.isConnected) { + const TBN = this.TBN; + if (TBN.isConnected) { + state.compilationString += ` + #ifdef TBNBLOCK + mat3 vTBN = ${TBN.associatedVariableName}; + #endif + `; + } 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`; diff --git a/packages/dev/core/src/Materials/Node/Blocks/Input/inputBlock.ts b/packages/dev/core/src/Materials/Node/Blocks/Input/inputBlock.ts index 4f7b619fb29..8d4f80f68c6 100644 --- a/packages/dev/core/src/Materials/Node/Blocks/Input/inputBlock.ts +++ b/packages/dev/core/src/Materials/Node/Blocks/Input/inputBlock.ts @@ -113,7 +113,6 @@ export class InputBlock extends NodeMaterialBlock { switch (this.name) { case "position": case "normal": - case "tangent": case "particle_positionw": this._type = NodeMaterialBlockConnectionPointTypes.Vector3; return this._type; @@ -133,6 +132,7 @@ export class InputBlock extends NodeMaterialBlock { case "world1": case "world2": case "world3": + case "tangent": this._type = NodeMaterialBlockConnectionPointTypes.Vector4; return this._type; case "color": 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 9656140cf9d..64fec3c1a15 100644 --- a/packages/dev/core/src/Materials/Node/Blocks/PBR/anisotropyBlock.ts +++ b/packages/dev/core/src/Materials/Node/Blocks/PBR/anisotropyBlock.ts @@ -8,6 +8,7 @@ import { NodeMaterialBlockTargets } from "../../Enums/nodeMaterialBlockTargets"; import { RegisterClass } from "../../../../Misc/typeStore"; import type { AbstractMesh } from "../../../../Meshes/abstractMesh"; import { NodeMaterialConnectionPointCustomObject } from "../../nodeMaterialConnectionPointCustomObject"; +import { TBNBlock } from "../Dual/TBNBlock"; /** * Block used to implement the anisotropy module of the PBR material @@ -37,6 +38,13 @@ export class AnisotropyBlock extends NodeMaterialBlock { this.registerInput("direction", NodeMaterialBlockConnectionPointTypes.Vector2, 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); + this.registerInput( + "TBN", + NodeMaterialBlockConnectionPointTypes.Object, + true, + NodeMaterialBlockTargets.VertexAndFragment, + new NodeMaterialConnectionPointCustomObject("TBN", this, NodeMaterialConnectionPointDirection.Input, TBNBlock, "TBNBlock") + ); this.registerOutput( "anisotropy", @@ -91,6 +99,14 @@ export class AnisotropyBlock extends NodeMaterialBlock { return this._inputs[3]; } + /** + * Gets the TBN input component + */ + // eslint-disable-next-line @typescript-eslint/naming-convention + public get TBN(): NodeMaterialConnectionPoint { + return this._inputs[4]; + } + /** * Gets the anisotropy object output component */ @@ -118,7 +134,14 @@ export class AnisotropyBlock extends NodeMaterialBlock { const tangentReplaceString = { search: /defined\(TANGENT\)/g, replace: worldTangent.isConnected ? "defined(TANGENT)" : "defined(IGNORE)" }; - if (worldTangent.isConnected) { + const TBN = this.TBN; + if (TBN.isConnected) { + state.compilationString += ` + #ifdef TBNBLOCK + mat3 vTBN = ${TBN.associatedVariableName}; + #endif + `; + } 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`; 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 ad71986f0bc..ca7b94d0bde 100644 --- a/packages/dev/core/src/Materials/Node/Blocks/PBR/clearCoatBlock.ts +++ b/packages/dev/core/src/Materials/Node/Blocks/PBR/clearCoatBlock.ts @@ -18,6 +18,7 @@ import type { PBRMetallicRoughnessBlock } from "./pbrMetallicRoughnessBlock"; import type { PerturbNormalBlock } from "../Fragment/perturbNormalBlock"; import { PBRClearCoatConfiguration } from "../../../PBR/pbrClearCoatConfiguration"; import { editableInPropertyPage, PropertyTypeForEdition } from "../../nodeMaterialDecorator"; +import { TBNBlock } from "../Dual/TBNBlock"; /** * Block used to implement the clear coat module of the PBR material @@ -45,6 +46,13 @@ export class ClearCoatBlock extends NodeMaterialBlock { this.registerInput("worldTangent", NodeMaterialBlockConnectionPointTypes.Vector4, true); this.registerInput("worldNormal", NodeMaterialBlockConnectionPointTypes.Vector4, true); this.worldNormal.acceptedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Vector3); + this.registerInput( + "TBN", + NodeMaterialBlockConnectionPointTypes.Object, + true, + NodeMaterialBlockTargets.VertexAndFragment, + new NodeMaterialConnectionPointCustomObject("TBN", this, NodeMaterialConnectionPointDirection.Input, TBNBlock, "TBNBlock") + ); this.registerOutput( "clearcoat", @@ -151,6 +159,14 @@ export class ClearCoatBlock extends NodeMaterialBlock { return this._inputs[9]; } + /** + * Gets the TBN input component + */ + // eslint-disable-next-line @typescript-eslint/naming-convention + public get TBN(): NodeMaterialConnectionPoint { + return this._inputs[10]; + } + /** * Gets the clear coat object output component */ @@ -216,7 +232,14 @@ export class ClearCoatBlock extends NodeMaterialBlock { const tangentReplaceString = { search: /defined\(TANGENT\)/g, replace: worldTangent.isConnected ? "defined(TANGENT)" : "defined(IGNORE)" }; - if (worldTangent.isConnected) { + const TBN = this.TBN; + if (TBN.isConnected) { + state.compilationString += ` + #ifdef TBNBLOCK + mat3 vTBN = ${TBN.associatedVariableName}; + #endif + `; + } 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`; diff --git a/packages/tools/nodeEditor/src/blockTools.ts b/packages/tools/nodeEditor/src/blockTools.ts index 69486ea2974..240f77d811a 100644 --- a/packages/tools/nodeEditor/src/blockTools.ts +++ b/packages/tools/nodeEditor/src/blockTools.ts @@ -42,6 +42,7 @@ import { LightInformationBlock } from "core/Materials/Node/Blocks/Vertex/lightIn import { MaxBlock } from "core/Materials/Node/Blocks/maxBlock"; import { MinBlock } from "core/Materials/Node/Blocks/minBlock"; import { PerturbNormalBlock } from "core/Materials/Node/Blocks/Fragment/perturbNormalBlock"; +import { TBNBlock } from "core/Materials/Node/Blocks/Dual/TBNBlock"; import { LengthBlock } from "core/Materials/Node/Blocks/lengthBlock"; import { DistanceBlock } from "core/Materials/Node/Blocks/distanceBlock"; import { FrontFacingBlock } from "core/Materials/Node/Blocks/Fragment/frontFacingBlock"; @@ -210,6 +211,8 @@ export class BlockTools { return new NegateBlock("Negate"); case "PerturbNormalBlock": return new PerturbNormalBlock("Perturb normal"); + case "TBNBlock": + return new TBNBlock("TBN"); case "RandomNumberBlock": return new RandomNumberBlock("Random number"); case "ReplaceColorBlock": diff --git a/packages/tools/nodeEditor/src/components/nodeList/nodeListComponent.tsx b/packages/tools/nodeEditor/src/components/nodeList/nodeListComponent.tsx index a9498a0220d..a3109bceede 100644 --- a/packages/tools/nodeEditor/src/components/nodeList/nodeListComponent.tsx +++ b/packages/tools/nodeEditor/src/components/nodeList/nodeListComponent.tsx @@ -75,6 +75,7 @@ export class NodeListComponent extends React.Component Date: Sun, 1 May 2022 21:00:40 +0200 Subject: [PATCH 2/9] Fix morph targets --- .../core/src/Materials/Node/Blocks/Vertex/morphTargetsBlock.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/dev/core/src/Materials/Node/Blocks/Vertex/morphTargetsBlock.ts b/packages/dev/core/src/Materials/Node/Blocks/Vertex/morphTargetsBlock.ts index 7fbe2a28e4e..6eaacbb88e9 100644 --- a/packages/dev/core/src/Materials/Node/Blocks/Vertex/morphTargetsBlock.ts +++ b/packages/dev/core/src/Materials/Node/Blocks/Vertex/morphTargetsBlock.ts @@ -30,7 +30,8 @@ export class MorphTargetsBlock extends NodeMaterialBlock { this.registerInput("position", NodeMaterialBlockConnectionPointTypes.Vector3); this.registerInput("normal", NodeMaterialBlockConnectionPointTypes.Vector3); - this.registerInput("tangent", NodeMaterialBlockConnectionPointTypes.Vector3); + this.registerInput("tangent", NodeMaterialBlockConnectionPointTypes.Vector4); + this.tangent.acceptedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Vector3); this.registerInput("uv", NodeMaterialBlockConnectionPointTypes.Vector2); this.registerOutput("positionOutput", NodeMaterialBlockConnectionPointTypes.Vector3); this.registerOutput("normalOutput", NodeMaterialBlockConnectionPointTypes.Vector3); From 75639a0594d1ed973c7048cd5758c4c4740de50a Mon Sep 17 00:00:00 2001 From: sebavan Date: Mon, 2 May 2022 20:51:04 +0200 Subject: [PATCH 3/9] FIX pr feedback --- .../dev/core/src/Materials/Node/Blocks/Dual/TBNBlock.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/dev/core/src/Materials/Node/Blocks/Dual/TBNBlock.ts b/packages/dev/core/src/Materials/Node/Blocks/Dual/TBNBlock.ts index ba1979bccc0..e0a2d28c132 100644 --- a/packages/dev/core/src/Materials/Node/Blocks/Dual/TBNBlock.ts +++ b/packages/dev/core/src/Materials/Node/Blocks/Dual/TBNBlock.ts @@ -123,12 +123,12 @@ export class TBNBlock extends NodeMaterialBlock { const normal = this.normal; const tangent = this.tangent; - let normalAvailable = normal.isConnected && normal.isConnectedToInputBlock; + let normalAvailable = normal.isConnected; if (normal.connectInputBlock?.isAttribute && !mesh.isVerticesDataPresent(normal.connectInputBlock?.name)) { normalAvailable = false; } - let tangentAvailable = tangent.isConnected && tangent.isConnectedToInputBlock; + let tangentAvailable = tangent.isConnected; if (tangent.connectInputBlock?.isAttribute && !mesh.isVerticesDataPresent(tangent.connectInputBlock?.name)) { tangentAvailable = false; } @@ -152,7 +152,7 @@ export class TBNBlock extends NodeMaterialBlock { state.compilationString += ` // ${this.name} - vec3 tbnNormal = normalize(${normal.associatedVariableName}); + vec3 tbnNormal = normalize(${normal.associatedVariableName}).xyz; vec3 tbnTangent = normalize(${tangent.associatedVariableName}.xyz); vec3 tbnBitangent = cross(tbnNormal, tbnTangent) * ${tangent.associatedVariableName}.w; ${TBN.associatedVariableName} = mat3(${world.associatedVariableName}) * mat3(tbnTangent, tbnBitangent, tbnNormal); From 8fb397cf762db25a4a3a00ab4c8ffd9273c99485 Mon Sep 17 00:00:00 2001 From: sebavan Date: Thu, 5 May 2022 22:57:35 +0200 Subject: [PATCH 4/9] Allow sRGB render Target creation --- packages/dev/core/src/Engines/thinEngine.ts | 5 ++++- .../dev/core/src/Materials/Textures/renderTargetTexture.ts | 5 ++++- .../core/src/Materials/Textures/textureCreationOptions.ts | 2 ++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/packages/dev/core/src/Engines/thinEngine.ts b/packages/dev/core/src/Engines/thinEngine.ts index 585be5303fe..17a1668397d 100644 --- a/packages/dev/core/src/Engines/thinEngine.ts +++ b/packages/dev/core/src/Engines/thinEngine.ts @@ -3704,6 +3704,8 @@ export class ThinEngine { fullOptions.format = Constants.TEXTUREFORMAT_RGBA; } + fullOptions.useSRGBBuffer = fullOptions.useSRGBBuffer && this._caps.supportSRGBBuffers && (this.webGLVersion > 1 || this.isWebGPU); + if (fullOptions.type === Constants.TEXTURETYPE_FLOAT && !this._caps.textureFloatLinearFiltering) { // if floating point linear (gl.FLOAT) then force to NEAREST_SAMPLINGMODE fullOptions.samplingMode = Constants.TEXTURE_NEAREST_SAMPLINGMODE; @@ -3718,12 +3720,13 @@ export class ThinEngine { const gl = this._gl; const texture = new InternalTexture(this, source); + texture._useSRGBBuffer = !!fullOptions.useSRGBBuffer; const width = (<{ width: number; height: number; layers?: number }>size).width || size; const height = (<{ width: number; height: number; layers?: number }>size).height || size; const layers = (<{ width: number; height: number; layers?: number }>size).layers || 0; const filters = this._getSamplingParameters(fullOptions.samplingMode, fullOptions.generateMipMaps ? true : false); const target = layers !== 0 ? gl.TEXTURE_2D_ARRAY : gl.TEXTURE_2D; - const sizedFormat = this._getRGBABufferInternalSizedFormat(fullOptions.type, fullOptions.format); + const sizedFormat = this._getRGBABufferInternalSizedFormat(fullOptions.type, fullOptions.format, fullOptions.useSRGBBuffer); const internalFormat = this._getInternalFormat(fullOptions.format); const type = this._getWebGLTextureType(fullOptions.type); diff --git a/packages/dev/core/src/Materials/Textures/renderTargetTexture.ts b/packages/dev/core/src/Materials/Textures/renderTargetTexture.ts index f40aff2a57f..e21c8a80a21 100644 --- a/packages/dev/core/src/Materials/Textures/renderTargetTexture.ts +++ b/packages/dev/core/src/Materials/Textures/renderTargetTexture.ts @@ -378,6 +378,7 @@ export class RenderTargetTexture extends Texture implements IRenderTargetTexture * @param samples sample count to use when creating the RTT * @param creationFlags specific flags to use when creating the texture (Constants.TEXTURE_CREATIONFLAG_STORAGE for storage textures, for eg) * @param noColorTarget True to indicate that no color target should be created. Useful if you only want to write to the depth buffer, for eg + * @param useSRGBBuffer True to create a SRGB texture */ constructor( name: string, @@ -395,7 +396,8 @@ export class RenderTargetTexture extends Texture implements IRenderTargetTexture delayAllocation = false, samples?: number, creationFlags?: number, - noColorTarget = false + noColorTarget = false, + useSRGBBuffer = false ) { super(null, scene, !generateMipMaps, undefined, samplingMode, undefined, undefined, undefined, undefined, format); scene = this.getScene(); @@ -440,6 +442,7 @@ export class RenderTargetTexture extends Texture implements IRenderTargetTexture samples, creationFlags, noColorTarget, + useSRGBBuffer }; if (this.samplingMode === Texture.NEAREST_SAMPLINGMODE) { diff --git a/packages/dev/core/src/Materials/Textures/textureCreationOptions.ts b/packages/dev/core/src/Materials/Textures/textureCreationOptions.ts index 8bd0dc3b956..d37fd5df1f4 100644 --- a/packages/dev/core/src/Materials/Textures/textureCreationOptions.ts +++ b/packages/dev/core/src/Materials/Textures/textureCreationOptions.ts @@ -20,6 +20,8 @@ export interface InternalTextureCreationOptions { samples?: number; /** Texture creation flags */ creationFlags?: number; + /** Creates the RTT in sRGB space */ + useSRGBBuffer?: boolean; } /** From 745f8980d178c9e9980aec2e321f4a8dde939233 Mon Sep 17 00:00:00 2001 From: sebavan Date: Fri, 6 May 2022 02:31:24 +0200 Subject: [PATCH 5/9] fix format --- packages/dev/core/src/Materials/Textures/renderTargetTexture.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/dev/core/src/Materials/Textures/renderTargetTexture.ts b/packages/dev/core/src/Materials/Textures/renderTargetTexture.ts index e21c8a80a21..e84259a6064 100644 --- a/packages/dev/core/src/Materials/Textures/renderTargetTexture.ts +++ b/packages/dev/core/src/Materials/Textures/renderTargetTexture.ts @@ -442,7 +442,7 @@ export class RenderTargetTexture extends Texture implements IRenderTargetTexture samples, creationFlags, noColorTarget, - useSRGBBuffer + useSRGBBuffer, }; if (this.samplingMode === Texture.NEAREST_SAMPLINGMODE) { From f48b26c388268a64a4e81b3924bc2ada664b1c72 Mon Sep 17 00:00:00 2001 From: sebavan Date: Fri, 6 May 2022 15:59:22 +0200 Subject: [PATCH 6/9] Fix NME Morph block with tangents --- .../src/Materials/Node/Blocks/Vertex/morphTargetsBlock.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/dev/core/src/Materials/Node/Blocks/Vertex/morphTargetsBlock.ts b/packages/dev/core/src/Materials/Node/Blocks/Vertex/morphTargetsBlock.ts index 6eaacbb88e9..c7431a62d23 100644 --- a/packages/dev/core/src/Materials/Node/Blocks/Vertex/morphTargetsBlock.ts +++ b/packages/dev/core/src/Materials/Node/Blocks/Vertex/morphTargetsBlock.ts @@ -35,7 +35,7 @@ export class MorphTargetsBlock extends NodeMaterialBlock { this.registerInput("uv", NodeMaterialBlockConnectionPointTypes.Vector2); this.registerOutput("positionOutput", NodeMaterialBlockConnectionPointTypes.Vector3); this.registerOutput("normalOutput", NodeMaterialBlockConnectionPointTypes.Vector3); - this.registerOutput("tangentOutput", NodeMaterialBlockConnectionPointTypes.Vector3); + this.registerOutput("tangentOutput", NodeMaterialBlockConnectionPointTypes.Vector4); this.registerOutput("uvOutput", NodeMaterialBlockConnectionPointTypes.Vector2); } @@ -230,10 +230,11 @@ export class MorphTargetsBlock extends NodeMaterialBlock { if (hasTangents) { injectionCode += `#ifdef MORPHTARGETS_TANGENT\r\n`; if (manager?.isUsingTextureForTargets) { - injectionCode += `${tangentOutput.associatedVariableName} += (readVector3FromRawSampler(${index}, vertexID) - ${tangent.associatedVariableName}) * morphTargetInfluences[${index}];\r\n`; + injectionCode += `${tangentOutput.associatedVariableName}.xyz += (readVector3FromRawSampler(${index}, vertexID) - ${tangent.associatedVariableName}.xyz) * morphTargetInfluences[${index}];\r\n`; } else { injectionCode += `${tangentOutput.associatedVariableName}.xyz += (tangent${index} - ${tangent.associatedVariableName}.xyz) * morphTargetInfluences[${index}];\r\n`; } + injectionCode += `${tangentOutput.associatedVariableName}.w = ${tangent.associatedVariableName}.w;\r\n`; injectionCode += `#endif\r\n`; } @@ -303,7 +304,7 @@ export class MorphTargetsBlock extends NodeMaterialBlock { state.compilationString += `#ifdef TANGENT\r\n`; state.compilationString += `${this._declareOutput(tangentOutput, state)} = ${tangent.associatedVariableName};\r\n`; state.compilationString += `#else\r\n`; - state.compilationString += `${this._declareOutput(tangentOutput, state)} = vec3(0., 0., 0.);\r\n`; + state.compilationString += `${this._declareOutput(tangentOutput, state)} = vec4(0., 0., 0., 0.);\r\n`; state.compilationString += `#endif\r\n`; state.compilationString += `#ifdef UV1\r\n`; state.compilationString += `${this._declareOutput(uvOutput, state)} = ${uv.associatedVariableName};\r\n`; From 009ca1696dac8ba4f09c22cea1b95fb9c8f18a8e Mon Sep 17 00:00:00 2001 From: sebavan Date: Fri, 6 May 2022 16:35:39 +0200 Subject: [PATCH 7/9] Fix PR comments --- .../src/Materials/Node/Blocks/Vertex/morphTargetsBlock.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/dev/core/src/Materials/Node/Blocks/Vertex/morphTargetsBlock.ts b/packages/dev/core/src/Materials/Node/Blocks/Vertex/morphTargetsBlock.ts index c7431a62d23..74edee244df 100644 --- a/packages/dev/core/src/Materials/Node/Blocks/Vertex/morphTargetsBlock.ts +++ b/packages/dev/core/src/Materials/Node/Blocks/Vertex/morphTargetsBlock.ts @@ -234,7 +234,13 @@ export class MorphTargetsBlock extends NodeMaterialBlock { } else { injectionCode += `${tangentOutput.associatedVariableName}.xyz += (tangent${index} - ${tangent.associatedVariableName}.xyz) * morphTargetInfluences[${index}];\r\n`; } - injectionCode += `${tangentOutput.associatedVariableName}.w = ${tangent.associatedVariableName}.w;\r\n`; + + if (tangent.type === NodeMaterialBlockConnectionPointTypes.Vector4) { + injectionCode += `${tangentOutput.associatedVariableName}.w = ${tangent.associatedVariableName}.w;\r\n`; + } + else { + injectionCode += `${tangentOutput.associatedVariableName}.w = 1.;\r\n`; + } injectionCode += `#endif\r\n`; } From 903887f53f1a3db7f9149d3c9d596cec97a0c6a8 Mon Sep 17 00:00:00 2001 From: sebavan Date: Fri, 6 May 2022 16:48:24 +0200 Subject: [PATCH 8/9] Format --- .../core/src/Materials/Node/Blocks/Vertex/morphTargetsBlock.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/dev/core/src/Materials/Node/Blocks/Vertex/morphTargetsBlock.ts b/packages/dev/core/src/Materials/Node/Blocks/Vertex/morphTargetsBlock.ts index 74edee244df..da06fa13cba 100644 --- a/packages/dev/core/src/Materials/Node/Blocks/Vertex/morphTargetsBlock.ts +++ b/packages/dev/core/src/Materials/Node/Blocks/Vertex/morphTargetsBlock.ts @@ -237,8 +237,7 @@ export class MorphTargetsBlock extends NodeMaterialBlock { if (tangent.type === NodeMaterialBlockConnectionPointTypes.Vector4) { injectionCode += `${tangentOutput.associatedVariableName}.w = ${tangent.associatedVariableName}.w;\r\n`; - } - else { + } else { injectionCode += `${tangentOutput.associatedVariableName}.w = 1.;\r\n`; } injectionCode += `#endif\r\n`; From 5ad940c4d56918b297534d283177be73e7ed158e Mon Sep 17 00:00:00 2001 From: sebavan Date: Tue, 10 May 2022 21:37:07 +0200 Subject: [PATCH 9/9] SSAO2 fix setting the prepass configuration --- .../RenderPipeline/Pipelines/ssao2RenderingPipeline.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/dev/core/src/PostProcesses/RenderPipeline/Pipelines/ssao2RenderingPipeline.ts b/packages/dev/core/src/PostProcesses/RenderPipeline/Pipelines/ssao2RenderingPipeline.ts index 93a5275c565..195f8312069 100644 --- a/packages/dev/core/src/PostProcesses/RenderPipeline/Pipelines/ssao2RenderingPipeline.ts +++ b/packages/dev/core/src/PostProcesses/RenderPipeline/Pipelines/ssao2RenderingPipeline.ts @@ -543,6 +543,10 @@ export class SSAO2RenderingPipeline extends PostProcessRenderPipeline { effect.setTexture("randomSampler", this._randomTexture); }; this._ssaoPostProcess.samples = this.textureSamples; + + if (!this._forceGeometryBuffer) { + this._ssaoPostProcess._prePassEffectConfiguration = new SSAO2Configuration(); + } } private _createSSAOCombinePostProcess(ratio: number, textureType: number): void { @@ -566,10 +570,6 @@ export class SSAO2RenderingPipeline extends PostProcessRenderPipeline { effect.setTextureFromPostProcessOutput("originalColor", this._originalColorPostProcess); }; this._ssaoCombinePostProcess.samples = this.textureSamples; - - if (!this._forceGeometryBuffer) { - this._ssaoCombinePostProcess._prePassEffectConfiguration = new SSAO2Configuration(); - } } private _createRandomTexture(): void {