playcanvas
Version:
Open-source WebGL/WebGPU 3D engine for the web
86 lines (76 loc) • 2.43 kB
JavaScript
const computeGsplatSortKeySource = `
var dataTransformA: texture_2d<u32>;
var<storage, read_write> sortKeys: array<u32>;
struct SortKeyUniforms {
cameraPosition: vec3f,
elementCount: u32,
cameraDirection: vec3f,
numBits: u32,
textureSize: u32,
minDist: f32,
invRange: f32,
numWorkgroupsX: u32,
numBins: u32
};
var<uniform> uniforms: SortKeyUniforms;
struct BinWeight {
base: f32,
divider: f32
};
var<storage, read> binWeights: array<BinWeight>;
#ifdef USE_INDIRECT_SORT
var<storage, read> compactedSplatIds: array<u32>;
var<storage, read> sortElementCountBuf: array<u32>;
#endif
fn main(
global_id: vec3u,
w_id: vec3u,
w_dim: vec3u,
TID: u32
) {
#ifdef USE_INDIRECT_SORT
let WORKGROUP_ID = w_id.x + w_id.y * w_dim.x;
let gid = WORKGROUP_ID * ({WORKGROUP_SIZE_X}u * {WORKGROUP_SIZE_Y}u) + TID;
#else
let gid = global_id.x + global_id.y * ({WORKGROUP_SIZE_X} * uniforms.numWorkgroupsX);
#endif
if (gid >= uniforms.elementCount) {
return;
}
#ifdef USE_INDIRECT_SORT
let visibleCount = sortElementCountBuf[0];
if (gid >= visibleCount) {
return;
}
let splatId = compactedSplatIds[gid];
#else
let splatId = gid;
#endif
let textureSize = uniforms.textureSize;
let uv = vec2i(i32(splatId % textureSize), i32(splatId / textureSize));
let packed = textureLoad(dataTransformA, uv, 0);
let worldCenter = vec3f(
bitcast<f32>(packed.r),
bitcast<f32>(packed.g),
bitcast<f32>(packed.b)
);
var dist: f32;
#ifdef RADIAL_SORT
let delta = worldCenter - uniforms.cameraPosition;
let radialDist = length(delta);
dist = (1.0 / uniforms.invRange) - radialDist - uniforms.minDist;
#else
let toSplat = worldCenter - uniforms.cameraPosition;
dist = dot(toSplat, uniforms.cameraDirection) - uniforms.minDist;
#endif
let numBins = uniforms.numBins;
let d = dist * uniforms.invRange * f32(numBins);
let binFloat = clamp(d, 0.0, f32(numBins) - 0.001);
let bin = u32(binFloat);
let binFrac = binFloat - f32(bin);
let sortKey = u32(binWeights[bin].base + binWeights[bin].divider * binFrac);
sortKeys[gid] = sortKey;
}
`;
export { computeGsplatSortKeySource };