@zkmake/three-studio 0.3.0 → 0.3.2
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/README.md +75 -19
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -33,15 +33,19 @@ const config: StudioConfig = {
|
|
|
33
33
|
};
|
|
34
34
|
```
|
|
35
35
|
|
|
36
|
-
`orbitViews(centre, near, { play })` gives `play
|
|
37
|
-
`back` and `top
|
|
38
|
-
|
|
39
|
-
|
|
36
|
+
`orbitViews(centre, near, { play })` gives `play` (when `play` is passed), `close` (along the play
|
|
37
|
+
bearing), `front`, `side`, `back` and `top`, all but `play` with a 40° lens (`fov` changes it).
|
|
38
|
+
`front` looks from +x; for an object facing another way, pass where its front camera stands,
|
|
39
|
+
`{ front: [0, 0.25, -1] }` for a vehicle driving down -z, and `side` and `back` turn with it. Write
|
|
40
|
+
your own as `{ position, target, fov?, near?, far?, zoom? }`. A link without `view=` opens `play`
|
|
41
|
+
(else the first view); `defaultView` on the config names another.
|
|
40
42
|
|
|
41
43
|
## With React Three Fiber
|
|
42
44
|
|
|
43
|
-
`<Studio>` is the whole page. Each variant renders its part; `stage` is
|
|
44
|
-
Pass the game's `<Canvas>` settings so variants look as they will in
|
|
45
|
+
`<Studio>` is the whole page: a canvas filling its parent. Each variant renders its part; `stage` is
|
|
46
|
+
what every variant stands in. Pass the game's `<Canvas>` settings so variants look as they will in
|
|
47
|
+
the game. Its variants are `StudioReactVariant`s, so a shared config is a
|
|
48
|
+
`StudioConfig<StudioReactVariant>`.
|
|
45
49
|
|
|
46
50
|
```tsx
|
|
47
51
|
import { Studio, type StudioReactVariant } from "@zkmake/three-studio/react";
|
|
@@ -73,10 +77,30 @@ useFrame(({ clock }) => {
|
|
|
73
77
|
});
|
|
74
78
|
```
|
|
75
79
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
`
|
|
80
|
+
| Prop | Does |
|
|
81
|
+
| ------------------------------ | ----------------------------------------------------------------- |
|
|
82
|
+
| `config` | Areas, variants, views |
|
|
83
|
+
| `canvas` | `<Canvas>` props, or a function of the state (per-area fog) |
|
|
84
|
+
| `stage` | `(state) => ReactNode`: lights, ground, background |
|
|
85
|
+
| `Canvas` | The `<Canvas>` component to mount. Default `@react-three/fiber`'s |
|
|
86
|
+
| `search` | The query to read. Default `location.search` |
|
|
87
|
+
| `onReady` | `(studio) => void`, with `mountStudio`'s handle |
|
|
88
|
+
| `className`, `style` | On the wrapper |
|
|
89
|
+
| `controls`, `audit`, `overlay` | As `mountStudio`'s, below |
|
|
90
|
+
| `globals`, `shotEndpoint` | As `mountStudio`'s, below |
|
|
91
|
+
|
|
92
|
+
`canvas.gl` is merged over `{ preserveDrawingBuffer: true }` and `canvas.camera` over the view's
|
|
93
|
+
lens, when they're plain objects.
|
|
94
|
+
|
|
95
|
+
A variant's `hud: (state) => ReactNode` draws DOM over the canvas (a HUD mockup); `saveShot` leaves
|
|
96
|
+
it out, as it does the overlay.
|
|
97
|
+
|
|
98
|
+
On React Three Fiber 10, whose default `Canvas` is WebGPU, a game drawn with WebGL (GLSL material
|
|
99
|
+
patches) passes `Canvas={Canvas}` from `@react-three/fiber/legacy`.
|
|
100
|
+
|
|
101
|
+
Building the `<Canvas>` yourself? Put `<StudioRig state={state} />` inside it for the same wiring,
|
|
102
|
+
with `state` from `resolveStudio(config, location.search)` made once (module scope or `useMemo`):
|
|
103
|
+
a new state remounts the rig. It takes the same rig props and `onReady`.
|
|
80
104
|
|
|
81
105
|
## Vanilla three
|
|
82
106
|
|
|
@@ -99,8 +123,14 @@ renderer.setAnimationLoop(() => {
|
|
|
99
123
|
```
|
|
100
124
|
|
|
101
125
|
`mountStudio` puts the camera at the view, adds OrbitControls, the overlay and the console helpers.
|
|
102
|
-
Turn any of them off with `controls: false`, `overlay: false`, `audit: false`, `globals: false
|
|
103
|
-
|
|
126
|
+
Turn any of them off with `controls: false`, `overlay: false`, `audit: false`, `globals: false`, or
|
|
127
|
+
pass options through: `audit` takes three-audit's `installAuditHelpers` options (it passes the
|
|
128
|
+
`renderer` itself), `overlay` a `container`. With post-processing, pass
|
|
129
|
+
`render: () => composer.render()` so shots include it. `shotEndpoint` sets where shots post, over
|
|
130
|
+
`?shots=`.
|
|
131
|
+
|
|
132
|
+
The handle has `state`, `camera`, `controls`, `overlay`, `setView(name)`, `saveShot(path)`,
|
|
133
|
+
`stats()`, `update()` and `dispose()`.
|
|
104
134
|
|
|
105
135
|
## The URL
|
|
106
136
|
|
|
@@ -108,14 +138,15 @@ post-processing, pass `render: () => composer.render()` so shots include it.
|
|
|
108
138
|
| -------------- | ------------------------------------------------------------------- |
|
|
109
139
|
| `area=<name>` | The area. A bare `?<name>` works too, as single-object studios link |
|
|
110
140
|
| `v=<name>` | The variant; the area's first by default |
|
|
111
|
-
| `view=<name>` | The camera view; `play` by default
|
|
141
|
+
| `view=<name>` | The camera view; `play` (or `defaultView`) by default |
|
|
112
142
|
| `t=<seconds>` | Freezes animation at that time, for steady shots (`useStudioTime`) |
|
|
113
143
|
| `wire=1` | Draws every material as wireframe, to read the topology |
|
|
114
144
|
| `clean=1` | Hides the overlay, for screenshots of the whole window |
|
|
115
145
|
| `shots=<port>` | Where `saveShot` posts, when `three-studio serve` isn't on 8787 |
|
|
116
146
|
|
|
117
147
|
Unknown names fall back to the defaults and are listed in `state.unknown`. `studioHref(state, change)`
|
|
118
|
-
builds links: a new area starts at its first variant
|
|
148
|
+
builds links: a new area starts at its first variant; the view, `wire`, `t` and `shots` carry over,
|
|
149
|
+
`clean` only when asked for.
|
|
119
150
|
|
|
120
151
|
The overlay puts areas and variants top left with the readout (`12 calls · 34,567 tris`) under them,
|
|
121
152
|
and views top right. View chips move the camera in place and update the URL; area and variant chips
|
|
@@ -134,6 +165,10 @@ await saveShot("round-1/trees-lush-play.png");
|
|
|
134
165
|
// "/…/shots/round-1/trees-lush-play.png 38 calls · 112,400 tris"
|
|
135
166
|
```
|
|
136
167
|
|
|
168
|
+
That `saveShot` is the page's, on `window` (`mountStudio` and `<Studio>` put it there): it draws
|
|
169
|
+
through the page's `render`, adds the readout and posts to the `?shots=` port. Paths are relative to
|
|
170
|
+
the receiver's folder, or absolute inside it.
|
|
171
|
+
|
|
137
172
|
Port 8787 taken (another receiver, another agent's pass)? `serve` says so: run it with
|
|
138
173
|
`--port 8797` and open the page with `&shots=8797`, which links on the page carry along.
|
|
139
174
|
|
|
@@ -143,8 +178,14 @@ works in a hidden browser pane where `requestAnimationFrame` never fires. The re
|
|
|
143
178
|
size instead of its pixels.
|
|
144
179
|
|
|
145
180
|
`window.studio` has the rest: `studio.setView("close")`, `studio.views`, `studio.stats()`,
|
|
146
|
-
`studio.state`,
|
|
147
|
-
(
|
|
181
|
+
`studio.state`, `studio.scene`, `studio.camera`, `studio.renderer`, `studio.saveShot`, and
|
|
182
|
+
`studio.installFrameShim()`, which keeps animations running in a hidden pane (frame rates from it
|
|
183
|
+
mean nothing; draws and triangles still hold).
|
|
184
|
+
|
|
185
|
+
Without a mounted studio, `saveShot(path, options)` from `@zkmake/three-studio` takes the pieces
|
|
186
|
+
itself: `canvas` (default the first on the page), `render`, `size`, `endpoint` (default
|
|
187
|
+
`http://127.0.0.1:8787`, `SHOT_PORT`) and `stats`. `canvasPng(canvas, { render, size })` is the
|
|
188
|
+
PNG alone.
|
|
148
189
|
|
|
149
190
|
## Comparing shots
|
|
150
191
|
|
|
@@ -156,9 +197,24 @@ npx @zkmake/three-studio montage compare.png before-play.png after-play.png befo
|
|
|
156
197
|
|
|
157
198
|
`diff` counts the pixels whose largest channel moved more than `--fuzz` (3% by default) and exits 1
|
|
158
199
|
when more than `--max` percent differ, so a stored baseline can gate CI. `--out` writes those pixels
|
|
159
|
-
in white over a dimmed copy of the first image
|
|
160
|
-
|
|
200
|
+
in white over a dimmed copy of the first image; `--json` prints `{ pixels, total, share, over }`.
|
|
201
|
+
Both images must be the same size. `montage` lays out before/after pairs side by side, rows
|
|
202
|
+
stacked, at half size (`--scale`, default 0.5; `--gap`, default 8 px before scaling). Bad arguments
|
|
203
|
+
or an unreadable file exit 2.
|
|
161
204
|
|
|
162
205
|
From a script, `@zkmake/three-studio/node` has the same pieces: `startShotServer`, `decodePng`,
|
|
163
206
|
`encodePng`, `diffImages`, `montage`, `scaleImage`. PNGs only, 8-bit, not interlaced: what canvases
|
|
164
|
-
and browsers save.
|
|
207
|
+
and browsers save. `startShotServer(folder, { port, host, log })` takes port 0 for a free one, and
|
|
208
|
+
its `url` is what `saveShot`'s `endpoint` takes.
|
|
209
|
+
|
|
210
|
+
## The rest
|
|
211
|
+
|
|
212
|
+
The core (`@zkmake/three-studio`, no DOM at import) also exports what the page is built from:
|
|
213
|
+
`applyView(camera, view, controls?)`, `setWireframe(root, on)`, `studioTime(state, elapsed)`,
|
|
214
|
+
`titleOf`, `installFrameShim()`, and the readout's `frameStats(renderer)` and `formatStats`. `/ui`
|
|
215
|
+
exports `mountStudioOverlay({ state, container?, onView? })`, the switchers and readout alone, and
|
|
216
|
+
`injectStyles` / `STUDIO_STYLES`.
|
|
217
|
+
|
|
218
|
+
## License
|
|
219
|
+
|
|
220
|
+
MIT
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zkmake/three-studio",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.2",
|
|
4
4
|
"description": "A dev page for three.js scenes: areas, variants and camera views from the URL, an orbit rig, a draw-call readout, audit helpers and screenshots an agent can take, plus a CLI to save and diff them. Vanilla three and React Three Fiber.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"devtools",
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"typecheck": "tsc"
|
|
52
52
|
},
|
|
53
53
|
"dependencies": {
|
|
54
|
-
"@zkmake/three-audit": "^0.
|
|
54
|
+
"@zkmake/three-audit": "^0.6.1"
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
57
57
|
"@arethetypeswrong/core": "catalog:",
|