@zkmake/three-meter 0.9.1 → 0.10.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 +38 -17
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/{mount-perf-hud-BKpk62Pp.d.ts → mount-perf-hud-MTPYNhG9.d.ts} +29 -9
- package/dist/{mount-perf-hud-CebnfB8t.js → mount-perf-hud-U_Xlj0Od.js} +260 -42
- package/dist/mount-perf-hud-U_Xlj0Od.js.map +1 -0
- 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 +64 -3
- package/dist/ui.d.ts +3 -3
- package/dist/ui.js +1 -1
- package/package.json +15 -25
- package/dist/mount-perf-hud-CebnfB8t.js.map +0 -1
- package/dist/performance-monitor-DsBp13ts.js.map +0 -1
package/README.md
CHANGED
|
@@ -22,19 +22,19 @@ load the scene up past the demo's triangle budget.
|
|
|
22
22
|
<tr>
|
|
23
23
|
<th>Dark</th>
|
|
24
24
|
<td valign="top">
|
|
25
|
-
<img src="https://raw.githubusercontent.com/zkmake/three-
|
|
25
|
+
<img src="https://raw.githubusercontent.com/zkmake/three-kit/main/docs/hud-full.png" width="318" alt="The HUD in full mode, dark theme. Option rows for theme (light, system, dark), explain metrics and a copy-report button; FPS, CPU and GPU sparklines with live values, the FPS graph showing a dashed budget line; then one row per metric, each with an icon, its value and a checkbox choosing whether the compact card shows it (FPS, calls, CPU, GPU, 1% low, frame p99, hitches, triangles, lines, points, render passes, geometries, textures, shaders), with the triangle count in amber for being over its budget; a top costs toggle; and a footer with the three-meter version, the three revision, a WebGL2 backend badge and the GPU name. Three discs beside it: a drag grip, the compact/full toggle and dim on leave." />
|
|
26
26
|
</td>
|
|
27
27
|
<td valign="top">
|
|
28
|
-
<img src="https://raw.githubusercontent.com/zkmake/three-
|
|
28
|
+
<img src="https://raw.githubusercontent.com/zkmake/three-kit/main/docs/hud-compact.png" width="314" alt="The HUD collapsed, dark theme: FPS and GPU sparklines with a dashed budget line on the FPS graph, a two-column grid of metrics with icons (FPS, calls, CPU, GPU, 1% low, frame p99, triangles in amber for being over budget, geometries, textures, shaders), and the footer with versions, backend and GPU. Three discs beside it: drag, expand and dim on leave." />
|
|
29
29
|
</td>
|
|
30
30
|
</tr>
|
|
31
31
|
<tr>
|
|
32
32
|
<th>Light</th>
|
|
33
33
|
<td valign="top">
|
|
34
|
-
<img src="https://raw.githubusercontent.com/zkmake/three-
|
|
34
|
+
<img src="https://raw.githubusercontent.com/zkmake/three-kit/main/docs/hud-full-light.png" width="318" alt="The HUD in full mode, light theme. Option rows for theme (light, system, dark), explain metrics and a copy-report button; FPS, CPU and GPU sparklines with live values, the FPS graph showing a dashed budget line; then one row per metric, each with an icon, its value and a checkbox choosing whether the compact card shows it (FPS, calls, CPU, GPU, 1% low, frame p99, hitches, triangles, lines, points, render passes, geometries, textures, shaders), with the triangle count in amber for being over its budget; a top costs toggle; and a footer with the three-meter version, the three revision, a WebGL2 backend badge and the GPU name. Three discs beside it: a drag grip, the compact/full toggle and dim on leave." />
|
|
35
35
|
</td>
|
|
36
36
|
<td valign="top">
|
|
37
|
-
<img src="https://raw.githubusercontent.com/zkmake/three-
|
|
37
|
+
<img src="https://raw.githubusercontent.com/zkmake/three-kit/main/docs/hud-compact-light.png" width="314" alt="The HUD collapsed, light theme: FPS and GPU sparklines with a dashed budget line on the FPS graph, a two-column grid of metrics with icons (FPS, calls, CPU, GPU, 1% low, frame p99, triangles in amber for being over budget, geometries, textures, shaders), and the footer with versions, backend and GPU. Three discs beside it: drag, expand and dim on leave." />
|
|
38
38
|
</td>
|
|
39
39
|
</tr>
|
|
40
40
|
</table>
|
|
@@ -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)
|
|
@@ -258,13 +279,13 @@ palette, override the `--perf-*` custom properties (`bg`, `fg`, `fg-dim`, `muted
|
|
|
258
279
|
|
|
259
280
|
## Examples
|
|
260
281
|
|
|
261
|
-
[`
|
|
282
|
+
[`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
283
|
one Vite app with both integrations of the same scene, swapped from the header.
|
|
263
|
-
[`src/demos/vanilla.ts`](
|
|
264
|
-
[`src/demos/r3f.tsx`](
|
|
284
|
+
[`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`;
|
|
285
|
+
[`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
286
|
`PerfHud`. Both set a 250K triangle budget on top of the timing defaults. `?r3f` opens on Fiber,
|
|
266
287
|
`?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
|
-
inside the panel overrides the HUD alone. Run `bun run dev` inside it.
|
|
288
|
+
inside the panel overrides the HUD alone. Run `bun run dev` inside it after a `bun install` at the repo root.
|
|
268
289
|
|
|
269
290
|
## Shipping it
|
|
270
291
|
|
|
@@ -282,7 +303,7 @@ custom properties on `.perf-hud` and `.perf-monitor`, or the `theme` option.
|
|
|
282
303
|
|
|
283
304
|
## Contributing
|
|
284
305
|
|
|
285
|
-
See [CONTRIBUTING.md](CONTRIBUTING.md). Changes ship with a changeset.
|
|
306
|
+
See [CONTRIBUTING.md](https://github.com/zkmake/three-kit/blob/main/CONTRIBUTING.md). Changes ship with a changeset.
|
|
286
307
|
|
|
287
308
|
## License
|
|
288
309
|
|
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:
|
|
@@ -1,27 +1,32 @@
|
|
|
1
|
-
import { p as TimingMetric, t as PerformanceMonitor } from "./performance-monitor-
|
|
1
|
+
import { p as TimingMetric, t as PerformanceMonitor } from "./performance-monitor-BoY_-GTt.js";
|
|
2
2
|
//#region src/ui/budgets.d.ts
|
|
3
3
|
/**
|
|
4
4
|
* Budgets: the value each metric should stay within. A reading past its
|
|
5
5
|
* budget turns amber in the card, and the FPS / CPU / GPU graphs draw the
|
|
6
|
-
* line once the series reaches it. `fps` and `
|
|
7
|
-
* everything else is a ceiling (worse above).
|
|
6
|
+
* line once the series reaches it. `fps`, `low` and `headroom` are floors
|
|
7
|
+
* (worse below); everything else is a ceiling (worse above).
|
|
8
8
|
*
|
|
9
|
-
* Timing budgets default from `targetFps
|
|
10
|
-
*
|
|
9
|
+
* Timing budgets default from `targetFps`: FPS at least 95% of it, 1% low at
|
|
10
|
+
* least half, CPU and GPU within one frame, p99 within one and a half,
|
|
11
|
+
* headroom at least zero. Without a `targetFps`, the detected refresh rate is
|
|
12
|
+
* used, then 60 until one is detected.
|
|
11
13
|
* Counts have no default, since what's reasonable depends on the scene. Pass
|
|
12
14
|
* `null` for a key to drop its default, or `false` for no budgets at all.
|
|
13
15
|
*/
|
|
14
|
-
type BudgetKey = "calls" | "cpu" | "fps" | "geometries" | "gpu" | "hitches" | "lines" | "low" | "p99" | "passes" | "points" | "shaders" | "textures" | "triangles";
|
|
16
|
+
type BudgetKey = "calls" | "cpu" | "fps" | "geometries" | "gpu" | "headroom" | "hitches" | "lines" | "low" | "p99" | "passes" | "points" | "refresh" | "shaders" | "textures" | "triangles";
|
|
15
17
|
type Budgets = Partial<Record<BudgetKey, number | null>> & {
|
|
16
|
-
/** The frame rate the defaults are derived from. Default 60. */
|
|
18
|
+
/** The frame rate the defaults are derived from. Default: the detected refresh rate, else 60. */
|
|
17
19
|
targetFps?: number;
|
|
18
20
|
};
|
|
19
21
|
type ResolvedBudgets = {
|
|
20
22
|
/** Frame budget in ms, `1000 / targetFps`. */
|
|
21
23
|
frameMs: number;
|
|
24
|
+
/** The rate the timing budgets came from: `targetFps`, the detected refresh, or 60. */
|
|
25
|
+
targetFps: number;
|
|
22
26
|
limits: Partial<Record<BudgetKey, number>>;
|
|
23
27
|
};
|
|
24
|
-
|
|
28
|
+
/** `detectedHz` is the monitor's refresh reading; an explicit `targetFps` wins over it. */
|
|
29
|
+
declare const resolveBudgets: (budgets: Budgets | false | undefined, detectedHz?: number | null) => ResolvedBudgets;
|
|
25
30
|
//#endregion
|
|
26
31
|
//#region src/ui/dock-panel.d.ts
|
|
27
32
|
declare const EDGES: readonly ["left", "right", "top", "bottom"];
|
|
@@ -200,6 +205,10 @@ declare class PerformanceView {
|
|
|
200
205
|
private readonly hudGraphs;
|
|
201
206
|
private readonly hudNumberEls;
|
|
202
207
|
private budgets;
|
|
208
|
+
private budgetsInput;
|
|
209
|
+
private detectedHz;
|
|
210
|
+
private readonly hider;
|
|
211
|
+
private readonly hiddenRows;
|
|
203
212
|
private rafId;
|
|
204
213
|
private lastPaintAt;
|
|
205
214
|
private readonly resizeObserver;
|
|
@@ -223,9 +232,20 @@ declare class PerformanceView {
|
|
|
223
232
|
private frame;
|
|
224
233
|
private render;
|
|
225
234
|
private renderCosts;
|
|
235
|
+
/** Name button (logs the objects) in a row; the caller appends the value cells and the eye. */
|
|
236
|
+
private costRowShell;
|
|
237
|
+
/** A hidden row: what hiding it saved, measured from the timing history. */
|
|
238
|
+
private hiddenCostRow;
|
|
239
|
+
private eyeButton;
|
|
240
|
+
private hideRow;
|
|
241
|
+
private showRow;
|
|
242
|
+
/** Everything hidden goes back: on closing top costs and on dispose. */
|
|
243
|
+
private showAllHidden;
|
|
226
244
|
private costsNote;
|
|
227
245
|
/** The monitor caches the environment once its backend settles; until then this re-reads. */
|
|
228
246
|
private renderFooter;
|
|
247
|
+
/** Budgets follow the detected refresh rate unless `targetFps` was given. */
|
|
248
|
+
private followRefresh;
|
|
229
249
|
private renderHud;
|
|
230
250
|
private paintNumber;
|
|
231
251
|
/** Value and sparkline, with the budget line drawn once the series reaches it. */
|
|
@@ -301,4 +321,4 @@ type PerfHudHandle = {
|
|
|
301
321
|
declare const mountPerfHud: (monitor: PerformanceMonitor, options?: MountPerfHudOptions) => PerfHudHandle;
|
|
302
322
|
//#endregion
|
|
303
323
|
export { dockPanel as C, resolveBudgets as D, ResolvedBudgets as E, ScreenEdge as S, Budgets as T, DefaultPlacement as _, PerformanceViewMode as a, DockPanelOptions as b, HudDefaults as c, HudSettingsOptions as d, HudTheme as f, isThemeMode as g, ThemeMode as h, PerformanceView as i, HudSelection as l, THEME_MODES as m, PerfHudHandle as n, PerformanceViewOptions as o, ResolvedTheme as p, mountPerfHud as r, DEFAULT_STORAGE_KEY as s, MountPerfHudOptions as t, HudSettings as u, DockAlign as v, BudgetKey as w, Placement as x, DockHandle as y };
|
|
304
|
-
//# sourceMappingURL=mount-perf-hud-
|
|
324
|
+
//# sourceMappingURL=mount-perf-hud-MTPYNhG9.d.ts.map
|