UNPKG

playcanvas

Version:

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

282 lines (281 loc) 11 kB
/** * Configuration object specifying a data binding for GSplatProcessor. * Defines where to read from (source) or write to (destination) including * the resource, component for instance textures, and which streams to access. */ export type GSplatProcessorBinding = { /** * - Resource to read/write from. */ resource?: GSplatResourceBase; /** * - Component for instance textures. If provided, * resource is automatically resolved from the component. */ component?: GSplatComponent; /** * - Names of streams to read/write. For destination, this is * required. For source, if omitted, all format streams except destination streams are used * automatically, providing getCenter/getColor/etc functions. Specify explicitly to limit * which streams are bound. */ streams?: string[]; }; /** * @import { GraphicsDevice } from '../../platform/graphics/graphics-device.js' * @import { GSplatResourceBase } from '../../scene/gsplat/gsplat-resource-base.js' * @import { GSplatStreamDescriptor } from '../../scene/gsplat/gsplat-format.js' * @import { Texture as TextureType } from '../../platform/graphics/texture.js' * @import { StorageBuffer } from '../../platform/graphics/storage-buffer.js' * @import { GSplatComponent } from '../components/gsplat/component.js' */ /** * @typedef {object} GSplatProcessorBinding * Configuration object specifying a data binding for GSplatProcessor. * Defines where to read from (source) or write to (destination) including * the resource, component for instance textures, and which streams to access. * @property {GSplatResourceBase} [resource] - Resource to read/write from. * @property {GSplatComponent} [component] - Component for instance textures. If provided, * resource is automatically resolved from the component. * @property {string[]} [streams] - Names of streams to read/write. For destination, this is * required. For source, if omitted, all format streams except destination streams are used * automatically, providing getCenter/getColor/etc functions. Specify explicitly to limit * which streams are bound. */ /** * GSplatProcessor enables GPU-based processing of Gaussian Splat data using custom shader code. * Gaussian Splats store per-splat attributes (position, rotation, scale, color, spherical harmonics) * in texture streams. This processor reads from source streams and writes results to destination * streams, enabling operations like painting, selection marking, or custom data transforms. * * Custom streams can be added to loaded gsplat resources via {@link GSplatFormat#addExtraStreams}, * or you can create fully procedural splat data using {@link GSplatContainer}. * * The source and destination can reference the same resource or component, as long as the read and * write streams don't overlap (you cannot read and write the same stream in one pass). * * By default (when source streams are not specified), the processor provides access to the format's * built-in getCenter(), getRotation(), getScale(), and getColor() functions for reading splat data. * Note: getCenter() must be called first as it loads shared data used by the other functions. * * Custom uniforms can be passed to the shader via {@link setParameter}, including scalar values, * vectors, and additional textures for effects like brush patterns or lookup tables. * * The following built-in uniforms are available in processing shaders: * - `srcNumSplats` (uint) - Number of splats in source resource * - `dstNumSplats` (uint) - Number of splats in destination resource * * @example * // Create a processor that reads splat positions and writes to a customColor texture * const processor = new pc.GSplatProcessor( * app.graphicsDevice, * { component: entity.gsplat }, // source: all streams auto-bound * { component: entity.gsplat, streams: ['customColor'] }, // destination: customColor stream only * { * processGLSL: ` * uniform vec4 uPaintSphere; * uniform vec4 uPaintColor; * * void process() { * vec3 center = getCenter(); * float dist = distance(center, uPaintSphere.xyz); * if (dist < uPaintSphere.w) { * writeCustomColor(uPaintColor); * } else { * writeCustomColor(vec4(0.0)); * } * } * `, * processWGSL: ` * uniform uPaintSphere: vec4f; * uniform uPaintColor: vec4f; * * fn process() { * let center = getCenter(); * let dist = distance(center, uniform.uPaintSphere.xyz); * if (dist < uniform.uPaintSphere.w) { * writeCustomColor(uniform.uPaintColor); * } else { * writeCustomColor(vec4f(0.0)); * } * } * ` * } * ); * * // Set uniforms and execute * processor.setParameter('uPaintSphere', [0, 1, 0, 0.5]); * processor.setParameter('uPaintColor', [1, 0, 0, 1]); * processor.process(); * * @category Graphics */ export class GSplatProcessor { /** * Creates a new GSplatProcessor instance. * * @param {GraphicsDevice} device - The graphics device. * @param {GSplatProcessorBinding} source - Source configuration specifying where to read from. * Can specify resource directly or component (for instance textures). * @param {GSplatProcessorBinding} destination - Destination configuration specifying where to write. * Can specify resource directly or component (for instance textures). * @param {object} options - Shader options for the processing logic. * @param {string} [options.processGLSL] - GLSL code at module scope. Must define a `void process()` * function that implements the processing logic. Can include uniform declarations and helper functions. * @param {string} [options.processWGSL] - WGSL code at module scope. Must define a `fn process()` * function that implements the processing logic. Can include uniform declarations and helper functions. */ constructor(device: GraphicsDevice, source: GSplatProcessorBinding, destination: GSplatProcessorBinding, options: { processGLSL?: string; processWGSL?: string; }); /** * @type {GraphicsDevice} * @private */ private _device; /** * Source binding configuration. * * @type {GSplatProcessorBinding} * @private */ private _source; /** * Destination binding configuration. * * @type {GSplatProcessorBinding} * @private */ private _destination; /** * Source resource (resolved from binding). * * @type {GSplatResourceBase} * @private */ private _srcResource; /** * Destination resource (resolved from binding). * * @type {GSplatResourceBase} * @private */ private _dstResource; /** * @type {GSplatStreamDescriptor[]} * @private */ private _dstStreamDescriptors; /** * Set of destination stream names for quick lookup. * * @type {Set<string>} * @private */ private _dstStreamNames; /** * Whether to use all input streams (no specific source streams requested). * * @type {boolean} * @private */ private _useAllInputStreams; /** * Pre-resolved source textures to bind during process(). * * @type {Array<{name: string, texture: TextureType}>} * @private */ private _srcTextures; /** * @type {RenderTarget|null} * @private */ private _renderTarget; /** * @type {QuadRender|null} * @private */ private _quadRender; /** * @type {RenderPassShaderQuad|null} * @private */ private _renderPass; /** * Shader parameters set by the user. * * @type {Map<string, { scopeId: object, data: number|number[]|ArrayBufferView|TextureType|StorageBuffer }>} * @private */ private _parameters; /** * The blend state to use when processing. Allows accumulation of results * (e.g., additive blending for painting). Defaults to no blending. * * @type {BlendState} */ blendState: BlendState; /** * Destroys this processor and releases all resources. */ destroy(): void; /** * Resolves a texture for the given stream name from a binding configuration. * * Resolution order: * 1. Component instance texture (if component provided and stream is instance-level) * 2. Resource texture * * @param {GSplatProcessorBinding} binding - The binding configuration. * @param {string} name - The stream name. * @param {GSplatResourceBase} resource - The resolved resource. * @returns {TextureType|null} The resolved texture, or null if not found. * @private */ private _resolveTexture; /** * Creates the MRT render target for destination streams. * * @private */ private _createRenderTarget; /** * Creates the shader and QuadRender for processing. * * @param {object} options - Shader options. * @private */ private _createShader; /** * Sets a shader parameter for this processor. Parameters are applied during processing. * * @param {string} name - The name of the parameter (uniform name in shader). * @param {number|number[]|ArrayBufferView|TextureType|StorageBuffer} data - The value for the parameter. */ setParameter(name: string, data: number | number[] | ArrayBufferView | TextureType | StorageBuffer): void; /** * Gets a shader parameter value previously set with {@link setParameter}. * * @param {string} name - The name of the parameter. * @returns {number|number[]|ArrayBufferView|TextureType|StorageBuffer|undefined} The parameter value, or undefined if not set. */ getParameter(name: string): number | number[] | ArrayBufferView | TextureType | StorageBuffer | undefined; /** * Removes a shader parameter. * * @param {string} name - The name of the parameter to remove. */ deleteParameter(name: string): void; /** * Executes the processing, reading from source streams and writing to destination streams. */ process(): void; } import type { GSplatResourceBase } from '../../scene/gsplat/gsplat-resource-base.js'; import type { GSplatComponent } from '../components/gsplat/component.js'; import { BlendState } from '../../platform/graphics/blend-state.js'; import type { Texture as TextureType } from '../../platform/graphics/texture.js'; import type { StorageBuffer } from '../../platform/graphics/storage-buffer.js'; import type { GraphicsDevice } from '../../platform/graphics/graphics-device.js';