rayzee 11.7.0 → 11.9.0
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 +31 -6
- package/dist/{ArchiveImporter-DYcRXeKE.js → ArchiveImporter-BJxszU_k.js} +2353 -1356
- package/dist/{BidirectionalIntegrator-BvjRpbTP.js → BidirectionalIntegrator-DWg66vAd.js} +302 -301
- package/dist/{BufferLayout-xPRH9jYD.js → BufferLayout-Bzgccg1o.js} +1 -0
- package/dist/{ColorManagement-oeEk7oSu.js → ColorManagement-B_HjAiy2.js} +1 -1
- package/dist/{EngineIssues-CIZnXHsF.js → EngineIssues-CfJiBaNj.js} +19 -8
- package/dist/{NeuralRetouch-ClaMiKYg.js → NeuralRetouch-BD9E-Yht.js} +2 -2
- package/dist/{NeuralSuperRes-WNEXun9s.js → NeuralSuperRes-C8Mf3tJX.js} +2 -2
- package/dist/{PathTracer-B9wZPPVL.js → PathTracer-DeE9UJ1n.js} +3530 -3402
- package/dist/{PhysicalSky-DcjItqKi.js → PhysicalSky-cKy75-oR.js} +45 -45
- package/dist/{RayzeeRenderer-p-NeE6E2.js → RayzeeRenderer-CzLyBA3G.js} +378 -374
- package/dist/SceneMetadata-C17UfOEp.js +183 -0
- package/dist/{SolarLimb-bZE6y63S.js → SolarLimb-DRYy8tln.js} +184 -172
- package/dist/{ToneMapGPU-sAs8wdgI.js → ToneMapGPU-4GPwoG_c.js} +13 -6
- package/dist/addons/archives.es.js +1 -1
- package/dist/addons/bidirectional.es.js +1 -1
- package/dist/addons/color.es.js +1 -1
- package/dist/addons/physical-sky.es.js +1 -1
- package/dist/addons/storage.es.js +1 -1
- package/dist/{openStorage-Fe9BoS1_.js → openStorage-CdyVjmps.js} +1 -1
- package/dist/rayzee-core.es.js +7 -7
- package/dist/rayzee.es.js +821 -794
- package/dist/rayzee.umd.js +112 -103
- package/dist/{sceneCachePolicy-B9w3BnaP.js → sceneCachePolicy-ywbGKHD3.js} +9 -6
- package/package.json +1 -1
- package/src/EngineDefaults.js +1 -0
- package/src/EngineIssues.js +21 -6
- package/src/Passes/AIUpscaler.js +4 -0
- package/src/Passes/OIDNDenoiser.js +8 -6
- package/src/Passes/OIDNTemporalHistory.js +1 -1
- package/src/PathTracerApp.js +10 -1
- package/src/Processor/ArchiveImporter.js +106 -27
- package/src/Processor/AssetLoader.js +22 -0
- package/src/Processor/BufferLayout.js +3 -3
- package/src/Processor/GeometryExtractor.js +12 -4
- package/src/Processor/LightSerializer.js +6 -2
- package/src/Processor/MaterialPacking.js +2 -2
- package/src/Processor/PBRT/PBRTMaterials.js +49 -13
- package/src/Processor/PBRT/PBRTParser.js +144 -22
- package/src/Processor/PBRT/PBRTSceneBuilder.js +287 -67
- package/src/Processor/PBRT/PBRTTextureBake.js +191 -9
- package/src/Processor/PBRT/index.js +19 -4
- package/src/Processor/PlatformImageLoader.js +9 -0
- package/src/Processor/SceneProcessor.js +42 -26
- package/src/Processor/TextureCreator.js +44 -4
- package/src/Processor/ToneMapCPU.js +34 -5
- package/src/Processor/ToneMapGPU.js +15 -9
- package/src/Processor/USD/USDScene.js +981 -17
- package/src/RayzeeRenderer.js +85 -28
- package/src/Stages/AutoExposure.js +21 -8
- package/src/Stages/Compositor.js +39 -1
- package/src/Stages/DenoiserSettings.js +0 -4
- package/src/Stages/LocalExposure.js +44 -18
- package/src/Stages/NRD.js +53 -24
- package/src/Stages/NormalDepth.js +12 -6
- package/src/Stages/PathTracer.js +27 -1
- package/src/Stages/PathTracerStage.js +14 -2
- package/src/Storage/SceneGraphCodec.js +6 -3
- package/src/TSL/BVHTraversal.js +33 -20
- package/src/TSL/CameraRay.js +12 -1
- package/src/TSL/Common.js +25 -8
- package/src/TSL/DebugKernel.js +3 -2
- package/src/TSL/Displacement.js +66 -113
- package/src/TSL/FinalWriteKernel.js +4 -7
- package/src/TSL/GenerateKernel.js +6 -2
- package/src/TSL/LightSplatKernel.js +7 -4
- package/src/TSL/LightsCore.js +6 -2
- package/src/TSL/LightsDirect.js +33 -11
- package/src/TSL/LightsSampling.js +45 -12
- package/src/TSL/SceneResources.js +19 -0
- package/src/TSL/ShadeKernel.js +3 -4
- package/src/TSL/Struct.js +1 -0
- package/src/integrators/BidirectionalIntegrator.js +1 -0
- package/src/managers/CameraManager.js +9 -0
- package/src/managers/DenoisingManager.js +1 -0
- package/src/managers/InteractionManager.js +6 -0
- package/src/managers/MaterialDataManager.js +11 -0
- package/src/managers/UniformManager.js +3 -1
- package/dist/SceneMetadata-D2Sh-0e-.js +0 -110
|
@@ -86,7 +86,9 @@ import {
|
|
|
86
86
|
offsetRayOrigin,
|
|
87
87
|
SHADOW_END,
|
|
88
88
|
REC709_LUMINANCE_COEFFICIENTS,
|
|
89
|
+
constructTBN,
|
|
89
90
|
} from './Common.js';
|
|
91
|
+
import { usesLightRadius } from './SceneResources.js';
|
|
90
92
|
import { sampleEnvironment, sampleEnvironmentExact } from './Environment.js';
|
|
91
93
|
import { shadowTerminatorOrigin } from './ShadowTerminator.js';
|
|
92
94
|
import { sunRadianceToward, sampleSunDisc } from './Sun.js';
|
|
@@ -233,8 +235,30 @@ export const sampleRectAreaLight = Fn( ( [ light, rayOrigin, ruv, lightSelection
|
|
|
233
235
|
|
|
234
236
|
} );
|
|
235
237
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
+
/**
|
|
239
|
+
* A point or spot light with a radius is a disc of it facing the lit point, as Cycles' with Soft Falloff: uniform on the
|
|
240
|
+
* disc, so on its axis the light gives intensity / ( d² + r² ) where a point gives intensity / d². Moves `toLight` and
|
|
241
|
+
* `distSq` to the sampled point and returns the disc's tilt toward it. No BSDF ray hits these lights, so no MIS.
|
|
242
|
+
*/
|
|
243
|
+
const aimAtLightDisc = ( light, toLight, distSq, ruv ) => {
|
|
244
|
+
|
|
245
|
+
const facing = float( 1.0 ).toVar();
|
|
246
|
+
If( light.radius.greaterThan( 0.0 ), () => {
|
|
247
|
+
|
|
248
|
+
const axis = toLight.div( sqrt( distSq ) ).toVar();
|
|
249
|
+
const r = light.radius.mul( sqrt( ruv.x ) );
|
|
250
|
+
const phi = ruv.y.mul( 2 * Math.PI );
|
|
251
|
+
toLight.addAssign( constructTBN( { N: axis } ).mul( vec3( r.mul( cos( phi ) ), r.mul( sin( phi ) ), 0.0 ) ) );
|
|
252
|
+
distSq.assign( dot( toLight, toLight ) );
|
|
253
|
+
facing.assign( max( dot( toLight, axis ).div( sqrt( distSq ) ), 0.0 ) );
|
|
254
|
+
|
|
255
|
+
} );
|
|
256
|
+
return facing;
|
|
257
|
+
|
|
258
|
+
};
|
|
259
|
+
|
|
260
|
+
// Spot light sampling; a radius makes it a disc (aimAtLightDisc), its cone still read from the centre.
|
|
261
|
+
export const sampleSpotLightWithRadius = Fn( ( [ light, rayOrigin, lightSelectionPdf, ruv ], builder ) => {
|
|
238
262
|
|
|
239
263
|
const ls_valid = tslBool( false ).toVar();
|
|
240
264
|
const ls_direction = vec3( 0.0, 1.0, 0.0 ).toVar();
|
|
@@ -250,11 +274,16 @@ export const sampleSpotLightWithRadius = Fn( ( [ light, rayOrigin, lightSelectio
|
|
|
250
274
|
// Guard against zero distance
|
|
251
275
|
If( lightDistSq.greaterThanEqual( 1e-20 ), () => {
|
|
252
276
|
|
|
277
|
+
// Compiled in only while some light has a radius (SceneResources lightRadius); otherwise the exact point code.
|
|
278
|
+
const sized = usesLightRadius( builder );
|
|
279
|
+
const centerDir = sized ? toLight.div( sqrt( lightDistSq ) ).toVar() : null;
|
|
280
|
+
const facing = sized ? aimAtLightDisc( light, toLight, lightDistSq, ruv ) : null;
|
|
253
281
|
const lightDist = sqrt( lightDistSq ).toVar();
|
|
254
282
|
const lightDir = toLight.div( lightDist ).toVar();
|
|
283
|
+
const coneDir = sized ? centerDir : lightDir;
|
|
255
284
|
|
|
256
285
|
// Check cone attenuation
|
|
257
|
-
const spotCosAngle = dot(
|
|
286
|
+
const spotCosAngle = dot( coneDir.negate(), light.direction ).toVar();
|
|
258
287
|
const coneCosAngle = cos( light.angle ).toVar();
|
|
259
288
|
|
|
260
289
|
ls_direction.assign( lightDir );
|
|
@@ -268,10 +297,11 @@ export const sampleSpotLightWithRadius = Fn( ( [ light, rayOrigin, lightSelectio
|
|
|
268
297
|
const distanceAttenuation = getDistanceAttenuation( { lightDistance: lightDist, cutoffDistance: light.distance, decayExponent: light.decay } );
|
|
269
298
|
|
|
270
299
|
// Gobo projection mask + IES photometric profile — both 1.0 when not assigned.
|
|
271
|
-
const goboMask = sampleSpotGoboMask( light,
|
|
272
|
-
const iesProfile = sampleIESProfile( light,
|
|
300
|
+
const goboMask = sampleSpotGoboMask( light, coneDir );
|
|
301
|
+
const iesProfile = sampleIESProfile( light, coneDir );
|
|
273
302
|
|
|
274
|
-
|
|
303
|
+
const emission = light.color.mul( light.intensity ).mul( distanceAttenuation ).mul( coneAttenuation ).mul( goboMask ).mul( iesProfile );
|
|
304
|
+
ls_emission.assign( sized ? emission.mul( facing ) : emission );
|
|
275
305
|
|
|
276
306
|
} );
|
|
277
307
|
|
|
@@ -290,7 +320,7 @@ export const sampleSpotLightWithRadius = Fn( ( [ light, rayOrigin, lightSelectio
|
|
|
290
320
|
} );
|
|
291
321
|
|
|
292
322
|
// Enhanced point light sampling with distance attenuation
|
|
293
|
-
export const samplePointLightWithAttenuation = Fn( ( [ light, rayOrigin, lightSelectionPdf ] ) => {
|
|
323
|
+
export const samplePointLightWithAttenuation = Fn( ( [ light, rayOrigin, lightSelectionPdf, ruv ], builder ) => {
|
|
294
324
|
|
|
295
325
|
const ls_valid = tslBool( false ).toVar();
|
|
296
326
|
const ls_direction = vec3( 0.0, 1.0, 0.0 ).toVar();
|
|
@@ -306,6 +336,8 @@ export const samplePointLightWithAttenuation = Fn( ( [ light, rayOrigin, lightSe
|
|
|
306
336
|
// Guard against zero distance
|
|
307
337
|
If( lightDistSq.greaterThanEqual( 1e-20 ), () => {
|
|
308
338
|
|
|
339
|
+
const sized = usesLightRadius( builder );
|
|
340
|
+
const facing = sized ? aimAtLightDisc( light, toLight, lightDistSq, ruv ) : null;
|
|
309
341
|
const lightDist = sqrt( lightDistSq ).toVar();
|
|
310
342
|
const lightDir = toLight.div( lightDist );
|
|
311
343
|
|
|
@@ -315,7 +347,8 @@ export const samplePointLightWithAttenuation = Fn( ( [ light, rayOrigin, lightSe
|
|
|
315
347
|
ls_lightType.assign( int( LIGHT_TYPE_POINT ) );
|
|
316
348
|
ls_direction.assign( lightDir );
|
|
317
349
|
ls_distance.assign( lightDist );
|
|
318
|
-
|
|
350
|
+
const emission = light.color.mul( light.intensity ).mul( distanceAttenuation );
|
|
351
|
+
ls_emission.assign( sized ? emission.mul( facing ) : emission );
|
|
319
352
|
ls_pdf.assign( lightSelectionPdf );
|
|
320
353
|
ls_valid.assign( tslBool( true ) );
|
|
321
354
|
|
|
@@ -614,7 +647,7 @@ export const sampleLightWithImportance = Fn( ( [
|
|
|
614
647
|
|
|
615
648
|
If( light.intensity.greaterThan( 0.0 ), () => {
|
|
616
649
|
|
|
617
|
-
const ptSample = LightSample.wrap( samplePointLightWithAttenuation( light, rayOrigin, lightSelectionPdf ) );
|
|
650
|
+
const ptSample = LightSample.wrap( samplePointLightWithAttenuation( light, rayOrigin, lightSelectionPdf, vec2( randomSeed.y, getRandomSample1D( pixelCoord, int( 0 ), dimBase.add( int( 15 ) ), rngState, resolution, frame ) ) ) );
|
|
618
651
|
r_valid.assign( ptSample.valid );
|
|
619
652
|
r_direction.assign( ptSample.direction );
|
|
620
653
|
r_emission.assign( ptSample.emission );
|
|
@@ -639,7 +672,7 @@ export const sampleLightWithImportance = Fn( ( [
|
|
|
639
672
|
|
|
640
673
|
If( light.intensity.greaterThan( 0.0 ), () => {
|
|
641
674
|
|
|
642
|
-
const spotSample = LightSample.wrap( sampleSpotLightWithRadius( light, rayOrigin, lightSelectionPdf ) );
|
|
675
|
+
const spotSample = LightSample.wrap( sampleSpotLightWithRadius( light, rayOrigin, lightSelectionPdf, vec2( randomSeed.y, getRandomSample1D( pixelCoord, int( 0 ), dimBase.add( int( 15 ) ), rngState, resolution, frame ) ) ) );
|
|
643
676
|
r_valid.assign( spotSample.valid );
|
|
644
677
|
r_direction.assign( spotSample.direction );
|
|
645
678
|
r_emission.assign( spotSample.emission );
|
|
@@ -702,7 +735,7 @@ export const sampleLightWithImportance = Fn( ( [
|
|
|
702
735
|
If( selectedType.equal( int( 2 ) ).and( selectedIdx.greaterThanEqual( int( 0 ) ) ), () => {
|
|
703
736
|
|
|
704
737
|
const light = PointLight.wrap( getPointLight( pointLightsBuffer, selectedIdx ) );
|
|
705
|
-
const ptSample = LightSample.wrap( samplePointLightWithAttenuation( light, rayOrigin, pdf ) );
|
|
738
|
+
const ptSample = LightSample.wrap( samplePointLightWithAttenuation( light, rayOrigin, pdf, vec2( randomSeed.y, getRandomSample1D( pixelCoord, int( 0 ), dimBase.add( int( 15 ) ), rngState, resolution, frame ) ) ) );
|
|
706
739
|
r_valid.assign( ptSample.valid );
|
|
707
740
|
r_direction.assign( ptSample.direction );
|
|
708
741
|
r_emission.assign( ptSample.emission );
|
|
@@ -716,7 +749,7 @@ export const sampleLightWithImportance = Fn( ( [
|
|
|
716
749
|
If( selectedType.equal( int( 3 ) ).and( selectedIdx.greaterThanEqual( int( 0 ) ) ), () => {
|
|
717
750
|
|
|
718
751
|
const light = SpotLight.wrap( getSpotLight( spotLightsBuffer, selectedIdx ) );
|
|
719
|
-
const spotSample = LightSample.wrap( sampleSpotLightWithRadius( light, rayOrigin, pdf ) );
|
|
752
|
+
const spotSample = LightSample.wrap( sampleSpotLightWithRadius( light, rayOrigin, pdf, vec2( randomSeed.y, getRandomSample1D( pixelCoord, int( 0 ), dimBase.add( int( 15 ) ), rngState, resolution, frame ) ) ) );
|
|
720
753
|
r_valid.assign( spotSample.valid );
|
|
721
754
|
r_direction.assign( spotSample.direction );
|
|
722
755
|
r_emission.assign( spotSample.emission );
|
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
* @property {?Node} iesProfiles - IES profile texture array, or null
|
|
13
13
|
* @property {?Node} alphaShadows - int uniform, 1 = shadow rays test texture alpha; null = never
|
|
14
14
|
* @property {?Object<string, boolean>} materialLayers - the MATERIAL_LAYERS some material uses; null = all of them
|
|
15
|
+
* @property {boolean} [lightRadius] - some point or spot light has a radius (path tracing only); false = all are points
|
|
16
|
+
* @property {boolean} [transmissionMaps] - some material has a transmission map; false = shadow rays never sample one
|
|
15
17
|
*/
|
|
16
18
|
|
|
17
19
|
import { context } from 'three/tsl';
|
|
@@ -49,3 +51,20 @@ export function materialLayers( builder ) {
|
|
|
49
51
|
return builder.context[ KEY ]?.materialLayers ?? ALL_MATERIAL_LAYERS;
|
|
50
52
|
|
|
51
53
|
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Whether the kernel being built samples light radii. Off unless a point or spot light has a radius, and off for the
|
|
57
|
+
* bidirectional integrator, whose light paths leave a light's centre. Outside a scene kernel (a test) it is on.
|
|
58
|
+
*/
|
|
59
|
+
export function usesLightRadius( builder ) {
|
|
60
|
+
|
|
61
|
+
return builder.context[ KEY ]?.lightRadius ?? true;
|
|
62
|
+
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** Whether the kernel being built has shadow rays sample transmission maps. Outside a scene kernel (a test) it does. */
|
|
66
|
+
export function usesTransmissionMaps( builder ) {
|
|
67
|
+
|
|
68
|
+
return builder.context[ KEY ]?.transmissionMaps ?? true;
|
|
69
|
+
|
|
70
|
+
}
|
package/src/TSL/ShadeKernel.js
CHANGED
|
@@ -653,8 +653,7 @@ export function buildShadeKernel( params ) {
|
|
|
653
653
|
// surface that escapes to env keeps alpha 1 (HAS_HIT_OPAQUE set), so glass-in-front-of-an-
|
|
654
654
|
// object stays opaque while glass-in-front-of-sky exports see-through.
|
|
655
655
|
// Ungated (was transparentBackground-only) so the alpha lane always carries coverage: it is the
|
|
656
|
-
// only hit/miss signal valid at FinalWrite
|
|
657
|
-
// when transparent-bg is off.
|
|
656
|
+
// only hit/miss signal valid at FinalWrite, which accumulates it as is.
|
|
658
657
|
If( flags.bitAnd( uint( RAY_FLAG.HAS_HIT_OPAQUE ) ).equal( uint( 0 ) ), () => {
|
|
659
658
|
|
|
660
659
|
currentRadiance.w.assign( 0.0 );
|
|
@@ -918,7 +917,7 @@ export function buildShadeKernel( params ) {
|
|
|
918
917
|
const displacedNormal = N.toVar();
|
|
919
918
|
If(
|
|
920
919
|
material.displacementMapIndex.greaterThanEqual( int( 0 ) )
|
|
921
|
-
.and( material.displacementScale.
|
|
920
|
+
.and( material.displacementScale.notEqual( 0.0 ) ),
|
|
922
921
|
() => {
|
|
923
922
|
|
|
924
923
|
const dispRay = Ray( { origin, direction } );
|
|
@@ -1004,7 +1003,7 @@ export function buildShadeKernel( params ) {
|
|
|
1004
1003
|
const albedo = matSamples.albedo.toVar();
|
|
1005
1004
|
If(
|
|
1006
1005
|
material.displacementMapIndex.greaterThanEqual( int( 0 ) )
|
|
1007
|
-
.and( material.displacementScale.
|
|
1006
|
+
.and( material.displacementScale.notEqual( 0.0 ) ),
|
|
1008
1007
|
() => {
|
|
1009
1008
|
|
|
1010
1009
|
N.assign( normalize( displacedNormal.add( matSamples.normal.sub( normalize( hitNormal ) ) ) ) );
|
package/src/TSL/Struct.js
CHANGED
|
@@ -336,6 +336,7 @@ export class BidirectionalIntegrator {
|
|
|
336
336
|
strategyView: bd.strategyView,
|
|
337
337
|
cameraPosition: bd.cameraPosition,
|
|
338
338
|
cameraForward: bd.cameraForward,
|
|
339
|
+
cameraClipStart: this.pt.cameraClipStart,
|
|
339
340
|
cameraViewMatrix: this.pt.cameraViewMatrix,
|
|
340
341
|
cameraProjectionMatrix: this.pt.cameraProjectionMatrix,
|
|
341
342
|
pixelArea: bd.pixelArea,
|
|
@@ -93,6 +93,7 @@ export class CameraManager extends EventDispatcher {
|
|
|
93
93
|
|
|
94
94
|
this.cameras = cameras;
|
|
95
95
|
this._userCameraCounter = 0;
|
|
96
|
+
this.camera.userData.clipStart = 0;
|
|
96
97
|
this.resetAutoFocus();
|
|
97
98
|
|
|
98
99
|
}
|
|
@@ -120,6 +121,7 @@ export class CameraManager extends EventDispatcher {
|
|
|
120
121
|
cam.userData.__rayzeeUserCamera = true;
|
|
121
122
|
cam.userData.__rayzeeEffects = this._captureEffects();
|
|
122
123
|
if ( this.controls ) cam.userData.__rayzeeOrbitTarget = this.controls.target.clone();
|
|
124
|
+
if ( src.userData.clipStart > 0 ) cam.userData.clipStart = src.userData.clipStart;
|
|
123
125
|
|
|
124
126
|
this._userCameraCounter += 1;
|
|
125
127
|
cam.name = name || `View Camera ${this._userCameraCounter}`;
|
|
@@ -310,6 +312,7 @@ export class CameraManager extends EventDispatcher {
|
|
|
310
312
|
this.camera.fov = s.fov;
|
|
311
313
|
this.camera.near = s.near;
|
|
312
314
|
this.camera.far = s.far;
|
|
315
|
+
this.camera.userData.clipStart = 0;
|
|
313
316
|
this.camera.updateProjectionMatrix();
|
|
314
317
|
this.camera.updateMatrixWorld( true );
|
|
315
318
|
|
|
@@ -380,6 +383,8 @@ export class CameraManager extends EventDispatcher {
|
|
|
380
383
|
if ( source.isPerspectiveCamera ) this.camera.fov = source.fov;
|
|
381
384
|
this.camera.near = source.near;
|
|
382
385
|
this.camera.far = source.far;
|
|
386
|
+
// Only an imported camera's clip start clips the render: see PathTracerStage._updateCameraUniforms.
|
|
387
|
+
this.camera.userData.clipStart = source.userData?.clipStart ?? 0;
|
|
383
388
|
this.camera.updateProjectionMatrix();
|
|
384
389
|
this.camera.updateMatrixWorld( true );
|
|
385
390
|
|
|
@@ -611,6 +616,7 @@ export class CameraManager extends EventDispatcher {
|
|
|
611
616
|
fov: camera.fov,
|
|
612
617
|
near: camera.near,
|
|
613
618
|
far: camera.far,
|
|
619
|
+
clipStart: camera.userData.clipStart ?? 0,
|
|
614
620
|
zoom: camera.zoom,
|
|
615
621
|
orthographic: !! camera.orthographic,
|
|
616
622
|
orthoHalfHeight: camera.orthoHalfHeight,
|
|
@@ -641,6 +647,7 @@ export class CameraManager extends EventDispatcher {
|
|
|
641
647
|
aspect: cam.aspect ?? null,
|
|
642
648
|
near: cam.near,
|
|
643
649
|
far: cam.far,
|
|
650
|
+
clipStart: cam.userData.clipStart ?? 0,
|
|
644
651
|
zoom: cam.zoom,
|
|
645
652
|
position: cam.position.toArray(),
|
|
646
653
|
quaternion: cam.quaternion.toArray(),
|
|
@@ -684,6 +691,7 @@ export class CameraManager extends EventDispatcher {
|
|
|
684
691
|
cam.updateMatrixWorld( true );
|
|
685
692
|
cam.userData.__rayzeeUserCamera = true;
|
|
686
693
|
cam.userData.__rayzeeEffects = fromPortable( entry.effects );
|
|
694
|
+
if ( entry.clipStart > 0 ) cam.userData.clipStart = entry.clipStart;
|
|
687
695
|
if ( entry.orbitTarget ) cam.userData.__rayzeeOrbitTarget = new Vector3().fromArray( entry.orbitTarget );
|
|
688
696
|
indexMap.set( entry.index, this.cameras.length );
|
|
689
697
|
this.cameras.push( cam );
|
|
@@ -730,6 +738,7 @@ export class CameraManager extends EventDispatcher {
|
|
|
730
738
|
camera.fov = v.fov;
|
|
731
739
|
camera.near = v.near;
|
|
732
740
|
camera.far = v.far;
|
|
741
|
+
camera.userData.clipStart = v.clipStart ?? 0;
|
|
733
742
|
this._setView( v.orthographic, v.orthoHalfHeight );
|
|
734
743
|
camera.zoom = v.zoom ?? 1;
|
|
735
744
|
camera.updateProjectionMatrix();
|
|
@@ -426,6 +426,7 @@ export class DenoisingManager extends EventDispatcher {
|
|
|
426
426
|
getToneMapping: () => this._getToneMapping(),
|
|
427
427
|
getSaturation: () => this._getSaturation(),
|
|
428
428
|
getDisplayGain: () => this._getDisplayGain?.() ?? null,
|
|
429
|
+
getTransparentBackground: () => !! this._settings?.get( 'transparentBackground' ),
|
|
429
430
|
} );
|
|
430
431
|
|
|
431
432
|
this.upscaler.enabled = DENOISER_DEFAULTS.enableUpscaler || false;
|
|
@@ -704,6 +704,12 @@ export class InteractionManager extends EventDispatcher {
|
|
|
704
704
|
*/
|
|
705
705
|
_intersectScene() {
|
|
706
706
|
|
|
707
|
+
// Nothing in front of an imported camera's clip plane is rendered, so nothing there is picked. An orthographic
|
|
708
|
+
// ray already starts on the near plane, which a switch to such a camera set to its clip start.
|
|
709
|
+
const clipStart = this.camera.userData?.clipStart ?? 0;
|
|
710
|
+
this.raycaster.near = clipStart > 0 && ! this.camera.isOrthographicCamera
|
|
711
|
+
? clipStart / Math.max( this.raycaster.ray.direction.dot( this.camera.getWorldDirection( _viewAxis ) ), 1e-4 )
|
|
712
|
+
: 0;
|
|
707
713
|
return this.isGeometryOnDisk?.() ? [] : this.raycaster.intersectObjects( this.scene.children, true );
|
|
708
714
|
|
|
709
715
|
}
|
|
@@ -342,6 +342,16 @@ export class MaterialDataManager {
|
|
|
342
342
|
|
|
343
343
|
}
|
|
344
344
|
|
|
345
|
+
/** Whether some material has a transmission map: only then do shadow rays sample one. */
|
|
346
|
+
hasTransmissionMaps() {
|
|
347
|
+
|
|
348
|
+
const data = this.materialStorageAttr?.array;
|
|
349
|
+
if ( ! data ) return false;
|
|
350
|
+
for ( let i = 0; i < this.materialCount; i ++ ) if ( data[ i * M.FLOATS_PER_MATERIAL + M.TRANSMISSION_MAP_INDEX ] >= 0 ) return true;
|
|
351
|
+
return false;
|
|
352
|
+
|
|
353
|
+
}
|
|
354
|
+
|
|
345
355
|
/**
|
|
346
356
|
* Where a material property's value came from, as a MATERIAL_VALUE_SOURCE. `default` means the
|
|
347
357
|
* model never said and the engine filled it in.
|
|
@@ -503,6 +513,7 @@ export class MaterialDataManager {
|
|
|
503
513
|
break;
|
|
504
514
|
case 'bumpScale': data[ stride + M.BUMP_SCALE ] = value; break;
|
|
505
515
|
case 'displacementScale': data[ stride + M.DISPLACEMENT_SCALE ] = value; break;
|
|
516
|
+
case 'displacementBias': data[ stride + M.DISPLACEMENT_BIAS ] = value; break;
|
|
506
517
|
case 'subsurface': data[ stride + M.SUBSURFACE ] = value; break;
|
|
507
518
|
case 'subsurfaceRadiusScale': data[ stride + M.SUBSURFACE_RADIUS_SCALE ] = value; break;
|
|
508
519
|
case 'subsurfaceAnisotropy': data[ stride + M.SUBSURFACE_ANISOTROPY ] = value; break;
|
|
@@ -23,7 +23,7 @@ const SHADER_NAMES = {
|
|
|
23
23
|
export const LIGHT_FLOATS = Object.freeze( {
|
|
24
24
|
directional: 12, // 8 light fields + gobo { index, signed intensity, scale, pad }
|
|
25
25
|
area: 16, // 13 base + normalize, spread, shape
|
|
26
|
-
point: 9
|
|
26
|
+
point: 10, // 9 light fields + radius
|
|
27
27
|
spot: 20, // 14 light fields + gobo { index, signed intensity } + IES { index, intensity } + 2 reserved
|
|
28
28
|
} );
|
|
29
29
|
|
|
@@ -301,6 +301,8 @@ export class UniformManager {
|
|
|
301
301
|
u( 'cameraProjectionMatrixInverse', new Matrix4(), 'mat4' );
|
|
302
302
|
u( 'cameraViewMatrix', new Matrix4(), 'mat4' );
|
|
303
303
|
u( 'cameraProjectionMatrix', new Matrix4(), 'mat4' );
|
|
304
|
+
// An imported camera's near clipping plane: camera rays start this far in front of it (0 = at the camera).
|
|
305
|
+
u( 'cameraClipStart', 0, 'float' );
|
|
304
306
|
|
|
305
307
|
// Projection: CAMERA_PROJECTION_IDS. Ranges are radians (UI carries degrees).
|
|
306
308
|
const radRange = ( [ min, max ] ) => new Vector2( min, max ).multiplyScalar( MathUtils.DEG2RAD );
|
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
//#region src/Processor/archiveFormats.js
|
|
2
|
-
var e = Object.freeze({
|
|
3
|
-
zip: {
|
|
4
|
-
type: "archive",
|
|
5
|
-
name: "ZIP Archive"
|
|
6
|
-
},
|
|
7
|
-
gz: {
|
|
8
|
-
type: "archive",
|
|
9
|
-
name: "Gzipped TAR Archive"
|
|
10
|
-
},
|
|
11
|
-
tgz: {
|
|
12
|
-
type: "archive",
|
|
13
|
-
name: "Gzipped TAR Archive"
|
|
14
|
-
},
|
|
15
|
-
tar: {
|
|
16
|
-
type: "archive",
|
|
17
|
-
name: "TAR Archive"
|
|
18
|
-
}
|
|
19
|
-
}), t = (e) => typeof Blob < "u" && e instanceof Blob, n = (e) => !!e && typeof e == "object" && !t(e) && e.files != null, r = (e) => e.startsWith(".") || e === "__MACOSX";
|
|
20
|
-
function i({ name: e = null, files: n }, { isModel: i = () => !1 } = {}) {
|
|
21
|
-
let a = /* @__PURE__ */ new Map();
|
|
22
|
-
for (let e of n) {
|
|
23
|
-
let n = t(e) ? e : e.file, i = t(e) ? e.webkitRelativePath || e.name : e.path, o = String(i ?? "").replace(/\\/g, "/").split("/").filter((e) => e && e !== ".").join("/");
|
|
24
|
-
!o || !n || o.split("/").some(r) || a.set(o, {
|
|
25
|
-
path: o,
|
|
26
|
-
file: n
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
let o = [...a.values()].sort((e, t) => e.path < t.path ? -1 : +(e.path > t.path)), s = o[0]?.path.split("/")[0], c = o.length > 0 && o.every((e) => e.path.startsWith(s + "/")) ? s : null;
|
|
30
|
-
return {
|
|
31
|
-
name: e ?? c ?? (o.find((e) => i(e.path)) ?? o[0])?.path.split("/").pop() ?? "Folder",
|
|
32
|
-
files: o,
|
|
33
|
-
flat: c === null && o.every((e) => !e.path.includes("/"))
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
//#endregion
|
|
37
|
-
//#region src/Processor/SceneMetadata.js
|
|
38
|
-
var a = [
|
|
39
|
-
"sourceFile",
|
|
40
|
-
"url",
|
|
41
|
-
"file"
|
|
42
|
-
];
|
|
43
|
-
function o(e) {
|
|
44
|
-
if (typeof e == "string") try {
|
|
45
|
-
let t = JSON.parse(e);
|
|
46
|
-
return t && typeof t == "object" ? t : null;
|
|
47
|
-
} catch {
|
|
48
|
-
return null;
|
|
49
|
-
}
|
|
50
|
-
return e && typeof e == "object" ? e : null;
|
|
51
|
-
}
|
|
52
|
-
function s(e) {
|
|
53
|
-
let t = typeof e == "string" ? parseFloat(e) : e;
|
|
54
|
-
return Number.isFinite(t) ? t : void 0;
|
|
55
|
-
}
|
|
56
|
-
function c(e) {
|
|
57
|
-
let t = o(e);
|
|
58
|
-
if (!t) return null;
|
|
59
|
-
let n = (e) => e && (e.environment !== void 0 || e.render !== void 0), r = o(t.rayzee);
|
|
60
|
-
return n(r) ? r : n(t) ? t : null;
|
|
61
|
-
}
|
|
62
|
-
function l(e) {
|
|
63
|
-
let t = o(e);
|
|
64
|
-
if (!t) return null;
|
|
65
|
-
let n = a.map((e) => t[e]).find((e) => typeof e == "string" && e.trim());
|
|
66
|
-
if (!n) return null;
|
|
67
|
-
let r = s(t.rotation), i = s(t.intensity), c = { sourceFile: n.trim() };
|
|
68
|
-
return r !== void 0 && (c.rotation = r), i !== void 0 && (c.intensity = Math.max(0, i)), c;
|
|
69
|
-
}
|
|
70
|
-
var u = [
|
|
71
|
-
"maxBounces",
|
|
72
|
-
"samples",
|
|
73
|
-
"width",
|
|
74
|
-
"height"
|
|
75
|
-
];
|
|
76
|
-
function d(e) {
|
|
77
|
-
let t = o(e);
|
|
78
|
-
if (!t) return null;
|
|
79
|
-
let n = {};
|
|
80
|
-
for (let e of u) {
|
|
81
|
-
let r = s(t[e]);
|
|
82
|
-
r !== void 0 && r > 0 && (n[e] = Math.round(r));
|
|
83
|
-
}
|
|
84
|
-
return Object.keys(n).length ? n : null;
|
|
85
|
-
}
|
|
86
|
-
function f(e) {
|
|
87
|
-
let t = c(e);
|
|
88
|
-
if (!t) return null;
|
|
89
|
-
let n = l(t.environment), r = d(t.render);
|
|
90
|
-
return !n && !r ? null : {
|
|
91
|
-
...n ? { environment: n } : {},
|
|
92
|
-
...r ? { render: r } : {}
|
|
93
|
-
};
|
|
94
|
-
}
|
|
95
|
-
function p(e) {
|
|
96
|
-
if (!e) return null;
|
|
97
|
-
let t = [
|
|
98
|
-
e.userData,
|
|
99
|
-
e.asset?.extras,
|
|
100
|
-
e.scene?.userData
|
|
101
|
-
];
|
|
102
|
-
Array.isArray(e.scenes) && t.push(...e.scenes.map((e) => e?.userData));
|
|
103
|
-
for (let e of t) {
|
|
104
|
-
let t = f(e);
|
|
105
|
-
if (t) return t;
|
|
106
|
-
}
|
|
107
|
-
return null;
|
|
108
|
-
}
|
|
109
|
-
//#endregion
|
|
110
|
-
export { i as a, n as i, f as n, e as r, p as t };
|