catalog.ts

examples/splats/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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
// Sample splats: single-file RDX of ext splats, hosted on Google Cloud
// Storage: the butterfly and the ceramic without spherical harmonics (in
// rdx/; ?splats= reads the same names elsewhere), the scans with SH3 (extSh,
// in rdx-sh/; ?splatsSh= reads them elsewhere, such as
// http://localhost:8000/build/data/rdx-sh). Every sample is stored
// y-down, so it is flipped upright.
import * as THREE from "three";

export interface Scan {
  label: string;
  url: string;
  // Camera mode it starts in (default orbit)
  mode?: "orbit" | "fly";
  // 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 (else framed from outside)
  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`, mode: "fly",
    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`, sky: true,
    view: { position: [0, 1.5, -1.2], target: [0, 1.5, 0], fov: 60 },
  },
  // In the middle of the nave, about 2.5 above the floor, looking along it
  grace: {
    label: "Grace interior (10M, SH3)", url: `${SPLATS_SH}/grace-interior-10m.rdx`, mode: "fly",
    view: { position: [-14, 8, -3], target: [-4, 8, -3], fov: 60 },
  },
  // Up: the ground within 3.5 of the origin; the view: side on, the bike by the bench
  bicycle: {
    label: "Bicycle (SH3)", url: `${SPLATS_SH}/bicycle.rdx`, mode: "fly", preBlur: true, sky: true,
    up: [-0.015, 0.97, 0.244], view: { position: [-3.5, 0.9, 0], target: [0, -0.7, 0], fov: 55 },
  },
  // Mip-NeRF 360's garden. Up: the ground and the table top (parallel within
  // 0.3 degrees); the view: GaussianSplats3D's garden demo (cameraUp
  // [0, -1, -0.54], within a degree of this up), looking down across the table
  garden: {
    label: "Garden (5.8M, SH3)", url: `${SPLATS_SH}/garden.rdx`, mode: "fly", preBlur: true, sky: true,
    up: [-0.01, 0.877, 0.48], view: { position: [-3.15, 0.43, 0.36], target: [1.5, -2.81, -0.36], fov: 50 },
  },
};

// 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;
}