@gnsx/three 0.184.8 → 0.184.10
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.tsl.js +5 -1
- package/build/three.tsl.min.js +1 -1
- package/build/three.webgpu.js +480 -8
- package/build/three.webgpu.min.js +1 -1
- package/build/three.webgpu.nodes.js +480 -8
- package/build/three.webgpu.nodes.min.js +1 -1
- package/examples/jsm/helpers/LightProbeGridCubeMapHelper.js +222 -0
- package/examples/jsm/helpers/LightProbeGridHelper.js +223 -99
- package/examples/jsm/inspector/tabs/Settings.js +1 -1
- package/examples/jsm/lighting/LightProbeGrid.js +628 -84
- package/examples/jsm/tsl/lighting/DynamicLightsNode.js +19 -1
- package/package.json +1 -1
- package/src/Three.TSL.js +4 -0
- package/src/nodes/Nodes.js +3 -0
- package/src/nodes/TSL.js +4 -0
- package/src/nodes/accessors/CubeTextureNode.js +7 -1
- package/src/nodes/accessors/TextureNode.js +21 -1
- package/src/nodes/functions/material/getLightProbeGridIrradiance.js +68 -0
- package/src/nodes/lighting/LightProbeGridNode.js +137 -0
- package/src/nodes/lighting/LightsNode.js +98 -1
- package/src/renderers/common/Background.js +33 -0
- package/src/renderers/common/RenderList.js +28 -0
- package/src/renderers/common/RenderObjects.js +47 -0
- package/src/renderers/common/Renderer.js +32 -2
- package/src/renderers/common/nodes/NodeManager.js +24 -0
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
LightsNode,
|
|
3
|
+
NodeUtils,
|
|
4
|
+
warn
|
|
5
|
+
} from 'three/webgpu';
|
|
2
6
|
import { nodeObject } from 'three/tsl';
|
|
3
7
|
|
|
4
8
|
import AmbientLightDataNode from './data/AmbientLightDataNode.js';
|
|
@@ -145,6 +149,16 @@ class DynamicLightsNode extends LightsNode {
|
|
|
145
149
|
|
|
146
150
|
}
|
|
147
151
|
|
|
152
|
+
// WITH_GENESYS
|
|
153
|
+
for ( let i = 0; i < this._lightProbeGrids.length; i ++ ) {
|
|
154
|
+
|
|
155
|
+
const lightProbeGrid = this._lightProbeGrids[ i ];
|
|
156
|
+
|
|
157
|
+
_hashData.push( lightProbeGrid.id );
|
|
158
|
+
|
|
159
|
+
}
|
|
160
|
+
// !WITH_GENESYS
|
|
161
|
+
|
|
148
162
|
const cacheKey = NodeUtils.hashArray( _hashData );
|
|
149
163
|
|
|
150
164
|
_hashData.length = 0;
|
|
@@ -230,6 +244,10 @@ class DynamicLightsNode extends LightsNode {
|
|
|
230
244
|
|
|
231
245
|
}
|
|
232
246
|
|
|
247
|
+
// WITH_GENESYS
|
|
248
|
+
this._appendLightProbeGridNode( lightNodes );
|
|
249
|
+
// !WITH_GENESYS
|
|
250
|
+
|
|
233
251
|
this._lightNodes = lightNodes;
|
|
234
252
|
|
|
235
253
|
}
|
package/package.json
CHANGED
package/src/Three.TSL.js
CHANGED
|
@@ -202,6 +202,10 @@ export const getCurrentStack = TSL.getCurrentStack;
|
|
|
202
202
|
export const getDirection = TSL.getDirection;
|
|
203
203
|
export const getDistanceAttenuation = TSL.getDistanceAttenuation;
|
|
204
204
|
export const getGeometryRoughness = TSL.getGeometryRoughness;
|
|
205
|
+
// WITH_GENESYS
|
|
206
|
+
export const getLightProbeGridIrradiance = TSL.getLightProbeGridIrradiance;
|
|
207
|
+
export const getLightProbeGridIrradianceAtUV = TSL.getLightProbeGridIrradianceAtUV;
|
|
208
|
+
// !WITH_GENESYS
|
|
205
209
|
export const getNormalFromDepth = TSL.getNormalFromDepth;
|
|
206
210
|
export const interleavedGradientNoise = TSL.interleavedGradientNoise;
|
|
207
211
|
export const vogelDiskSample = TSL.vogelDiskSample;
|
package/src/nodes/Nodes.js
CHANGED
|
@@ -116,6 +116,9 @@ export { default as IESSpotLightNode } from './lighting/IESSpotLightNode.js';
|
|
|
116
116
|
export { default as IrradianceNode } from './lighting/IrradianceNode.js';
|
|
117
117
|
export { default as LightingContextNode } from './lighting/LightingContextNode.js';
|
|
118
118
|
export { default as LightingNode } from './lighting/LightingNode.js';
|
|
119
|
+
// WITH_GENESYS
|
|
120
|
+
export { default as LightProbeGridNode } from './lighting/LightProbeGridNode.js';
|
|
121
|
+
// !WITH_GENESYS
|
|
119
122
|
export { default as LightProbeNode } from './lighting/LightProbeNode.js';
|
|
120
123
|
export { default as LightsNode } from './lighting/LightsNode.js';
|
|
121
124
|
// WITH_GENESYS
|
package/src/nodes/TSL.js
CHANGED
|
@@ -168,6 +168,10 @@ export { default as V_GGX_SmithCorrelated } from './functions/BSDF/V_GGX_SmithCo
|
|
|
168
168
|
export * from './lighting/LightUtils.js';
|
|
169
169
|
|
|
170
170
|
export { default as getGeometryRoughness } from './functions/material/getGeometryRoughness.js';
|
|
171
|
+
// WITH_GENESYS
|
|
172
|
+
export { default as getLightProbeGridIrradiance } from './functions/material/getLightProbeGridIrradiance.js';
|
|
173
|
+
export { getLightProbeGridIrradianceAtUV } from './functions/material/getLightProbeGridIrradiance.js';
|
|
174
|
+
// !WITH_GENESYS
|
|
171
175
|
export { default as getParallaxCorrectNormal } from './functions/material/getParallaxCorrectNormal.js';
|
|
172
176
|
export { default as getRoughness } from './functions/material/getRoughness.js';
|
|
173
177
|
export { default as getShIrradianceAt } from './functions/material/getShIrradianceAt.js';
|
|
@@ -126,7 +126,13 @@ class CubeTextureNode extends TextureNode {
|
|
|
126
126
|
|
|
127
127
|
// rotate first
|
|
128
128
|
|
|
129
|
-
|
|
129
|
+
// WITH_GENESYS: Skip material/scene env rotation in compute — no material or scene context.
|
|
130
|
+
if ( builder.shaderStage !== 'compute' ) {
|
|
131
|
+
|
|
132
|
+
uvNode = materialEnvRotation.mul( uvNode );
|
|
133
|
+
|
|
134
|
+
}
|
|
135
|
+
// !WITH_GENESYS
|
|
130
136
|
|
|
131
137
|
// flip
|
|
132
138
|
|
|
@@ -366,7 +366,27 @@ class TextureNode extends UniformNode {
|
|
|
366
366
|
|
|
367
367
|
if ( this.updateMatrix === true ) {
|
|
368
368
|
|
|
369
|
-
|
|
369
|
+
// eslint-disable-next-line no-constant-condition
|
|
370
|
+
if ( true ) {
|
|
371
|
+
|
|
372
|
+
// WITH_GENESYS: Do not apply UV matrix to integer texel coords or storage textures.
|
|
373
|
+
const explicitUV = this.uvNode;
|
|
374
|
+
const explicitUVType = explicitUV ? explicitUV.getNodeType( builder ) : null;
|
|
375
|
+
const isIntegerTexelCoord = explicitUVType === 'uvec2' || explicitUVType === 'uvec3' || explicitUVType === 'ivec2' || explicitUVType === 'ivec3';
|
|
376
|
+
const isStorageTexture = texture.isStorageTexture === true;
|
|
377
|
+
|
|
378
|
+
if ( isIntegerTexelCoord === false && isStorageTexture === false ) {
|
|
379
|
+
|
|
380
|
+
uvNode = this.getTransformedUV( uvNode );
|
|
381
|
+
|
|
382
|
+
}
|
|
383
|
+
// !WITH_GENESYS
|
|
384
|
+
|
|
385
|
+
} else {
|
|
386
|
+
|
|
387
|
+
uvNode = this.getTransformedUV( uvNode );
|
|
388
|
+
|
|
389
|
+
}
|
|
370
390
|
|
|
371
391
|
}
|
|
372
392
|
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { Fn, max, vec3 } from '../../tsl/TSLBase.js';
|
|
2
|
+
|
|
3
|
+
export const getLightProbeGridIrradianceAtUV = /*@__PURE__*/ Fn( ( { probesSH, probesResolution, gridUVW, worldNormal } ) => {
|
|
4
|
+
|
|
5
|
+
const res = probesResolution;
|
|
6
|
+
const uvw = gridUVW.toVar();
|
|
7
|
+
|
|
8
|
+
const nz = res.z;
|
|
9
|
+
const paddedSlices = nz.add( 2.0 );
|
|
10
|
+
const atlasDepth = paddedSlices.mul( 7.0 );
|
|
11
|
+
const uvZBase = uvw.z.mul( nz ).add( 1.0 );
|
|
12
|
+
|
|
13
|
+
const atlasUv = ( sliceOffset ) => vec3( uvw.x, uvw.y, uvZBase.add( paddedSlices.mul( sliceOffset ) ).div( atlasDepth ) );
|
|
14
|
+
|
|
15
|
+
const s0 = probesSH.sample( atlasUv( 0.0 ) );
|
|
16
|
+
const s1 = probesSH.sample( atlasUv( 1.0 ) );
|
|
17
|
+
const s2 = probesSH.sample( atlasUv( 2.0 ) );
|
|
18
|
+
const s3 = probesSH.sample( atlasUv( 3.0 ) );
|
|
19
|
+
const s4 = probesSH.sample( atlasUv( 4.0 ) );
|
|
20
|
+
const s5 = probesSH.sample( atlasUv( 5.0 ) );
|
|
21
|
+
const s6 = probesSH.sample( atlasUv( 6.0 ) );
|
|
22
|
+
|
|
23
|
+
const c0 = s0.xyz;
|
|
24
|
+
const c1 = vec3( s0.w, s1.x, s1.y );
|
|
25
|
+
const c2 = vec3( s1.z, s1.w, s2.x );
|
|
26
|
+
const c3 = s2.yzw;
|
|
27
|
+
const c4 = s3.xyz;
|
|
28
|
+
const c5 = vec3( s3.w, s4.x, s4.y );
|
|
29
|
+
const c6 = vec3( s4.z, s4.w, s5.x );
|
|
30
|
+
const c7 = s5.yzw;
|
|
31
|
+
const c8 = s6.xyz;
|
|
32
|
+
|
|
33
|
+
const x = worldNormal.x, y = worldNormal.y, z = worldNormal.z;
|
|
34
|
+
|
|
35
|
+
let result = c0.mul( 0.886227 );
|
|
36
|
+
result = result.add( c1.mul( 2.0 * 0.511664 ).mul( y ) );
|
|
37
|
+
result = result.add( c2.mul( 2.0 * 0.511664 ).mul( z ) );
|
|
38
|
+
result = result.add( c3.mul( 2.0 * 0.511664 ).mul( x ) );
|
|
39
|
+
result = result.add( c4.mul( 2.0 * 0.429043 ).mul( x ).mul( y ) );
|
|
40
|
+
result = result.add( c5.mul( 2.0 * 0.429043 ).mul( y ).mul( z ) );
|
|
41
|
+
result = result.add( c6.mul( z.mul( z ).mul( 0.743125 ).sub( 0.247708 ) ) );
|
|
42
|
+
result = result.add( c7.mul( 2.0 * 0.429043 ).mul( x ).mul( z ) );
|
|
43
|
+
result = result.add( c8.mul( 0.429043 ).mul( x.mul( x ).sub( y.mul( y ) ) ) );
|
|
44
|
+
|
|
45
|
+
return max( result, vec3( 0.0 ) );
|
|
46
|
+
|
|
47
|
+
} );
|
|
48
|
+
|
|
49
|
+
const getLightProbeGridIrradiance = /*@__PURE__*/ Fn( ( { probesSH, probesMin, probesMax, probesResolution, worldPosition, worldNormal } ) => {
|
|
50
|
+
|
|
51
|
+
const res = probesResolution;
|
|
52
|
+
const gridRange = probesMax.sub( probesMin ).toVar();
|
|
53
|
+
const resMinusOne = res.sub( 1.0 );
|
|
54
|
+
const probeSpacing = gridRange.div( resMinusOne ).toVar();
|
|
55
|
+
|
|
56
|
+
const samplePos = worldPosition.add( worldNormal.mul( probeSpacing ).mul( 0.5 ) );
|
|
57
|
+
const gridUVW = samplePos.sub( probesMin ).div( gridRange ).clamp( 0.0, 1.0 ).mul( resMinusOne.div( res ) ).add( vec3( 0.5 ).div( res ) );
|
|
58
|
+
|
|
59
|
+
return getLightProbeGridIrradianceAtUV( {
|
|
60
|
+
probesSH,
|
|
61
|
+
probesResolution,
|
|
62
|
+
gridUVW,
|
|
63
|
+
worldNormal
|
|
64
|
+
} );
|
|
65
|
+
|
|
66
|
+
} );
|
|
67
|
+
|
|
68
|
+
export default getLightProbeGridIrradiance;
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import LightingNode from './LightingNode.js';
|
|
2
|
+
import { normalWorld } from '../accessors/Normal.js';
|
|
3
|
+
import { positionWorld } from '../accessors/Position.js';
|
|
4
|
+
import { texture3D } from '../accessors/Texture3DNode.js';
|
|
5
|
+
import { NodeUpdateType } from '../core/constants.js';
|
|
6
|
+
import { uniform } from '../core/UniformNode.js';
|
|
7
|
+
import getLightProbeGridIrradiance from '../functions/material/getLightProbeGridIrradiance.js';
|
|
8
|
+
import { FloatType, LinearFilter, RGBAFormat } from '../../constants.js';
|
|
9
|
+
import { Data3DTexture } from '../../textures/Data3DTexture.js';
|
|
10
|
+
import { Vector3 } from '../../math/Vector3.js';
|
|
11
|
+
|
|
12
|
+
const _objectPosition = /*@__PURE__*/ new Vector3();
|
|
13
|
+
const _emptyTexture = /*@__PURE__*/ new Data3DTexture( new Float32Array( 1 * 1 * 28 * 4 ), 1, 1, 28 );
|
|
14
|
+
|
|
15
|
+
_emptyTexture.format = RGBAFormat;
|
|
16
|
+
_emptyTexture.type = FloatType;
|
|
17
|
+
_emptyTexture.minFilter = LinearFilter;
|
|
18
|
+
_emptyTexture.magFilter = LinearFilter;
|
|
19
|
+
_emptyTexture.needsUpdate = true;
|
|
20
|
+
|
|
21
|
+
function findLightProbeGrid( volumes, object ) {
|
|
22
|
+
|
|
23
|
+
if ( volumes.length === 0 ) return null;
|
|
24
|
+
|
|
25
|
+
if ( volumes.length === 1 ) {
|
|
26
|
+
|
|
27
|
+
return volumes[ 0 ].texture !== null ? volumes[ 0 ] : null;
|
|
28
|
+
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
_objectPosition.setFromMatrixPosition( object.matrixWorld );
|
|
32
|
+
|
|
33
|
+
for ( let i = 0, l = volumes.length; i < l; i ++ ) {
|
|
34
|
+
|
|
35
|
+
const volume = volumes[ i ];
|
|
36
|
+
|
|
37
|
+
if ( volume.texture !== null && volume.boundingBox.containsPoint( _objectPosition ) ) return volume;
|
|
38
|
+
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return null;
|
|
42
|
+
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Adds diffuse irradiance from the active LightProbeGrid to WebGPU node materials.
|
|
47
|
+
*
|
|
48
|
+
* @augments LightingNode
|
|
49
|
+
*/
|
|
50
|
+
class LightProbeGridNode extends LightingNode {
|
|
51
|
+
|
|
52
|
+
static get type() {
|
|
53
|
+
|
|
54
|
+
return 'LightProbeGridNode';
|
|
55
|
+
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Constructs a new light probe grid node.
|
|
60
|
+
*
|
|
61
|
+
* @param {Array<Object3D>} [lightProbeGrids=[]] - Light probe grids collected from the scene.
|
|
62
|
+
*/
|
|
63
|
+
constructor( lightProbeGrids = [] ) {
|
|
64
|
+
|
|
65
|
+
super();
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* This flag can be used for type testing.
|
|
69
|
+
*
|
|
70
|
+
* @type {boolean}
|
|
71
|
+
* @readonly
|
|
72
|
+
* @default true
|
|
73
|
+
*/
|
|
74
|
+
this.isLightProbeGridNode = true;
|
|
75
|
+
|
|
76
|
+
this.lightProbeGrids = lightProbeGrids;
|
|
77
|
+
this.activeLightProbeGrid = null;
|
|
78
|
+
|
|
79
|
+
this.probesSH = texture3D( _emptyTexture );
|
|
80
|
+
this.probesMin = uniform( new Vector3() );
|
|
81
|
+
this.probesMax = uniform( new Vector3( 1, 1, 1 ) );
|
|
82
|
+
this.probesResolution = uniform( new Vector3( 2, 2, 2 ) );
|
|
83
|
+
|
|
84
|
+
this.updateType = NodeUpdateType.OBJECT;
|
|
85
|
+
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
update( frame ) {
|
|
89
|
+
|
|
90
|
+
const activeLightProbeGrid = findLightProbeGrid( this.lightProbeGrids, frame.object );
|
|
91
|
+
|
|
92
|
+
this.activeLightProbeGrid = activeLightProbeGrid;
|
|
93
|
+
|
|
94
|
+
if ( activeLightProbeGrid !== null ) {
|
|
95
|
+
|
|
96
|
+
activeLightProbeGrid.updateBoundingBox();
|
|
97
|
+
|
|
98
|
+
this.probesSH.value = activeLightProbeGrid.texture;
|
|
99
|
+
this.probesMin.value.copy( activeLightProbeGrid.boundingBox.min );
|
|
100
|
+
this.probesMax.value.copy( activeLightProbeGrid.boundingBox.max );
|
|
101
|
+
this.probesResolution.value.copy( activeLightProbeGrid.resolution );
|
|
102
|
+
|
|
103
|
+
} else {
|
|
104
|
+
|
|
105
|
+
this.probesSH.value = _emptyTexture;
|
|
106
|
+
this.probesMin.value.set( 0, 0, 0 );
|
|
107
|
+
this.probesMax.value.set( 1, 1, 1 );
|
|
108
|
+
this.probesResolution.value.set( 2, 2, 2 );
|
|
109
|
+
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
setup( builder ) {
|
|
115
|
+
|
|
116
|
+
const irradiance = getLightProbeGridIrradiance( {
|
|
117
|
+
probesSH: this.probesSH,
|
|
118
|
+
probesMin: this.probesMin,
|
|
119
|
+
probesMax: this.probesMax,
|
|
120
|
+
probesResolution: this.probesResolution,
|
|
121
|
+
worldPosition: positionWorld,
|
|
122
|
+
worldNormal: normalWorld
|
|
123
|
+
} );
|
|
124
|
+
|
|
125
|
+
builder.context.irradiance.addAssign( irradiance );
|
|
126
|
+
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
getHash() {
|
|
130
|
+
|
|
131
|
+
return `lightProbeGrid-${ this.lightProbeGrids.map( ( lightProbeGrid ) => lightProbeGrid.id ).join( ',' ) }`;
|
|
132
|
+
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export default LightProbeGridNode;
|
|
@@ -2,6 +2,9 @@ import Node from '../core/Node.js';
|
|
|
2
2
|
import { nodeObject, property, vec3 } from '../tsl/TSLBase.js';
|
|
3
3
|
import { hashArray } from '../core/NodeUtils.js';
|
|
4
4
|
import { warn } from '../../utils.js';
|
|
5
|
+
// WITH_GENESYS
|
|
6
|
+
import LightProbeGridNode from './LightProbeGridNode.js';
|
|
7
|
+
// !WITH_GENESYS
|
|
5
8
|
|
|
6
9
|
const sortLights = ( lights ) => {
|
|
7
10
|
|
|
@@ -79,6 +82,25 @@ class LightsNode extends Node {
|
|
|
79
82
|
*/
|
|
80
83
|
this._lights = [];
|
|
81
84
|
|
|
85
|
+
// WITH_GENESYS
|
|
86
|
+
/**
|
|
87
|
+
* A list of light probe grids collected from the scene.
|
|
88
|
+
*
|
|
89
|
+
* @private
|
|
90
|
+
* @type {Array<Object3D>}
|
|
91
|
+
*/
|
|
92
|
+
this._lightProbeGrids = [];
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Cached light probe grid node reused across {@link LightsNode#setupLightsNode} calls.
|
|
96
|
+
*
|
|
97
|
+
* @private
|
|
98
|
+
* @type {?LightProbeGridNode}
|
|
99
|
+
* @default null
|
|
100
|
+
*/
|
|
101
|
+
this._lightProbeGridNode = null;
|
|
102
|
+
// !WITH_GENESYS
|
|
103
|
+
|
|
82
104
|
/**
|
|
83
105
|
* For each light in the scene, this node will create a
|
|
84
106
|
* corresponding light node.
|
|
@@ -136,6 +158,18 @@ class LightsNode extends Node {
|
|
|
136
158
|
|
|
137
159
|
}
|
|
138
160
|
|
|
161
|
+
// WITH_GENESYS
|
|
162
|
+
const lightProbeGrids = this._lightProbeGrids;
|
|
163
|
+
|
|
164
|
+
for ( let i = 0; i < lightProbeGrids.length; i ++ ) {
|
|
165
|
+
|
|
166
|
+
const lightProbeGrid = lightProbeGrids[ i ];
|
|
167
|
+
|
|
168
|
+
_hashData.push( lightProbeGrid.id );
|
|
169
|
+
|
|
170
|
+
}
|
|
171
|
+
// !WITH_GENESYS
|
|
172
|
+
|
|
139
173
|
const cacheKey = hashArray( _hashData );
|
|
140
174
|
|
|
141
175
|
_hashData.length = 0;
|
|
@@ -244,10 +278,44 @@ class LightsNode extends Node {
|
|
|
244
278
|
|
|
245
279
|
}
|
|
246
280
|
|
|
281
|
+
// WITH_GENESYS
|
|
282
|
+
this._appendLightProbeGridNode( lightNodes );
|
|
283
|
+
// !WITH_GENESYS
|
|
284
|
+
|
|
247
285
|
this._lightNodes = lightNodes;
|
|
248
286
|
|
|
249
287
|
}
|
|
250
288
|
|
|
289
|
+
// WITH_GENESYS
|
|
290
|
+
/**
|
|
291
|
+
* Appends the cached {@link LightProbeGridNode} for the current probe grids.
|
|
292
|
+
*
|
|
293
|
+
* @private
|
|
294
|
+
* @param {Array<LightingNode>} lightNodes - The light nodes array being built.
|
|
295
|
+
*/
|
|
296
|
+
_appendLightProbeGridNode( lightNodes ) {
|
|
297
|
+
|
|
298
|
+
if ( this._lightProbeGrids.length === 0 ) {
|
|
299
|
+
|
|
300
|
+
return;
|
|
301
|
+
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
if ( this._lightProbeGridNode === null ) {
|
|
305
|
+
|
|
306
|
+
this._lightProbeGridNode = new LightProbeGridNode( this._lightProbeGrids );
|
|
307
|
+
|
|
308
|
+
} else {
|
|
309
|
+
|
|
310
|
+
this._lightProbeGridNode.lightProbeGrids = this._lightProbeGrids;
|
|
311
|
+
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
lightNodes.push( this._lightProbeGridNode );
|
|
315
|
+
|
|
316
|
+
}
|
|
317
|
+
// !WITH_GENESYS
|
|
318
|
+
|
|
251
319
|
/**
|
|
252
320
|
* Sets up a direct light in the lighting model.
|
|
253
321
|
*
|
|
@@ -394,6 +462,31 @@ class LightsNode extends Node {
|
|
|
394
462
|
|
|
395
463
|
}
|
|
396
464
|
|
|
465
|
+
// WITH_GENESYS
|
|
466
|
+
/**
|
|
467
|
+
* Configures this node with an array of light probe grids.
|
|
468
|
+
*
|
|
469
|
+
* @param {Array<Object3D>} lightProbeGrids - An array of light probe grids.
|
|
470
|
+
* @return {LightsNode} A reference to this node.
|
|
471
|
+
*/
|
|
472
|
+
setLightProbeGrids( lightProbeGrids ) {
|
|
473
|
+
|
|
474
|
+
this._lightProbeGrids = lightProbeGrids;
|
|
475
|
+
|
|
476
|
+
if ( this._lightProbeGridNode !== null ) {
|
|
477
|
+
|
|
478
|
+
this._lightProbeGridNode.lightProbeGrids = lightProbeGrids;
|
|
479
|
+
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
this._lightNodes = null;
|
|
483
|
+
this._lightNodesHash = null;
|
|
484
|
+
|
|
485
|
+
return this;
|
|
486
|
+
|
|
487
|
+
}
|
|
488
|
+
// !WITH_GENESYS
|
|
489
|
+
|
|
397
490
|
/**
|
|
398
491
|
* Returns an array of the scene's lights.
|
|
399
492
|
*
|
|
@@ -412,7 +505,11 @@ class LightsNode extends Node {
|
|
|
412
505
|
*/
|
|
413
506
|
get hasLights() {
|
|
414
507
|
|
|
415
|
-
return this._lights.length > 0
|
|
508
|
+
return this._lights.length > 0
|
|
509
|
+
// WITH_GENESYS
|
|
510
|
+
|| this._lightProbeGrids.length > 0
|
|
511
|
+
// !WITH_GENESYS
|
|
512
|
+
;
|
|
416
513
|
|
|
417
514
|
}
|
|
418
515
|
|
|
@@ -44,6 +44,39 @@ class Background extends DataMap {
|
|
|
44
44
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
+
// WITH_GENESYS
|
|
48
|
+
/**
|
|
49
|
+
* Disposes the renderer-owned background skybox mesh (material and geometry)
|
|
50
|
+
* for `scene` and clears cached mesh state.
|
|
51
|
+
*
|
|
52
|
+
* Does not dispose {@link Scene#background}.
|
|
53
|
+
*
|
|
54
|
+
* @param {Scene} scene - The scene.
|
|
55
|
+
*/
|
|
56
|
+
disposeScene( scene ) {
|
|
57
|
+
|
|
58
|
+
if ( this.has( scene ) === false ) return;
|
|
59
|
+
|
|
60
|
+
const sceneData = this.get( scene );
|
|
61
|
+
|
|
62
|
+
const backgroundMesh = sceneData.backgroundMesh;
|
|
63
|
+
|
|
64
|
+
if ( backgroundMesh !== undefined ) {
|
|
65
|
+
|
|
66
|
+
this.renderer._objects.disposeObjectResources( backgroundMesh, scene );
|
|
67
|
+
|
|
68
|
+
backgroundMesh.material.dispose();
|
|
69
|
+
backgroundMesh.geometry.dispose();
|
|
70
|
+
|
|
71
|
+
delete sceneData.backgroundMesh;
|
|
72
|
+
delete sceneData.backgroundMeshNode;
|
|
73
|
+
delete sceneData.backgroundCacheKey;
|
|
74
|
+
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
}
|
|
78
|
+
// !WITH_GENESYS
|
|
79
|
+
|
|
47
80
|
/**
|
|
48
81
|
* Updates the background for the given scene. Depending on how `Scene.background`
|
|
49
82
|
* or `Scene.backgroundNode` are configured, this method might configure a simple clear
|
|
@@ -161,6 +161,15 @@ class RenderList {
|
|
|
161
161
|
*/
|
|
162
162
|
this.lightsArray = [];
|
|
163
163
|
|
|
164
|
+
// WITH_GENESYS
|
|
165
|
+
/**
|
|
166
|
+
* The scene's light probe grids stored in an array.
|
|
167
|
+
*
|
|
168
|
+
* @type {Array<Object3D>}
|
|
169
|
+
*/
|
|
170
|
+
this.lightProbeGridsArray = [];
|
|
171
|
+
// !WITH_GENESYS
|
|
172
|
+
|
|
164
173
|
/**
|
|
165
174
|
* The scene.
|
|
166
175
|
*
|
|
@@ -202,6 +211,9 @@ class RenderList {
|
|
|
202
211
|
this.bundles.length = 0;
|
|
203
212
|
|
|
204
213
|
this.lightsArray.length = 0;
|
|
214
|
+
// WITH_GENESYS
|
|
215
|
+
this.lightProbeGridsArray.length = 0;
|
|
216
|
+
// !WITH_GENESYS
|
|
205
217
|
|
|
206
218
|
this.occlusionQueryCount = 0;
|
|
207
219
|
|
|
@@ -353,6 +365,19 @@ class RenderList {
|
|
|
353
365
|
|
|
354
366
|
}
|
|
355
367
|
|
|
368
|
+
// WITH_GENESYS
|
|
369
|
+
/**
|
|
370
|
+
* Pushes a light probe grid into the render list.
|
|
371
|
+
*
|
|
372
|
+
* @param {Object3D} lightProbeGrid - The light probe grid.
|
|
373
|
+
*/
|
|
374
|
+
pushLightProbeGrid( lightProbeGrid ) {
|
|
375
|
+
|
|
376
|
+
this.lightProbeGridsArray.push( lightProbeGrid );
|
|
377
|
+
|
|
378
|
+
}
|
|
379
|
+
// !WITH_GENESYS
|
|
380
|
+
|
|
356
381
|
/**
|
|
357
382
|
* Sorts the internal render lists.
|
|
358
383
|
*
|
|
@@ -376,6 +401,9 @@ class RenderList {
|
|
|
376
401
|
// update lights
|
|
377
402
|
|
|
378
403
|
this.lightsNode.setLights( this.lightsArray );
|
|
404
|
+
// WITH_GENESYS
|
|
405
|
+
this.lightsNode.setLightProbeGrids( this.lightProbeGridsArray );
|
|
406
|
+
// !WITH_GENESYS
|
|
379
407
|
|
|
380
408
|
// Clear references from inactive renderItems in the list
|
|
381
409
|
|
|
@@ -207,6 +207,53 @@ class RenderObjects {
|
|
|
207
207
|
|
|
208
208
|
}
|
|
209
209
|
|
|
210
|
+
// WITH_GENESYS
|
|
211
|
+
/**
|
|
212
|
+
* Disposes every {@link RenderObject} associated with `scene`.
|
|
213
|
+
*
|
|
214
|
+
* @param {Scene} scene - The scene being removed.
|
|
215
|
+
*/
|
|
216
|
+
disposeSceneResources( scene ) {
|
|
217
|
+
|
|
218
|
+
const renderObjects = Array.from( this._renderObjects );
|
|
219
|
+
|
|
220
|
+
for ( const renderObject of renderObjects ) {
|
|
221
|
+
|
|
222
|
+
if ( renderObject.scene === scene ) {
|
|
223
|
+
|
|
224
|
+
renderObject.dispose();
|
|
225
|
+
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Disposes every {@link RenderObject} for `object` drawn with `scene`.
|
|
234
|
+
* Call before disposing a renderer-owned mesh (e.g. background skybox) so WebGPU
|
|
235
|
+
* bindings are released while the renderer keeps running.
|
|
236
|
+
*
|
|
237
|
+
* @param {Object3D} object - The 3D object.
|
|
238
|
+
* @param {Scene} scene - The scene reference used when the object was rendered.
|
|
239
|
+
*/
|
|
240
|
+
disposeObjectResources( object, scene ) {
|
|
241
|
+
|
|
242
|
+
const renderObjects = Array.from( this._renderObjects );
|
|
243
|
+
|
|
244
|
+
for ( const renderObject of renderObjects ) {
|
|
245
|
+
|
|
246
|
+
if ( renderObject.object === object && renderObject.scene === scene ) {
|
|
247
|
+
|
|
248
|
+
renderObject.dispose();
|
|
249
|
+
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
}
|
|
255
|
+
// !WITH_GENESYS
|
|
256
|
+
|
|
210
257
|
/**
|
|
211
258
|
* Factory method for creating render objects with the given list of parameters.
|
|
212
259
|
*
|
|
@@ -935,7 +935,11 @@ class Renderer {
|
|
|
935
935
|
|
|
936
936
|
renderList.pushLight( object );
|
|
937
937
|
|
|
938
|
-
}
|
|
938
|
+
} else if ( object.isLightProbeGrid && object.layers.test( camera.layers ) ) { // WITH_GENESYS
|
|
939
|
+
|
|
940
|
+
renderList.pushLightProbeGrid( object );
|
|
941
|
+
|
|
942
|
+
} // !WITH_GENESYS
|
|
939
943
|
|
|
940
944
|
} );
|
|
941
945
|
|
|
@@ -2552,6 +2556,28 @@ class Renderer {
|
|
|
2552
2556
|
|
|
2553
2557
|
}
|
|
2554
2558
|
|
|
2559
|
+
// WITH_GENESYS
|
|
2560
|
+
/**
|
|
2561
|
+
* Releases renderer resources scoped to `scene` when the scene is removed but
|
|
2562
|
+
* this renderer instance continues to run. Disposes matching {@link RenderObject}s,
|
|
2563
|
+
* the internal background skybox mesh, and cached background/environment nodes.
|
|
2564
|
+
*
|
|
2565
|
+
* Does not call `texture.dispose()` on {@link Scene#background} or
|
|
2566
|
+
* {@link Scene#environment}; the caller remains responsible for those textures.
|
|
2567
|
+
*
|
|
2568
|
+
* @param {Scene} scene - The scene being removed.
|
|
2569
|
+
*/
|
|
2570
|
+
disposeSceneResources( scene ) {
|
|
2571
|
+
|
|
2572
|
+
if ( this._initialized !== true ) return;
|
|
2573
|
+
|
|
2574
|
+
this._objects.disposeSceneResources( scene );
|
|
2575
|
+
this._nodes.clearSceneBackgroundAndEnvironmentNodes( scene );
|
|
2576
|
+
this._background.disposeScene( scene );
|
|
2577
|
+
|
|
2578
|
+
}
|
|
2579
|
+
// !WITH_GENESYS
|
|
2580
|
+
|
|
2555
2581
|
/**
|
|
2556
2582
|
* Sets the given render target. Calling this method means the renderer does not
|
|
2557
2583
|
* target the default framebuffer (meaning the canvas) anymore but a custom framebuffer.
|
|
@@ -3085,7 +3111,11 @@ class Renderer {
|
|
|
3085
3111
|
|
|
3086
3112
|
renderList.pushLight( object );
|
|
3087
3113
|
|
|
3088
|
-
} else if ( object.
|
|
3114
|
+
} else if ( object.isLightProbeGrid ) { // WITH_GENESYS
|
|
3115
|
+
|
|
3116
|
+
renderList.pushLightProbeGrid( object );
|
|
3117
|
+
|
|
3118
|
+
} else if ( object.isSprite ) { // !WITH_GENESYS
|
|
3089
3119
|
|
|
3090
3120
|
const frustum = camera.isArrayCamera ? _frustumArray : _frustum;
|
|
3091
3121
|
|