UNPKG

playcanvas

Version:

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

159 lines (158 loc) 6.25 kB
/** * A class for generating GPU sort keys from GSplat world-space positions using compute shaders. * Supports both linear (forward vector) and radial (distance) sorting modes with camera-relative * bin weighting for precision optimization near the camera. * * @ignore */ export class GSplatSortKeyCompute { /** * Creates a new GSplatSortKeyCompute instance. * * @param {GraphicsDevice} device - The graphics device (must support compute). */ constructor(device: GraphicsDevice); /** * The graphics device. * * @type {GraphicsDevice} */ device: GraphicsDevice; /** * Allocated capacity for sort keys (grow-only). * * @type {number} */ allocatedCount: number; /** * Output sort keys storage buffer. * * @type {StorageBuffer|null} */ keysBuffer: StorageBuffer | null; /** * Storage buffer for combined bin weights (binBase + binDivider). * * @type {StorageBuffer|null} */ binWeightsBuffer: StorageBuffer | null; /** * Current compute instance. * * @type {Compute|null} */ compute: Compute | null; /** * Whether the current compute instance is for radial sorting. * * @type {boolean} */ computeRadialSort: boolean; /** * Whether the current compute instance uses indirect sort (with compaction). * * @type {boolean} */ computeUseIndirectSort: boolean; /** * Bind group format for the compute shader (without compaction). * * @type {BindGroupFormat|null} */ bindGroupFormat: BindGroupFormat | null; /** * Bind group format for the compute shader (with indirect sort + compaction). * * @type {BindGroupFormat|null} */ bindGroupFormatIndirect: BindGroupFormat | null; /** * Uniform buffer format. * * @type {UniformBufferFormat|null} */ uniformBufferFormat: UniformBufferFormat | null; /** * Shared bin weights utility for computing camera-relative precision weighting. * * @type {GSplatSortBinWeights} */ binWeightsUtil: GSplatSortBinWeights; /** * Reusable array for camera position uniform. * * @type {Float32Array} */ cameraPositionData: Float32Array; /** * Reusable array for camera direction uniform. * * @type {Float32Array} */ cameraDirectionData: Float32Array; /** * Destroys all resources. */ destroy(): void; /** * Gets or creates the compute instance for the specified sort mode. * Destroys and recreates the compute instance if the mode changes. * * @param {boolean} computeRadialSort - Whether to get the radial sort variant. * @param {boolean} computeUseIndirectSort - Whether indirect dispatch with compaction is used. * @returns {Compute} The compute instance. * @private */ private _getCompute; /** * Creates the bind group formats for the compute shaders. * * @private */ private _createBindGroupFormat; /** * Ensures the keys buffer has at least the required capacity. * * @param {number} elementCount - Required number of elements. * @private */ private _ensureCapacity; /** * Generates sort keys from the work buffer using direct dispatch (no culling/compaction). * * @param {GSplatWorkBuffer} workBuffer - The work buffer containing world-space splat data. * @param {GraphNode} cameraNode - The camera node for position and direction. * @param {boolean} computeRadialSort - Whether to use radial sorting mode. * @param {number} elementCount - Number of splats to process. * @param {number} numBits - Number of bits for sort keys (determines bucket count). * @param {number} minDist - Minimum distance value for normalization. * @param {number} maxDist - Maximum distance value for normalization. * @returns {StorageBuffer} The storage buffer containing generated sort keys. */ generate(workBuffer: GSplatWorkBuffer, cameraNode: GraphNode, computeRadialSort: boolean, elementCount: number, numBits: number, minDist: number, maxDist: number): StorageBuffer; /** * Generates sort keys using indirect dispatch. Only `visibleCount` threads are launched * (GPU-determined), reducing key generation work proportionally to the culled fraction. * * @param {GSplatWorkBuffer} workBuffer - The work buffer containing world-space splat data. * @param {GraphNode} cameraNode - The camera node for position and direction. * @param {boolean} computeRadialSort - Whether to use radial sorting mode. * @param {number} maxElementCount - Maximum number of splats (buffer allocation size). * @param {number} numBits - Number of bits for sort keys. * @param {number} minDist - Minimum distance value for normalization. * @param {number} maxDist - Maximum distance value for normalization. * @param {StorageBuffer} compactedSplatIds - Compacted visible splat IDs. * @param {StorageBuffer} sortElementCountBuffer - GPU-written buffer containing visible count. * @param {number} dispatchSlot - Slot index in the device's indirect dispatch buffer. * @returns {StorageBuffer} The storage buffer containing generated sort keys. */ generateIndirect(workBuffer: GSplatWorkBuffer, cameraNode: GraphNode, computeRadialSort: boolean, maxElementCount: number, numBits: number, minDist: number, maxDist: number, compactedSplatIds: StorageBuffer, sortElementCountBuffer: StorageBuffer, dispatchSlot: number): StorageBuffer; } import type { GraphicsDevice } from '../../platform/graphics/graphics-device.js'; import { StorageBuffer } from '../../platform/graphics/storage-buffer.js'; import { Compute } from '../../platform/graphics/compute.js'; import { BindGroupFormat } from '../../platform/graphics/bind-group-format.js'; import { UniformBufferFormat } from '../../platform/graphics/uniform-buffer-format.js'; import { GSplatSortBinWeights } from './gsplat-sort-bin-weights.js'; import type { GSplatWorkBuffer } from './gsplat-work-buffer.js'; import type { GraphNode } from '../graph-node.js';