stats-gl 3.7.0 → 4.0.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 +360 -84
- package/addons/StatsGLNode.js +201 -0
- package/addons/StatsGLNodeWorker.js +198 -0
- package/dist/core.cjs +421 -0
- package/dist/core.cjs.map +1 -0
- package/dist/core.js +421 -0
- package/dist/core.js.map +1 -0
- package/dist/main.cjs +417 -244
- package/dist/main.cjs.map +1 -1
- package/dist/main.js +415 -243
- package/dist/main.js.map +1 -1
- package/dist/panel.cjs +12 -3
- package/dist/panel.cjs.map +1 -1
- package/dist/panel.js +12 -3
- package/dist/panel.js.map +1 -1
- package/dist/panelTexture.cjs +93 -0
- package/dist/panelTexture.cjs.map +1 -0
- package/dist/panelTexture.js +93 -0
- package/dist/panelTexture.js.map +1 -0
- package/dist/profiler.cjs +95 -0
- package/dist/profiler.cjs.map +1 -0
- package/dist/profiler.js +95 -0
- package/dist/profiler.js.map +1 -0
- package/dist/stats-gl.d.ts +335 -72
- package/dist/statsGLNode.cjs +89 -0
- package/dist/statsGLNode.cjs.map +1 -0
- package/dist/statsGLNode.js +89 -0
- package/dist/statsGLNode.js.map +1 -0
- package/dist/textureCapture.cjs +283 -0
- package/dist/textureCapture.cjs.map +1 -0
- package/dist/textureCapture.js +283 -0
- package/dist/textureCapture.js.map +1 -0
- package/lib/core.ts +579 -0
- package/lib/main.ts +514 -403
- package/lib/panel.ts +18 -4
- package/lib/panelTexture.ts +122 -0
- package/lib/profiler.ts +124 -0
- package/lib/statsGLNode.ts +124 -0
- package/lib/textureCapture.ts +403 -0
- package/lib/webgpu.d.ts +190 -0
- package/package.json +6 -4
package/README.md
CHANGED
|
@@ -1,111 +1,115 @@
|
|
|
1
|
-
#
|
|
1
|
+
# stats-gl
|
|
2
2
|
[](https://www.npmjs.com/package/stats-gl)
|
|
3
3
|
[](https://www.npmjs.com/package/stats-gl)
|
|
4
4
|
|
|
5
|
-
WebGL/WebGPU Performance Monitor
|
|
5
|
+
WebGL/WebGPU Performance Monitor with real-time FPS, CPU, and GPU timing. Supports Three.js, native WebGL2/WebGPU, Web Workers, and texture preview panels.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
[Live Demo](https://stats.renaudrohlinger.com/)
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
https://github.com/RenaudRohlinger/stats-gl/assets/15867665/3fdafff4-1357-4872-9baf-0629dbaf9d8c
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
###
|
|
13
|
+
### Note: To support GPU monitoring on Safari you need to enable Timer Queries under WebKit Feature Flags > WebGL Timer Queries
|
|
14
14
|
|
|
15
|
-
##
|
|
16
|
-
|
|
17
|
-
`stats-gl` is a comprehensive tool to monitor WebGL performance. The Stats class provides methods to create performance panels, log performance metrics, and manage the display and layout of these panels. The performance metrics logged include FPS, CPU, and GPU. The GPU logging is available only if the user's browser supports the WebGL 2.0 `EXT_disjoint_timer_query_webgl2` extension or WebGPU Timestamp Queries.
|
|
18
|
-
|
|
19
|
-
In addition to logging real-time performance data, the class also provides methods to calculate and display average performance metrics over a specified interval.
|
|
20
|
-
|
|
21
|
-
## ⬇️ Installation
|
|
22
|
-
|
|
23
|
-
Stats-gl is available as an npm package. You can install it using the following command:
|
|
15
|
+
## Installation
|
|
24
16
|
|
|
25
17
|
```bash
|
|
26
18
|
npm install stats-gl
|
|
27
19
|
```
|
|
28
20
|
|
|
29
|
-
##
|
|
30
|
-
|
|
31
|
-
Below is an example of how you can use this class in your code:
|
|
32
|
-
```js
|
|
33
|
-
import Stats from "stats-gl";
|
|
34
|
-
|
|
35
|
-
// create a new Stats object
|
|
36
|
-
const stats = new Stats({
|
|
37
|
-
trackGPU: false,
|
|
38
|
-
trackHz: false,
|
|
39
|
-
trackCPT: false,
|
|
40
|
-
logsPerSecond: 4,
|
|
41
|
-
graphsPerSecond: 30,
|
|
42
|
-
samplesLog: 40,
|
|
43
|
-
samplesGraph: 10,
|
|
44
|
-
precision: 2,
|
|
45
|
-
horizontal: true,
|
|
46
|
-
minimal: false,
|
|
47
|
-
mode: 0
|
|
48
|
-
});
|
|
21
|
+
## Quick Start
|
|
49
22
|
|
|
50
|
-
|
|
51
|
-
document.body.appendChild( stats.dom );
|
|
23
|
+
### Three.js (WebGL or WebGPU)
|
|
52
24
|
|
|
53
|
-
|
|
54
|
-
stats
|
|
55
|
-
|
|
56
|
-
stats.end();
|
|
25
|
+
```js
|
|
26
|
+
import Stats from 'stats-gl';
|
|
27
|
+
import * as THREE from 'three';
|
|
57
28
|
|
|
58
|
-
stats
|
|
59
|
-
|
|
60
|
-
stats.end();
|
|
29
|
+
const stats = new Stats({ trackGPU: true });
|
|
30
|
+
document.body.appendChild(stats.dom);
|
|
61
31
|
|
|
32
|
+
const renderer = new THREE.WebGLRenderer(); // or WebGPURenderer
|
|
33
|
+
stats.init(renderer);
|
|
62
34
|
|
|
63
|
-
|
|
64
|
-
|
|
35
|
+
function animate() {
|
|
36
|
+
renderer.render(scene, camera); // or renderAsync for WebGPU
|
|
37
|
+
stats.update();
|
|
38
|
+
}
|
|
39
|
+
renderer.setAnimationLoop(animate);
|
|
65
40
|
```
|
|
66
41
|
|
|
42
|
+
### Native WebGL2
|
|
67
43
|
|
|
68
|
-
Quick start with threejs:
|
|
69
44
|
```js
|
|
70
|
-
import
|
|
45
|
+
import Stats from 'stats-gl';
|
|
71
46
|
|
|
72
|
-
|
|
73
|
-
|
|
47
|
+
const stats = new Stats({ trackGPU: true });
|
|
48
|
+
const canvas = document.querySelector('#canvas');
|
|
49
|
+
stats.init(canvas);
|
|
50
|
+
document.body.appendChild(stats.dom);
|
|
74
51
|
|
|
75
|
-
|
|
52
|
+
function animate() {
|
|
53
|
+
stats.begin();
|
|
54
|
+
// ... your WebGL draw calls ...
|
|
55
|
+
stats.end();
|
|
56
|
+
stats.update();
|
|
57
|
+
requestAnimationFrame(animate);
|
|
58
|
+
}
|
|
59
|
+
animate();
|
|
60
|
+
```
|
|
76
61
|
|
|
77
|
-
|
|
78
|
-
container.appendChild( stats.dom );
|
|
62
|
+
### Native WebGPU
|
|
79
63
|
|
|
80
|
-
|
|
81
|
-
|
|
64
|
+
```js
|
|
65
|
+
import Stats from 'stats-gl';
|
|
82
66
|
|
|
83
|
-
const
|
|
67
|
+
const adapter = await navigator.gpu.requestAdapter();
|
|
68
|
+
const device = await adapter.requestDevice({ requiredFeatures: ['timestamp-query'] });
|
|
69
|
+
const context = canvas.getContext('webgpu');
|
|
84
70
|
|
|
85
|
-
stats
|
|
71
|
+
const stats = new Stats({ trackGPU: true });
|
|
72
|
+
stats.init(device); // Pass the GPUDevice
|
|
73
|
+
document.body.appendChild(stats.dom);
|
|
86
74
|
|
|
87
75
|
function animate() {
|
|
76
|
+
stats.begin();
|
|
88
77
|
|
|
89
|
-
|
|
78
|
+
const encoder = device.createCommandEncoder();
|
|
79
|
+
const pass = encoder.beginRenderPass({
|
|
80
|
+
colorAttachments: [...],
|
|
81
|
+
timestampWrites: stats.getTimestampWrites() // Enable GPU timing
|
|
82
|
+
});
|
|
83
|
+
// ... your draw calls ...
|
|
84
|
+
pass.end();
|
|
90
85
|
|
|
91
|
-
|
|
92
|
-
|
|
86
|
+
stats.end(encoder); // Pass encoder to resolve timestamps
|
|
87
|
+
device.queue.submit([encoder.finish()]);
|
|
93
88
|
|
|
89
|
+
stats.update();
|
|
90
|
+
requestAnimationFrame(animate);
|
|
94
91
|
}
|
|
92
|
+
animate();
|
|
95
93
|
```
|
|
96
|
-
|
|
94
|
+
|
|
95
|
+
### React Three Fiber
|
|
96
|
+
|
|
97
|
+
A `<StatsGl />` component is available through [@react-three/drei](https://github.com/pmndrs/drei):
|
|
98
|
+
|
|
97
99
|
```jsx
|
|
98
100
|
import { Canvas } from '@react-three/fiber'
|
|
99
101
|
import { StatsGl } from '@react-three/drei'
|
|
100
102
|
|
|
101
103
|
const Scene = () => (
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
104
|
+
<Canvas>
|
|
105
|
+
<StatsGl />
|
|
106
|
+
</Canvas>
|
|
105
107
|
)
|
|
106
108
|
```
|
|
107
109
|
|
|
108
|
-
|
|
110
|
+
### Tresjs (Vue)
|
|
111
|
+
|
|
112
|
+
A `<StatsGl />` component is available through [cientos](https://cientos.tresjs.org/guide/misc/stats-gl.html):
|
|
109
113
|
|
|
110
114
|
```vue
|
|
111
115
|
<script setup lang="ts">
|
|
@@ -119,33 +123,305 @@ import { StatsGl } from '@tresjs/cientos'
|
|
|
119
123
|
</TresCanvas>
|
|
120
124
|
</template>
|
|
121
125
|
```
|
|
122
|
-
## ⚙️ Parameters
|
|
123
|
-
The constructor for the Stats class accepts an options object with the following properties:
|
|
124
126
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
127
|
+
## Parameters
|
|
128
|
+
|
|
129
|
+
| Parameter | Type | Default | Description |
|
|
130
|
+
|-----------|------|---------|-------------|
|
|
131
|
+
| `trackFPS` | boolean | `true` | Enable built-in FPS and CPU panels |
|
|
132
|
+
| `trackGPU` | boolean | `false` | Enable GPU timing (requires extension support) |
|
|
133
|
+
| `trackHz` | boolean | `false` | Enable refresh rate detection |
|
|
134
|
+
| `trackCPT` | boolean | `false` | Enable Three.js compute shader timing (WebGPU only) |
|
|
135
|
+
| `logsPerSecond` | number | `4` | How often to update text display |
|
|
136
|
+
| `graphsPerSecond` | number | `30` | How often to update graphs |
|
|
137
|
+
| `samplesLog` | number | `40` | Number of samples for text averaging |
|
|
138
|
+
| `samplesGraph` | number | `10` | Number of samples for graph averaging |
|
|
139
|
+
| `precision` | number | `2` | Decimal places for CPU/GPU values |
|
|
140
|
+
| `minimal` | boolean | `false` | Minimal mode - click to cycle panels |
|
|
141
|
+
| `horizontal` | boolean | `true` | Horizontal panel layout |
|
|
142
|
+
| `mode` | number | `0` | Initial panel (0=FPS, 1=CPU, 2=GPU) |
|
|
143
|
+
|
|
144
|
+
## Web Worker / OffscreenCanvas
|
|
145
|
+
|
|
146
|
+
stats-gl supports rendering in a Web Worker using OffscreenCanvas. Use `StatsProfiler` in the worker to collect timing data, and send it to the main thread where `Stats` displays it.
|
|
147
|
+
|
|
148
|
+
**Worker (offscreen rendering):**
|
|
149
|
+
```js
|
|
150
|
+
import { StatsProfiler } from 'stats-gl';
|
|
151
|
+
|
|
152
|
+
const profiler = new StatsProfiler({ trackGPU: true });
|
|
153
|
+
|
|
154
|
+
self.onmessage = async (e) => {
|
|
155
|
+
if (e.data.type === 'init') {
|
|
156
|
+
const canvas = e.data.canvas;
|
|
157
|
+
const gl = canvas.getContext('webgl2');
|
|
158
|
+
await profiler.init(gl);
|
|
159
|
+
requestAnimationFrame(loop);
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
function loop() {
|
|
164
|
+
profiler.begin();
|
|
165
|
+
// ... your rendering code ...
|
|
166
|
+
profiler.end();
|
|
167
|
+
profiler.update();
|
|
168
|
+
|
|
169
|
+
// Send timing data to main thread
|
|
170
|
+
self.postMessage({ type: 'stats', ...profiler.getData() });
|
|
171
|
+
requestAnimationFrame(loop);
|
|
172
|
+
}
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
**Main thread:**
|
|
176
|
+
```js
|
|
177
|
+
import Stats from 'stats-gl';
|
|
178
|
+
|
|
179
|
+
const stats = new Stats({ trackGPU: true });
|
|
180
|
+
document.body.appendChild(stats.dom);
|
|
181
|
+
|
|
182
|
+
const canvas = document.getElementById('canvas');
|
|
183
|
+
const offscreen = canvas.transferControlToOffscreen();
|
|
184
|
+
|
|
185
|
+
const worker = new Worker('worker.js', { type: 'module' });
|
|
186
|
+
worker.postMessage({ type: 'init', canvas: offscreen }, [offscreen]);
|
|
187
|
+
|
|
188
|
+
worker.onmessage = (e) => {
|
|
189
|
+
if (e.data.type === 'stats') {
|
|
190
|
+
stats.setData(e.data);
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
function loop() {
|
|
195
|
+
stats.update();
|
|
196
|
+
requestAnimationFrame(loop);
|
|
197
|
+
}
|
|
198
|
+
loop();
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
### StatsProfiler API
|
|
202
|
+
|
|
203
|
+
`StatsProfiler` is a headless version of `Stats` designed for workers:
|
|
204
|
+
|
|
205
|
+
- `init(canvas | device)` - Initialize with WebGL context, OffscreenCanvas, or GPUDevice
|
|
206
|
+
- `begin()` / `end(encoder?)` - Wrap your render calls (pass encoder for native WebGPU)
|
|
207
|
+
- `getTimestampWrites()` - Get timestampWrites config for native WebGPU render pass
|
|
208
|
+
- `update()` - Process timing data
|
|
209
|
+
- `getData()` - Returns `{ fps, cpu, gpu, gpuCompute }`
|
|
210
|
+
- `captureTexture(source, sourceId)` - Capture texture to ImageBitmap for transfer
|
|
211
|
+
|
|
212
|
+
### Stats.setData()
|
|
213
|
+
|
|
214
|
+
Use `stats.setData(data)` to feed external timing data into the Stats UI. When set, `update()` uses this data instead of internal timing.
|
|
215
|
+
|
|
216
|
+
## Texture Preview Panels
|
|
217
|
+
|
|
218
|
+
Display render target previews alongside performance metrics. Supports both WebGL and WebGPU.
|
|
219
|
+
|
|
220
|
+
### Three.js Usage
|
|
221
|
+
|
|
222
|
+
```js
|
|
223
|
+
const stats = new Stats({ trackGPU: true });
|
|
224
|
+
stats.init(renderer);
|
|
225
|
+
|
|
226
|
+
// Create a texture panel
|
|
227
|
+
const panel = stats.addTexturePanel('GBuffer');
|
|
228
|
+
|
|
229
|
+
// Set texture source (WebGLRenderTarget or WebGPU RenderTarget)
|
|
230
|
+
const renderTarget = new THREE.WebGLRenderTarget(width, height);
|
|
231
|
+
stats.setTexture('GBuffer', renderTarget);
|
|
232
|
+
|
|
233
|
+
// In render loop - textures update automatically
|
|
234
|
+
function animate() {
|
|
235
|
+
renderer.setRenderTarget(renderTarget);
|
|
236
|
+
renderer.render(scene, camera);
|
|
237
|
+
renderer.setRenderTarget(null);
|
|
238
|
+
renderer.render(scene, camera);
|
|
239
|
+
stats.update();
|
|
240
|
+
}
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
### Worker Texture Transfer
|
|
244
|
+
|
|
245
|
+
```js
|
|
246
|
+
// Worker - capture and transfer texture
|
|
247
|
+
const bitmap = await profiler.captureTexture(renderTarget, 'gbuffer');
|
|
248
|
+
self.postMessage(
|
|
249
|
+
{ type: 'texture', name: 'GBuffer', bitmap, width, height },
|
|
250
|
+
[bitmap]
|
|
251
|
+
);
|
|
252
|
+
|
|
253
|
+
// Main thread - receive and display
|
|
254
|
+
worker.onmessage = (e) => {
|
|
255
|
+
if (e.data.type === 'texture') {
|
|
256
|
+
stats.setTextureBitmap(e.data.name, e.data.bitmap, e.data.width, e.data.height);
|
|
257
|
+
}
|
|
258
|
+
};
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
### Texture Panel API
|
|
262
|
+
|
|
263
|
+
- `stats.addTexturePanel(name)` - Create a new texture preview panel
|
|
264
|
+
- `stats.setTexture(name, source)` - Set Three.js RenderTarget source
|
|
265
|
+
- `stats.setTextureWebGL(name, framebuffer, width, height)` - Set raw WebGL framebuffer
|
|
266
|
+
- `stats.setTextureBitmap(name, bitmap, width?, height?)` - Set ImageBitmap (for workers)
|
|
267
|
+
- `stats.removeTexturePanel(name)` - Remove a texture panel
|
|
268
|
+
|
|
269
|
+
## TSL Node Capture (WebGPU)
|
|
270
|
+
|
|
271
|
+
Capture any Three.js TSL node for live preview. Works with MRT, post-processing, and custom shaders.
|
|
272
|
+
|
|
273
|
+
### Main Thread Usage
|
|
274
|
+
|
|
275
|
+
```js
|
|
276
|
+
import Stats from 'stats-gl';
|
|
277
|
+
import { statsGL } from 'stats-gl/addons/StatsGLNode.js';
|
|
278
|
+
import { addMethodChaining } from 'three/tsl';
|
|
279
|
+
|
|
280
|
+
// Enable .toStatsGL() method on TSL nodes
|
|
281
|
+
addMethodChaining('toStatsGL', statsGL);
|
|
282
|
+
|
|
283
|
+
const stats = new Stats({ trackGPU: true });
|
|
284
|
+
stats.init(renderer);
|
|
285
|
+
document.body.appendChild(stats.dom);
|
|
286
|
+
|
|
287
|
+
// In your PostProcessing setup:
|
|
288
|
+
const scenePass = pass(scene, camera);
|
|
289
|
+
scenePass.setMRT(mrt({
|
|
290
|
+
output,
|
|
291
|
+
normal: directionToColor(normalView),
|
|
292
|
+
diffuse: diffuseColor
|
|
293
|
+
}));
|
|
294
|
+
|
|
295
|
+
// Register nodes for capture - panels are created automatically
|
|
296
|
+
scenePass.getTextureNode('diffuse').toStatsGL('Diffuse', stats);
|
|
297
|
+
scenePass.getTextureNode('normal').toStatsGL('Normal', stats);
|
|
298
|
+
scenePass.getLinearDepthNode().toStatsGL('Depth', stats);
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
### Web Worker Usage
|
|
302
|
+
|
|
303
|
+
For OffscreenCanvas rendering in workers, use the worker addon:
|
|
304
|
+
|
|
305
|
+
**Worker:**
|
|
306
|
+
```js
|
|
307
|
+
import { StatsProfiler } from 'stats-gl';
|
|
308
|
+
import { statsGLWorker, flushCaptures } from 'stats-gl/addons/StatsGLNodeWorker.js';
|
|
309
|
+
import { addMethodChaining } from 'three/tsl';
|
|
310
|
+
|
|
311
|
+
addMethodChaining('toStatsGL', statsGLWorker);
|
|
312
|
+
|
|
313
|
+
const profiler = new StatsProfiler({ trackGPU: true });
|
|
314
|
+
await profiler.init(renderer);
|
|
315
|
+
|
|
316
|
+
// Register nodes (no stats instance needed in worker)
|
|
317
|
+
diffuseNode.toStatsGL('Diffuse');
|
|
318
|
+
normalNode.toStatsGL('Normal');
|
|
319
|
+
depthNode.toStatsGL('Depth');
|
|
320
|
+
|
|
321
|
+
async function render() {
|
|
322
|
+
profiler.begin();
|
|
323
|
+
postProcessing.render();
|
|
324
|
+
profiler.end();
|
|
325
|
+
profiler.update();
|
|
326
|
+
|
|
327
|
+
// Send stats to main thread
|
|
328
|
+
self.postMessage({ type: 'stats', data: profiler.getData() });
|
|
329
|
+
|
|
330
|
+
// Capture and transfer TSL nodes
|
|
331
|
+
const captures = await flushCaptures(renderer);
|
|
332
|
+
for (const { name, bitmap } of captures) {
|
|
333
|
+
self.postMessage({ type: 'texture', name, bitmap }, [bitmap]);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
**Main Thread:**
|
|
339
|
+
```js
|
|
340
|
+
import Stats from 'stats-gl';
|
|
341
|
+
|
|
342
|
+
const stats = new Stats({ trackGPU: true });
|
|
343
|
+
document.body.appendChild(stats.dom);
|
|
344
|
+
|
|
345
|
+
// Create panels for worker captures
|
|
346
|
+
stats.addTexturePanel('Diffuse');
|
|
347
|
+
stats.addTexturePanel('Normal');
|
|
348
|
+
stats.addTexturePanel('Depth');
|
|
349
|
+
|
|
350
|
+
worker.onmessage = (e) => {
|
|
351
|
+
if (e.data.type === 'stats') stats.setData(e.data.data);
|
|
352
|
+
if (e.data.type === 'texture') {
|
|
353
|
+
stats.setTextureBitmap(e.data.name, e.data.bitmap);
|
|
354
|
+
}
|
|
355
|
+
};
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
### Transform Callback
|
|
359
|
+
|
|
360
|
+
Use a callback to transform the node before capture (e.g., linearize depth):
|
|
361
|
+
|
|
362
|
+
```js
|
|
363
|
+
depthNode.toStatsGL('Depth', stats, (node) => linearizeDepth(node));
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
## Custom Panels
|
|
367
|
+
|
|
368
|
+
Add custom metrics panels:
|
|
369
|
+
|
|
370
|
+
```js
|
|
371
|
+
const customPanel = stats.addPanel(new Stats.Panel('COUNT', '#ff0', '#220'));
|
|
372
|
+
|
|
373
|
+
function animate() {
|
|
374
|
+
// Update with value and max
|
|
375
|
+
customPanel.update(currentValue, maxValue, 2); // 2 decimal places
|
|
376
|
+
customPanel.updateGraph(currentValue, maxValue);
|
|
377
|
+
stats.update();
|
|
378
|
+
}
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
## API Reference
|
|
382
|
+
|
|
383
|
+
### Default Export: Stats
|
|
384
|
+
|
|
385
|
+
Main class with DOM rendering.
|
|
136
386
|
|
|
137
|
-
|
|
387
|
+
```js
|
|
388
|
+
import Stats from 'stats-gl';
|
|
389
|
+
|
|
390
|
+
const stats = new Stats(options);
|
|
391
|
+
stats.init(renderer); // Initialize with Three.js renderer, canvas, or GPUDevice
|
|
392
|
+
stats.begin(); // Start timing (auto-called for Three.js)
|
|
393
|
+
stats.end(encoder?); // End timing (pass encoder for native WebGPU)
|
|
394
|
+
stats.update(); // Update display
|
|
395
|
+
stats.setData(data); // Set external timing data
|
|
396
|
+
stats.getTimestampWrites(); // Get timestampWrites for native WebGPU render pass
|
|
397
|
+
stats.dispose(); // Clean up resources
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
### Named Exports
|
|
401
|
+
|
|
402
|
+
```js
|
|
403
|
+
import Stats, {
|
|
404
|
+
StatsProfiler, // Headless profiler for workers
|
|
405
|
+
PanelTexture, // Texture preview panel class
|
|
406
|
+
TextureCaptureWebGL, // WebGL texture capture utility
|
|
407
|
+
TextureCaptureWebGPU, // WebGPU texture capture utility
|
|
408
|
+
StatsGLCapture // Addon capture helper
|
|
409
|
+
} from 'stats-gl';
|
|
410
|
+
|
|
411
|
+
// TSL Node capture addons (WebGPU only)
|
|
412
|
+
import { statsGL } from 'stats-gl/addons/StatsGLNode.js';
|
|
413
|
+
import { statsGLWorker, flushCaptures } from 'stats-gl/addons/StatsGLNodeWorker.js';
|
|
414
|
+
```
|
|
138
415
|
|
|
416
|
+
## Contributing
|
|
139
417
|
|
|
140
|
-
|
|
141
|
-
Contributions to Stats-gl are welcome.
|
|
418
|
+
Contributions to stats-gl are welcome. Please report any issues or bugs you encounter.
|
|
142
419
|
|
|
143
|
-
|
|
420
|
+
## License
|
|
144
421
|
|
|
145
|
-
## 📜 License
|
|
146
422
|
This project is licensed under the MIT License.
|
|
147
423
|
|
|
148
|
-
##
|
|
424
|
+
## Maintainers
|
|
149
425
|
|
|
150
|
-
- [
|
|
151
|
-
- [
|
|
426
|
+
- [@onirenaud](https://twitter.com/onirenaud)
|
|
427
|
+
- [@utsuboco](https://twitter.com/utsuboco)
|