three-gpu-pathtracer 0.0.22 → 0.0.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -4
- package/build/index.module.js +465 -57
- package/build/index.module.js.map +1 -1
- package/build/index.umd.cjs +464 -56
- package/build/index.umd.cjs.map +1 -1
- package/package.json +13 -13
- package/src/core/PathTracingRenderer.js +48 -1
- package/src/core/PathTracingSceneGenerator.js +21 -2
- package/src/core/WebGLPathTracer.js +68 -13
- package/src/core/utils/BakedGeometry.js +23 -0
- package/src/core/utils/BufferAttributeUtils.js +11 -3
- package/src/core/utils/MeshDiff.js +6 -13
- package/src/core/utils/StaticGeometryGenerator.js +18 -3
- package/src/core/utils/mergeGeometries.js +14 -1
- package/src/index.d.ts +2 -1
- package/src/materials/MaterialBase.js +11 -0
- package/src/materials/pathtracing/PhysicalPathTracingMaterial.js +2 -1
- package/src/materials/pathtracing/glsl/attenuate_hit_function.glsl.js +2 -1
- package/src/materials/pathtracing/glsl/camera_util_functions.glsl.js +1 -1
- package/src/materials/pathtracing/glsl/get_surface_record_function.glsl.js +2 -1
- package/src/materials/surface/AmbientOcclusionMaterial.js +2 -0
- package/src/shader/bvh/inside_fog_volume_function.glsl.js +1 -1
- package/src/shader/structs/material_struct.glsl.js +3 -1
- package/src/uniforms/MaterialsTexture.js +4 -1
- package/src/uniforms/StratifiedSamplesTexture.js +55 -3
- package/src/uniforms/stratified/StratifiedSampler.js +19 -7
- package/src/uniforms/stratified/StratifiedSamplerCombined.js +14 -4
- package/src/utils/CubeToEquirectGenerator.js +159 -0
package/build/index.umd.cjs
CHANGED
|
@@ -45,12 +45,18 @@
|
|
|
45
45
|
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
// Confirms that the two provided attributes are compatible
|
|
48
|
+
// Confirms that the two provided attributes are compatible. Returns false if they are not.
|
|
49
49
|
function validateAttributes( attr1, attr2 ) {
|
|
50
50
|
|
|
51
51
|
if ( ! attr1 && ! attr2 ) {
|
|
52
52
|
|
|
53
|
-
return;
|
|
53
|
+
return true;
|
|
54
|
+
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if ( Boolean( attr1 ) !== Boolean( attr2 ) ) {
|
|
58
|
+
|
|
59
|
+
return false;
|
|
54
60
|
|
|
55
61
|
}
|
|
56
62
|
|
|
@@ -61,10 +67,12 @@
|
|
|
61
67
|
|
|
62
68
|
if ( ! sameCount || ! sameNormalized || ! sameType || ! sameItemSize ) {
|
|
63
69
|
|
|
64
|
-
|
|
70
|
+
return false;
|
|
65
71
|
|
|
66
72
|
}
|
|
67
73
|
|
|
74
|
+
return true;
|
|
75
|
+
|
|
68
76
|
}
|
|
69
77
|
|
|
70
78
|
function validateMergeability( geometries ) {
|
|
@@ -271,7 +279,20 @@
|
|
|
271
279
|
const attr = geometry.getAttribute( key );
|
|
272
280
|
if ( ! skip ) {
|
|
273
281
|
|
|
274
|
-
|
|
282
|
+
if ( key === 'color' && targetAttribute.itemSize !== attr.itemSize ) {
|
|
283
|
+
|
|
284
|
+
// make sure the color attribute is aligned with itemSize 3 to 4
|
|
285
|
+
for ( let index = offset, l = attr.count; index < l; index ++ ) {
|
|
286
|
+
|
|
287
|
+
attr.setXYZW( index, targetAttribute.getX( index ), targetAttribute.getY( index ), targetAttribute.getZ( index ), 1.0 );
|
|
288
|
+
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
} else {
|
|
292
|
+
|
|
293
|
+
copyAttributeContents( attr, targetAttribute, offset );
|
|
294
|
+
|
|
295
|
+
}
|
|
275
296
|
|
|
276
297
|
}
|
|
277
298
|
|
|
@@ -432,29 +453,22 @@
|
|
|
432
453
|
|
|
433
454
|
}
|
|
434
455
|
|
|
435
|
-
function attributeSort( a, b ) {
|
|
436
|
-
|
|
437
|
-
if ( a.uuid > b.uuid ) return 1;
|
|
438
|
-
if ( a.uuid < b.uuid ) return - 1;
|
|
439
|
-
return 0;
|
|
440
|
-
|
|
441
|
-
}
|
|
442
|
-
|
|
443
456
|
function getGeometryHash( geometry ) {
|
|
444
457
|
|
|
445
|
-
let hash =
|
|
458
|
+
let hash = geometry.uuid;
|
|
446
459
|
const attributes = Object.values( geometry.attributes );
|
|
447
460
|
if ( geometry.index ) {
|
|
448
461
|
|
|
449
462
|
attributes.push( geometry.index );
|
|
463
|
+
hash += `index|${ geometry.index.version }`;
|
|
450
464
|
|
|
451
465
|
}
|
|
452
466
|
|
|
453
|
-
|
|
467
|
+
const keys = Object.keys( attributes ).sort();
|
|
468
|
+
for ( const key of keys ) {
|
|
454
469
|
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
hash += `${ attr.uuid }_${ attr.version }|`;
|
|
470
|
+
const attr = attributes[ key ];
|
|
471
|
+
hash += `${ key }_${ attr.version }|`;
|
|
458
472
|
|
|
459
473
|
}
|
|
460
474
|
|
|
@@ -885,6 +899,28 @@
|
|
|
885
899
|
|
|
886
900
|
}
|
|
887
901
|
|
|
902
|
+
// returns whether the passed mesh is compatible with this baked geometry
|
|
903
|
+
// such that it can be updated without resizing attributes
|
|
904
|
+
isCompatible( mesh, attributes ) {
|
|
905
|
+
|
|
906
|
+
const geometry = mesh.geometry;
|
|
907
|
+
for ( let i = 0; i < attributes.length; i ++ ) {
|
|
908
|
+
|
|
909
|
+
const key = attributes[ i ];
|
|
910
|
+
const attr1 = geometry.attributes[ key ];
|
|
911
|
+
const attr2 = this.attributes[ key ];
|
|
912
|
+
if ( attr1 && ! validateAttributes( attr1, attr2 ) ) {
|
|
913
|
+
|
|
914
|
+
return false;
|
|
915
|
+
|
|
916
|
+
}
|
|
917
|
+
|
|
918
|
+
}
|
|
919
|
+
|
|
920
|
+
return true;
|
|
921
|
+
|
|
922
|
+
}
|
|
923
|
+
|
|
888
924
|
updateFrom( mesh, options ) {
|
|
889
925
|
|
|
890
926
|
const diff = this._diff;
|
|
@@ -1074,15 +1110,24 @@
|
|
|
1074
1110
|
unusedMeshKeys.delete( meshKey );
|
|
1075
1111
|
|
|
1076
1112
|
// initialize the intermediate geometry
|
|
1077
|
-
if
|
|
1113
|
+
// if the mesh and source geometry have changed in such a way that they are no longer
|
|
1114
|
+
// compatible then regenerate the baked geometry from scratch
|
|
1115
|
+
let geom = _intermediateGeometry.get( meshKey );
|
|
1116
|
+
if ( ! geom || ! geom.isCompatible( mesh, this.attributes ) ) {
|
|
1117
|
+
|
|
1118
|
+
if ( geom ) {
|
|
1078
1119
|
|
|
1079
|
-
|
|
1120
|
+
geom.dispose();
|
|
1121
|
+
|
|
1122
|
+
}
|
|
1123
|
+
|
|
1124
|
+
geom = new BakedGeometry();
|
|
1125
|
+
_intermediateGeometry.set( meshKey, geom );
|
|
1080
1126
|
|
|
1081
1127
|
}
|
|
1082
1128
|
|
|
1083
1129
|
// transform the geometry into the intermediate buffer geometry, saving whether
|
|
1084
1130
|
// or not it changed.
|
|
1085
|
-
const geom = _intermediateGeometry.get( meshKey );
|
|
1086
1131
|
if ( geom.updateFrom( mesh, convertOptions ) ) {
|
|
1087
1132
|
|
|
1088
1133
|
// TODO: provide option for only generating the set of attributes that are present
|
|
@@ -1134,6 +1179,12 @@
|
|
|
1134
1179
|
|
|
1135
1180
|
// get the list of geometries to merge
|
|
1136
1181
|
let forceUpdate = false;
|
|
1182
|
+
if ( meshes.length !== previousMergeInfo.length ) {
|
|
1183
|
+
|
|
1184
|
+
forceUpdate = true;
|
|
1185
|
+
|
|
1186
|
+
}
|
|
1187
|
+
|
|
1137
1188
|
for ( let i = 0, l = meshes.length; i < l; i ++ ) {
|
|
1138
1189
|
|
|
1139
1190
|
const mesh = meshes[ i ];
|
|
@@ -1279,6 +1330,7 @@
|
|
|
1279
1330
|
this._bvhWorker = null;
|
|
1280
1331
|
this._pendingGenerate = null;
|
|
1281
1332
|
this._buildAsync = false;
|
|
1333
|
+
this._materialUuids = null;
|
|
1282
1334
|
|
|
1283
1335
|
}
|
|
1284
1336
|
|
|
@@ -1360,12 +1412,29 @@
|
|
|
1360
1412
|
// generate the geometry
|
|
1361
1413
|
const result = staticGeometryGenerator.generate( geometry );
|
|
1362
1414
|
const materials = result.materials;
|
|
1415
|
+
let needsMaterialIndexUpdate = result.changeType !== NO_CHANGE || this._materialUuids === null || this._materialUuids.length !== length;
|
|
1416
|
+
if ( ! needsMaterialIndexUpdate ) {
|
|
1417
|
+
|
|
1418
|
+
for ( let i = 0, length = materials.length; i < length; i ++ ) {
|
|
1419
|
+
|
|
1420
|
+
const material = materials[ i ];
|
|
1421
|
+
if ( material.uuid !== this._materialUuids[ i ] ) {
|
|
1422
|
+
|
|
1423
|
+
needsMaterialIndexUpdate = true;
|
|
1424
|
+
break;
|
|
1425
|
+
|
|
1426
|
+
}
|
|
1427
|
+
|
|
1428
|
+
}
|
|
1429
|
+
|
|
1430
|
+
}
|
|
1431
|
+
|
|
1363
1432
|
const textures = getTextures$1( materials );
|
|
1364
1433
|
const { lights, iesTextures } = getLights$1( objects );
|
|
1365
|
-
|
|
1366
|
-
if ( result.changeType !== NO_CHANGE ) {
|
|
1434
|
+
if ( needsMaterialIndexUpdate ) {
|
|
1367
1435
|
|
|
1368
1436
|
updateMaterialIndexAttribute( geometry, materials, materials );
|
|
1437
|
+
this._materialUuids = materials.map( material => material.uuid );
|
|
1369
1438
|
|
|
1370
1439
|
}
|
|
1371
1440
|
|
|
@@ -1409,6 +1478,7 @@
|
|
|
1409
1478
|
return {
|
|
1410
1479
|
bvhChanged: result.changeType !== NO_CHANGE,
|
|
1411
1480
|
bvh: this.bvh,
|
|
1481
|
+
needsMaterialIndexUpdate,
|
|
1412
1482
|
lights,
|
|
1413
1483
|
iesTextures,
|
|
1414
1484
|
geometry,
|
|
@@ -1445,6 +1515,17 @@
|
|
|
1445
1515
|
|
|
1446
1516
|
class MaterialBase extends three.ShaderMaterial {
|
|
1447
1517
|
|
|
1518
|
+
set needsUpdate( v ) {
|
|
1519
|
+
|
|
1520
|
+
super.needsUpdate = true;
|
|
1521
|
+
this.dispatchEvent( {
|
|
1522
|
+
|
|
1523
|
+
type: 'recompilation',
|
|
1524
|
+
|
|
1525
|
+
} );
|
|
1526
|
+
|
|
1527
|
+
}
|
|
1528
|
+
|
|
1448
1529
|
constructor( shader ) {
|
|
1449
1530
|
|
|
1450
1531
|
super( shader );
|
|
@@ -2825,7 +2906,7 @@
|
|
|
2825
2906
|
|
|
2826
2907
|
}
|
|
2827
2908
|
|
|
2828
|
-
const MATERIAL_PIXELS =
|
|
2909
|
+
const MATERIAL_PIXELS = 47;
|
|
2829
2910
|
const MATERIAL_STRIDE = MATERIAL_PIXELS * 4;
|
|
2830
2911
|
|
|
2831
2912
|
class MaterialFeatures {
|
|
@@ -3250,6 +3331,9 @@
|
|
|
3250
3331
|
// specularIntensityMap transform 43
|
|
3251
3332
|
index += writeTextureMatrixToArray( m, 'specularIntensityMap', floatArray, index );
|
|
3252
3333
|
|
|
3334
|
+
// alphaMap transform 45
|
|
3335
|
+
index += writeTextureMatrixToArray( m, 'alphaMap', floatArray, index );
|
|
3336
|
+
|
|
3253
3337
|
}
|
|
3254
3338
|
|
|
3255
3339
|
// check if the contents have changed
|
|
@@ -3445,11 +3529,11 @@
|
|
|
3445
3529
|
// - https://github.com/hoverinc/ray-tracing-renderer
|
|
3446
3530
|
// - http://www.pbr-book.org/3ed-2018/Sampling_and_Reconstruction/Stratified_Sampling.html
|
|
3447
3531
|
|
|
3448
|
-
function shuffle( arr ) {
|
|
3532
|
+
function shuffle( arr, random = Math.random() ) {
|
|
3449
3533
|
|
|
3450
3534
|
for ( let i = arr.length - 1; i > 0; i -- ) {
|
|
3451
3535
|
|
|
3452
|
-
const j = Math.floor(
|
|
3536
|
+
const j = Math.floor( random() * ( i + 1 ) );
|
|
3453
3537
|
const x = arr[ i ];
|
|
3454
3538
|
arr[ i ] = arr[ j ];
|
|
3455
3539
|
arr[ j ] = x;
|
|
@@ -3464,7 +3548,7 @@
|
|
|
3464
3548
|
// dimensions : The number of dimensions to generate stratified values for
|
|
3465
3549
|
class StratifiedSampler {
|
|
3466
3550
|
|
|
3467
|
-
constructor( strataCount, dimensions ) {
|
|
3551
|
+
constructor( strataCount, dimensions, random = Math.random ) {
|
|
3468
3552
|
|
|
3469
3553
|
const l = strataCount ** dimensions;
|
|
3470
3554
|
const strata = new Uint16Array( l );
|
|
@@ -3481,7 +3565,19 @@
|
|
|
3481
3565
|
|
|
3482
3566
|
this.strataCount = strataCount;
|
|
3483
3567
|
|
|
3484
|
-
this.
|
|
3568
|
+
this.reset = function () {
|
|
3569
|
+
|
|
3570
|
+
for ( let i = 0; i < l; i ++ ) {
|
|
3571
|
+
|
|
3572
|
+
strata[ i ] = i;
|
|
3573
|
+
|
|
3574
|
+
}
|
|
3575
|
+
|
|
3576
|
+
index = 0;
|
|
3577
|
+
|
|
3578
|
+
};
|
|
3579
|
+
|
|
3580
|
+
this.reshuffle = function () {
|
|
3485
3581
|
|
|
3486
3582
|
index = 0;
|
|
3487
3583
|
|
|
@@ -3493,8 +3589,8 @@
|
|
|
3493
3589
|
|
|
3494
3590
|
if ( index >= strata.length ) {
|
|
3495
3591
|
|
|
3496
|
-
shuffle( strata );
|
|
3497
|
-
this.
|
|
3592
|
+
shuffle( strata, random );
|
|
3593
|
+
this.reshuffle();
|
|
3498
3594
|
|
|
3499
3595
|
}
|
|
3500
3596
|
|
|
@@ -3502,7 +3598,7 @@
|
|
|
3502
3598
|
|
|
3503
3599
|
for ( let i = 0; i < dimensions; i ++ ) {
|
|
3504
3600
|
|
|
3505
|
-
samples[ i ] = ( stratum % strataCount +
|
|
3601
|
+
samples[ i ] = ( stratum % strataCount + random() ) / strataCount;
|
|
3506
3602
|
stratum = Math.floor( stratum / strataCount );
|
|
3507
3603
|
|
|
3508
3604
|
}
|
|
@@ -3520,7 +3616,7 @@
|
|
|
3520
3616
|
// Stratified set of data with each tuple stratified separately and combined
|
|
3521
3617
|
class StratifiedSamplerCombined {
|
|
3522
3618
|
|
|
3523
|
-
constructor( strataCount, listOfDimensions ) {
|
|
3619
|
+
constructor( strataCount, listOfDimensions, random = Math.random ) {
|
|
3524
3620
|
|
|
3525
3621
|
let totalDim = 0;
|
|
3526
3622
|
for ( const dim of listOfDimensions ) {
|
|
@@ -3534,7 +3630,7 @@
|
|
|
3534
3630
|
let offset = 0;
|
|
3535
3631
|
for ( const dim of listOfDimensions ) {
|
|
3536
3632
|
|
|
3537
|
-
const sampler = new StratifiedSampler( strataCount, dim );
|
|
3633
|
+
const sampler = new StratifiedSampler( strataCount, dim, random );
|
|
3538
3634
|
sampler.samples = new Float32Array( combined.buffer, offset, sampler.samples.length );
|
|
3539
3635
|
offset += sampler.samples.length * 4;
|
|
3540
3636
|
strataObjs.push( sampler );
|
|
@@ -3557,11 +3653,21 @@
|
|
|
3557
3653
|
|
|
3558
3654
|
};
|
|
3559
3655
|
|
|
3560
|
-
this.
|
|
3656
|
+
this.reshuffle = function () {
|
|
3561
3657
|
|
|
3562
3658
|
for ( const strata of strataObjs ) {
|
|
3563
3659
|
|
|
3564
|
-
strata.
|
|
3660
|
+
strata.reshuffle();
|
|
3661
|
+
|
|
3662
|
+
}
|
|
3663
|
+
|
|
3664
|
+
};
|
|
3665
|
+
|
|
3666
|
+
this.reset = function () {
|
|
3667
|
+
|
|
3668
|
+
for ( const strata of strataObjs ) {
|
|
3669
|
+
|
|
3670
|
+
strata.reset();
|
|
3565
3671
|
|
|
3566
3672
|
}
|
|
3567
3673
|
|
|
@@ -3571,6 +3677,36 @@
|
|
|
3571
3677
|
|
|
3572
3678
|
}
|
|
3573
3679
|
|
|
3680
|
+
// https://stackoverflow.com/questions/424292/seedable-javascript-random-number-generator
|
|
3681
|
+
class RandomGenerator {
|
|
3682
|
+
|
|
3683
|
+
constructor( seed = 0 ) {
|
|
3684
|
+
|
|
3685
|
+
// LCG using GCC's constants
|
|
3686
|
+
this.m = 0x80000000; // 2**31;
|
|
3687
|
+
this.a = 1103515245;
|
|
3688
|
+
this.c = 12345;
|
|
3689
|
+
|
|
3690
|
+
this.seed = seed;
|
|
3691
|
+
|
|
3692
|
+
}
|
|
3693
|
+
|
|
3694
|
+
nextInt() {
|
|
3695
|
+
|
|
3696
|
+
this.seed = ( this.a * this.seed + this.c ) % this.m;
|
|
3697
|
+
return this.seed;
|
|
3698
|
+
|
|
3699
|
+
}
|
|
3700
|
+
|
|
3701
|
+
nextFloat() {
|
|
3702
|
+
|
|
3703
|
+
// returns in range [0,1]
|
|
3704
|
+
return this.nextInt() / ( this.m - 1 );
|
|
3705
|
+
|
|
3706
|
+
}
|
|
3707
|
+
|
|
3708
|
+
}
|
|
3709
|
+
|
|
3574
3710
|
class StratifiedSamplesTexture extends three.DataTexture {
|
|
3575
3711
|
|
|
3576
3712
|
constructor( count = 1, depth = 1, strata = 8 ) {
|
|
@@ -3581,22 +3717,37 @@
|
|
|
3581
3717
|
|
|
3582
3718
|
this.strata = strata;
|
|
3583
3719
|
this.sampler = null;
|
|
3720
|
+
this.generator = new RandomGenerator();
|
|
3721
|
+
this.stableNoise = false;
|
|
3722
|
+
this.random = () => {
|
|
3723
|
+
|
|
3724
|
+
if ( this.stableNoise ) {
|
|
3725
|
+
|
|
3726
|
+
return this.generator.nextFloat();
|
|
3727
|
+
|
|
3728
|
+
} else {
|
|
3729
|
+
|
|
3730
|
+
return Math.random();
|
|
3731
|
+
|
|
3732
|
+
}
|
|
3733
|
+
|
|
3734
|
+
};
|
|
3584
3735
|
|
|
3585
3736
|
this.init( count, depth, strata );
|
|
3586
3737
|
|
|
3587
3738
|
}
|
|
3588
3739
|
|
|
3589
|
-
init( count, depth, strata = this.strata ) {
|
|
3740
|
+
init( count = this.image.height, depth = this.image.width, strata = this.strata ) {
|
|
3590
3741
|
|
|
3591
3742
|
const { image } = this;
|
|
3592
|
-
if ( image.width === depth && image.height === count ) {
|
|
3743
|
+
if ( image.width === depth && image.height === count && this.sampler !== null ) {
|
|
3593
3744
|
|
|
3594
3745
|
return;
|
|
3595
3746
|
|
|
3596
3747
|
}
|
|
3597
3748
|
|
|
3598
3749
|
const dimensions = new Array( count * depth ).fill( 4 );
|
|
3599
|
-
const sampler = new StratifiedSamplerCombined( strata, dimensions );
|
|
3750
|
+
const sampler = new StratifiedSamplerCombined( strata, dimensions, this.random );
|
|
3600
3751
|
|
|
3601
3752
|
image.width = depth;
|
|
3602
3753
|
image.height = count;
|
|
@@ -3616,6 +3767,13 @@
|
|
|
3616
3767
|
|
|
3617
3768
|
}
|
|
3618
3769
|
|
|
3770
|
+
reset() {
|
|
3771
|
+
|
|
3772
|
+
this.sampler.reset();
|
|
3773
|
+
this.generator.seed = 0;
|
|
3774
|
+
|
|
3775
|
+
}
|
|
3776
|
+
|
|
3619
3777
|
}
|
|
3620
3778
|
|
|
3621
3779
|
function shuffleArray( array, random = Math.random ) {
|
|
@@ -4255,6 +4413,7 @@
|
|
|
4255
4413
|
mat3 iridescenceThicknessMapTransform;
|
|
4256
4414
|
mat3 specularColorMapTransform;
|
|
4257
4415
|
mat3 specularIntensityMapTransform;
|
|
4416
|
+
mat3 alphaMapTransform;
|
|
4258
4417
|
|
|
4259
4418
|
};
|
|
4260
4419
|
|
|
@@ -4275,7 +4434,7 @@
|
|
|
4275
4434
|
|
|
4276
4435
|
Material readMaterialInfo( sampler2D tex, uint index ) {
|
|
4277
4436
|
|
|
4278
|
-
uint i = index *
|
|
4437
|
+
uint i = index * uint( MATERIAL_PIXELS );
|
|
4279
4438
|
|
|
4280
4439
|
vec4 s0 = texelFetch1D( tex, i + 0u );
|
|
4281
4440
|
vec4 s1 = texelFetch1D( tex, i + 1u );
|
|
@@ -4374,6 +4533,7 @@
|
|
|
4374
4533
|
m.iridescenceThicknessMapTransform = m.iridescenceThicknessMap == - 1 ? mat3( 1.0 ) : readTextureTransform( tex, firstTextureTransformIdx + 24u );
|
|
4375
4534
|
m.specularColorMapTransform = m.specularColorMap == - 1 ? mat3( 1.0 ) : readTextureTransform( tex, firstTextureTransformIdx + 26u );
|
|
4376
4535
|
m.specularIntensityMapTransform = m.specularIntensityMap == - 1 ? mat3( 1.0 ) : readTextureTransform( tex, firstTextureTransformIdx + 28u );
|
|
4536
|
+
m.alphaMapTransform = m.alphaMap == - 1 ? mat3( 1.0 ) : readTextureTransform( tex, firstTextureTransformIdx + 30u );
|
|
4377
4537
|
|
|
4378
4538
|
return m;
|
|
4379
4539
|
|
|
@@ -6140,7 +6300,7 @@
|
|
|
6140
6300
|
// returns whether the given material is a fog material or not
|
|
6141
6301
|
bool isMaterialFogVolume( sampler2D materials, uint materialIndex ) {
|
|
6142
6302
|
|
|
6143
|
-
uint i = materialIndex *
|
|
6303
|
+
uint i = materialIndex * uint( MATERIAL_PIXELS );
|
|
6144
6304
|
vec4 s14 = texelFetch1D( materials, i + 14u );
|
|
6145
6305
|
return bool( int( s14.b ) & 4 );
|
|
6146
6306
|
|
|
@@ -6370,7 +6530,8 @@ bool bvhIntersectFogVolumeHit(
|
|
|
6370
6530
|
// alphaMap
|
|
6371
6531
|
if ( material.alphaMap != - 1 ) {
|
|
6372
6532
|
|
|
6373
|
-
|
|
6533
|
+
vec3 uvPrime = material.alphaMapTransform * vec3( uv, 1 );
|
|
6534
|
+
albedo.a *= texture2D( textures, vec3( uvPrime.xy, material.alphaMap ) ).x;
|
|
6374
6535
|
|
|
6375
6536
|
}
|
|
6376
6537
|
|
|
@@ -6512,7 +6673,7 @@ bool bvhIntersectFogVolumeHit(
|
|
|
6512
6673
|
vec3 shapeUVW= rand3( 1 );
|
|
6513
6674
|
int blades = physicalCamera.apertureBlades;
|
|
6514
6675
|
float anamorphicRatio = physicalCamera.anamorphicRatio;
|
|
6515
|
-
vec2 apertureSample =
|
|
6676
|
+
vec2 apertureSample = sampleAperture( blades, shapeUVW );
|
|
6516
6677
|
apertureSample *= physicalCamera.bokehSize * 0.5 * 1e-3;
|
|
6517
6678
|
|
|
6518
6679
|
// rotate the aperture shape
|
|
@@ -6682,7 +6843,8 @@ bool bvhIntersectFogVolumeHit(
|
|
|
6682
6843
|
// alphaMap
|
|
6683
6844
|
if ( material.alphaMap != - 1 ) {
|
|
6684
6845
|
|
|
6685
|
-
|
|
6846
|
+
vec3 uvPrime = material.alphaMapTransform * vec3( uv, 1 );
|
|
6847
|
+
albedo.a *= texture2D( textures, vec3( uvPrime.xy, material.alphaMap ) ).x;
|
|
6686
6848
|
|
|
6687
6849
|
}
|
|
6688
6850
|
|
|
@@ -7097,6 +7259,7 @@ bool bvhIntersectFogVolumeHit(
|
|
|
7097
7259
|
ATTR_TANGENT: 1,
|
|
7098
7260
|
ATTR_UV: 2,
|
|
7099
7261
|
ATTR_COLOR: 3,
|
|
7262
|
+
MATERIAL_PIXELS: MATERIAL_PIXELS,
|
|
7100
7263
|
},
|
|
7101
7264
|
|
|
7102
7265
|
uniforms: {
|
|
@@ -7779,6 +7942,9 @@ bool bvhIntersectFogVolumeHit(
|
|
|
7779
7942
|
|
|
7780
7943
|
set material( v ) {
|
|
7781
7944
|
|
|
7945
|
+
this._fsQuad.material.removeEventListener( 'recompilation', this._compileFunction );
|
|
7946
|
+
v.addEventListener( 'recompilation', this._compileFunction );
|
|
7947
|
+
|
|
7782
7948
|
this._fsQuad.material = v;
|
|
7783
7949
|
|
|
7784
7950
|
}
|
|
@@ -7815,6 +7981,12 @@ bool bvhIntersectFogVolumeHit(
|
|
|
7815
7981
|
|
|
7816
7982
|
}
|
|
7817
7983
|
|
|
7984
|
+
get isCompiling() {
|
|
7985
|
+
|
|
7986
|
+
return Boolean( this._compilePromise );
|
|
7987
|
+
|
|
7988
|
+
}
|
|
7989
|
+
|
|
7818
7990
|
constructor( renderer ) {
|
|
7819
7991
|
|
|
7820
7992
|
this.camera = null;
|
|
@@ -7832,6 +8004,7 @@ bool bvhIntersectFogVolumeHit(
|
|
|
7832
8004
|
this._blendQuad = new Pass_js.FullScreenQuad( new BlendMaterial() );
|
|
7833
8005
|
this._task = null;
|
|
7834
8006
|
this._currentTile = 0;
|
|
8007
|
+
this._compilePromise = null;
|
|
7835
8008
|
|
|
7836
8009
|
this._sobolTarget = new SobolNumberMapGenerator().generate( renderer );
|
|
7837
8010
|
|
|
@@ -7856,6 +8029,33 @@ bool bvhIntersectFogVolumeHit(
|
|
|
7856
8029
|
} ),
|
|
7857
8030
|
];
|
|
7858
8031
|
|
|
8032
|
+
// function for listening to for triggered compilation so we can wait for compilation to finish
|
|
8033
|
+
// before starting to render
|
|
8034
|
+
this._compileFunction = () => {
|
|
8035
|
+
|
|
8036
|
+
const promise = this.compileMaterial( this._fsQuad._mesh );
|
|
8037
|
+
promise.then( () => {
|
|
8038
|
+
|
|
8039
|
+
if ( this._compilePromise === promise ) {
|
|
8040
|
+
|
|
8041
|
+
this._compilePromise = null;
|
|
8042
|
+
|
|
8043
|
+
}
|
|
8044
|
+
|
|
8045
|
+
} );
|
|
8046
|
+
|
|
8047
|
+
this._compilePromise = promise;
|
|
8048
|
+
|
|
8049
|
+
};
|
|
8050
|
+
|
|
8051
|
+
this.material.addEventListener( 'recompilation', this._compileFunction );
|
|
8052
|
+
|
|
8053
|
+
}
|
|
8054
|
+
|
|
8055
|
+
compileMaterial() {
|
|
8056
|
+
|
|
8057
|
+
return this._renderer.compileAsync( this._fsQuad._mesh );
|
|
8058
|
+
|
|
7859
8059
|
}
|
|
7860
8060
|
|
|
7861
8061
|
setCamera( camera ) {
|
|
@@ -7887,7 +8087,6 @@ bool bvhIntersectFogVolumeHit(
|
|
|
7887
8087
|
material.setDefine( 'CAMERA_TYPE', cameraType );
|
|
7888
8088
|
|
|
7889
8089
|
this.camera = camera;
|
|
7890
|
-
// this.reset();
|
|
7891
8090
|
|
|
7892
8091
|
}
|
|
7893
8092
|
|
|
@@ -7954,9 +8153,11 @@ bool bvhIntersectFogVolumeHit(
|
|
|
7954
8153
|
this.samples = 0;
|
|
7955
8154
|
this._task = null;
|
|
7956
8155
|
|
|
8156
|
+
this.material.stratifiedTexture.stableNoise = this.stableNoise;
|
|
7957
8157
|
if ( this.stableNoise ) {
|
|
7958
8158
|
|
|
7959
8159
|
this.material.seed = 0;
|
|
8160
|
+
this.material.stratifiedTexture.reset();
|
|
7960
8161
|
|
|
7961
8162
|
}
|
|
7962
8163
|
|
|
@@ -7964,6 +8165,15 @@ bool bvhIntersectFogVolumeHit(
|
|
|
7964
8165
|
|
|
7965
8166
|
update() {
|
|
7966
8167
|
|
|
8168
|
+
// ensure we've updated our defines before rendering so we can ensure we
|
|
8169
|
+
// can wait for compilation to finish
|
|
8170
|
+
this.material.onBeforeRender();
|
|
8171
|
+
if ( this.isCompiling ) {
|
|
8172
|
+
|
|
8173
|
+
return;
|
|
8174
|
+
|
|
8175
|
+
}
|
|
8176
|
+
|
|
7967
8177
|
if ( ! this._task ) {
|
|
7968
8178
|
|
|
7969
8179
|
this._task = renderTask.call( this );
|
|
@@ -8183,6 +8393,150 @@ bool bvhIntersectFogVolumeHit(
|
|
|
8183
8393
|
|
|
8184
8394
|
}
|
|
8185
8395
|
|
|
8396
|
+
class CubeToEquirectMaterial extends three.ShaderMaterial {
|
|
8397
|
+
|
|
8398
|
+
constructor() {
|
|
8399
|
+
|
|
8400
|
+
super( {
|
|
8401
|
+
|
|
8402
|
+
uniforms: {
|
|
8403
|
+
|
|
8404
|
+
envMap: { value: null },
|
|
8405
|
+
flipEnvMap: { value: - 1 },
|
|
8406
|
+
|
|
8407
|
+
},
|
|
8408
|
+
|
|
8409
|
+
vertexShader: /* glsl */`
|
|
8410
|
+
varying vec2 vUv;
|
|
8411
|
+
void main() {
|
|
8412
|
+
|
|
8413
|
+
vUv = uv;
|
|
8414
|
+
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
|
|
8415
|
+
|
|
8416
|
+
}`,
|
|
8417
|
+
|
|
8418
|
+
fragmentShader: /* glsl */`
|
|
8419
|
+
#define ENVMAP_TYPE_CUBE_UV
|
|
8420
|
+
|
|
8421
|
+
uniform samplerCube envMap;
|
|
8422
|
+
uniform float flipEnvMap;
|
|
8423
|
+
varying vec2 vUv;
|
|
8424
|
+
|
|
8425
|
+
#include <common>
|
|
8426
|
+
#include <cube_uv_reflection_fragment>
|
|
8427
|
+
|
|
8428
|
+
${ util_functions }
|
|
8429
|
+
|
|
8430
|
+
void main() {
|
|
8431
|
+
|
|
8432
|
+
vec3 rayDirection = equirectUvToDirection( vUv );
|
|
8433
|
+
rayDirection.x *= flipEnvMap;
|
|
8434
|
+
gl_FragColor = textureCube( envMap, rayDirection );
|
|
8435
|
+
|
|
8436
|
+
}`
|
|
8437
|
+
} );
|
|
8438
|
+
|
|
8439
|
+
this.depthWrite = false;
|
|
8440
|
+
this.depthTest = false;
|
|
8441
|
+
|
|
8442
|
+
}
|
|
8443
|
+
|
|
8444
|
+
}
|
|
8445
|
+
|
|
8446
|
+
class CubeToEquirectGenerator {
|
|
8447
|
+
|
|
8448
|
+
constructor( renderer ) {
|
|
8449
|
+
|
|
8450
|
+
this._renderer = renderer;
|
|
8451
|
+
this._quad = new Pass_js.FullScreenQuad( new CubeToEquirectMaterial() );
|
|
8452
|
+
|
|
8453
|
+
}
|
|
8454
|
+
|
|
8455
|
+
generate( source, width = null, height = null ) {
|
|
8456
|
+
|
|
8457
|
+
if ( ! source.isCubeTexture ) {
|
|
8458
|
+
|
|
8459
|
+
throw new Error( 'CubeToEquirectMaterial: Source can only be cube textures.' );
|
|
8460
|
+
|
|
8461
|
+
}
|
|
8462
|
+
|
|
8463
|
+
const image = source.images[ 0 ];
|
|
8464
|
+
const renderer = this._renderer;
|
|
8465
|
+
const quad = this._quad;
|
|
8466
|
+
|
|
8467
|
+
// determine the dimensions if not provided
|
|
8468
|
+
if ( width === null ) {
|
|
8469
|
+
|
|
8470
|
+
width = 4 * image.height;
|
|
8471
|
+
|
|
8472
|
+
}
|
|
8473
|
+
|
|
8474
|
+
if ( height === null ) {
|
|
8475
|
+
|
|
8476
|
+
height = 2 * image.height;
|
|
8477
|
+
|
|
8478
|
+
}
|
|
8479
|
+
|
|
8480
|
+
const target = new three.WebGLRenderTarget( width, height, {
|
|
8481
|
+
type: three.FloatType,
|
|
8482
|
+
colorSpace: image.colorSpace,
|
|
8483
|
+
} );
|
|
8484
|
+
|
|
8485
|
+
// prep the cube map data
|
|
8486
|
+
const imageHeight = image.height;
|
|
8487
|
+
const maxMip = Math.log2( imageHeight ) - 2;
|
|
8488
|
+
const texelHeight = 1.0 / imageHeight;
|
|
8489
|
+
const texelWidth = 1.0 / ( 3 * Math.max( Math.pow( 2, maxMip ), 7 * 16 ) );
|
|
8490
|
+
|
|
8491
|
+
quad.material.defines.CUBEUV_MAX_MIP = `${ maxMip }.0`;
|
|
8492
|
+
quad.material.defines.CUBEUV_TEXEL_WIDTH = texelWidth;
|
|
8493
|
+
quad.material.defines.CUBEUV_TEXEL_HEIGHT = texelHeight;
|
|
8494
|
+
quad.material.uniforms.envMap.value = source;
|
|
8495
|
+
quad.material.uniforms.flipEnvMap.value = source.isRenderTargetTexture ? 1 : - 1;
|
|
8496
|
+
quad.material.needsUpdate = true;
|
|
8497
|
+
|
|
8498
|
+
// save state and render the contents
|
|
8499
|
+
const currentTarget = renderer.getRenderTarget();
|
|
8500
|
+
const currentAutoClear = renderer.autoClear;
|
|
8501
|
+
renderer.autoClear = true;
|
|
8502
|
+
renderer.setRenderTarget( target );
|
|
8503
|
+
quad.render( renderer );
|
|
8504
|
+
renderer.setRenderTarget( currentTarget );
|
|
8505
|
+
renderer.autoClear = currentAutoClear;
|
|
8506
|
+
|
|
8507
|
+
// read the data back
|
|
8508
|
+
const buffer = new Uint16Array( width * height * 4 );
|
|
8509
|
+
const readBuffer = new Float32Array( width * height * 4 );
|
|
8510
|
+
renderer.readRenderTargetPixels( target, 0, 0, width, height, readBuffer );
|
|
8511
|
+
target.dispose();
|
|
8512
|
+
|
|
8513
|
+
for ( let i = 0, l = readBuffer.length; i < l; i ++ ) {
|
|
8514
|
+
|
|
8515
|
+
buffer[ i ] = three.DataUtils.toHalfFloat( readBuffer[ i ] );
|
|
8516
|
+
|
|
8517
|
+
}
|
|
8518
|
+
|
|
8519
|
+
// produce the data texture
|
|
8520
|
+
const result = new three.DataTexture( buffer, width, height, three.RGBAFormat, three.HalfFloatType );
|
|
8521
|
+
result.minFilter = three.LinearMipMapLinearFilter;
|
|
8522
|
+
result.magFilter = three.LinearFilter;
|
|
8523
|
+
result.wrapS = three.RepeatWrapping;
|
|
8524
|
+
result.wrapT = three.RepeatWrapping;
|
|
8525
|
+
result.mapping = three.EquirectangularReflectionMapping;
|
|
8526
|
+
result.needsUpdate = true;
|
|
8527
|
+
|
|
8528
|
+
return result;
|
|
8529
|
+
|
|
8530
|
+
}
|
|
8531
|
+
|
|
8532
|
+
dispose() {
|
|
8533
|
+
|
|
8534
|
+
this._quad.dispose();
|
|
8535
|
+
|
|
8536
|
+
}
|
|
8537
|
+
|
|
8538
|
+
}
|
|
8539
|
+
|
|
8186
8540
|
function supportsFloatBlending( renderer ) {
|
|
8187
8541
|
|
|
8188
8542
|
return renderer.extensions.get( 'EXT_float_blend' );
|
|
@@ -8258,6 +8612,24 @@ bool bvhIntersectFogVolumeHit(
|
|
|
8258
8612
|
|
|
8259
8613
|
}
|
|
8260
8614
|
|
|
8615
|
+
get stableNoise() {
|
|
8616
|
+
|
|
8617
|
+
return this._pathTracer.stableNoise;
|
|
8618
|
+
|
|
8619
|
+
}
|
|
8620
|
+
|
|
8621
|
+
set stableNoise( v ) {
|
|
8622
|
+
|
|
8623
|
+
this._pathTracer.stableNoise = v;
|
|
8624
|
+
|
|
8625
|
+
}
|
|
8626
|
+
|
|
8627
|
+
get isCompiling() {
|
|
8628
|
+
|
|
8629
|
+
return Boolean( this._pathTracer.isCompiling );
|
|
8630
|
+
|
|
8631
|
+
}
|
|
8632
|
+
|
|
8261
8633
|
constructor( renderer ) {
|
|
8262
8634
|
|
|
8263
8635
|
// members
|
|
@@ -8266,6 +8638,7 @@ bool bvhIntersectFogVolumeHit(
|
|
|
8266
8638
|
this._pathTracer = new PathTracingRenderer( renderer );
|
|
8267
8639
|
this._queueReset = false;
|
|
8268
8640
|
this._clock = new three.Clock();
|
|
8641
|
+
this._compilePromise = null;
|
|
8269
8642
|
|
|
8270
8643
|
this._lowResPathTracer = new PathTracingRenderer( renderer );
|
|
8271
8644
|
this._lowResPathTracer.tiles.set( 1, 1 );
|
|
@@ -8278,6 +8651,10 @@ bool bvhIntersectFogVolumeHit(
|
|
|
8278
8651
|
} ) );
|
|
8279
8652
|
this._materials = null;
|
|
8280
8653
|
|
|
8654
|
+
this._previousEnvironment = null;
|
|
8655
|
+
this._previousBackground = null;
|
|
8656
|
+
this._internalBackground = null;
|
|
8657
|
+
|
|
8281
8658
|
// options
|
|
8282
8659
|
this.renderDelay = 100;
|
|
8283
8660
|
this.minSamples = 5;
|
|
@@ -8406,6 +8783,13 @@ bool bvhIntersectFogVolumeHit(
|
|
|
8406
8783
|
const scene = this.scene;
|
|
8407
8784
|
const material = this._pathTracer.material;
|
|
8408
8785
|
|
|
8786
|
+
if ( this._internalBackground ) {
|
|
8787
|
+
|
|
8788
|
+
this._internalBackground.dispose();
|
|
8789
|
+
this._internalBackground = null;
|
|
8790
|
+
|
|
8791
|
+
}
|
|
8792
|
+
|
|
8409
8793
|
// update scene background
|
|
8410
8794
|
material.backgroundBlur = scene.backgroundBlurriness;
|
|
8411
8795
|
material.backgroundIntensity = scene.backgroundIntensity ?? 1;
|
|
@@ -8433,6 +8817,17 @@ bool bvhIntersectFogVolumeHit(
|
|
|
8433
8817
|
material.backgroundMap = colorBackground;
|
|
8434
8818
|
material.backgroundAlpha = 1;
|
|
8435
8819
|
|
|
8820
|
+
} else if ( scene.background.isCubeTexture ) {
|
|
8821
|
+
|
|
8822
|
+
if ( scene.background !== this._previousBackground ) {
|
|
8823
|
+
|
|
8824
|
+
const background = new CubeToEquirectGenerator( this._renderer ).generate( scene.background );
|
|
8825
|
+
this._internalBackground = background;
|
|
8826
|
+
material.backgroundMap = background;
|
|
8827
|
+
material.backgroundAlpha = 1;
|
|
8828
|
+
|
|
8829
|
+
}
|
|
8830
|
+
|
|
8436
8831
|
} else {
|
|
8437
8832
|
|
|
8438
8833
|
material.backgroundMap = scene.background;
|
|
@@ -8441,26 +8836,32 @@ bool bvhIntersectFogVolumeHit(
|
|
|
8441
8836
|
}
|
|
8442
8837
|
|
|
8443
8838
|
// update scene environment
|
|
8444
|
-
material.environmentIntensity = scene.environmentIntensity ?? 1;
|
|
8839
|
+
material.environmentIntensity = scene.environment !== null ? ( scene.environmentIntensity ?? 1 ) : 0;
|
|
8445
8840
|
material.environmentRotation.makeRotationFromEuler( scene.environmentRotation ).invert();
|
|
8446
8841
|
if ( this._previousEnvironment !== scene.environment ) {
|
|
8447
8842
|
|
|
8448
|
-
if ( scene.environment ) {
|
|
8843
|
+
if ( scene.environment !== null ) {
|
|
8449
8844
|
|
|
8450
|
-
|
|
8451
|
-
// OES_texture_float_linear or OES_texture_half_float_linear. Requires changes to
|
|
8452
|
-
// the equirect uniform
|
|
8453
|
-
material.envMapInfo.updateFrom( scene.environment );
|
|
8845
|
+
if ( scene.environment.isCubeTexture ) {
|
|
8454
8846
|
|
|
8455
|
-
|
|
8847
|
+
const environment = new CubeToEquirectGenerator( this._renderer ).generate( scene.environment );
|
|
8848
|
+
material.envMapInfo.updateFrom( environment );
|
|
8849
|
+
|
|
8850
|
+
} else {
|
|
8851
|
+
|
|
8852
|
+
// TODO: Consider setting this to the highest supported bit depth by checking for
|
|
8853
|
+
// OES_texture_float_linear or OES_texture_half_float_linear. Requires changes to
|
|
8854
|
+
// the equirect uniform
|
|
8855
|
+
material.envMapInfo.updateFrom( scene.environment );
|
|
8456
8856
|
|
|
8457
|
-
|
|
8857
|
+
}
|
|
8458
8858
|
|
|
8459
8859
|
}
|
|
8460
8860
|
|
|
8461
8861
|
}
|
|
8462
8862
|
|
|
8463
8863
|
this._previousEnvironment = scene.environment;
|
|
8864
|
+
this._previousBackground = scene.background;
|
|
8464
8865
|
this.reset();
|
|
8465
8866
|
|
|
8466
8867
|
}
|
|
@@ -8472,6 +8873,7 @@ bool bvhIntersectFogVolumeHit(
|
|
|
8472
8873
|
geometry,
|
|
8473
8874
|
bvh,
|
|
8474
8875
|
bvhChanged,
|
|
8876
|
+
needsMaterialIndexUpdate,
|
|
8475
8877
|
} = results;
|
|
8476
8878
|
|
|
8477
8879
|
this._materials = materials;
|
|
@@ -8489,6 +8891,10 @@ bool bvhIntersectFogVolumeHit(
|
|
|
8489
8891
|
geometry.attributes.color,
|
|
8490
8892
|
);
|
|
8491
8893
|
|
|
8894
|
+
}
|
|
8895
|
+
|
|
8896
|
+
if ( needsMaterialIndexUpdate ) {
|
|
8897
|
+
|
|
8492
8898
|
material.materialIndexAttribute.updateFrom( geometry.attributes.materialIndex );
|
|
8493
8899
|
|
|
8494
8900
|
}
|
|
@@ -8531,7 +8937,7 @@ bool bvhIntersectFogVolumeHit(
|
|
|
8531
8937
|
// render the path tracing sample after enough time has passed
|
|
8532
8938
|
const delta = clock.getDelta() * 1e3;
|
|
8533
8939
|
const elapsedTime = clock.getElapsedTime() * 1e3;
|
|
8534
|
-
if ( ! this.pausePathTracing && this.enablePathTracing && this.renderDelay <= elapsedTime ) {
|
|
8940
|
+
if ( ! this.pausePathTracing && this.enablePathTracing && this.renderDelay <= elapsedTime && ! this.isCompiling ) {
|
|
8535
8941
|
|
|
8536
8942
|
pathTracer.update();
|
|
8537
8943
|
|
|
@@ -8564,7 +8970,7 @@ bool bvhIntersectFogVolumeHit(
|
|
|
8564
8970
|
// render the fallback if we haven't rendered enough samples, are paused, or are occluded
|
|
8565
8971
|
if ( ! this.enablePathTracing || this.samples < minSamples || quad.material.opacity < 1 ) {
|
|
8566
8972
|
|
|
8567
|
-
if ( this.dynamicLowRes ) {
|
|
8973
|
+
if ( this.dynamicLowRes && ! this.isCompiling ) {
|
|
8568
8974
|
|
|
8569
8975
|
if ( lowResPathTracer.samples < 1 ) {
|
|
8570
8976
|
|
|
@@ -8579,7 +8985,9 @@ bool bvhIntersectFogVolumeHit(
|
|
|
8579
8985
|
quad.render( renderer );
|
|
8580
8986
|
quad.material.opacity = currentOpacity;
|
|
8581
8987
|
|
|
8582
|
-
}
|
|
8988
|
+
}
|
|
8989
|
+
|
|
8990
|
+
if ( ! this.dynamicLowRes && this.rasterizeScene || this.dynamicLowRes && this.isCompiling ) {
|
|
8583
8991
|
|
|
8584
8992
|
this.rasterizeSceneCallback( this.scene, this.camera );
|
|
8585
8993
|
|
|
@@ -8617,8 +9025,8 @@ bool bvhIntersectFogVolumeHit(
|
|
|
8617
9025
|
|
|
8618
9026
|
dispose() {
|
|
8619
9027
|
|
|
8620
|
-
this.
|
|
8621
|
-
this.
|
|
9028
|
+
this._quad.dispose();
|
|
9029
|
+
this._quad.material.dispose();
|
|
8622
9030
|
this._pathTracer.dispose();
|
|
8623
9031
|
|
|
8624
9032
|
}
|