@solidrt/3d 0.0.54 → 0.0.56
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +1121 -177
- package/README.md +15 -7
- package/examples/README.md +86 -5
- package/examples/aim.tsx +2 -3
- package/examples/cascades.tsx +20 -5
- package/examples/collision.tsx +250 -0
- package/examples/first-person.tsx +119 -0
- package/examples/fleet.tsx +194 -0
- package/examples/fog.tsx +173 -0
- package/examples/instanced.tsx +72 -32
- package/examples/lamps.tsx +92 -0
- package/examples/lit.tsx +3 -5
- package/examples/materials.tsx +150 -0
- package/examples/model-load.tsx +95 -0
- package/examples/model.glb +0 -0
- package/examples/model.tsx +32 -6
- package/examples/pick.tsx +2 -4
- package/examples/probe.tsx +101 -0
- package/examples/scene-background.tsx +2 -4
- package/examples/scene-basic.tsx +2 -4
- package/examples/scene-views.tsx +32 -3
- package/examples/shadows.tsx +2 -4
- package/examples/sky-lit.tsx +86 -0
- package/examples/skybox.tsx +128 -0
- package/examples/sprites.tsx +4 -6
- package/examples/standard.tsx +132 -0
- package/examples/sweep-paths.tsx +2 -4
- package/package.json +3 -3
- package/src/camera.ts +148 -0
- package/src/clip.ts +96 -0
- package/src/collision.ts +199 -0
- package/src/color.ts +32 -0
- package/src/components.tsx +773 -82
- package/src/environment-bake.ts +492 -0
- package/src/environment.ts +325 -0
- package/src/first-person.ts +306 -0
- package/src/geometry.ts +6 -2
- package/src/glsl.ts +1390 -82
- package/src/gltf.ts +432 -112
- package/src/index.ts +57 -9
- package/src/light.ts +383 -0
- package/src/material.ts +682 -216
- package/src/math.ts +110 -0
- package/src/mesh.ts +728 -0
- package/src/mixer.ts +476 -0
- package/src/model-file.ts +80 -15
- package/src/model.ts +211 -34
- package/src/node.ts +506 -0
- package/src/orbit.ts +97 -48
- package/src/scene-pointer.ts +166 -0
- package/src/scene-shadows.ts +471 -0
- package/src/scene.ts +1304 -1532
- package/tools/environment.ts +69 -0
- package/tools/model.ts +4 -3
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
|
|
3
|
+
// srt tool 3d/environment: bake a Radiance .hdr panorama into a .srte
|
|
4
|
+
// environment file - the six cube faces and their GGX-prefiltered mip
|
|
5
|
+
// chain in linear float, the exact chain loadEnvironment uploads as an
|
|
6
|
+
// explicit rgba16f cube (no runtime conversion, no generated mipmaps, no
|
|
7
|
+
// half-float render support needed). Unity convolves its reflection
|
|
8
|
+
// probes at import the same way; Three (PMREMGenerator) and Godot do it
|
|
9
|
+
// at runtime every time the sky changes. Put the output under assets/ so
|
|
10
|
+
// it ships with the app.
|
|
11
|
+
//
|
|
12
|
+
// srt tool 3d/environment <in.hdr> [-o <out.srte>] [--size <edge>]
|
|
13
|
+
//
|
|
14
|
+
// --size is the cube's face edge: 128 (default) is Unity's probe default
|
|
15
|
+
// and enough for every surface short of a mirror; 256 (Godot's radiance
|
|
16
|
+
// default, Three's PMREM cap) for a mirror-finish showpiece, at four
|
|
17
|
+
// times the bytes (a float32 file is 21 KiB per 1k texels: 2 MiB at 128).
|
|
18
|
+
|
|
19
|
+
import { readFileSync, writeFileSync } from "node:fs"
|
|
20
|
+
import { basename, extname } from "node:path"
|
|
21
|
+
import { decodeHdr, encodeEnvironment, panoramaToCube, prefilterCube } from "../src/environment-bake.ts"
|
|
22
|
+
|
|
23
|
+
// The face edge default and its allowed range (powers of two).
|
|
24
|
+
const DEFAULT_SIZE = 128
|
|
25
|
+
const MIN_SIZE = 16
|
|
26
|
+
const MAX_SIZE = 1024
|
|
27
|
+
|
|
28
|
+
function usage(error?: string): never {
|
|
29
|
+
if (error) console.error(error)
|
|
30
|
+
console.log("Usage: srt tool 3d/environment <in.hdr> [-o <out.srte>] [--size <edge>]")
|
|
31
|
+
process.exit(error ? 1 : 0)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
let input: string | undefined
|
|
35
|
+
let output: string | undefined
|
|
36
|
+
let size = DEFAULT_SIZE
|
|
37
|
+
let args = process.argv.slice(2)
|
|
38
|
+
for (let i = 0; i < args.length; i++) {
|
|
39
|
+
let arg = args[i]!
|
|
40
|
+
if (arg === "--help" || arg === "-h") usage()
|
|
41
|
+
else if (arg === "-o" || arg === "--output") {
|
|
42
|
+
output = args[++i]
|
|
43
|
+
if (output === undefined) usage("Missing value for " + arg)
|
|
44
|
+
} else if (arg === "--size") {
|
|
45
|
+
let value = args[++i]
|
|
46
|
+
if (value === undefined) usage("Missing value for --size")
|
|
47
|
+
size = Number(value)
|
|
48
|
+
if (!Number.isInteger(size) || size < MIN_SIZE || size > MAX_SIZE || (size & (size - 1)) !== 0) {
|
|
49
|
+
usage("--size must be a power of two from " + MIN_SIZE + " to " + MAX_SIZE + ", got " + value)
|
|
50
|
+
}
|
|
51
|
+
} else if (arg.startsWith("-")) usage("Unknown option " + arg)
|
|
52
|
+
else if (input === undefined) input = arg
|
|
53
|
+
else usage("Unexpected argument " + arg)
|
|
54
|
+
}
|
|
55
|
+
if (input === undefined) usage("Missing input file")
|
|
56
|
+
if (output === undefined) output = basename(input, extname(input)) + ".srte"
|
|
57
|
+
|
|
58
|
+
let started = performance.now()
|
|
59
|
+
let panorama = decodeHdr(new Uint8Array(readFileSync(input)))
|
|
60
|
+
let decoded = performance.now()
|
|
61
|
+
let levels = prefilterCube(panoramaToCube(panorama, size), size)
|
|
62
|
+
let baked = performance.now()
|
|
63
|
+
let encoded = encodeEnvironment(levels, size)
|
|
64
|
+
writeFileSync(output, encoded)
|
|
65
|
+
|
|
66
|
+
console.log(
|
|
67
|
+
`${output}: ${size} cube, ${levels.length} levels, ${(encoded.byteLength / 1024).toFixed(0)} KiB ` +
|
|
68
|
+
`(${panorama.width}x${panorama.height} panorama decoded in ${(decoded - started).toFixed(0)} ms, baked in ${(baked - decoded).toFixed(0)} ms)`,
|
|
69
|
+
)
|
package/tools/model.ts
CHANGED
|
@@ -12,6 +12,7 @@ import { readFileSync, writeFileSync } from "node:fs"
|
|
|
12
12
|
import { basename, dirname, extname, join } from "node:path"
|
|
13
13
|
import { parseGltf } from "../src/gltf.ts"
|
|
14
14
|
import { encodeModel } from "../src/model-file.ts"
|
|
15
|
+
import { layoutStride } from "../src/geometry.ts"
|
|
15
16
|
|
|
16
17
|
function usage(error?: string): never {
|
|
17
18
|
if (error) console.error(error)
|
|
@@ -44,9 +45,9 @@ let encoded = encodeModel(data)
|
|
|
44
45
|
writeFileSync(output, encoded)
|
|
45
46
|
|
|
46
47
|
let triangles = data.parts.reduce((n, p) => n + p.geometry.indices.length / 3, 0)
|
|
47
|
-
let vertices = data.parts.reduce((n, p) => n + p.geometry.vertices.length /
|
|
48
|
+
let vertices = data.parts.reduce((n, p) => n + p.geometry.vertices.length / layoutStride(p.geometry.layout), 0)
|
|
48
49
|
console.log(
|
|
49
|
-
`${output}: ${data.parts.length} parts, ${vertices} vertices, ${triangles} triangles, ` +
|
|
50
|
-
`${data.materials.length} materials, ${data.images.length} images, ${(encoded.byteLength / 1024).toFixed(0)} KiB ` +
|
|
50
|
+
`${output}: ${data.nodes.length} nodes, ${data.parts.length} parts, ${vertices} vertices, ${triangles} triangles, ` +
|
|
51
|
+
`${data.clips.length} clips, ${data.materials.length} materials, ${data.images.length} images, ${(encoded.byteLength / 1024).toFixed(0)} KiB ` +
|
|
51
52
|
`(parsed in ${parsed.toFixed(0)} ms)`,
|
|
52
53
|
)
|