playcanvas
Version:
Open-source WebGL/WebGPU 3D engine for the web
159 lines (158 loc) • 6.25 kB
TypeScript
/**
* 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';