playcanvas
Version:
PlayCanvas WebGL game engine
70 lines (68 loc) • 2.78 kB
JavaScript
var gsplatCompressedDataVS = `
var packedTexture: texture_2d<u32>;
var chunkTexture: texture_2d<f32>;
var<private> chunkDataA: vec4f;
var<private> chunkDataB: vec4f;
var<private> chunkDataC: vec4f;
var<private> chunkDataD: vec4f;
var<private> chunkDataE: vec4f;
var<private> packedData: vec4u;
fn unpack111011(bits: u32) -> vec3f {
return (vec3f((vec3<u32>(bits) >> vec3<u32>(21u, 11u, 0u)) & vec3<u32>(0x7ffu, 0x3ffu, 0x7ffu))) / vec3f(2047.0, 1023.0, 2047.0);
}
fn unpack8888(bits: u32) -> vec4f {
return vec4f(
f32((bits >> 24u) & 0xffu),
f32((bits >> 16u) & 0xffu),
f32((bits >> 8u) & 0xffu),
f32(bits & 0xffu)
) / 255.0;
}
const norm_const: f32 = 1.0 / (sqrt(2.0) * 0.5);
fn unpackRotation(bits: u32) -> vec4f {
let a = (f32((bits >> 20u) & 0x3ffu) / 1023.0 - 0.5) * norm_const;
let b = (f32((bits >> 10u) & 0x3ffu) / 1023.0 - 0.5) * norm_const;
let c = (f32(bits & 0x3ffu) / 1023.0 - 0.5) * norm_const;
let m = sqrt(1.0 - (a * a + b * b + c * c));
let mode = bits >> 30u;
if (mode == 0u) { return vec4f(m, a, b, c); }
if (mode == 1u) { return vec4f(a, m, b, c); }
if (mode == 2u) { return vec4f(a, b, m, c); }
return vec4f(a, b, c, m);
}
fn readCenter(source: ptr<function, SplatSource>) -> vec3f {
let tex_size_u = textureDimensions(chunkTexture, 0);
let w: u32 = tex_size_u.x / 5u;
let chunkId: u32 = source.id / 256u;
let chunkUV: vec2<i32> = vec2<i32>(i32((chunkId % w) * 5u), i32(chunkId / w));
chunkDataA = textureLoad(chunkTexture, chunkUV + vec2<i32>(0, 0), 0);
chunkDataB = textureLoad(chunkTexture, chunkUV + vec2<i32>(1, 0), 0);
chunkDataC = textureLoad(chunkTexture, chunkUV + vec2<i32>(2, 0), 0);
chunkDataD = textureLoad(chunkTexture, chunkUV + vec2<i32>(3, 0), 0);
chunkDataE = textureLoad(chunkTexture, chunkUV + vec2<i32>(4, 0), 0);
packedData = textureLoad(packedTexture, source.uv, 0);
return mix(chunkDataA.xyz, vec3f(chunkDataA.w, chunkDataB.xy), unpack111011(packedData.x));
}
fn readColor(source: ptr<function, SplatSource>) -> vec4f {
let r = unpack8888(packedData.w);
return vec4f(mix(chunkDataD.xyz, vec3f(chunkDataD.w, chunkDataE.xy), r.rgb), r.w);
}
fn getRotation() -> vec4f {
return unpackRotation(packedData.y);
}
fn getScale() -> vec3f {
return exp(mix(vec3f(chunkDataB.zw, chunkDataC.x), chunkDataC.yzw, unpack111011(packedData.z)));
}
fn readCovariance(source: ptr<function, SplatSource>, covA_ptr: ptr<function, vec3f>, covB_ptr: ptr<function, vec3f>) {
let rot = quatToMat3(getRotation());
let scale = getScale();
let M = transpose(mat3x3f(
scale.x * rot[0],
scale.y * rot[1],
scale.z * rot[2]
));
*covA_ptr = vec3f(dot(M[0], M[0]), dot(M[0], M[1]), dot(M[0], M[2]));
*covB_ptr = vec3f(dot(M[1], M[1]), dot(M[1], M[2]), dot(M[2], M[2]));
}
`;
export { gsplatCompressedDataVS as default };