UNPKG

@babylonjs/core

Version:

Getting started? Play directly with the Babylon.js API using our [playground](https://playground.babylonjs.com/). It also contains a lot of samples to learn how to use it.

161 lines 7.28 kB
import { NodeMaterialBlock } from "../../nodeMaterialBlock.js"; import { NodeMaterialBlockConnectionPointTypes } from "../../Enums/nodeMaterialBlockConnectionPointTypes.js"; import { NodeMaterialBlockTargets } from "../../Enums/nodeMaterialBlockTargets.js"; import { RegisterClass } from "../../../../Misc/typeStore.js"; import { VertexBuffer } from "../../../../Meshes/buffer.js"; /** * Block used for the Gaussian Splatting */ export class GaussianSplattingBlock extends NodeMaterialBlock { /** * Create a new GaussianSplattingBlock * @param name defines the block name */ constructor(name) { super(name, NodeMaterialBlockTargets.Vertex); this._isUnique = true; this.registerInput("splatPosition", NodeMaterialBlockConnectionPointTypes.Vector3, false, NodeMaterialBlockTargets.Vertex); this.registerInput("splatScale", NodeMaterialBlockConnectionPointTypes.Vector2, true, NodeMaterialBlockTargets.Vertex); this.registerInput("world", NodeMaterialBlockConnectionPointTypes.Matrix, false, NodeMaterialBlockTargets.Vertex); this.registerInput("view", NodeMaterialBlockConnectionPointTypes.Matrix, false, NodeMaterialBlockTargets.Vertex); this.registerInput("projection", NodeMaterialBlockConnectionPointTypes.Matrix, false, NodeMaterialBlockTargets.Vertex); this.registerOutput("splatVertex", NodeMaterialBlockConnectionPointTypes.Vector4, NodeMaterialBlockTargets.Vertex); this.registerOutput("SH", NodeMaterialBlockConnectionPointTypes.Color3, NodeMaterialBlockTargets.Vertex); } /** * Gets the current class name * @returns the class name */ getClassName() { return "GaussianSplattingBlock"; } /** * Gets the position input component */ get splatPosition() { return this._inputs[0]; } /** * Gets the scale input component */ get splatScale() { return this._inputs[1]; } /** * Gets the View matrix input component */ get world() { return this._inputs[2]; } /** * Gets the View matrix input component */ get view() { return this._inputs[3]; } /** * Gets the projection matrix input component */ get projection() { return this._inputs[4]; } /** * Gets the splatVertex output component */ get splatVertex() { return this._outputs[0]; } /** * Gets the SH output contribution */ get SH() { return this._outputs[1]; } /** * Initialize the block and prepare the context for build * @param state defines the state that will be used for the build */ initialize(state) { state._excludeVariableName("focal"); state._excludeVariableName("invViewport"); state._excludeVariableName("kernelSize"); state._excludeVariableName("eyePosition"); } /** * Update defines for shader compilation * @param defines defines the material defines to update * @param nodeMaterial defines the node material requesting the update * @param mesh defines the mesh to be rendered */ prepareDefines(defines, nodeMaterial, mesh) { if (!mesh) { return; } if (mesh.getClassName() == "GaussianSplattingMesh") { defines.setValue("SH_DEGREE", mesh.shDegree, true); } } _buildBlock(state) { super._buildBlock(state); if (state.target === NodeMaterialBlockTargets.Fragment) { return; } state.sharedData.blocksWithDefines.push(this); const comments = `//${this.name}`; state._emitFunctionFromInclude("gaussianSplattingVertexDeclaration", comments); state._emitFunctionFromInclude("gaussianSplatting", comments); state._emitFunctionFromInclude("helperFunctions", comments); state._emitUniformFromString("focal", NodeMaterialBlockConnectionPointTypes.Vector2); state._emitUniformFromString("invViewport", NodeMaterialBlockConnectionPointTypes.Vector2); state._emitUniformFromString("kernelSize", NodeMaterialBlockConnectionPointTypes.Float); state._emitUniformFromString("eyePosition", NodeMaterialBlockConnectionPointTypes.Vector3); state.attributes.push(VertexBuffer.PositionKind); state.attributes.push("splatIndex0"); state.attributes.push("splatIndex1"); state.attributes.push("splatIndex2"); state.attributes.push("splatIndex3"); state.sharedData.nodeMaterial.backFaceCulling = false; const splatPosition = this.splatPosition; const splatScale = this.splatScale; const world = this.world; const view = this.view; const projection = this.projection; const output = this.splatVertex; const sh = this.SH; const addF = state.fSuffix; let splatScaleParameter = `vec2${addF}(1.,1.)`; if (splatScale.isConnected) { splatScaleParameter = splatScale.associatedVariableName; } let input = "position"; let uniforms = ""; if (state.shaderLanguage === 1 /* ShaderLanguage.WGSL */) { input = "input.position"; uniforms = ", uniforms.focal, uniforms.invViewport, uniforms.kernelSize"; } if (this.SH.isConnected) { state.compilationString += `#if SH_DEGREE > 0\n`; if (state.shaderLanguage === 1 /* ShaderLanguage.WGSL */) { state.compilationString += `let worldRot: mat3x3f = mat3x3f(${world.associatedVariableName}[0].xyz, ${world.associatedVariableName}[1].xyz, ${world.associatedVariableName}[2].xyz);`; state.compilationString += `let normWorldRot: mat3x3f = inverseMat3(worldRot);`; state.compilationString += `var eyeToSplatLocalSpace: vec3f = normalize(normWorldRot * (${splatPosition.associatedVariableName}.xyz - uniforms.eyePosition));\n`; } else { state.compilationString += `mat3 worldRot = mat3(${world.associatedVariableName});`; state.compilationString += `mat3 normWorldRot = inverseMat3(worldRot);`; state.compilationString += `vec3 eyeToSplatLocalSpace = normalize(normWorldRot * (${splatPosition.associatedVariableName}.xyz - eyePosition));\n`; } state.compilationString += `${state._declareOutput(sh)} = computeSH(splat, eyeToSplatLocalSpace);\n`; state.compilationString += `#else\n`; state.compilationString += `${state._declareOutput(sh)} = vec3${addF}(0.,0.,0.);\n`; state.compilationString += `#endif;\n`; } else { state.compilationString += `${state._declareOutput(sh)} = vec3${addF}(0.,0.,0.);`; } state.compilationString += `${state._declareOutput(output)} = gaussianSplatting(${input}.xy, ${splatPosition.associatedVariableName}, ${splatScaleParameter}, covA, covB, ${world.associatedVariableName}, ${view.associatedVariableName}, ${projection.associatedVariableName}${uniforms});\n`; return this; } } RegisterClass("BABYLON.GaussianSplattingBlock", GaussianSplattingBlock); //# sourceMappingURL=gaussianSplattingBlock.js.map