UNPKG

playcanvas

Version:

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

130 lines (129 loc) 4.83 kB
/** * @import { GraphicsDevice } from '../../platform/graphics/graphics-device.js' * @import { ShaderMaterial } from '../materials/shader-material.js' * @import { GSplatFormat } from './gsplat-format.js' */ /** * A container for procedural Gaussian Splat data. This class allows you to create splat data * programmatically using either a built-in format or a custom format with your own texture * streams and read code. * * A default format is provided via {@link GSplatFormat.createDefaultFormat} which uses float * textures for easy CPU population. * * @example * // Example 1: Using the default format (easy CPU population) * const format = GSplatFormat.createDefaultFormat(device); * const container = new GSplatContainer(device, 100, format); * * // Float format textures are straightforward to fill * const centerTex = container.getTexture('dataCenter'); * const pixels = centerTex.lock(); * // pixels is Float32Array, fill with [x, y, z, 0, x, y, z, 0, ...] * centerTex.unlock(); * * // Set bounding box * container.aabb = new BoundingBox(); * * // fill centers only if you need CPU sorting * container.centers.set([x0, y0, z0, x1, y1, z1, ...]); // xyz per splat * * // Add to scene * entity.addComponent('gsplat', { resource: container }); * * @example * // Example 2: Using a custom format * const format = new GSplatFormat(device, [ * { name: 'data', format: PIXELFORMAT_RGBA32F } * ], { * // Shader code to read splat attributes from the texture * readGLSL: ` * vec4 d = loadData(); * splatCenter = d.xyz; * splatColor = vec4(1.0); * splatScale = vec3(d.w); * splatRotation = vec4(0, 0, 0, 1); * `, * readWGSL: ` * let d = loadData(); * splatCenter = d.xyz; * splatColor = vec4f(1.0); * splatScale = vec3f(d.w); * splatRotation = vec4f(0, 0, 0, 1); * ` * }); * * const container = new GSplatContainer(device, 100, format); * * @category Graphics */ export class GSplatContainer extends GSplatResourceBase { /** * Creates a new GSplatContainer instance. * * @param {GraphicsDevice} device - The graphics device. * @param {number} maxSplats - Maximum number of splats this container can hold. * @param {GSplatFormat} format - The format descriptor with streams and read code. Use * {@link GSplatFormat.createDefaultFormat} for the built-in format, or create a custom * {@link GSplatFormat}. */ constructor(device: GraphicsDevice, maxSplats: number, format: GSplatFormat); /** * Maximum number of splats this container can hold. * * Internal note: We cannot (easily) implement resizing of the container, due textures needing * to be constant for the world state in GsplatInfo. This is non-issue for gpu based sorting * of course, but not for cpu based sorting. The workaround is to recreate container when the * size changes. * * @private */ private _maxSplats; /** * Current number of splats to render. * * @private */ private _numSplats; /** * Maximum number of splats this container can hold. * * @type {number} */ get maxSplats(): number; /** * Gets the number of splats to render. * * @type {number} */ get numSplats(): number; /** * Updates the container after modifying texture data and centers. Call this after filling * data to signal that the container contents have changed. * * @param {number} [numSplats] - Number of splats to render. Defaults to current value. * Must be between 0 and {@link maxSplats}. * @param {boolean} [centersUpdated] - Whether the centers array was modified. Set to * false when only numSplats changes but center positions remain the same, to avoid the cost * of re-cloning centers in the sorter (can be significant for large containers). */ update(numSplats?: number, centersUpdated?: boolean): void; /** * Configures material defines for this container. * * @param {Map<string, string>} defines - The defines map to configure. * @ignore */ configureMaterialDefines(defines: Map<string, string>): void; /** * Configures a material to use this container's data. * * @param {ShaderMaterial} material - The material to configure. * @ignore */ configureMaterial(material: ShaderMaterial, workBufferModifier: any, formatDeclarations: any): void; } import { GSplatResourceBase } from './gsplat-resource-base.js'; import type { ShaderMaterial } from '../materials/shader-material.js'; import type { GraphicsDevice } from '../../platform/graphics/graphics-device.js'; import type { GSplatFormat } from './gsplat-format.js';