catalog.ts
examples/fxedit/catalog.ts · raw · open the example · all examples · site home
Exports: ScanSPLATSSPLATS_SHSCANSscanRotationskyTexture
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
// Sample splats (after ../splats/catalog.ts): single-file RDX of ext splats
// on Google Cloud Storage, the objects without spherical harmonics (in rdx/;
// ?splats= reads the same names elsewhere), Sutro with SH3 (in rdx-sh/;
// ?splatsSh=), all stored y-down, so flipped upright. Objects are normalized
// to 1.6 units and framed from outside, scenes to 8 units and start at their
// view.
import * as THREE from "three";
export interface Scan {
label: string;
url: string;
scene?: boolean;
// Trained with the 3DGS screen-space dilation: pre-blur (keeps thin
// structures) instead of blur
preBlur?: boolean;
// Outdoors: a sky behind the splats
sky?: boolean;
// Measured up direction after the flip (ground normal), turned to +y
up?: [number, number, number];
// Where the camera starts, in the scan's upright frame before scaling
view?: { position: [number, number, number]; target: [number, number, number]; fov: number };
}
export const SPLATS = new URLSearchParams(location.search).get("splats") ?? "https://storage.googleapis.com/forge-dev-public/asundqui/radix/261009/rdx";
export const SPLATS_SH = new URLSearchParams(location.search).get("splatsSh") ?? "https://storage.googleapis.com/forge-dev-public/asundqui/radix/261015/rdx-sh";
export const SCANS: Record<string, Scan> = {
butterfly: { label: "Butterfly", url: `${SPLATS}/butterfly-ai.rdx` },
// Inside the cave, clear of the floaters around it
ceramic: {
label: "Ceramic", url: `${SPLATS}/ceramic.rdx`,
view: { position: [-0.23, 1.83, -4.12], target: [0, 0, 0], fov: 50 },
},
// Spark's SOGS example view: at the tower's foot, looking at it
sutro: {
label: "Sutro (2M, SH3)", url: `${SPLATS_SH}/sutro-2m.rdx`, scene: true, preBlur: true, sky: true,
view: { position: [0, 1.5, -1.2], target: [0, 1.5, 0], fov: 60 },
},
};
// Upright: the flip, then the up correction
export function scanRotation({ up }: Scan) {
const flip = new THREE.Quaternion(1, 0, 0, 0);
return up ? new THREE.Quaternion().setFromUnitVectors(new THREE.Vector3(...up).normalize(), new THREE.Vector3(0, 1, 0)).multiply(flip) : flip;
}
// Outdoor scans: a sky gradient around the view (zenith blue to a pale
// horizon, hazy below), as an equirectangular background
let sky: THREE.CanvasTexture | undefined;
export function skyTexture() {
if (!sky) {
const canvas = Object.assign(document.createElement("canvas"), { width: 4, height: 512 });
const g = canvas.getContext("2d")!;
const gradient = g.createLinearGradient(0, 0, 0, 512);
gradient.addColorStop(0, "#2f6fb8");
gradient.addColorStop(0.3, "#6fa6dc");
gradient.addColorStop(0.49, "#d6e7f5");
gradient.addColorStop(0.52, "#c9cfd4");
gradient.addColorStop(1, "#5d6166");
g.fillStyle = gradient;
g.fillRect(0, 0, 4, 512);
sky = new THREE.CanvasTexture(canvas);
sky.mapping = THREE.EquirectangularReflectionMapping;
sky.colorSpace = THREE.SRGBColorSpace;
}
return sky;
}