@gnsx/three 0.184.12 → 0.184.13

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gnsx/three",
3
- "version": "0.184.12",
3
+ "version": "0.184.13",
4
4
  "description": "JavaScript 3D library",
5
5
  "type": "module",
6
6
  "main": "./build/three.cjs",
package/src/Three.Core.js CHANGED
@@ -164,6 +164,11 @@ export { createCanvasElement, setConsoleFunction, getConsoleFunction, log, warn,
164
164
  export * from './constants.js';
165
165
  export * from './Three.Legacy.js';
166
166
 
167
+ // WITH_GENESYS
168
+ export { ProfilerService, profile, profileClass } from './profiler/ProfilerService.js';
169
+ // !WITH_GENESYS
170
+
171
+
167
172
  if ( typeof __THREE_DEVTOOLS__ !== 'undefined' ) {
168
173
 
169
174
  __THREE_DEVTOOLS__.dispatchEvent( new CustomEvent( 'register', { detail: {
package/src/Three.js CHANGED
@@ -8,6 +8,3 @@ export { UniformsUtils } from './renderers/shaders/UniformsUtils.js';
8
8
  export { ShaderChunk } from './renderers/shaders/ShaderChunk.js';
9
9
  export { PMREMGenerator } from './extras/PMREMGenerator.js';
10
10
  export { WebGLUtils } from './renderers/webgl/WebGLUtils.js';
11
- // WITH_GENESYS
12
- export { ProfilerService, profile, profileClass } from './profiler/ProfilerService.js';
13
- // !WITH_GENESYS
@@ -1,5 +1,9 @@
1
1
  import { NodeUpdateType } from './constants.js';
2
2
 
3
+ // WITH_GENESYS
4
+ import { ProfilerService } from '../../profiler/ProfilerService.js';
5
+ // !WITH_GENESYS
6
+
3
7
  /**
4
8
  * Management class for updating nodes. The module tracks metrics like
5
9
  * the elapsed time, delta time, the render and frame ID to correctly
@@ -146,6 +150,11 @@ class NodeFrame {
146
150
  */
147
151
  updateBeforeNode( node ) {
148
152
 
153
+ // WITH_GENESYS
154
+ const label = `${node.type}.updateBefore`;
155
+ ProfilerService.begin( label );
156
+ // !WITH_GENESYS
157
+
149
158
  const updateType = node.getUpdateBeforeType();
150
159
  const reference = node.updateReference( this );
151
160
 
@@ -191,6 +200,10 @@ class NodeFrame {
191
200
 
192
201
  }
193
202
 
203
+ // WITH_GENESYS
204
+ ProfilerService.end( label );
205
+ // !WITH_GENESYS
206
+
194
207
  }
195
208
 
196
209
  /**
@@ -203,6 +216,11 @@ class NodeFrame {
203
216
  */
204
217
  updateAfterNode( node ) {
205
218
 
219
+ // WITH_GENESYS
220
+ const label = `${node.type}.updateAfter`;
221
+ ProfilerService.begin( label );
222
+ // !WITH_GENESYS
223
+
206
224
  const updateType = node.getUpdateAfterType();
207
225
  const reference = node.updateReference( this );
208
226
 
@@ -240,6 +258,10 @@ class NodeFrame {
240
258
 
241
259
  }
242
260
 
261
+ // WITH_GENESYS
262
+ ProfilerService.end( label );
263
+ // !WITH_GENESYS
264
+
243
265
  }
244
266
 
245
267
  /**
@@ -24,6 +24,10 @@ import { uv } from '../accessors/UV.js';
24
24
  import { positionLocal } from '../accessors/Position.js';
25
25
  import { uniform } from '../core/UniformNode.js';
26
26
 
27
+ // WITH_GENESYS
28
+ import { ProfilerService } from '../../profiler/ProfilerService.js';
29
+ // !WITH_GENESYS
30
+
27
31
  //
28
32
 
29
33
  const _shadowRenderObjectLibrary = /*@__PURE__*/ new ChainMap();
@@ -676,6 +680,10 @@ class ShadowNode extends ShadowBaseNode {
676
680
  */
677
681
  renderShadow( frame ) {
678
682
 
683
+ // WITH_GENESYS
684
+ ProfilerService.begin( 'ShadowNode.renderShadow' );
685
+ // !WITH_GENESYS
686
+
679
687
  const { shadow, shadowMap, light } = this;
680
688
  const { renderer, scene } = frame;
681
689
 
@@ -691,6 +699,10 @@ class ShadowNode extends ShadowBaseNode {
691
699
 
692
700
  scene.name = currentSceneName;
693
701
 
702
+ // WITH_GENESYS
703
+ ProfilerService.end( 'ShadowNode.renderShadow' );
704
+ // !WITH_GENESYS
705
+
694
706
  }
695
707
 
696
708
  /**
@@ -756,6 +768,10 @@ class ShadowNode extends ShadowBaseNode {
756
768
  */
757
769
  vsmPass( renderer ) {
758
770
 
771
+ // WITH_GENESYS
772
+ ProfilerService.begin( 'ShadowNode.vsmPass' );
773
+ // !WITH_GENESYS
774
+
759
775
  const { shadow } = this;
760
776
 
761
777
  const depth = this.shadowMap.depth;
@@ -770,6 +786,10 @@ class ShadowNode extends ShadowBaseNode {
770
786
  _quadMesh.material = this.vsmMaterialHorizontal;
771
787
  _quadMesh.render( renderer );
772
788
 
789
+ // WITH_GENESYS
790
+ ProfilerService.end( 'ShadowNode.vsmPass' );
791
+ // !WITH_GENESYS
792
+
773
793
  }
774
794
 
775
795
  /**
@@ -48,11 +48,12 @@ class ProfilerServiceClass {
48
48
  this.cursors = new Map();
49
49
  /** @type {Map<string, number>} */
50
50
  this.counts = new Map();
51
- /** @type {Map<string, number>} */
51
+ /** @type {Map<string, Array<{ startTime: number, startMark: string, traced: boolean }>>} */
52
52
  this.marks = new Map();
53
- /** @type {Array<{ name: string, ph: 'X', ts: number, dur: number, pid: 1, tid: 1, cat: 'gnsx' }>} */
53
+ /** @type {ChromeTraceEvent[]} */
54
54
  this.traceEvents = [];
55
55
  this.traceStartTime = 0;
56
+ this._markId = 0;
56
57
 
57
58
  if ( this._enabled ) {
58
59
 
@@ -133,8 +134,32 @@ class ProfilerServiceClass {
133
134
  */
134
135
  _beginImpl( label ) {
135
136
 
136
- performance.mark( `gnsx:${label}:start` );
137
- this.marks.set( label, performance.now() );
137
+ const startTime = performance.now();
138
+ const startMark = `gnsx:${label}:start:${++ this._markId}`;
139
+ let stack = this.marks.get( label );
140
+ if ( stack === undefined ) {
141
+
142
+ stack = [];
143
+ this.marks.set( label, stack );
144
+
145
+ }
146
+
147
+ const traced = this._profile === 'full' && this.traceEvents.length < MAX_TRACE_EVENTS;
148
+ if ( traced ) {
149
+
150
+ this.traceEvents.push( {
151
+ name: label,
152
+ ph: 'B',
153
+ ts: this._getTraceTimestamp( startTime ),
154
+ pid: 1,
155
+ tid: 1,
156
+ cat: 'gnsx',
157
+ } );
158
+
159
+ }
160
+
161
+ performance.mark( startMark );
162
+ stack.push( { startTime, startMark, traced } );
138
163
 
139
164
  }
140
165
 
@@ -143,15 +168,18 @@ class ProfilerServiceClass {
143
168
  */
144
169
  _endImpl( label ) {
145
170
 
146
- const startTime = this.marks.get( label );
147
- if ( startTime === undefined ) return;
148
- this.marks.delete( label );
171
+ const stack = this.marks.get( label );
172
+ const mark = stack?.pop();
173
+ if ( mark === undefined ) return;
174
+ if ( stack.length === 0 ) this.marks.delete( label );
149
175
 
150
176
  const now = performance.now();
177
+ const { startTime, startMark, traced } = mark;
151
178
  const duration = now - startTime;
179
+ const endMark = `gnsx:${label}:end:${++ this._markId}`;
152
180
 
153
- performance.mark( `gnsx:${label}:end` );
154
- performance.measure( `gnsx:${label}`, `gnsx:${label}:start`, `gnsx:${label}:end` );
181
+ performance.mark( endMark );
182
+ performance.measure( `gnsx:${label}`, startMark, endMark );
155
183
 
156
184
  let buffer = this.buffers.get( label );
157
185
  if ( ! buffer ) {
@@ -168,13 +196,12 @@ class ProfilerServiceClass {
168
196
  this.cursors.set( label, ( cursor + 1 ) % RING_SIZE );
169
197
  this.counts.set( label, Math.min( ( this.counts.get( label ) + 1 ), RING_SIZE ) );
170
198
 
171
- if ( this._profile === 'full' && this.traceEvents.length < MAX_TRACE_EVENTS ) {
199
+ if ( traced ) {
172
200
 
173
201
  this.traceEvents.push( {
174
202
  name: label,
175
- ph: 'X',
176
- ts: Math.round( ( startTime - this.traceStartTime ) * 1000 ),
177
- dur: Math.max( 1, Math.round( duration * 1000 ) ),
203
+ ph: 'E',
204
+ ts: this._getTraceTimestamp( now ),
178
205
  pid: 1,
179
206
  tid: 1,
180
207
  cat: 'gnsx',
@@ -264,7 +291,24 @@ class ProfilerServiceClass {
264
291
  */
265
292
  exportChromeTrace() {
266
293
 
267
- return { traceEvents: [ ...this.traceEvents ] };
294
+ return {
295
+ displayTimeUnit: 'ms',
296
+ traceEvents: [
297
+ { name: 'process_name', ph: 'M', pid: 1, args: { name: 'Genesys Profiler' } },
298
+ { name: 'thread_name', ph: 'M', pid: 1, tid: 1, args: { name: 'Main Thread' } },
299
+ ...this.traceEvents,
300
+ ],
301
+ };
302
+
303
+ }
304
+
305
+ /**
306
+ * @param {number} time
307
+ * @return {number}
308
+ */
309
+ _getTraceTimestamp( time ) {
310
+
311
+ return ( time - this.traceStartTime ) * 1000;
268
312
 
269
313
  }
270
314
 
@@ -323,6 +367,7 @@ class ProfilerServiceClass {
323
367
  this.marks.clear();
324
368
  this.traceEvents = [];
325
369
  this.traceStartTime = performance.now();
370
+ this._markId = 0;
326
371
 
327
372
  }
328
373
 
@@ -346,10 +391,29 @@ class ProfilerServiceClass {
346
391
  * @property {number} frameBudget Percentage of a 60 fps frame budget (16.67 ms)
347
392
  */
348
393
 
394
+ /**
395
+ * @typedef {Object} ChromeTraceEvent
396
+ * @property {string} name
397
+ * @property {'B'|'E'} ph
398
+ * @property {number} ts
399
+ * @property {1} pid
400
+ * @property {1} tid
401
+ * @property {'gnsx'} cat
402
+ */
403
+
404
+ /**
405
+ * @typedef {Object} ChromeTraceMetadataEvent
406
+ * @property {'process_name'|'thread_name'} name
407
+ * @property {'M'} ph
408
+ * @property {1} pid
409
+ * @property {1} [tid]
410
+ * @property {{ name: string }} args
411
+ */
412
+
349
413
  /**
350
414
  * @typedef {Object} ChromeTrace
351
- * @property {Array<{ name: string, ph: 'X', ts: number, dur: number, pid: 1, tid: 1, cat: 'gnsx' }>} traceEvents
352
- * @property {{ 'clock-offset-since-epoch-ns'?: number }|undefined} [metadata]
415
+ * @property {'ms'} displayTimeUnit
416
+ * @property {Array<ChromeTraceEvent|ChromeTraceMetadataEvent>} traceEvents
353
417
  */
354
418
 
355
419
  /**
@@ -367,15 +431,24 @@ function applyProfileToMethod( label, descriptor ) {
367
431
  function profiled( ...args ) {
368
432
 
369
433
  ProfilerService.begin( label );
370
- const result = original.apply( this, args );
371
- if ( result instanceof Promise ) {
434
+ try {
372
435
 
373
- return result.finally( () => ProfilerService.end( label ) );
436
+ const result = original.apply( this, args );
437
+ if ( result instanceof Promise ) {
374
438
 
375
- }
439
+ return result.finally( () => ProfilerService.end( label ) );
440
+
441
+ }
376
442
 
377
- ProfilerService.end( label );
378
- return result;
443
+ ProfilerService.end( label );
444
+ return result;
445
+
446
+ } catch ( error ) {
447
+
448
+ ProfilerService.end( label );
449
+ throw error;
450
+
451
+ }
379
452
 
380
453
  }
381
454
 
@@ -36,6 +36,7 @@ import { float, vec3, vec4, Fn } from '../../nodes/tsl/TSLCore.js';
36
36
  // WITH_GENESYS
37
37
  import { detachRendererReference } from '../../nodes/accessors/RendererReferenceNode.js';
38
38
  import { toneMappingExposure } from '../../nodes/display/ToneMappingNode.js';
39
+ import { ProfilerService } from '../../profiler/ProfilerService.js';
39
40
  // !WITH_GENESYS
40
41
  import { reference } from '../../nodes/accessors/ReferenceNode.js';
41
42
  import { highpModelNormalViewMatrix, highpModelViewMatrix } from '../../nodes/accessors/ModelNode.js';
@@ -1214,6 +1215,10 @@ class Renderer {
1214
1215
  */
1215
1216
  _renderBundle( bundle, sceneRef, lightsNode ) {
1216
1217
 
1218
+ // WITH_GENESYS
1219
+ ProfilerService.begin( 'renderBundle' );
1220
+ // !WITH_GENESYS
1221
+
1217
1222
  const { bundleGroup, camera, renderList } = bundle;
1218
1223
 
1219
1224
  const renderContext = this._currentRenderContext;
@@ -1280,6 +1285,10 @@ class Renderer {
1280
1285
 
1281
1286
  this.backend.addBundle( renderContext, renderBundle );
1282
1287
 
1288
+ // WITH_GENESYS
1289
+ ProfilerService.end( 'renderBundle' );
1290
+ // !WITH_GENESYS
1291
+
1283
1292
  }
1284
1293
 
1285
1294
  /**
@@ -1299,6 +1308,10 @@ class Renderer {
1299
1308
  */
1300
1309
  render( scene, camera ) {
1301
1310
 
1311
+ // WITH_GENESYS
1312
+ ProfilerService.begin( 'Renderer.render' );
1313
+ // !WITH_GENESYS
1314
+
1302
1315
  if ( this._initialized === false ) {
1303
1316
 
1304
1317
  throw new Error( 'Renderer: .render() called before the backend is initialized. Use "await renderer.init();" before rendering.' );
@@ -1307,6 +1320,10 @@ class Renderer {
1307
1320
 
1308
1321
  this._renderScene( scene, camera );
1309
1322
 
1323
+ // WITH_GENESYS
1324
+ ProfilerService.end( 'Renderer.render' );
1325
+ // !WITH_GENESYS
1326
+
1310
1327
  }
1311
1328
 
1312
1329
  /**
@@ -1426,6 +1443,10 @@ class Renderer {
1426
1443
 
1427
1444
  if ( this._isDeviceLost === true ) return;
1428
1445
 
1446
+ // WITH_GENESYS
1447
+ ProfilerService.begin( 'Renderer._renderScene' );
1448
+ // !WITH_GENESYS
1449
+
1429
1450
  //
1430
1451
 
1431
1452
  const frameBufferTarget = useFrameBufferTarget ? this._getFrameBufferTarget() : null;
@@ -1583,7 +1604,13 @@ class Renderer {
1583
1604
 
1584
1605
  //
1585
1606
 
1607
+ // WITH_GENESYS
1608
+ ProfilerService.begin( 'scene.updateMatrixWorld' );
1609
+ // !WITH_GENESYS
1586
1610
  if ( scene.matrixWorldAutoUpdate === true ) scene.updateMatrixWorld();
1611
+ // WITH_GENESYS
1612
+ ProfilerService.end( 'scene.updateMatrixWorld' );
1613
+ // !WITH_GENESYS
1587
1614
 
1588
1615
  if ( camera.parent === null && camera.matrixWorldAutoUpdate === true ) camera.updateMatrixWorld();
1589
1616
 
@@ -1647,11 +1674,23 @@ class Renderer {
1647
1674
 
1648
1675
  }
1649
1676
 
1677
+ // WITH_GENESYS
1678
+ ProfilerService.begin( 'buildRenderList' );
1679
+ // !WITH_GENESYS
1680
+
1650
1681
  const renderList = this._renderLists.get( scene, camera );
1651
1682
  renderList.begin();
1652
1683
 
1684
+ // WITH_GENESYS
1685
+ ProfilerService.begin( '_projectObject' );
1686
+ // !WITH_GENESYS
1687
+
1653
1688
  this._projectObject( scene, camera, 0, renderList, renderContext.clippingContext );
1654
1689
 
1690
+ // WITH_GENESYS
1691
+ ProfilerService.end( '_projectObject' );
1692
+ // !WITH_GENESYS
1693
+
1655
1694
  renderList.finish();
1656
1695
 
1657
1696
  if ( this.sortObjects === true ) {
@@ -1660,6 +1699,10 @@ class Renderer {
1660
1699
 
1661
1700
  }
1662
1701
 
1702
+ // WITH_GENESYS
1703
+ ProfilerService.end( 'buildRenderList' );
1704
+ // !WITH_GENESYS
1705
+
1663
1706
  //
1664
1707
 
1665
1708
  if ( renderTarget !== null ) {
@@ -1766,6 +1809,10 @@ class Renderer {
1766
1809
 
1767
1810
  //
1768
1811
 
1812
+ // WITH_GENESYS
1813
+ ProfilerService.end( 'Renderer._renderScene' );
1814
+ // !WITH_GENESYS
1815
+
1769
1816
  return renderContext;
1770
1817
 
1771
1818
  }
@@ -3248,6 +3295,10 @@ class Renderer {
3248
3295
  */
3249
3296
  _renderTransparents( renderList, doublePassList, camera, scene, lightsNode ) {
3250
3297
 
3298
+ // WITH_GENESYS
3299
+ ProfilerService.begin( '_renderTransparents' );
3300
+ // !WITH_GENESYS
3301
+
3251
3302
  if ( doublePassList.length > 0 ) {
3252
3303
 
3253
3304
  // render back side
@@ -3284,6 +3335,10 @@ class Renderer {
3284
3335
 
3285
3336
  }
3286
3337
 
3338
+ // WITH_GENESYS
3339
+ ProfilerService.end( '_renderTransparents' );
3340
+ // !WITH_GENESYS
3341
+
3287
3342
  }
3288
3343
 
3289
3344
  /**
@@ -3298,6 +3353,11 @@ class Renderer {
3298
3353
  */
3299
3354
  _renderObjects( renderList, camera, scene, lightsNode, passId = null ) {
3300
3355
 
3356
+ // WITH_GENESYS
3357
+ const label = `${this._currentRenderObjectFunction?.name || 'renderObject'} (${renderList.length})`;
3358
+ ProfilerService.begin( label );
3359
+ // !WITH_GENESYS
3360
+
3301
3361
  for ( let i = 0, il = renderList.length; i < il; i ++ ) {
3302
3362
 
3303
3363
  const { object, geometry, material, group, clippingContext } = renderList[ i ];
@@ -3306,6 +3366,10 @@ class Renderer {
3306
3366
 
3307
3367
  }
3308
3368
 
3369
+ // WITH_GENESYS
3370
+ ProfilerService.end( label );
3371
+ // !WITH_GENESYS
3372
+
3309
3373
  }
3310
3374
 
3311
3375
  /**