UNPKG

playcanvas

Version:

Open-source WebGL/WebGPU 3D engine for the web

130 lines (129 loc) 4.74 kB
import { Debug } from "../../core/debug.js"; import { PIXELFORMAT_RGBA8, PIXELFORMAT_RGBA32F } from "../../platform/graphics/constants.js"; import { GSplatResourceBase } from "./gsplat-resource-base.js"; import { GSplatFormat } from "./gsplat-format.js"; class GSplatSogResource extends GSplatResourceBase { /** * @param {GraphicsDevice} device - The graphics device. * @param {GSplatSogData} gsplatData - The splat data. * @param {object} [options] - Passed to {@link GSplatResourceBase} constructor. */ constructor(device, gsplatData, options = {}) { super(device, gsplatData, options); const { meta, means_l } = gsplatData; const isV2 = meta.version === 2; const hasSH = gsplatData.shBands > 0; if (means_l) { this.streams.textureDimensions.set(means_l.width, means_l.height); } this.streams.textures.set("means_l", gsplatData.means_l); this.streams.textures.set("means_u", gsplatData.means_u); this.streams.textures.set("quats", gsplatData.quats); this.streams.textures.set("scales", gsplatData.scales); this.streams.textures.set("sh0", gsplatData.sh0); if (hasSH) { this.streams.textures.set("sh_labels", gsplatData.sh_labels); this.streams.textures.set("sh_centroids", gsplatData.sh_centroids); } if (isV2) { Debug.assert(gsplatData.codebookTexture, "GSplatSogResource: V2 asset is missing codebookTexture - prepareCodebook() must be called first."); this.streams.textures.set("sogCodebook", gsplatData.codebookTexture); } const streams = [ { name: "means_l", format: PIXELFORMAT_RGBA8 }, { name: "means_u", format: PIXELFORMAT_RGBA8 }, { name: "quats", format: PIXELFORMAT_RGBA8 }, { name: "scales", format: PIXELFORMAT_RGBA8 }, { name: "sh0", format: PIXELFORMAT_RGBA8 } ]; if (hasSH) { streams.push({ name: "sh_labels", format: PIXELFORMAT_RGBA8 }); streams.push({ name: "sh_centroids", format: PIXELFORMAT_RGBA8 }); } if (isV2) { streams.push({ name: "sogCodebook", format: PIXELFORMAT_RGBA32F }); } this._format = new GSplatFormat(device, streams, { readGLSL: '#include "gsplatSogVS"', readWGSL: '#include "gsplatSogVS"' }); this._populateParameters(); } /** * Opts each of the owned source textures into releasing its CPU-side ImageBitmap after * upload. Called by the gsplat octree, which re-creates these resources from scratch on * device loss and therefore does not need the CPU source retained for re-upload. * * @ignore */ releaseTextureSources() { const d = ( /** @type {GSplatSogData} */ this.gsplatData ); d.means_l?.setReleaseSourceAfterUpload(); d.means_u?.setReleaseSourceAfterUpload(); d.quats?.setReleaseSourceAfterUpload(); d.scales?.setReleaseSourceAfterUpload(); d.sh0?.setReleaseSourceAfterUpload(); d.sh_centroids?.setReleaseSourceAfterUpload(); d.sh_labels?.setReleaseSourceAfterUpload(); } /** @protected */ _actualDestroy() { this.streams.textures.delete("means_l"); this.streams.textures.delete("means_u"); this.streams.textures.delete("quats"); this.streams.textures.delete("scales"); this.streams.textures.delete("sh0"); this.streams.textures.delete("sh_labels"); this.streams.textures.delete("sh_centroids"); this.streams.textures.delete("sogCodebook"); this.gsplatData.destroy(); super._actualDestroy(); } /** * Populates the parameters map with dequantization uniforms. * V1 needs per-axis/component min/max ranges. V2 derives everything from the codebook LUT * texture so only the means min/max are required. * * @private */ _populateParameters() { const { meta } = ( /** @type {GSplatSogData} */ this.gsplatData ); if (meta.means) { this.parameters.set("means_mins", meta.means.mins); this.parameters.set("means_maxs", meta.means.maxs); } if (meta.version !== 2) { if (meta.scales) { this.parameters.set("scales_mins", meta.scales.mins); this.parameters.set("scales_maxs", meta.scales.maxs); } if (meta.sh0) { this.parameters.set("sh0_mins", meta.sh0.mins); this.parameters.set("sh0_maxs", meta.sh0.maxs); } if (meta.shN) { this.parameters.set("shN_mins", meta.shN.mins); this.parameters.set("shN_maxs", meta.shN.maxs); } } } configureMaterialDefines(defines) { const gsplatData = ( /** @type {GSplatSogData} */ this.gsplatData ); defines.set("SH_BANDS", gsplatData.shBands); if (gsplatData.meta.version === 2) { defines.set("SOG_V2", ""); } } } export { GSplatSogResource };