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.

186 lines 6.8 kB
import { __decorate } from "../../tslib.es6.js"; import { serialize, expandToProperty } from "../../Misc/decorators.js"; import { Color3 } from "../../Maths/math.color.js"; import { MaterialPluginBase } from "../materialPluginBase.js"; import { RegisterClass } from "../../Misc/typeStore.js"; import { GetGaussianSplattingMaxPartCount } from "./gaussianSplattingMaterial.js"; /** * Plugin for GaussianSplattingMaterial that replaces per-splat colors with a * solid color per compound-mesh part. Each part index maps to a single Color3 * value, which is looked up in a uniform array in the fragment shader. */ export class GaussianSplattingSolidColorMaterialPlugin extends MaterialPluginBase { /** @internal */ _onIsEnabledChanged() { // Intentional no-op: isEnabled is applied via a uniform in // bindForSubMesh, so no dirty-marking or recompilation is needed. } /** * Creates a new GaussianSplatSolidColorPlugin. * @param material The GaussianSplattingMaterial to attach the plugin to. * @param partColors A map from part index to the solid Color3 for that part. * @param maxPartCount The maximum number of parts supported. This determines the size of the uniform array. */ constructor(material, partColors, maxPartCount) { super(material, "GaussianSplatSolidColor", 200); this._isEnabled = true; /** * Whether the solid-color override is active. When false, splats * render with their original per-splat colors. * Toggled via a shader uniform so no recompilation is required. */ this.isEnabled = true; this._partColors = partColors; this._maxPartCount = maxPartCount ?? GetGaussianSplattingMaxPartCount(material.getScene().getEngine()); this._enable(true); } /** * Updates the part colors dynamically. * @param partColors A map from part index to the solid Color3 for that part. */ updatePartColors(partColors) { this._partColors = partColors; } // --- Plugin overrides --- /** * @returns the class name */ getClassName() { return "GaussianSplattingSolidColorMaterialPlugin"; } /** * Indicates this plugin supports both GLSL and WGSL. * @param shaderLanguage the shader language to check * @returns true for GLSL and WGSL */ isCompatible(shaderLanguage) { switch (shaderLanguage) { case 0 /* ShaderLanguage.GLSL */: case 1 /* ShaderLanguage.WGSL */: return true; default: return false; } } /** * Always ready — no textures or async resources to wait on. * @param _defines the defines * @param _scene the scene * @param _engine the engine * @param _subMesh the submesh * @returns true */ isReadyForSubMesh(_defines, _scene, _engine, _subMesh) { return true; } /** * Returns custom shader code fragments to inject solid-color rendering. * * @param shaderType "vertex" or "fragment" * @param shaderLanguage the shader language to use (default: GLSL) * @returns null or a map of injection point names to code strings */ getCustomCode(shaderType, shaderLanguage = 0 /* ShaderLanguage.GLSL */) { const maxPartCount = this._maxPartCount; if (shaderLanguage === 1 /* ShaderLanguage.WGSL */) { return this._getCustomCodeWGSL(shaderType, maxPartCount); } return this._getCustomCodeGLSL(shaderType, maxPartCount); } _getCustomCodeGLSL(shaderType, maxPartCount) { if (shaderType === "vertex") { return { CUSTOM_VERTEX_DEFINITIONS: `varying float vPartIndex;`, CUSTOM_VERTEX_UPDATE: ` #if IS_COMPOUND vPartIndex = float(splat.partIndex); #else vPartIndex = 0.0; #endif `, }; } else if (shaderType === "fragment") { return { CUSTOM_FRAGMENT_DEFINITIONS: ` varying float vPartIndex; uniform float solidColorEnabled; uniform vec3 partColors[${maxPartCount}]; `, CUSTOM_FRAGMENT_BEFORE_FRAGCOLOR: ` if (solidColorEnabled > 0.5) { int partIdx = int(vPartIndex + 0.5); finalColor = vec4(partColors[partIdx], finalColor.w); } `, }; } return null; } _getCustomCodeWGSL(shaderType, maxPartCount) { if (shaderType === "vertex") { return { CUSTOM_VERTEX_DEFINITIONS: `varying vPartIndex: f32;`, CUSTOM_VERTEX_UPDATE: ` #if IS_COMPOUND vertexOutputs.vPartIndex = f32(splat.partIndex); #else vertexOutputs.vPartIndex = 0.0; #endif `, }; } else if (shaderType === "fragment") { return { CUSTOM_FRAGMENT_DEFINITIONS: ` varying vPartIndex: f32; uniform solidColorEnabled: f32; uniform partColors: array<vec3f, ${maxPartCount}>; `, CUSTOM_FRAGMENT_BEFORE_FRAGCOLOR: ` if (uniforms.solidColorEnabled > 0.5) { var partIdx: i32 = i32(fragmentInputs.vPartIndex + 0.5); finalColor = vec4f(uniforms.partColors[partIdx], finalColor.w); } `, }; } return null; } /** * Registers the plugin uniforms with the engine so that * the Effect can resolve their locations. * @returns uniform descriptions */ getUniforms() { return { externalUniforms: ["partColors", "solidColorEnabled"], }; } /** * Binds the plugin uniforms each frame. * @param _uniformBuffer the uniform buffer (unused — we bind directly on the effect) * @param _scene the current scene * @param _engine the current engine * @param subMesh the submesh being rendered */ bindForSubMesh(_uniformBuffer, _scene, _engine, subMesh) { const effect = subMesh.effect; if (!effect) { return; } effect.setFloat("solidColorEnabled", this._isEnabled ? 1.0 : 0.0); const colorArray = []; for (let i = 0; i < this._maxPartCount; i++) { const color = this._partColors[i] ?? new Color3(0, 0, 0); colorArray.push(color.r, color.g, color.b); } effect.setArray3("partColors", colorArray); } } __decorate([ serialize(), expandToProperty("_onIsEnabledChanged") ], GaussianSplattingSolidColorMaterialPlugin.prototype, "isEnabled", void 0); RegisterClass("BABYLON.GaussianSplattingSolidColorMaterialPlugin", GaussianSplattingSolidColorMaterialPlugin); //# sourceMappingURL=gaussianSplattingSolidColorMaterialPlugin.js.map