@gnsx/three 0.186.8 → 0.186.9

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.
@@ -28570,7 +28570,15 @@ class BatchedMesh extends Mesh {
28570
28570
  // the vertices to draw (3 lines per triangle) so we multiply the draw counts / starts and make
28571
28571
  // assumptions about the index buffer byte size.
28572
28572
  let multiDrawMultiplier = 1;
28573
- if ( material.wireframe ) {
28573
+ // WITH_GENESYS
28574
+ // Same rule as materialDrawsWireframe, inlined so this core class does not import the node library.
28575
+ // A legacy renderer has no debug view, so only the material flag applies there.
28576
+ const debugView = renderer !== null && renderer !== undefined && renderer.debug !== undefined ? renderer.debug.view : undefined;
28577
+ const wireframe = material.wireframe === true || ( debugView === 'wireframe' && material.isShadowPassMaterial !== true && material.allowOverride !== false );
28578
+ // !WITH_GENESYS
28579
+ // const wireframe = material.wireframe === true;
28580
+
28581
+ if ( wireframe ) {
28574
28582
 
28575
28583
  multiDrawMultiplier = 2;
28576
28584
  bytesPerElement = geometry.attributes.position.count > 65535 ? 4 : 2;
@@ -32456,6 +32456,69 @@ class ChainMap {
32456
32456
 
32457
32457
  }
32458
32458
 
32459
+ // WITH_GENESYS
32460
+ // Wireframe debug view. Scene meshes are drawn as lines. Lighting is unchanged.
32461
+ // !WITH_GENESYS
32462
+
32463
+ /**
32464
+ * Wireframe. Each scene mesh is drawn as lines along its triangle edges.
32465
+ * Lighting, color, and tone mapping stay the same as the shaded view.
32466
+ * Shadow passes and fullscreen quads stay triangles.
32467
+ *
32468
+ * @type {string}
32469
+ */
32470
+ const DEBUG_VIEW_WIREFRAME = 'wireframe';
32471
+
32472
+ /**
32473
+ * Whether the wireframe debug view should take over this draw.
32474
+ * Shadow passes stay triangles so shadows still cover the surface. Fullscreen quads stay
32475
+ * triangles so post-processing still fills the screen. A material with `allowOverride`
32476
+ * false (the renderer skybox) stays shaded behind the edges.
32477
+ *
32478
+ * @param {Material} material - The material being drawn.
32479
+ * @param {?Renderer} renderer - The renderer. May be null.
32480
+ * @param {?Object3D} [object=null] - The object being drawn.
32481
+ * @return {boolean} `true` when the debug view forces a wireframe.
32482
+ */
32483
+ function debugViewForcesWireframe( material, renderer, object = null ) {
32484
+
32485
+ const debug = renderer !== null && renderer !== undefined ? renderer.debug : undefined;
32486
+
32487
+ if ( debug === undefined || debug.view !== DEBUG_VIEW_WIREFRAME ) return false;
32488
+
32489
+ if ( material.isShadowPassMaterial === true ) return false;
32490
+
32491
+ if ( material.allowOverride === false ) return false;
32492
+
32493
+ // Lines and points already draw as lines. Rewriting their index as triangle edges
32494
+ // would skip vertices. Quad meshes are fullscreen passes.
32495
+ if ( object === null || object === undefined || object.isMesh !== true || object.isQuadMesh === true ) return false;
32496
+
32497
+ return true;
32498
+
32499
+ }
32500
+
32501
+ /**
32502
+ * Whether this draw should use line topology.
32503
+ * A material that already sets `wireframe` stays a wireframe in every view.
32504
+ * The wireframe debug view forces it for scene meshes. A renderer without `debug`
32505
+ * (the legacy WebGL renderer) only honors the material flag.
32506
+ *
32507
+ * @param {Material} material - The material being drawn.
32508
+ * @param {?Renderer} renderer - The renderer. May be null.
32509
+ * @param {?Object3D} [object=null] - The object being drawn.
32510
+ * @return {boolean} `true` when the draw is lines.
32511
+ */
32512
+ function materialDrawsWireframe( material, renderer, object = null ) {
32513
+
32514
+ if ( material.wireframe === true ) return true;
32515
+
32516
+ return debugViewForcesWireframe( material, renderer, object );
32517
+
32518
+ }
32519
+
32520
+ // !WITH_GENESYS
32521
+
32459
32522
  let _id$a = 0;
32460
32523
  const _protoKeysCache = new WeakMap();
32461
32524
 
@@ -33090,7 +33153,12 @@ class RenderObject {
33090
33153
 
33091
33154
  let rangeFactor = 1;
33092
33155
 
33093
- if ( material.wireframe === true && ! object.isPoints && ! object.isLineSegments && ! object.isLine && ! object.isLineLoop ) {
33156
+ // WITH_GENESYS
33157
+ const wireframe = materialDrawsWireframe( material, this.renderer, object );
33158
+ // !WITH_GENESYS
33159
+ // const wireframe = material.wireframe === true;
33160
+
33161
+ if ( wireframe === true && ! object.isPoints && ! object.isLineSegments && ! object.isLine && ! object.isLineLoop ) {
33094
33162
 
33095
33163
  rangeFactor = 2;
33096
33164
 
@@ -33978,6 +34046,8 @@ class Attributes extends DataMap {
33978
34046
 
33979
34047
  }
33980
34048
 
34049
+ // !WITH_GENESYS
34050
+
33981
34051
  /**
33982
34052
  * Returns the wireframe version for the given geometry.
33983
34053
  *
@@ -34345,7 +34415,12 @@ class Geometries extends DataMap {
34345
34415
 
34346
34416
  let index = geometry.index;
34347
34417
 
34348
- if ( material.wireframe === true ) {
34418
+ // WITH_GENESYS
34419
+ const wireframe = materialDrawsWireframe( material, renderObject.renderer, renderObject.object );
34420
+ // !WITH_GENESYS
34421
+ // const wireframe = material.wireframe === true;
34422
+
34423
+ if ( wireframe === true ) {
34349
34424
 
34350
34425
  const wireframes = this.wireframes;
34351
34426
 
@@ -64787,7 +64862,7 @@ class Renderer {
64787
64862
  * @property {?Function} onNodeBuilderCreated - A callback function that is executed after a node builder has been created and before it is built.
64788
64863
  * @property {?Function} onShaderError - A callback function that is executed when a shader error happens. Only supported with WebGL 2 right now.
64789
64864
  * @property {Function} getShaderAsync - Allows the get the raw shader code for the given scene, camera and 3D object.
64790
- * @property {string} view - Debug view. `shaderComplexity`, `lightingComplexity`, `overdraw`, and `shaderComplexityAndOverdraw` replace the shaded color with a heatmap. `shaderComplexityAndOverdraw` multiplies the shader cost by the overdraw count. `bufferVisualization` shows one material channel. `lightingOnly` and `detailLighting` light a flat gray surface. `drawCall` lights each submitted draw with its own diffuse color. `frontBackFace` draws both windings and tints the side facing the camera. `shadowCaster` lights a mesh green when it casts shadows and gray when it does not. `doubleSide` lights a single-sided surface gray, a visible double-sided back face blue, and a hidden double-sided back face red.
64865
+ * @property {string} view - Debug view. `shaderComplexity`, `lightingComplexity`, `overdraw`, and `shaderComplexityAndOverdraw` replace the shaded color with a heatmap. `shaderComplexityAndOverdraw` multiplies the shader cost by the overdraw count. `bufferVisualization` shows one material channel. `lightingOnly` and `detailLighting` light a flat gray surface. `drawCall` lights each submitted draw with its own diffuse color. `frontBackFace` draws both windings and tints the side facing the camera. `shadowCaster` lights a mesh green when it casts shadows and gray when it does not. `doubleSide` lights a single-sided surface gray, a visible double-sided back face blue, and a hidden double-sided back face red. `wireframe` draws each mesh as lines along its triangle edges. Lighting stays the same as the shaded view. Shadow passes and fullscreen quads stay triangles.
64791
64866
  * @property {string} buffer - Channel drawn by `bufferVisualization`: `baseColor`, `worldNormal`, `roughness`, `metallic`, `ambientOcclusion`, or `emissive`.
64792
64867
  * @property {number} shaderComplexityBudget - Proxy budget that fills the shader-complexity ramp.
64793
64868
  * @property {number} quadOverdrawBudget - Overlapping fragments that fill the quad-overdraw ramp.
@@ -77976,9 +78051,16 @@ class WebGLBackend extends Backend {
77976
78051
  else if ( object.isLineLoop ) renderer.mode = gl.LINE_LOOP;
77977
78052
  else {
77978
78053
 
77979
- if ( material.wireframe === true ) {
78054
+ // WITH_GENESYS
78055
+ const wireframe = materialDrawsWireframe( material, this.renderer, object );
78056
+ const linewidth = material.wireframeLinewidth !== undefined ? material.wireframeLinewidth : 1;
78057
+ // !WITH_GENESYS
78058
+ // const wireframe = material.wireframe === true;
78059
+ // const linewidth = material.wireframeLinewidth;
78060
+
78061
+ if ( wireframe === true ) {
77980
78062
 
77981
- state.setLineWidth( material.wireframeLinewidth * this.renderer.getPixelRatio() );
78063
+ state.setLineWidth( linewidth * this.renderer.getPixelRatio() );
77982
78064
  renderer.mode = gl.LINES;
77983
78065
 
77984
78066
  } else {
@@ -80216,6 +80298,8 @@ class NodeStorageBuffer extends StorageBuffer {
80216
80298
 
80217
80299
  }
80218
80300
 
80301
+ // !WITH_GENESYS
80302
+
80219
80303
  const _commandList = [ null ];
80220
80304
 
80221
80305
  /**
@@ -80430,7 +80514,10 @@ class WebGPUUtils {
80430
80514
  getPrimitiveTopology( object, material ) {
80431
80515
 
80432
80516
  if ( object.isPoints ) return GPUPrimitiveTopology.PointList;
80433
- else if ( object.isLineSegments || ( object.isMesh && material.wireframe === true ) ) return GPUPrimitiveTopology.LineList;
80517
+ // WITH_GENESYS
80518
+ else if ( object.isLineSegments || ( object.isMesh && materialDrawsWireframe( material, this.backend.renderer, object ) ) ) return GPUPrimitiveTopology.LineList;
80519
+ // !WITH_GENESYS
80520
+ // else if ( object.isLineSegments || ( object.isMesh && material.wireframe === true ) ) return GPUPrimitiveTopology.LineList;
80434
80521
  else if ( object.isLine ) return GPUPrimitiveTopology.LineStrip;
80435
80522
  else if ( object.isMesh ) return GPUPrimitiveTopology.TriangleList;
80436
80523
 
@@ -32456,6 +32456,69 @@ class ChainMap {
32456
32456
 
32457
32457
  }
32458
32458
 
32459
+ // WITH_GENESYS
32460
+ // Wireframe debug view. Scene meshes are drawn as lines. Lighting is unchanged.
32461
+ // !WITH_GENESYS
32462
+
32463
+ /**
32464
+ * Wireframe. Each scene mesh is drawn as lines along its triangle edges.
32465
+ * Lighting, color, and tone mapping stay the same as the shaded view.
32466
+ * Shadow passes and fullscreen quads stay triangles.
32467
+ *
32468
+ * @type {string}
32469
+ */
32470
+ const DEBUG_VIEW_WIREFRAME = 'wireframe';
32471
+
32472
+ /**
32473
+ * Whether the wireframe debug view should take over this draw.
32474
+ * Shadow passes stay triangles so shadows still cover the surface. Fullscreen quads stay
32475
+ * triangles so post-processing still fills the screen. A material with `allowOverride`
32476
+ * false (the renderer skybox) stays shaded behind the edges.
32477
+ *
32478
+ * @param {Material} material - The material being drawn.
32479
+ * @param {?Renderer} renderer - The renderer. May be null.
32480
+ * @param {?Object3D} [object=null] - The object being drawn.
32481
+ * @return {boolean} `true` when the debug view forces a wireframe.
32482
+ */
32483
+ function debugViewForcesWireframe( material, renderer, object = null ) {
32484
+
32485
+ const debug = renderer !== null && renderer !== undefined ? renderer.debug : undefined;
32486
+
32487
+ if ( debug === undefined || debug.view !== DEBUG_VIEW_WIREFRAME ) return false;
32488
+
32489
+ if ( material.isShadowPassMaterial === true ) return false;
32490
+
32491
+ if ( material.allowOverride === false ) return false;
32492
+
32493
+ // Lines and points already draw as lines. Rewriting their index as triangle edges
32494
+ // would skip vertices. Quad meshes are fullscreen passes.
32495
+ if ( object === null || object === undefined || object.isMesh !== true || object.isQuadMesh === true ) return false;
32496
+
32497
+ return true;
32498
+
32499
+ }
32500
+
32501
+ /**
32502
+ * Whether this draw should use line topology.
32503
+ * A material that already sets `wireframe` stays a wireframe in every view.
32504
+ * The wireframe debug view forces it for scene meshes. A renderer without `debug`
32505
+ * (the legacy WebGL renderer) only honors the material flag.
32506
+ *
32507
+ * @param {Material} material - The material being drawn.
32508
+ * @param {?Renderer} renderer - The renderer. May be null.
32509
+ * @param {?Object3D} [object=null] - The object being drawn.
32510
+ * @return {boolean} `true` when the draw is lines.
32511
+ */
32512
+ function materialDrawsWireframe( material, renderer, object = null ) {
32513
+
32514
+ if ( material.wireframe === true ) return true;
32515
+
32516
+ return debugViewForcesWireframe( material, renderer, object );
32517
+
32518
+ }
32519
+
32520
+ // !WITH_GENESYS
32521
+
32459
32522
  let _id$a = 0;
32460
32523
  const _protoKeysCache = new WeakMap();
32461
32524
 
@@ -33090,7 +33153,12 @@ class RenderObject {
33090
33153
 
33091
33154
  let rangeFactor = 1;
33092
33155
 
33093
- if ( material.wireframe === true && ! object.isPoints && ! object.isLineSegments && ! object.isLine && ! object.isLineLoop ) {
33156
+ // WITH_GENESYS
33157
+ const wireframe = materialDrawsWireframe( material, this.renderer, object );
33158
+ // !WITH_GENESYS
33159
+ // const wireframe = material.wireframe === true;
33160
+
33161
+ if ( wireframe === true && ! object.isPoints && ! object.isLineSegments && ! object.isLine && ! object.isLineLoop ) {
33094
33162
 
33095
33163
  rangeFactor = 2;
33096
33164
 
@@ -33978,6 +34046,8 @@ class Attributes extends DataMap {
33978
34046
 
33979
34047
  }
33980
34048
 
34049
+ // !WITH_GENESYS
34050
+
33981
34051
  /**
33982
34052
  * Returns the wireframe version for the given geometry.
33983
34053
  *
@@ -34345,7 +34415,12 @@ class Geometries extends DataMap {
34345
34415
 
34346
34416
  let index = geometry.index;
34347
34417
 
34348
- if ( material.wireframe === true ) {
34418
+ // WITH_GENESYS
34419
+ const wireframe = materialDrawsWireframe( material, renderObject.renderer, renderObject.object );
34420
+ // !WITH_GENESYS
34421
+ // const wireframe = material.wireframe === true;
34422
+
34423
+ if ( wireframe === true ) {
34349
34424
 
34350
34425
  const wireframes = this.wireframes;
34351
34426
 
@@ -64787,7 +64862,7 @@ class Renderer {
64787
64862
  * @property {?Function} onNodeBuilderCreated - A callback function that is executed after a node builder has been created and before it is built.
64788
64863
  * @property {?Function} onShaderError - A callback function that is executed when a shader error happens. Only supported with WebGL 2 right now.
64789
64864
  * @property {Function} getShaderAsync - Allows the get the raw shader code for the given scene, camera and 3D object.
64790
- * @property {string} view - Debug view. `shaderComplexity`, `lightingComplexity`, `overdraw`, and `shaderComplexityAndOverdraw` replace the shaded color with a heatmap. `shaderComplexityAndOverdraw` multiplies the shader cost by the overdraw count. `bufferVisualization` shows one material channel. `lightingOnly` and `detailLighting` light a flat gray surface. `drawCall` lights each submitted draw with its own diffuse color. `frontBackFace` draws both windings and tints the side facing the camera. `shadowCaster` lights a mesh green when it casts shadows and gray when it does not. `doubleSide` lights a single-sided surface gray, a visible double-sided back face blue, and a hidden double-sided back face red.
64865
+ * @property {string} view - Debug view. `shaderComplexity`, `lightingComplexity`, `overdraw`, and `shaderComplexityAndOverdraw` replace the shaded color with a heatmap. `shaderComplexityAndOverdraw` multiplies the shader cost by the overdraw count. `bufferVisualization` shows one material channel. `lightingOnly` and `detailLighting` light a flat gray surface. `drawCall` lights each submitted draw with its own diffuse color. `frontBackFace` draws both windings and tints the side facing the camera. `shadowCaster` lights a mesh green when it casts shadows and gray when it does not. `doubleSide` lights a single-sided surface gray, a visible double-sided back face blue, and a hidden double-sided back face red. `wireframe` draws each mesh as lines along its triangle edges. Lighting stays the same as the shaded view. Shadow passes and fullscreen quads stay triangles.
64791
64866
  * @property {string} buffer - Channel drawn by `bufferVisualization`: `baseColor`, `worldNormal`, `roughness`, `metallic`, `ambientOcclusion`, or `emissive`.
64792
64867
  * @property {number} shaderComplexityBudget - Proxy budget that fills the shader-complexity ramp.
64793
64868
  * @property {number} quadOverdrawBudget - Overlapping fragments that fill the quad-overdraw ramp.
@@ -77976,9 +78051,16 @@ class WebGLBackend extends Backend {
77976
78051
  else if ( object.isLineLoop ) renderer.mode = gl.LINE_LOOP;
77977
78052
  else {
77978
78053
 
77979
- if ( material.wireframe === true ) {
78054
+ // WITH_GENESYS
78055
+ const wireframe = materialDrawsWireframe( material, this.renderer, object );
78056
+ const linewidth = material.wireframeLinewidth !== undefined ? material.wireframeLinewidth : 1;
78057
+ // !WITH_GENESYS
78058
+ // const wireframe = material.wireframe === true;
78059
+ // const linewidth = material.wireframeLinewidth;
78060
+
78061
+ if ( wireframe === true ) {
77980
78062
 
77981
- state.setLineWidth( material.wireframeLinewidth * this.renderer.getPixelRatio() );
78063
+ state.setLineWidth( linewidth * this.renderer.getPixelRatio() );
77982
78064
  renderer.mode = gl.LINES;
77983
78065
 
77984
78066
  } else {
@@ -80216,6 +80298,8 @@ class NodeStorageBuffer extends StorageBuffer {
80216
80298
 
80217
80299
  }
80218
80300
 
80301
+ // !WITH_GENESYS
80302
+
80219
80303
  const _commandList = [ null ];
80220
80304
 
80221
80305
  /**
@@ -80430,7 +80514,10 @@ class WebGPUUtils {
80430
80514
  getPrimitiveTopology( object, material ) {
80431
80515
 
80432
80516
  if ( object.isPoints ) return GPUPrimitiveTopology.PointList;
80433
- else if ( object.isLineSegments || ( object.isMesh && material.wireframe === true ) ) return GPUPrimitiveTopology.LineList;
80517
+ // WITH_GENESYS
80518
+ else if ( object.isLineSegments || ( object.isMesh && materialDrawsWireframe( material, this.backend.renderer, object ) ) ) return GPUPrimitiveTopology.LineList;
80519
+ // !WITH_GENESYS
80520
+ // else if ( object.isLineSegments || ( object.isMesh && material.wireframe === true ) ) return GPUPrimitiveTopology.LineList;
80434
80521
  else if ( object.isLine ) return GPUPrimitiveTopology.LineStrip;
80435
80522
  else if ( object.isMesh ) return GPUPrimitiveTopology.TriangleList;
80436
80523
 
@@ -143,6 +143,7 @@ class Settings extends Parameters {
143
143
  this._bufferState = bufferState;
144
144
  this._debugViewControl = modesGroup.add( debugViewState, 'view', {
145
145
  'Shaded': 'none',
146
+ 'Wireframe': 'wireframe',
146
147
  'Draw Call': 'drawCall',
147
148
  'Shader Complexity': 'shaderComplexity',
148
149
  'Lighting Complexity': 'lightingComplexity',
@@ -164,7 +165,7 @@ class Settings extends Parameters {
164
165
  this._syncBufferRow( view );
165
166
  window.dispatchEvent( new Event( 'genesys-debug-view' ) );
166
167
 
167
- } ).info( 'Shaded color, a cost heatmap, per-pixel overdraw, shader cost times overdraw, one material channel, lighting on a flat gray surface, one lit color per draw, a tint for the front and back of each face, green and gray for objects that do and do not cast shadows, or red where a double-sided back face is hidden. The Overdraw toggle above draws on top when both are enabled.' );
168
+ } ).info( 'Shaded color, mesh edges with the same lighting, a cost heatmap, per-pixel overdraw, shader cost times overdraw, one material channel, lighting on a flat gray surface, one lit color per draw, a tint for the front and back of each face, green and gray for objects that do and do not cast shadows, or red where a double-sided back face is hidden. The Overdraw toggle above draws on top when both are enabled.' );
168
169
 
169
170
  this._bufferControl = modesGroup.add( bufferState, 'buffer', {
170
171
  'Base Color': 'baseColor',
@@ -195,7 +196,7 @@ class Settings extends Parameters {
195
196
  const renderer = this.inspector.getRenderer();
196
197
  const view = renderer !== null && renderer.debug !== undefined ? renderer.debug.view : null;
197
198
 
198
- if ( view === 'none' || view === 'shaderComplexity' || view === 'lightingComplexity' || view === 'overdraw' || view === 'shaderComplexityAndOverdraw' || view === 'bufferVisualization' || view === 'lightingOnly' || view === 'detailLighting' || view === 'drawCall' || view === 'frontBackFace' || view === 'shadowCaster' || view === 'doubleSide' ) {
199
+ if ( view === 'none' || view === 'wireframe' || view === 'shaderComplexity' || view === 'lightingComplexity' || view === 'overdraw' || view === 'shaderComplexityAndOverdraw' || view === 'bufferVisualization' || view === 'lightingOnly' || view === 'detailLighting' || view === 'drawCall' || view === 'frontBackFace' || view === 'shadowCaster' || view === 'doubleSide' ) {
199
200
 
200
201
  if ( this._debugViewState.view !== view ) {
201
202
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gnsx/three",
3
- "version": "0.186.8",
3
+ "version": "0.186.9",
4
4
  "description": "JavaScript 3D library",
5
5
  "type": "module",
6
6
  "main": "./build/three.module.js",
@@ -0,0 +1,60 @@
1
+ // WITH_GENESYS
2
+ // Wireframe debug view. Scene meshes are drawn as lines. Lighting is unchanged.
3
+ // !WITH_GENESYS
4
+
5
+ /**
6
+ * Wireframe. Each scene mesh is drawn as lines along its triangle edges.
7
+ * Lighting, color, and tone mapping stay the same as the shaded view.
8
+ * Shadow passes and fullscreen quads stay triangles.
9
+ *
10
+ * @type {string}
11
+ */
12
+ export const DEBUG_VIEW_WIREFRAME = 'wireframe';
13
+
14
+ /**
15
+ * Whether the wireframe debug view should take over this draw.
16
+ * Shadow passes stay triangles so shadows still cover the surface. Fullscreen quads stay
17
+ * triangles so post-processing still fills the screen. A material with `allowOverride`
18
+ * false (the renderer skybox) stays shaded behind the edges.
19
+ *
20
+ * @param {Material} material - The material being drawn.
21
+ * @param {?Renderer} renderer - The renderer. May be null.
22
+ * @param {?Object3D} [object=null] - The object being drawn.
23
+ * @return {boolean} `true` when the debug view forces a wireframe.
24
+ */
25
+ export function debugViewForcesWireframe( material, renderer, object = null ) {
26
+
27
+ const debug = renderer !== null && renderer !== undefined ? renderer.debug : undefined;
28
+
29
+ if ( debug === undefined || debug.view !== DEBUG_VIEW_WIREFRAME ) return false;
30
+
31
+ if ( material.isShadowPassMaterial === true ) return false;
32
+
33
+ if ( material.allowOverride === false ) return false;
34
+
35
+ // Lines and points already draw as lines. Rewriting their index as triangle edges
36
+ // would skip vertices. Quad meshes are fullscreen passes.
37
+ if ( object === null || object === undefined || object.isMesh !== true || object.isQuadMesh === true ) return false;
38
+
39
+ return true;
40
+
41
+ }
42
+
43
+ /**
44
+ * Whether this draw should use line topology.
45
+ * A material that already sets `wireframe` stays a wireframe in every view.
46
+ * The wireframe debug view forces it for scene meshes. A renderer without `debug`
47
+ * (the legacy WebGL renderer) only honors the material flag.
48
+ *
49
+ * @param {Material} material - The material being drawn.
50
+ * @param {?Renderer} renderer - The renderer. May be null.
51
+ * @param {?Object3D} [object=null] - The object being drawn.
52
+ * @return {boolean} `true` when the draw is lines.
53
+ */
54
+ export function materialDrawsWireframe( material, renderer, object = null ) {
55
+
56
+ if ( material.wireframe === true ) return true;
57
+
58
+ return debugViewForcesWireframe( material, renderer, object );
59
+
60
+ }
@@ -1540,7 +1540,15 @@ class BatchedMesh extends Mesh {
1540
1540
  // the vertices to draw (3 lines per triangle) so we multiply the draw counts / starts and make
1541
1541
  // assumptions about the index buffer byte size.
1542
1542
  let multiDrawMultiplier = 1;
1543
- if ( material.wireframe ) {
1543
+ // WITH_GENESYS
1544
+ // Same rule as materialDrawsWireframe, inlined so this core class does not import the node library.
1545
+ // A legacy renderer has no debug view, so only the material flag applies there.
1546
+ const debugView = renderer !== null && renderer !== undefined && renderer.debug !== undefined ? renderer.debug.view : undefined;
1547
+ const wireframe = material.wireframe === true || ( debugView === 'wireframe' && material.isShadowPassMaterial !== true && material.allowOverride !== false );
1548
+ // !WITH_GENESYS
1549
+ // const wireframe = material.wireframe === true;
1550
+
1551
+ if ( wireframe ) {
1544
1552
 
1545
1553
  multiDrawMultiplier = 2;
1546
1554
  bytesPerElement = geometry.attributes.position.count > 65535 ? 4 : 2;
@@ -2,6 +2,9 @@ import DataMap from './DataMap.js';
2
2
  import { AttributeType } from './Constants.js';
3
3
 
4
4
  import { Uint16BufferAttribute, Uint32BufferAttribute } from '../../core/BufferAttribute.js';
5
+ // WITH_GENESYS
6
+ import { materialDrawsWireframe } from '../../nodes/display/WireframeDebug.js';
7
+ // !WITH_GENESYS
5
8
 
6
9
  /**
7
10
  * Returns the wireframe version for the given geometry.
@@ -370,7 +373,12 @@ class Geometries extends DataMap {
370
373
 
371
374
  let index = geometry.index;
372
375
 
373
- if ( material.wireframe === true ) {
376
+ // WITH_GENESYS
377
+ const wireframe = materialDrawsWireframe( material, renderObject.renderer, renderObject.object );
378
+ // !WITH_GENESYS
379
+ // const wireframe = material.wireframe === true;
380
+
381
+ if ( wireframe === true ) {
374
382
 
375
383
  const wireframes = this.wireframes;
376
384
 
@@ -1,4 +1,7 @@
1
1
  import { hash, hashString } from '../../nodes/core/NodeUtils.js';
2
+ // WITH_GENESYS
3
+ import { materialDrawsWireframe } from '../../nodes/display/WireframeDebug.js';
4
+ // !WITH_GENESYS
2
5
 
3
6
  let _id = 0;
4
7
  const _protoKeysCache = new WeakMap();
@@ -634,7 +637,12 @@ class RenderObject {
634
637
 
635
638
  let rangeFactor = 1;
636
639
 
637
- if ( material.wireframe === true && ! object.isPoints && ! object.isLineSegments && ! object.isLine && ! object.isLineLoop ) {
640
+ // WITH_GENESYS
641
+ const wireframe = materialDrawsWireframe( material, this.renderer, object );
642
+ // !WITH_GENESYS
643
+ // const wireframe = material.wireframe === true;
644
+
645
+ if ( wireframe === true && ! object.isPoints && ! object.isLineSegments && ! object.isLine && ! object.isLineLoop ) {
638
646
 
639
647
  rangeFactor = 2;
640
648
 
@@ -746,7 +746,7 @@ class Renderer {
746
746
  * @property {?Function} onNodeBuilderCreated - A callback function that is executed after a node builder has been created and before it is built.
747
747
  * @property {?Function} onShaderError - A callback function that is executed when a shader error happens. Only supported with WebGL 2 right now.
748
748
  * @property {Function} getShaderAsync - Allows the get the raw shader code for the given scene, camera and 3D object.
749
- * @property {string} view - Debug view. `shaderComplexity`, `lightingComplexity`, `overdraw`, and `shaderComplexityAndOverdraw` replace the shaded color with a heatmap. `shaderComplexityAndOverdraw` multiplies the shader cost by the overdraw count. `bufferVisualization` shows one material channel. `lightingOnly` and `detailLighting` light a flat gray surface. `drawCall` lights each submitted draw with its own diffuse color. `frontBackFace` draws both windings and tints the side facing the camera. `shadowCaster` lights a mesh green when it casts shadows and gray when it does not. `doubleSide` lights a single-sided surface gray, a visible double-sided back face blue, and a hidden double-sided back face red.
749
+ * @property {string} view - Debug view. `shaderComplexity`, `lightingComplexity`, `overdraw`, and `shaderComplexityAndOverdraw` replace the shaded color with a heatmap. `shaderComplexityAndOverdraw` multiplies the shader cost by the overdraw count. `bufferVisualization` shows one material channel. `lightingOnly` and `detailLighting` light a flat gray surface. `drawCall` lights each submitted draw with its own diffuse color. `frontBackFace` draws both windings and tints the side facing the camera. `shadowCaster` lights a mesh green when it casts shadows and gray when it does not. `doubleSide` lights a single-sided surface gray, a visible double-sided back face blue, and a hidden double-sided back face red. `wireframe` draws each mesh as lines along its triangle edges. Lighting stays the same as the shaded view. Shadow passes and fullscreen quads stay triangles.
750
750
  * @property {string} buffer - Channel drawn by `bufferVisualization`: `baseColor`, `worldNormal`, `roughness`, `metallic`, `ambientOcclusion`, or `emissive`.
751
751
  * @property {number} shaderComplexityBudget - Proxy budget that fills the shader-complexity ramp.
752
752
  * @property {number} quadOverdrawBudget - Overlapping fragments that fill the quad-overdraw ramp.
@@ -12,6 +12,9 @@ import { GLFeatureName } from './utils/WebGLConstants.js';
12
12
  import { WebGLBufferRenderer } from './WebGLBufferRenderer.js';
13
13
 
14
14
  import { isTypedArray, warnOnce, warn, error } from '../../utils.js';
15
+ // WITH_GENESYS
16
+ import { materialDrawsWireframe } from '../../nodes/display/WireframeDebug.js';
17
+ // !WITH_GENESYS
15
18
  import { WebGLCoordinateSystem, TimestampQuery, Compatibility } from '../../constants.js';
16
19
  import WebGLTimestampQueryPool from './utils/WebGLTimestampQueryPool.js';
17
20
 
@@ -1207,9 +1210,16 @@ class WebGLBackend extends Backend {
1207
1210
  else if ( object.isLineLoop ) renderer.mode = gl.LINE_LOOP;
1208
1211
  else {
1209
1212
 
1210
- if ( material.wireframe === true ) {
1213
+ // WITH_GENESYS
1214
+ const wireframe = materialDrawsWireframe( material, this.renderer, object );
1215
+ const linewidth = material.wireframeLinewidth !== undefined ? material.wireframeLinewidth : 1;
1216
+ // !WITH_GENESYS
1217
+ // const wireframe = material.wireframe === true;
1218
+ // const linewidth = material.wireframeLinewidth;
1219
+
1220
+ if ( wireframe === true ) {
1211
1221
 
1212
- state.setLineWidth( material.wireframeLinewidth * this.renderer.getPixelRatio() );
1222
+ state.setLineWidth( linewidth * this.renderer.getPixelRatio() );
1213
1223
  renderer.mode = gl.LINES;
1214
1224
 
1215
1225
  } else {
@@ -1,5 +1,8 @@
1
1
  import { HalfFloatType, UnsignedByteType } from '../../../constants.js';
2
2
  import { GPUPrimitiveTopology, GPUTextureFormat } from './WebGPUConstants.js';
3
+ // WITH_GENESYS
4
+ import { materialDrawsWireframe } from '../../../nodes/display/WireframeDebug.js';
5
+ // !WITH_GENESYS
3
6
 
4
7
  const _commandList = [ null ];
5
8
 
@@ -215,7 +218,10 @@ class WebGPUUtils {
215
218
  getPrimitiveTopology( object, material ) {
216
219
 
217
220
  if ( object.isPoints ) return GPUPrimitiveTopology.PointList;
218
- else if ( object.isLineSegments || ( object.isMesh && material.wireframe === true ) ) return GPUPrimitiveTopology.LineList;
221
+ // WITH_GENESYS
222
+ else if ( object.isLineSegments || ( object.isMesh && materialDrawsWireframe( material, this.backend.renderer, object ) ) ) return GPUPrimitiveTopology.LineList;
223
+ // !WITH_GENESYS
224
+ // else if ( object.isLineSegments || ( object.isMesh && material.wireframe === true ) ) return GPUPrimitiveTopology.LineList;
219
225
  else if ( object.isLine ) return GPUPrimitiveTopology.LineStrip;
220
226
  else if ( object.isMesh ) return GPUPrimitiveTopology.TriangleList;
221
227