Yosun's picture
Deploy TripoSplat WebGPU demo
31c7d49 verified
Raw
History Blame Contribute Delete
5.35 kB
import assert from 'node:assert/strict'
import test from 'node:test'
import {
BackgroundRemovalRequiredError,
CancelledError,
preprocessTripoSplatRgba,
} from '../dist/index.js'
import {
buildTripoSplatEncoderTensors,
calculateTripoSplatCrop,
calculateTripoSplatResize,
compositeRgbaOnBlack,
cropRgba,
erodeAlpha,
resizeRgbaLanczos,
} from '../dist/preprocess.js'
test('resize geometry follows Python ties-to-even rounding', () => {
assert.deepEqual(calculateTripoSplatResize(5, 4, 2), {
width: 2,
height: 2,
scale: 0.5,
})
assert.deepEqual(calculateTripoSplatResize(7, 4, 2), {
width: 4,
height: 2,
scale: 0.5,
})
})
test('square crop geometry keeps official centering, padding, and truncation', () => {
assert.deepEqual(
calculateTripoSplatCrop({ minX: 1, minY: 2, maxX: 5, maxY: 4 }),
{ left: 0, top: 0, right: 5, bottom: 5 },
)
const cropped = cropRgba(
{
width: 2,
height: 2,
data: Uint8ClampedArray.from([
1, 2, 3, 4, 5, 6, 7, 8,
9, 10, 11, 12, 13, 14, 15, 16,
]),
},
{ left: -1, top: 0, right: 2, bottom: 3 },
)
assert.equal(cropped.width, 3)
assert.equal(cropped.height, 3)
assert.deepEqual([...cropped.data.slice(4, 12)], [1, 2, 3, 4, 5, 6, 7, 8])
assert.deepEqual([...cropped.data.slice(28)], new Array(8).fill(0))
})
test('Pillow-compatible RGBA operations preserve edge and alpha integer semantics', () => {
const resized = resizeRgbaLanczos({
width: 2,
height: 1,
data: Uint8ClampedArray.from([255, 0, 0, 0, 0, 0, 255, 255]),
}, 8, 1)
assert.deepEqual([...resized.data], [
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 255, 28,
0, 0, 255, 93,
0, 0, 255, 162,
0, 0, 255, 227,
0, 0, 255, 255,
0, 0, 255, 255,
])
const alphaRamp = {
width: 3,
height: 1,
data: Uint8ClampedArray.from([0, 0, 0, 7, 0, 0, 0, 19, 0, 0, 0, 31]),
}
assert.deepEqual(
[...erodeAlpha(alphaRamp, 1).data].filter((_value, index) => index % 4 === 3),
[7, 7, 19],
)
assert.equal(compositeRgbaOnBlack({
width: 1,
height: 1,
data: Uint8ClampedArray.from([127, 0, 0, 127]),
}).data[0], 63)
})
test('encoder tensors are planar NCHW with official RGB, DINOv3, and VAE domains', () => {
const image = {
width: 2,
height: 1,
data: Uint8ClampedArray.from([0, 127, 255, 255, 128, 0]),
}
const tensors = buildTripoSplatEncoderTensors(image)
assert.deepEqual(tensors.rgb.dims, [1, 3, 1, 2])
assert.deepEqual(tensors.dinov3.dims, [1, 3, 1, 2])
assert.deepEqual(tensors.vae.dims, [1, 3, 1, 2])
const rgb = [0, 1, Math.fround(127 / 255), Math.fround(128 / 255), 1, 0]
assert.deepEqual([...tensors.rgb.data], rgb)
assert.deepEqual([...tensors.vae.data], rgb.map((value) => Math.fround(Math.fround(value * 2) - 1)))
const means = [0.485, 0.456, 0.406]
const standardDeviations = [0.229, 0.224, 0.225]
const expectedDino = rgb.map((value, index) => {
const channel = Math.floor(index / 2)
return Math.fround(
Math.fround(value - Math.fround(means[channel]))
/ Math.fround(standardDeviations[channel]),
)
})
assert.deepEqual([...tensors.dinov3.data], expectedDino)
})
test('opaque raw input requires real external segmentation', async () => {
const opaque = {
width: 2,
height: 2,
data: new Uint8ClampedArray(2 * 2 * 4).fill(255),
}
await assert.rejects(
preprocessTripoSplatRgba(opaque, { canvasSize: 2, erodeRadius: 0 }),
(error) => error instanceof BackgroundRemovalRequiredError
&& error.code === 'BACKGROUND_REMOVAL_REQUIRED'
&& error.stage === 'preprocessing',
)
const prepared = await preprocessTripoSplatRgba(opaque, {
canvasSize: 2,
erodeRadius: 0,
inputIsPrepared: true,
})
assert.deepEqual([...prepared.image.data], new Array(12).fill(255))
assert.equal(prepared.usedBackgroundRemoval, false)
let removerCalls = 0
const segmented = await preprocessTripoSplatRgba(opaque, {
canvasSize: 2,
erodeRadius: 0,
async removeBackground(resized, { signal } = {}) {
removerCalls += 1
assert.equal(signal, undefined)
return {
width: resized.width,
height: resized.height,
data: Uint8ClampedArray.from([
255, 255, 255, 0,
255, 255, 255, 255,
255, 255, 255, 255,
255, 255, 255, 0,
]),
}
},
})
assert.equal(removerCalls, 1)
assert.equal(segmented.usedBackgroundRemoval, true)
assert.ok(segmented.foreground.data.some((value, index) => index % 4 === 3 && value === 0))
await assert.rejects(
preprocessTripoSplatRgba(opaque, {
canvasSize: 2,
erodeRadius: 0,
removeBackground: (resized) => ({
width: resized.width + 1,
height: resized.height,
data: new Uint8ClampedArray((resized.width + 1) * resized.height * 4),
}),
}),
/Background remover changed image size/,
)
})
test('pure preprocessing honors a pre-aborted AbortSignal', async () => {
const controller = new AbortController()
controller.abort('test cancellation')
await assert.rejects(
preprocessTripoSplatRgba({
width: 1,
height: 1,
data: Uint8ClampedArray.from([0, 0, 0, 0]),
}, { signal: controller.signal }),
(error) => error instanceof CancelledError,
)
})