@gnsx/three 0.186.5 → 0.186.7
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/build/three.webgpu.js +1454 -917
- package/build/three.webgpu.nodes.js +1454 -917
- package/examples/jsm/inspector/tabs/Settings.js +9 -6
- package/package.json +1 -1
- package/src/materials/nodes/NodeMaterial.js +56 -16
- package/src/nodes/display/ComplexityDebug.js +56 -7
- package/src/nodes/display/DoubleSideDebug.js +152 -0
- package/src/nodes/display/DrawCallDebug.js +3 -2
- package/src/nodes/display/FrontBackFaceDebug.js +88 -0
- package/src/nodes/display/LightingDebug.js +3 -2
- package/src/nodes/display/ShadowCasterDebug.js +69 -0
- package/src/renderers/common/Background.js +3 -1
- package/src/renderers/common/RenderObject.js +1 -1
- package/src/renderers/common/RenderPipeline.js +34 -5
- package/src/renderers/common/Renderer.js +90 -8
- package/src/renderers/common/nodes/NodeManager.js +4 -4
- package/src/renderers/webgl-fallback/WebGLBackend.js +8 -2
- package/src/renderers/webgl-fallback/utils/WebGLState.js +37 -7
- package/src/renderers/webgpu/utils/WebGPUPipelineUtils.js +16 -6
|
@@ -4,6 +4,9 @@ import { vec4, renderOutput, context } from '../../nodes/TSL.js';
|
|
|
4
4
|
import { NoToneMapping } from '../../constants.js';
|
|
5
5
|
import QuadMesh from '../../renderers/common/QuadMesh.js';
|
|
6
6
|
import { warnOnce } from '../../utils.js';
|
|
7
|
+
// WITH_GENESYS
|
|
8
|
+
import { debugViewAccumulates, debugViewSkipsToneMapping } from '../../nodes/display/ComplexityDebug.js';
|
|
9
|
+
// !WITH_GENESYS
|
|
7
10
|
|
|
8
11
|
/**
|
|
9
12
|
* This module is responsible to manage the rendering pipeline setups in apps.
|
|
@@ -139,7 +142,12 @@ class RenderPipeline {
|
|
|
139
142
|
const outputColorSpace = renderer.outputColorSpace;
|
|
140
143
|
|
|
141
144
|
renderer.toneMapping = NoToneMapping;
|
|
142
|
-
|
|
145
|
+
|
|
146
|
+
// WITH_GENESYS
|
|
147
|
+
// Accumulating views colorize in the renderer's output pass, which must still encode the color space.
|
|
148
|
+
if ( debugViewAccumulates( renderer.debug.view ) !== true ) renderer.outputColorSpace = ColorManagement.workingColorSpace;
|
|
149
|
+
// !WITH_GENESYS
|
|
150
|
+
// renderer.outputColorSpace = ColorManagement.workingColorSpace;
|
|
143
151
|
|
|
144
152
|
//
|
|
145
153
|
|
|
@@ -215,19 +223,40 @@ class RenderPipeline {
|
|
|
215
223
|
*/
|
|
216
224
|
_update() {
|
|
217
225
|
|
|
218
|
-
|
|
226
|
+
// WITH_GENESYS
|
|
227
|
+
// Debug views drawn without tone mapping must match the direct path. An accumulating
|
|
228
|
+
// view copies the raw ratio here, and the renderer's output pass colorizes it.
|
|
229
|
+
const view = this.renderer.debug.view;
|
|
230
|
+
const toneMapping = debugViewSkipsToneMapping( view ) ? NoToneMapping : this.renderer.toneMapping;
|
|
231
|
+
const outputColorSpace = debugViewAccumulates( view ) ? ColorManagement.workingColorSpace : this.renderer.outputColorSpace;
|
|
232
|
+
|
|
233
|
+
if ( this._toneMapping !== toneMapping ) {
|
|
219
234
|
|
|
220
|
-
this._toneMapping =
|
|
235
|
+
this._toneMapping = toneMapping;
|
|
221
236
|
this.needsUpdate = true;
|
|
222
237
|
|
|
223
238
|
}
|
|
224
239
|
|
|
225
|
-
if ( this._outputColorSpace !==
|
|
240
|
+
if ( this._outputColorSpace !== outputColorSpace ) {
|
|
226
241
|
|
|
227
|
-
this._outputColorSpace =
|
|
242
|
+
this._outputColorSpace = outputColorSpace;
|
|
228
243
|
this.needsUpdate = true;
|
|
229
244
|
|
|
230
245
|
}
|
|
246
|
+
// !WITH_GENESYS
|
|
247
|
+
// if ( this._toneMapping !== this.renderer.toneMapping ) {
|
|
248
|
+
//
|
|
249
|
+
// this._toneMapping = this.renderer.toneMapping;
|
|
250
|
+
// this.needsUpdate = true;
|
|
251
|
+
//
|
|
252
|
+
// }
|
|
253
|
+
//
|
|
254
|
+
// if ( this._outputColorSpace !== this.renderer.outputColorSpace ) {
|
|
255
|
+
//
|
|
256
|
+
// this._outputColorSpace = this.renderer.outputColorSpace;
|
|
257
|
+
// this.needsUpdate = true;
|
|
258
|
+
//
|
|
259
|
+
// }
|
|
231
260
|
|
|
232
261
|
if ( this.needsUpdate === true ) {
|
|
233
262
|
|
|
@@ -30,15 +30,16 @@ import { Matrix4 } from '../../math/Matrix4.js';
|
|
|
30
30
|
import { Vector2 } from '../../math/Vector2.js';
|
|
31
31
|
import { Vector4 } from '../../math/Vector4.js';
|
|
32
32
|
import { RenderTarget } from '../../core/RenderTarget.js';
|
|
33
|
-
import { DoubleSide, BackSide, FrontSide, SRGBColorSpace, NoToneMapping, LinearFilter, HalfFloatType, RGBAFormat, PCFShadowMap, PCFSoftShadowMap, VSMShadowMap, RenderObjectRefreshType } from '../../constants.js';
|
|
33
|
+
import { DoubleSide, BackSide, FrontSide, EqualDepth, SRGBColorSpace, NoToneMapping, LinearFilter, HalfFloatType, RGBAFormat, PCFShadowMap, PCFSoftShadowMap, VSMShadowMap, RenderObjectRefreshType } from '../../constants.js';
|
|
34
34
|
|
|
35
35
|
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
39
|
import { ProfilerService } from '../../profiler/ProfilerService.js';
|
|
40
|
-
import {
|
|
41
|
-
import {
|
|
40
|
+
import { DEBUG_VIEW_NONE, DEFAULT_QUAD_OVERDRAW_BUDGET, DEFAULT_SHADER_COMPLEXITY_BUDGET, debugViewAccumulates, debugViewSkipsToneMapping } from '../../nodes/display/ComplexityDebug.js';
|
|
41
|
+
import { DEBUG_VIEW_DOUBLE_SIDE, meshCanHideOwnBack } from '../../nodes/display/DoubleSideDebug.js';
|
|
42
|
+
import { DEFAULT_BUFFER } from '../../nodes/display/BufferDebug.js';
|
|
42
43
|
// !WITH_GENESYS
|
|
43
44
|
import { reference } from '../../nodes/accessors/ReferenceNode.js';
|
|
44
45
|
import { highpModelNormalViewMatrix, highpModelViewMatrix } from '../../nodes/accessors/ModelNode.js';
|
|
@@ -745,7 +746,7 @@ class Renderer {
|
|
|
745
746
|
* @property {?Function} onNodeBuilderCreated - A callback function that is executed after a node builder has been created and before it is built.
|
|
746
747
|
* @property {?Function} onShaderError - A callback function that is executed when a shader error happens. Only supported with WebGL 2 right now.
|
|
747
748
|
* @property {Function} getShaderAsync - Allows the get the raw shader code for the given scene, camera and 3D object.
|
|
748
|
-
* @property {string} view - Debug view. `shaderComplexity`, `lightingComplexity`, `
|
|
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
750
|
* @property {string} buffer - Channel drawn by `bufferVisualization`: `baseColor`, `worldNormal`, `roughness`, `metallic`, `ambientOcclusion`, or `emissive`.
|
|
750
751
|
* @property {number} shaderComplexityBudget - Proxy budget that fills the shader-complexity ramp.
|
|
751
752
|
* @property {number} quadOverdrawBudget - Overlapping fragments that fill the quad-overdraw ramp.
|
|
@@ -768,6 +769,8 @@ class Renderer {
|
|
|
768
769
|
buffer: DEFAULT_BUFFER,
|
|
769
770
|
shaderComplexityBudget: DEFAULT_SHADER_COMPLEXITY_BUDGET,
|
|
770
771
|
quadOverdrawBudget: DEFAULT_QUAD_OVERDRAW_BUDGET,
|
|
772
|
+
doubleSideHidden: false,
|
|
773
|
+
doubleSideBack: false,
|
|
771
774
|
// !WITH_GENESYS
|
|
772
775
|
getShaderAsync: async ( scene, camera, object ) => {
|
|
773
776
|
|
|
@@ -1988,6 +1991,10 @@ class Renderer {
|
|
|
1988
1991
|
if ( this.opaque === true && opaqueObjects.length > 0 ) this._renderObjects( opaqueObjects, camera, sceneRef, lightsNode );
|
|
1989
1992
|
if ( this.transparent === true && transparentObjects.length > 0 ) this._renderTransparents( transparentObjects, transparentDoublePassObjects, camera, sceneRef, lightsNode );
|
|
1990
1993
|
|
|
1994
|
+
// WITH_GENESYS
|
|
1995
|
+
this._renderDoubleSideHidden( opaqueObjects, transparentObjects, camera, sceneRef, lightsNode );
|
|
1996
|
+
// !WITH_GENESYS
|
|
1997
|
+
|
|
1991
1998
|
// finish render pass
|
|
1992
1999
|
|
|
1993
2000
|
this.backend.finishRender( renderContext );
|
|
@@ -2705,7 +2712,8 @@ class Renderer {
|
|
|
2705
2712
|
|
|
2706
2713
|
// WITH_GENESYS
|
|
2707
2714
|
// Accumulating views write a scalar into an intermediate target, then the output pass colorizes it.
|
|
2708
|
-
|
|
2715
|
+
// Only screen output needs one. An off-screen target, such as a scene pass, already is the target.
|
|
2716
|
+
return useToneMapping || useColorSpace || ( debugViewAccumulates( this.debug.view ) && this.isOutputTarget );
|
|
2709
2717
|
// !WITH_GENESYS
|
|
2710
2718
|
// return useToneMapping || useColorSpace;
|
|
2711
2719
|
|
|
@@ -2759,9 +2767,7 @@ class Renderer {
|
|
|
2759
2767
|
get currentToneMapping() {
|
|
2760
2768
|
|
|
2761
2769
|
// WITH_GENESYS
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
if ( view === DEBUG_VIEW_SHADER_COMPLEXITY || view === DEBUG_VIEW_SHADER_COMPLEXITY_AND_QUADS || view === DEBUG_VIEW_LIGHTING_COMPLEXITY || view === DEBUG_VIEW_QUAD_OVERDRAW || view === DEBUG_VIEW_BUFFER ) {
|
|
2770
|
+
if ( debugViewSkipsToneMapping( this.debug.view ) ) {
|
|
2765
2771
|
|
|
2766
2772
|
return NoToneMapping;
|
|
2767
2773
|
|
|
@@ -3559,6 +3565,82 @@ class Renderer {
|
|
|
3559
3565
|
|
|
3560
3566
|
}
|
|
3561
3567
|
|
|
3568
|
+
// WITH_GENESYS
|
|
3569
|
+
/**
|
|
3570
|
+
* Paints a double-sided mesh red where its own front face is the nearest surface and the
|
|
3571
|
+
* mesh has faces pointing the other way. A different mesh in front keeps its own color.
|
|
3572
|
+
* A flat card has no opposing faces, so it stays gray or blue. A shadow pass is left alone.
|
|
3573
|
+
*
|
|
3574
|
+
* @private
|
|
3575
|
+
* @param {Array<Object>} opaqueObjects - The opaque render list.
|
|
3576
|
+
* @param {Array<Object>} transparentObjects - The transparent render list.
|
|
3577
|
+
* @param {Camera} camera - The camera.
|
|
3578
|
+
* @param {Scene} scene - The scene.
|
|
3579
|
+
* @param {LightsNode} lightsNode - The current lights node.
|
|
3580
|
+
*/
|
|
3581
|
+
_renderDoubleSideHidden( opaqueObjects, transparentObjects, camera, scene, lightsNode ) {
|
|
3582
|
+
|
|
3583
|
+
if ( this.debug.view !== DEBUG_VIEW_DOUBLE_SIDE ) return;
|
|
3584
|
+
|
|
3585
|
+
if ( scene.overrideMaterial !== null && scene.overrideMaterial.isShadowPassMaterial === true ) return;
|
|
3586
|
+
|
|
3587
|
+
const list = [];
|
|
3588
|
+
const saved = new Map();
|
|
3589
|
+
|
|
3590
|
+
const collect = ( objects ) => {
|
|
3591
|
+
|
|
3592
|
+
for ( let i = 0, l = objects.length; i < l; i ++ ) {
|
|
3593
|
+
|
|
3594
|
+
const entry = objects[ i ];
|
|
3595
|
+
const material = entry.material;
|
|
3596
|
+
const geometry = entry.object.geometry;
|
|
3597
|
+
|
|
3598
|
+
if ( entry.object.isMesh !== true || material.side !== DoubleSide || material.isShadowPassMaterial === true ) continue;
|
|
3599
|
+
|
|
3600
|
+
if ( geometry === undefined || meshCanHideOwnBack( geometry ) !== true ) continue;
|
|
3601
|
+
|
|
3602
|
+
list.push( entry );
|
|
3603
|
+
|
|
3604
|
+
if ( saved.has( material ) ) continue;
|
|
3605
|
+
|
|
3606
|
+
saved.set( material, {
|
|
3607
|
+
side: material.side,
|
|
3608
|
+
depthFunc: material.depthFunc,
|
|
3609
|
+
depthWrite: material.depthWrite
|
|
3610
|
+
} );
|
|
3611
|
+
|
|
3612
|
+
}
|
|
3613
|
+
|
|
3614
|
+
};
|
|
3615
|
+
|
|
3616
|
+
collect( opaqueObjects );
|
|
3617
|
+
collect( transparentObjects );
|
|
3618
|
+
|
|
3619
|
+
if ( list.length === 0 ) return;
|
|
3620
|
+
|
|
3621
|
+
for ( const material of saved.keys() ) {
|
|
3622
|
+
|
|
3623
|
+
material.side = FrontSide;
|
|
3624
|
+
material.depthFunc = EqualDepth;
|
|
3625
|
+
material.depthWrite = false;
|
|
3626
|
+
|
|
3627
|
+
}
|
|
3628
|
+
|
|
3629
|
+
this.debug.doubleSideHidden = true;
|
|
3630
|
+
this._renderObjects( list, camera, scene, lightsNode, 'doubleSideHidden' );
|
|
3631
|
+
this.debug.doubleSideHidden = false;
|
|
3632
|
+
|
|
3633
|
+
for ( const [ material, state ] of saved ) {
|
|
3634
|
+
|
|
3635
|
+
material.side = state.side;
|
|
3636
|
+
material.depthFunc = state.depthFunc;
|
|
3637
|
+
material.depthWrite = state.depthWrite;
|
|
3638
|
+
|
|
3639
|
+
}
|
|
3640
|
+
|
|
3641
|
+
}
|
|
3642
|
+
// !WITH_GENESYS
|
|
3643
|
+
|
|
3562
3644
|
/**
|
|
3563
3645
|
* Renders the transparent objects from the given render lists.
|
|
3564
3646
|
*
|
|
@@ -10,7 +10,7 @@ import { builtin } from '../../../nodes/accessors/BuiltinNode.js';
|
|
|
10
10
|
import { CubeUVReflectionMapping, EquirectangularReflectionMapping, EquirectangularRefractionMapping, NoToneMapping } from '../../../constants.js';
|
|
11
11
|
// WITH_GENESYS
|
|
12
12
|
import { vec4 } from '../../../nodes/tsl/TSLCore.js';
|
|
13
|
-
import { colorizeQuadOverdraw, colorizeShaderComplexity,
|
|
13
|
+
import { colorizeQuadOverdraw, colorizeShaderComplexity, DEBUG_VIEW_OVERDRAW, DEBUG_VIEW_SHADER_COMPLEXITY, DEBUG_VIEW_SHADER_COMPLEXITY_AND_OVERDRAW, SHADER_COMPLEXITY_QUAD_COUNT_SCALE } from '../../../nodes/display/ComplexityDebug.js';
|
|
14
14
|
// !WITH_GENESYS
|
|
15
15
|
import { hashArray } from '../../../nodes/core/NodeUtils.js';
|
|
16
16
|
import { error } from '../../../utils.js';
|
|
@@ -1035,9 +1035,9 @@ class NodeManager extends DataMap {
|
|
|
1035
1035
|
}
|
|
1036
1036
|
|
|
1037
1037
|
// WITH_GENESYS
|
|
1038
|
-
if ( renderer.debug.view === DEBUG_VIEW_SHADER_COMPLEXITY || renderer.debug.view ===
|
|
1038
|
+
if ( renderer.debug.view === DEBUG_VIEW_SHADER_COMPLEXITY || renderer.debug.view === DEBUG_VIEW_SHADER_COMPLEXITY_AND_OVERDRAW ) {
|
|
1039
1039
|
|
|
1040
|
-
const complexity = renderer.debug.view ===
|
|
1040
|
+
const complexity = renderer.debug.view === DEBUG_VIEW_SHADER_COMPLEXITY_AND_OVERDRAW
|
|
1041
1041
|
? sampled.r.mul( sampled.g ).mul( SHADER_COMPLEXITY_QUAD_COUNT_SCALE )
|
|
1042
1042
|
: sampled.r;
|
|
1043
1043
|
|
|
@@ -1045,7 +1045,7 @@ class NodeManager extends DataMap {
|
|
|
1045
1045
|
|
|
1046
1046
|
}
|
|
1047
1047
|
|
|
1048
|
-
if ( renderer.debug.view ===
|
|
1048
|
+
if ( renderer.debug.view === DEBUG_VIEW_OVERDRAW ) {
|
|
1049
1049
|
|
|
1050
1050
|
return vec4( colorizeQuadOverdraw( sampled.r ), 1 ).renderOutput( NoToneMapping, renderer.currentColorSpace );
|
|
1051
1051
|
|
|
@@ -1124,11 +1124,17 @@ class WebGLBackend extends Backend {
|
|
|
1124
1124
|
|
|
1125
1125
|
const frontFaceCW = ( object.isMesh && object.matrixWorld.determinantAffine() < 0 );
|
|
1126
1126
|
|
|
1127
|
-
|
|
1127
|
+
// WITH_GENESYS
|
|
1128
|
+
state.setMaterial( material, frontFaceCW, hardwareClippingPlanes, object );
|
|
1129
|
+
// !WITH_GENESYS
|
|
1130
|
+
// state.setMaterial( material, frontFaceCW, hardwareClippingPlanes );
|
|
1128
1131
|
|
|
1129
1132
|
if ( context.mrt !== null && context.textures !== null ) {
|
|
1130
1133
|
|
|
1131
|
-
|
|
1134
|
+
// WITH_GENESYS
|
|
1135
|
+
state.setMRTBlending( context.textures, context.mrt, material, object );
|
|
1136
|
+
// !WITH_GENESYS
|
|
1137
|
+
// state.setMRTBlending( context.textures, context.mrt, material );
|
|
1132
1138
|
|
|
1133
1139
|
}
|
|
1134
1140
|
|
|
@@ -12,7 +12,8 @@ import { Color } from '../../../math/Color.js';
|
|
|
12
12
|
import { Vector4 } from '../../../math/Vector4.js';
|
|
13
13
|
import { error, ReversedDepthFuncs, warnOnce } from '../../../utils.js';
|
|
14
14
|
// WITH_GENESYS
|
|
15
|
-
import {
|
|
15
|
+
import { debugDrawAccumulates, debugDrawReplacesCost } from '../../../nodes/display/ComplexityDebug.js';
|
|
16
|
+
import { DEBUG_VIEW_FRONT_BACK_FACE } from '../../../nodes/display/FrontBackFaceDebug.js';
|
|
16
17
|
// !WITH_GENESYS
|
|
17
18
|
|
|
18
19
|
let equationToGL, factorToGL;
|
|
@@ -288,7 +289,7 @@ class WebGLState {
|
|
|
288
289
|
|
|
289
290
|
}
|
|
290
291
|
|
|
291
|
-
setMRTBlending( textures, mrt, material ) {
|
|
292
|
+
setMRTBlending( textures, mrt, material, object = null ) {
|
|
292
293
|
|
|
293
294
|
const gl = this.gl;
|
|
294
295
|
const drawBuffersIndexedExt = this.backend.drawBuffersIndexedExt;
|
|
@@ -301,6 +302,24 @@ class WebGLState {
|
|
|
301
302
|
|
|
302
303
|
}
|
|
303
304
|
|
|
305
|
+
// WITH_GENESYS
|
|
306
|
+
// Every attachment matches the single-target path. Opaque material blending would replace a sum that should add.
|
|
307
|
+
if ( debugDrawAccumulates( this.backend.renderer, material, object ) ) {
|
|
308
|
+
|
|
309
|
+
const dst = debugDrawReplacesCost( this.backend.renderer.debug.view, material ) ? gl.ZERO : gl.ONE;
|
|
310
|
+
|
|
311
|
+
for ( let i = 0; i < textures.length; i ++ ) {
|
|
312
|
+
|
|
313
|
+
drawBuffersIndexedExt.blendEquationSeparateiOES( i, gl.FUNC_ADD, gl.FUNC_ADD );
|
|
314
|
+
drawBuffersIndexedExt.blendFuncSeparateiOES( i, gl.ONE, dst, gl.ONE, gl.ZERO );
|
|
315
|
+
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
return;
|
|
319
|
+
|
|
320
|
+
}
|
|
321
|
+
// !WITH_GENESYS
|
|
322
|
+
|
|
304
323
|
for ( let i = 0; i < textures.length; i ++ ) {
|
|
305
324
|
|
|
306
325
|
const texture = textures[ i ];
|
|
@@ -923,14 +942,22 @@ class WebGLState {
|
|
|
923
942
|
* @param {Material} material - The material to configure the state for.
|
|
924
943
|
* @param {number} frontFaceCW - Whether the front faces are counter-clockwise or not.
|
|
925
944
|
* @param {number} hardwareClippingPlanes - The number of hardware clipping planes.
|
|
945
|
+
* @param {?Object3D} [object=null] - The object being drawn. Used by the accumulating debug views.
|
|
926
946
|
*/
|
|
927
|
-
setMaterial( material, frontFaceCW, hardwareClippingPlanes ) {
|
|
947
|
+
setMaterial( material, frontFaceCW, hardwareClippingPlanes, object = null ) {
|
|
928
948
|
|
|
929
949
|
const { gl } = this;
|
|
930
950
|
|
|
931
|
-
|
|
951
|
+
// WITH_GENESYS
|
|
952
|
+
const drawBothSides = material.side === DoubleSide || ( this.backend.renderer.debug.view === DEBUG_VIEW_FRONT_BACK_FACE && material.isShadowPassMaterial !== true );
|
|
953
|
+
|
|
954
|
+
drawBothSides
|
|
932
955
|
? this.disable( gl.CULL_FACE )
|
|
933
956
|
: this.enable( gl.CULL_FACE );
|
|
957
|
+
// !WITH_GENESYS
|
|
958
|
+
// material.side === DoubleSide
|
|
959
|
+
// ? this.disable( gl.CULL_FACE )
|
|
960
|
+
// : this.enable( gl.CULL_FACE );
|
|
934
961
|
|
|
935
962
|
let flipSided = ( material.side === BackSide );
|
|
936
963
|
if ( frontFaceCW ) flipSided = ! flipSided;
|
|
@@ -938,10 +965,13 @@ class WebGLState {
|
|
|
938
965
|
this.setFlipSided( flipSided );
|
|
939
966
|
|
|
940
967
|
// WITH_GENESYS
|
|
941
|
-
// WebGL has no cached render pipeline.
|
|
942
|
-
|
|
968
|
+
// WebGL has no cached render pipeline. The accumulate blend is applied on each draw instead.
|
|
969
|
+
// Alpha is replaced so it stays coverage, as in a shaded pass, for later compositing.
|
|
970
|
+
if ( debugDrawAccumulates( this.backend.renderer, material, object ) ) {
|
|
971
|
+
|
|
972
|
+
const dstFactor = debugDrawReplacesCost( this.backend.renderer.debug.view, material ) ? ZeroFactor : OneFactor;
|
|
943
973
|
|
|
944
|
-
this.setBlending(
|
|
974
|
+
this.setBlending( CustomBlending, AddEquation, OneFactor, dstFactor, AddEquation, OneFactor, ZeroFactor, material.blendColor, material.blendAlpha, true );
|
|
945
975
|
|
|
946
976
|
} else if ( material.blending === NormalBlending && material.transparent === false ) {
|
|
947
977
|
|
|
@@ -16,7 +16,8 @@ import {
|
|
|
16
16
|
|
|
17
17
|
import { error, ReversedDepthFuncs, warn, warnOnce } from '../../../utils.js';
|
|
18
18
|
// WITH_GENESYS
|
|
19
|
-
import {
|
|
19
|
+
import { debugDrawAccumulates, debugDrawReplacesCost } from '../../../nodes/display/ComplexityDebug.js';
|
|
20
|
+
import { DEBUG_VIEW_FRONT_BACK_FACE } from '../../../nodes/display/FrontBackFaceDebug.js';
|
|
20
21
|
// !WITH_GENESYS
|
|
21
22
|
|
|
22
23
|
import GPUComputePipelineDescriptor from '../descriptors/GPUComputePipelineDescriptor.js';
|
|
@@ -110,18 +111,22 @@ class WebGPUPipelineUtils {
|
|
|
110
111
|
}
|
|
111
112
|
|
|
112
113
|
// WITH_GENESYS
|
|
113
|
-
//
|
|
114
|
-
|
|
114
|
+
// Quad overdraw and translucent shader complexity add. Opaque shader complexity replaces
|
|
115
|
+
// the stored cost, so the nearest surface wins without a depth pre-pass.
|
|
116
|
+
// Alpha is replaced so it stays coverage, as in a shaded pass, for later compositing.
|
|
117
|
+
if ( debugDrawAccumulates( backend.renderer, material, object ) ) {
|
|
118
|
+
|
|
119
|
+
const replaceCost = debugDrawReplacesCost( backend.renderer.debug.view, material );
|
|
115
120
|
|
|
116
121
|
materialBlending = {
|
|
117
122
|
color: {
|
|
118
123
|
srcFactor: GPUBlendFactor.One,
|
|
119
|
-
dstFactor: GPUBlendFactor.One,
|
|
124
|
+
dstFactor: replaceCost ? GPUBlendFactor.Zero : GPUBlendFactor.One,
|
|
120
125
|
operation: GPUBlendOperation.Add
|
|
121
126
|
},
|
|
122
127
|
alpha: {
|
|
123
128
|
srcFactor: GPUBlendFactor.One,
|
|
124
|
-
dstFactor: GPUBlendFactor.
|
|
129
|
+
dstFactor: GPUBlendFactor.Zero,
|
|
125
130
|
operation: GPUBlendOperation.Add
|
|
126
131
|
}
|
|
127
132
|
};
|
|
@@ -942,7 +947,12 @@ class WebGPUPipelineUtils {
|
|
|
942
947
|
|
|
943
948
|
//
|
|
944
949
|
|
|
945
|
-
|
|
950
|
+
// WITH_GENESYS
|
|
951
|
+
// Front/back face draws both windings. Depth still hides a face behind the shell.
|
|
952
|
+
const drawBothSides = material.side === DoubleSide || ( this.backend.renderer.debug.view === DEBUG_VIEW_FRONT_BACK_FACE && material.isShadowPassMaterial !== true );
|
|
953
|
+
descriptor.cullMode = drawBothSides ? GPUCullMode.None : GPUCullMode.Back;
|
|
954
|
+
// !WITH_GENESYS
|
|
955
|
+
// descriptor.cullMode = ( material.side === DoubleSide ) ? GPUCullMode.None : GPUCullMode.Back;
|
|
946
956
|
|
|
947
957
|
return descriptor;
|
|
948
958
|
|