@zkmake/three-meter 0.9.2 → 0.11.0
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 +55 -11
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/{mount-perf-hud-BL84ddLm.js → mount-perf-hud-DZKJ1L3J.js} +1444 -1089
- package/dist/mount-perf-hud-DZKJ1L3J.js.map +1 -0
- package/dist/{mount-perf-hud-BKpk62Pp.d.ts → mount-perf-hud-MTPYNhG9.d.ts} +29 -9
- package/dist/{performance-monitor-DgHxeQ2X.d.ts → performance-monitor-BoY_-GTt.d.ts} +13 -1
- package/dist/{performance-monitor-DsBp13ts.js → performance-monitor-BqnoiLEs.js} +87 -9
- package/dist/performance-monitor-BqnoiLEs.js.map +1 -0
- package/dist/react.d.ts +2 -2
- package/dist/react.js +2 -2
- package/dist/styles.css +121 -8
- package/dist/ui.d.ts +45 -4
- package/dist/ui.js +2 -2
- package/package.json +14 -9
- package/dist/mount-perf-hud-BL84ddLm.js.map +0 -1
- package/dist/performance-monitor-DsBp13ts.js.map +0 -1
package/README.md
CHANGED
|
@@ -142,18 +142,30 @@ second, like a hidden tab, are left out. Read them with `monitor.getFrameStats()
|
|
|
142
142
|
|
|
143
143
|
```ts
|
|
144
144
|
monitor.getFrameStats();
|
|
145
|
-
// { frames: 1000, lowFps: 97.6, p99Ms: 10.2, hitches: 3 }
|
|
145
|
+
// { frames: 1000, lowFps: 97.6, p99Ms: 10.2, hitches: 3, refreshHz: 120 }
|
|
146
146
|
```
|
|
147
147
|
|
|
148
|
+
## Refresh rate and headroom
|
|
149
|
+
|
|
150
|
+
**Refresh** is the rate the loop runs at when it keeps up: the display's refresh rate, or the app's
|
|
151
|
+
own cap if it throttles itself. It comes from the fastest tenth of recent frames, with each interval
|
|
152
|
+
averaged against the next so a late frame and the early one after it don't read as a faster display,
|
|
153
|
+
then snapped to a common rate (60, 120, 144, …). It needs 60 frames.
|
|
154
|
+
|
|
155
|
+
**Headroom** is the spare time in each frame: the frame budget minus whichever of CPU and GPU took
|
|
156
|
+
longer. At 120 Hz with 3 ms of GPU work that's 5.3 ms. Below zero, frames miss the display's refresh,
|
|
157
|
+
and the row turns amber.
|
|
158
|
+
|
|
148
159
|
## Budgets
|
|
149
160
|
|
|
150
161
|
A value past its budget turns amber in the full view and the compact HUD, and its tooltip names the
|
|
151
162
|
budget. The FPS, CPU and GPU graphs draw the budget as a dashed line once the series reaches it; the
|
|
152
163
|
scale never stretches to fit it, so a quiet graph keeps its detail.
|
|
153
164
|
|
|
154
|
-
Timing budgets come from `targetFps
|
|
155
|
-
|
|
156
|
-
|
|
165
|
+
Timing budgets come from `targetFps`: FPS at least 95% of it, 1% low at least half, CPU and GPU
|
|
166
|
+
within one frame, frame p99 within one and a half, headroom at least zero. Leave `targetFps` out and
|
|
167
|
+
they follow the detected refresh rate, so a 120 Hz display gets 8.3 ms budgets (60 until it's
|
|
168
|
+
detected). Counts have no default, since what's reasonable depends on the scene. Set your own:
|
|
157
169
|
|
|
158
170
|
```ts
|
|
159
171
|
mountPerfHud(monitor, { budgets: { targetFps: 120, calls: 500, triangles: 2_000_000 } });
|
|
@@ -166,7 +178,7 @@ hud.setBudgets({ gpu: null }); // null drops a default; false drops them all
|
|
|
166
178
|
|
|
167
179
|
The HUD tells you there are 400 draw calls; **top costs** tells you which objects they come from.
|
|
168
180
|
Tick it in the full view for the five biggest costs in the main render pass, grouped by **meshes** or
|
|
169
|
-
**materials**, sorted by draw calls or triangles. Click a row to log its three objects to the
|
|
181
|
+
**materials**, sorted by draw calls or triangles. Click a row's name to log its three objects to the
|
|
170
182
|
console.
|
|
171
183
|
|
|
172
184
|
```text
|
|
@@ -186,9 +198,18 @@ walks the scene only while open, twice a second.
|
|
|
186
198
|
|
|
187
199
|
```ts
|
|
188
200
|
monitor.getSceneCost();
|
|
189
|
-
// { calls: 309, triangles: 57548, meshes: [{ label: "tree", calls: 300, … }, …], materials: […] }
|
|
201
|
+
// { calls: 309, triangles: 57548, meshes: [{ key: "mesh:tree…", label: "tree", calls: 300, … }, …], materials: […] }
|
|
190
202
|
```
|
|
191
203
|
|
|
204
|
+
### Test a cost by hiding it
|
|
205
|
+
|
|
206
|
+
Calls and triangles aren't time. The eye on each row hides its objects, every copy in the scene
|
|
207
|
+
including ones off screen, and the row then shows what that saved: GPU time averaged over 30 frames
|
|
208
|
+
before and after hiding (CPU time where there's no GPU timer), like `−4.3 ms GPU`. Hidden rows stay
|
|
209
|
+
listed so you can show them again. Everything comes back when you untick top costs or the HUD is
|
|
210
|
+
disposed, and objects that were already invisible stay that way. `monitor.getObjectsForKey(key)`
|
|
211
|
+
returns the same objects for a row's `key`.
|
|
212
|
+
|
|
192
213
|
## Bug reports
|
|
193
214
|
|
|
194
215
|
The **report** row's copy button puts a Markdown snapshot on the clipboard: versions, backend, GPU,
|
|
@@ -196,9 +217,9 @@ the current metrics, the stutter stats, the top three meshes, the viewport and t
|
|
|
196
217
|
`formatReport(monitor)` from `@zkmake/three-meter/ui` returns the same text.
|
|
197
218
|
|
|
198
219
|
```text
|
|
199
|
-
three-meter v0.
|
|
220
|
+
three-meter v0.10.0 · three r186 · WebGL2 · Apple M4 Max
|
|
200
221
|
FPS 120 · 1% low 98 · p99 10.2 ms · hitches 3 / 1,000 frames
|
|
201
|
-
CPU 0.2 ms · GPU 0.7 ms
|
|
222
|
+
CPU 0.2 ms · GPU 0.7 ms · refresh 120 Hz · headroom 7.6 ms
|
|
202
223
|
Calls 1 · passes 1 · triangles 24,000 · lines 0 · points 0
|
|
203
224
|
Geometries 1 · textures 1 · shaders 1
|
|
204
225
|
Top: tree ×300 (300 calls, 9,600 tris) · house (6 calls, 12 tris) · dome (2 calls, 7,936 tris)
|
|
@@ -256,12 +277,35 @@ The resolved theme lands on `data-theme` of `.perf-hud` and `.perf-monitor`. To
|
|
|
256
277
|
palette, override the `--perf-*` custom properties (`bg`, `fg`, `fg-dim`, `muted`, `row`,
|
|
257
278
|
`border`, `accent`, `warn`, `shadow`) on those selectors. `warn` is the over-budget amber.
|
|
258
279
|
|
|
280
|
+
## The dev-panel frame
|
|
281
|
+
|
|
282
|
+
The HUD's frame is `mountDevPanel` from `@zkmake/three-meter/ui`: the docked host, a card with a
|
|
283
|
+
brand label on top, and the drag / expand-compact / dim-on-leave discs. Other zkmake dev panels
|
|
284
|
+
(`@zkmake/three-textures`) mount through it too, so they all dock, wake, dim and theme the same way.
|
|
285
|
+
A tool of your own can use it:
|
|
286
|
+
|
|
287
|
+
```ts
|
|
288
|
+
const panel = mountDevPanel({
|
|
289
|
+
brand: "my-tool",
|
|
290
|
+
label: "My tool",
|
|
291
|
+
content: myElement,
|
|
292
|
+
theme: new HudTheme("system"),
|
|
293
|
+
storageKey: "my-tool",
|
|
294
|
+
onToggle: () => myElement.classList.toggle("is-compact"),
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
panel.detail.textContent = "3 items"; // the brand row's right-hand slot
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
The card is `.perf-hud__card`, holding `.perf-hud__brand` and your content (the HUD's is
|
|
301
|
+
`.perf-monitor`).
|
|
302
|
+
|
|
259
303
|
## Examples
|
|
260
304
|
|
|
261
|
-
[`
|
|
305
|
+
[`apps/three-meter-site`](https://github.com/zkmake/three-kit/tree/main/apps/three-meter-site) is what runs at [three-meter.pages.dev](https://three-meter.pages.dev/):
|
|
262
306
|
one Vite app with both integrations of the same scene, swapped from the header.
|
|
263
|
-
[`src/demos/vanilla.ts`](https://github.com/zkmake/three-kit/blob/main/
|
|
264
|
-
[`src/demos/r3f.tsx`](https://github.com/zkmake/three-kit/blob/main/
|
|
307
|
+
[`src/demos/vanilla.ts`](https://github.com/zkmake/three-kit/blob/main/apps/three-meter-site/src/demos/vanilla.ts) is plain three with `mountPerfHud`;
|
|
308
|
+
[`src/demos/r3f.tsx`](https://github.com/zkmake/three-kit/blob/main/apps/three-meter-site/src/demos/r3f.tsx) is React Three Fiber with `PerfSampler` and
|
|
265
309
|
`PerfHud`. Both set a 250K triangle budget on top of the timing defaults. `?r3f` opens on Fiber,
|
|
266
310
|
`?webgpu` uses `WebGPURenderer` in either, `?count=` scales the scene. The header's theme toggle sets the page theme and the HUD's `theme` layer together; the row
|
|
267
311
|
inside the panel overrides the HUD alone. Run `bun run dev` inside it after a `bun install` at the repo root.
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as GpuTiming, c as RenderBackend, d as Sample, f as SceneCost, i as FrameStats, l as RenderCounts, n as CostEntry, o as PerfRenderer, p as TimingMetric, r as Environment, s as PerformanceMonitorOptions, t as PerformanceMonitor, u as ResourceCounts } from "./performance-monitor-
|
|
1
|
+
import { a as GpuTiming, c as RenderBackend, d as Sample, f as SceneCost, i as FrameStats, l as RenderCounts, n as CostEntry, o as PerfRenderer, p as TimingMetric, r as Environment, s as PerformanceMonitorOptions, t as PerformanceMonitor, u as ResourceCounts } from "./performance-monitor-BoY_-GTt.js";
|
|
2
2
|
//#region src/core/ring-buffer.d.ts
|
|
3
3
|
/**
|
|
4
4
|
* Fixed-capacity numeric ring buffer. Backs the per-frame timing history the
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as RingBuffer, t as PerformanceMonitor } from "./performance-monitor-
|
|
1
|
+
import { n as RingBuffer, t as PerformanceMonitor } from "./performance-monitor-BqnoiLEs.js";
|
|
2
2
|
//#region src/core/wrap-animation-loop.ts
|
|
3
3
|
/**
|
|
4
4
|
* Wrap a `renderer.setAnimationLoop` callback so each tick is one frame:
|