rayzee 10.0.0 → 11.1.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.
Files changed (176) hide show
  1. package/README.md +252 -44
  2. package/dist/ActiveColor-YvuQq44O.js +13 -0
  3. package/dist/ArchiveImporter-Hn35o6Z5.js +5145 -0
  4. package/dist/AssetConfig-DSEntE65.js +30 -0
  5. package/dist/BidirectionalIntegrator-CBw8hkeu.js +946 -0
  6. package/dist/BufferLayout-D_IBo2ci.js +150 -0
  7. package/dist/ColorManagement-oeEk7oSu.js +1488 -0
  8. package/dist/EngineEvents-Ci8dVWCP.js +73 -0
  9. package/dist/EngineIssues-CIZnXHsF.js +72 -0
  10. package/dist/FileFormats-sPGJeCRc.js +102 -0
  11. package/dist/Logger-dDDGj9Av.js +97 -0
  12. package/dist/{NeuralRetouch-CYgkQY8Z.js → NeuralRetouch-BzNpiVHZ.js} +8 -6
  13. package/dist/{NeuralSuperRes-PkgDLQcD.js → NeuralSuperRes-Bk7bHg2B.js} +55 -120
  14. package/dist/PathTracer-72XufKAr.js +29976 -0
  15. package/dist/PhysicalSky-BgjdV88k.js +1219 -0
  16. package/dist/RayzeeRenderer-1QRO97eq.js +3551 -0
  17. package/dist/SolarLimb-CPaeZVwz.js +721 -0
  18. package/dist/ToneMapGPU-CjU3osDd.js +177 -0
  19. package/dist/ViewTransforms-CYN7bq2w.js +255 -0
  20. package/dist/WorkingMatrix-C6y233hT.js +27 -0
  21. package/dist/ZipReader-gDSWr0I5.js +98 -0
  22. package/dist/addons/archives.es.js +3 -0
  23. package/dist/addons/bidirectional.es.js +2 -0
  24. package/dist/addons/color.es.js +3 -0
  25. package/dist/addons/formats.es.js +2 -0
  26. package/dist/addons/physical-sky.es.js +2 -0
  27. package/dist/addons/storage.es.js +3 -0
  28. package/dist/archiveFormats-tnAoUL1j.js +94 -0
  29. package/dist/identity-DrQsGT2o.js +39 -0
  30. package/dist/openStorage-DwcBRUj7.js +820 -0
  31. package/dist/rayzee-core.es.js +12 -0
  32. package/dist/rayzee.es.js +2551 -44024
  33. package/dist/rayzee.umd.js +528 -487
  34. package/dist/sceneCachePolicy-C67jbci-.js +443 -0
  35. package/dist/shared-BGBcSxBQ.js +17 -0
  36. package/package.json +23 -2
  37. package/src/Color/ActiveColor.js +34 -0
  38. package/src/Color/BasicColor.js +147 -0
  39. package/src/Color/ColorManagement.js +7 -31
  40. package/src/Color/ViewTransforms.js +5 -1
  41. package/src/EngineDefaults.js +62 -1029
  42. package/src/EngineEvents.js +2 -0
  43. package/src/EngineIssues.js +2 -0
  44. package/src/Headless.js +6 -5
  45. package/src/Passes/AIUpscaler.js +58 -141
  46. package/src/Passes/OIDNDenoiser.js +92 -65
  47. package/src/Passes/OIDNTemporalHistory.js +1 -1
  48. package/src/PathTracerApp.js +620 -4026
  49. package/src/Pipeline/PipelineContext.js +0 -4
  50. package/src/Platform.js +36 -0
  51. package/src/Processor/ArchiveCache.js +20 -7
  52. package/src/Processor/ArchiveImporter.js +1265 -0
  53. package/src/Processor/ArchiveReader.js +22 -4
  54. package/src/Processor/AssetLoader.js +327 -1763
  55. package/src/Processor/AtmosphereModel.js +1 -2
  56. package/src/Processor/BVHBuilder.js +14 -126
  57. package/src/Processor/BVHLeafFold.js +4 -6
  58. package/src/Processor/BVHRefitter.js +67 -46
  59. package/src/Processor/BufferLayout.js +291 -0
  60. package/src/Processor/EmissiveTriangleBuilder.js +1 -1
  61. package/src/Processor/EnvironmentExactTable.js +187 -0
  62. package/src/Processor/EquirectHDRInfo.js +30 -223
  63. package/src/Processor/FileFormats.js +116 -0
  64. package/src/Processor/GLTFDecoders.js +85 -0
  65. package/src/Processor/GLTFDiffuseTransmission.js +63 -0
  66. package/src/Processor/GeometryExtractor.js +15 -5
  67. package/src/Processor/HostMemory.js +7 -1
  68. package/src/Processor/IESParser.js +47 -35
  69. package/src/Processor/InstanceTable.js +1 -1
  70. package/src/Processor/KernelManager.js +35 -2
  71. package/src/Processor/MaterialPacking.js +10 -8
  72. package/src/Processor/PBRT/PBRTMaterials.js +254 -42
  73. package/src/Processor/PBRT/PBRTParser.js +49 -19
  74. package/src/Processor/PBRT/PBRTScattering.js +93 -0
  75. package/src/Processor/PBRT/PBRTSceneBuilder.js +1050 -75
  76. package/src/Processor/PBRT/PBRTTextureBake.js +179 -0
  77. package/src/Processor/PBRT/PFM.js +59 -0
  78. package/src/Processor/PackedRayBuffer.js +116 -9
  79. package/src/Processor/ParallelBVHBuilder.js +3 -6
  80. package/src/Processor/PhysicalSky.js +5 -4
  81. package/src/Processor/PlatformImageLoader.js +50 -6
  82. package/src/Processor/QueueManager.js +39 -5
  83. package/src/Processor/ReinsertionOptimizer.js +2 -2
  84. package/src/Processor/SceneMetadata.js +30 -5
  85. package/src/Processor/SceneProcessor.js +53 -62
  86. package/src/Processor/ShaderBuilder.js +6 -16
  87. package/src/Processor/SimpleSky.js +1 -62
  88. package/src/Processor/SolarLimb.js +3 -0
  89. package/src/Processor/SplitBLAS.js +1 -1
  90. package/src/Processor/StorageTexturePool.js +22 -1
  91. package/src/Processor/TLASBuilder.js +1 -3
  92. package/src/Processor/TextureBuckets.js +237 -0
  93. package/src/Processor/TextureCreator.js +181 -8
  94. package/src/Processor/ToneMapGPU.js +64 -15
  95. package/src/Processor/Workers/BVHRefitWorker.js +5 -2
  96. package/src/Processor/Workers/BVHSubtreeWorker.js +1 -34
  97. package/src/Processor/Workers/BVHWorker.js +5 -18
  98. package/src/Processor/Workers/CDFWorker.js +6 -183
  99. package/src/Processor/Workers/TexturesWorker.js +103 -18
  100. package/src/Processor/archiveFormats.js +7 -0
  101. package/src/Processor/utils.js +2 -1
  102. package/src/RayzeeRenderer.js +3900 -0
  103. package/src/RenderSettings.js +68 -62
  104. package/src/Stages/ASVGF.js +13 -14
  105. package/src/Stages/AutoExposure.js +17 -17
  106. package/src/Stages/BilateralFilter.js +2 -1
  107. package/src/Stages/Compositor.js +8 -23
  108. package/src/Stages/DenoiserSettings.js +182 -0
  109. package/src/Stages/EdgeFilter.js +2 -1
  110. package/src/Stages/MotionVector.js +1 -1
  111. package/src/Stages/NRD.js +11 -5
  112. package/src/Stages/NormalDepth.js +12 -8
  113. package/src/Stages/PathTracer.js +336 -43
  114. package/src/Stages/PathTracerStage.js +69 -66
  115. package/src/Stages/Variance.js +1 -1
  116. package/src/Storage/BLASCache.js +1 -1
  117. package/src/Storage/CDFCache.js +18 -17
  118. package/src/Storage/DownloadCache.js +1 -1
  119. package/src/Storage/SceneGraphCodec.js +46 -3
  120. package/src/Storage/SpillStore.js +1 -1
  121. package/src/Storage/StorageManager.js +45 -9
  122. package/src/Storage/areas.js +4 -0
  123. package/src/TSL/BVHTraversal.js +50 -25
  124. package/src/TSL/Bidirectional.js +208 -0
  125. package/src/TSL/BidirectionalLamps.js +132 -0
  126. package/src/TSL/Clearcoat.js +15 -6
  127. package/src/TSL/Common.js +20 -15
  128. package/src/TSL/ConnectKernel.js +167 -0
  129. package/src/TSL/Debugger.js +1 -1
  130. package/src/TSL/Displacement.js +4 -3
  131. package/src/TSL/EmissiveSampling.js +65 -18
  132. package/src/TSL/Environment.js +77 -106
  133. package/src/TSL/EnvironmentCDF.js +85 -39
  134. package/src/TSL/ExtendKernel.js +8 -3
  135. package/src/TSL/FinalWriteKernel.js +4 -4
  136. package/src/TSL/GenerateKernel.js +18 -4
  137. package/src/TSL/HitFacet.js +35 -5
  138. package/src/TSL/LightBVHSampling.js +40 -9
  139. package/src/TSL/LightGenerateKernel.js +293 -0
  140. package/src/TSL/LightGuide.js +198 -0
  141. package/src/TSL/LightSplatKernel.js +180 -0
  142. package/src/TSL/LightVisibility.js +111 -0
  143. package/src/TSL/LightsCore.js +13 -38
  144. package/src/TSL/LightsDirect.js +28 -29
  145. package/src/TSL/LightsIndirect.js +3 -1
  146. package/src/TSL/LightsSampling.js +239 -51
  147. package/src/TSL/MaterialEvaluation.js +113 -31
  148. package/src/TSL/MaterialProperties.js +44 -17
  149. package/src/TSL/MaterialTransmission.js +52 -47
  150. package/src/TSL/MergeKernel.js +224 -0
  151. package/src/TSL/PathTracerCore.js +65 -29
  152. package/src/TSL/Random.js +5 -1
  153. package/src/TSL/SceneResources.js +51 -0
  154. package/src/TSL/ShadeKernel.js +985 -101
  155. package/src/TSL/Struct.js +10 -0
  156. package/src/TSL/Sun.js +1 -1
  157. package/src/TSL/TextureSampling.js +66 -61
  158. package/src/addons/archives.js +14 -0
  159. package/src/addons/bidirectional.js +13 -0
  160. package/src/addons/color.js +32 -0
  161. package/src/addons/formats.js +16 -0
  162. package/src/addons/physicalSky.js +14 -0
  163. package/src/addons/storage.js +19 -0
  164. package/src/core.js +31 -0
  165. package/src/index.js +13 -23
  166. package/src/integrators/BidirectionalIntegrator.js +838 -0
  167. package/src/managers/AnimationManager.js +88 -6
  168. package/src/managers/CameraManager.js +103 -46
  169. package/src/managers/DenoisingManager.js +14 -10
  170. package/src/managers/EnvironmentManager.js +125 -103
  171. package/src/managers/GoboManager.js +9 -0
  172. package/src/managers/MaterialDataManager.js +48 -37
  173. package/src/managers/UniformManager.js +32 -10
  174. package/dist/ToneMapGPU-B6XIe3DU.js +0 -544
  175. package/dist/rolldown-runtime-CAFD8bLK.js +0 -11
  176. package/src/Processor/TreeletOptimizer.js +0 -574
@@ -1,5 +1,4 @@
1
1
  import { BVHBuilder } from '../BVHBuilder.js';
2
- import { TreeletOptimizer } from '../TreeletOptimizer.js';
3
2
  import { ReinsertionOptimizer } from '../ReinsertionOptimizer.js';
4
3
 
5
4
  self.onmessage = function ( e ) {
@@ -9,7 +8,6 @@ self.onmessage = function ( e ) {
9
8
  sharedTriangleData, sharedCentroids, sharedBMin, sharedBMax, sharedIndices,
10
9
  triangleCount,
11
10
  maxLeafSize, numBins, maxBins, minBins,
12
- treeletConfig,
13
11
  reinsertionConfig,
14
12
  reportProgress
15
13
  } = e.data;
@@ -46,8 +44,7 @@ self.onmessage = function ( e ) {
46
44
  builder.splitStats = {
47
45
  sahSplits: 0, objectMedianSplits: 0, spatialMedianSplits: 0,
48
46
  failedSplits: 0, avgBinsUsed: 0, totalSplitAttempts: 0,
49
- mortonSortTime: 0, totalBuildTime: 0, treeletOptimizationTime: 0,
50
- treeletsProcessed: 0, treeletsImproved: 0, averageSAHImprovement: 0,
47
+ mortonSortTime: 0, totalBuildTime: 0,
51
48
  initTime: 0, sahBuildTime: 0, reorderTime: 0
52
49
  };
53
50
 
@@ -70,36 +67,6 @@ self.onmessage = function ( e ) {
70
67
  task.preMaxX, task.preMaxY, task.preMaxZ
71
68
  );
72
69
 
73
- // Treelet optimization on subtree
74
- if ( treeletConfig && treeletConfig.enabled && ( task.end - task.start ) > 1000 ) {
75
-
76
- const isLargeSubtree = ( task.end - task.start ) > 50000;
77
- const adaptiveSize = isLargeSubtree ? 3 : ( treeletConfig.size || 5 );
78
- const adaptiveMax = isLargeSubtree ? 10 : 20;
79
-
80
- const optimizer = new TreeletOptimizer( builder.traversalCost, builder.intersectionCost );
81
- optimizer.setTreeletSize( adaptiveSize );
82
- optimizer.setMinImprovement( treeletConfig.minImprovement || 0.02 );
83
- optimizer.setMaxTreelets( adaptiveMax );
84
-
85
- const passes = treeletConfig.passes || 1;
86
- for ( let pass = 0; pass < passes; pass ++ ) {
87
-
88
- try {
89
-
90
- optimizer.optimizeBVH( root, null );
91
-
92
- } catch ( err ) {
93
-
94
- console.error( `[BVHSubtreeWorker] Treelet pass ${pass + 1} error:`, err );
95
- break;
96
-
97
- }
98
-
99
- }
100
-
101
- }
102
-
103
70
  // Reinsertion optimization on subtree
104
71
  if ( reinsertionConfig && reinsertionConfig.enabled && ( task.end - task.start ) > 1000 ) {
105
72
 
@@ -41,19 +41,13 @@ function handlePhase1( data ) {
41
41
  sharedTriangleData, sharedCentroids, sharedBMin, sharedBMax,
42
42
  sharedIndices, sharedMortonCodes,
43
43
  triangleCount, depth, parallelDepth,
44
- reportProgress, treeletOptimization
44
+ reportProgress
45
45
  } = data;
46
46
 
47
47
  try {
48
48
 
49
49
  const builder = new BVHBuilder();
50
50
 
51
- if ( treeletOptimization ) {
52
-
53
- builder.setTreeletConfig( treeletOptimization );
54
-
55
- }
56
-
57
51
  const progressCallback = reportProgress ? ( progress ) => {
58
52
 
59
53
  self.postMessage( { type: 'progress', progress } );
@@ -77,8 +71,7 @@ function handlePhase1( data ) {
77
71
  builder.splitStats = {
78
72
  sahSplits: 0, objectMedianSplits: 0, spatialMedianSplits: 0,
79
73
  failedSplits: 0, avgBinsUsed: 0, totalSplitAttempts: 0,
80
- mortonSortTime: 0, totalBuildTime: 0, treeletOptimizationTime: 0,
81
- treeletsProcessed: 0, treeletsImproved: 0, averageSAHImprovement: 0,
74
+ mortonSortTime: 0, totalBuildTime: 0,
82
75
  initTime: 0, sahBuildTime: 0, reorderTime: 0
83
76
  };
84
77
 
@@ -193,7 +186,7 @@ function handleAssemble( data ) {
193
186
 
194
187
  function handleFullBuild( data ) {
195
188
 
196
- const { triangleData, triangleByteOffset, triangleByteLength, depth, reportProgress, treeletOptimization, reinsertionOptimization, sharedReorderBuffer, maxLeafSize, numBins, maxBins, minBins, foldLeaves: fold } = data;
189
+ const { triangleData, triangleByteOffset, triangleByteLength, depth, reportProgress, reinsertionOptimization, sharedReorderBuffer, maxLeafSize, numBins, maxBins, minBins, foldLeaves: fold } = data;
197
190
  const builder = new BVHBuilder();
198
191
  // Honor the build params forwarded from SceneProcessor (previously ignored → default leaf 8).
199
192
  if ( maxLeafSize !== undefined ) builder.maxLeafSize = maxLeafSize;
@@ -203,12 +196,6 @@ function handleFullBuild( data ) {
203
196
 
204
197
  try {
205
198
 
206
- if ( treeletOptimization ) {
207
-
208
- builder.setTreeletConfig( treeletOptimization );
209
-
210
- }
211
-
212
199
  if ( reinsertionOptimization ) {
213
200
 
214
201
  builder.setReinsertionConfig( reinsertionOptimization );
@@ -248,7 +235,7 @@ function handleFullBuild( data ) {
248
235
  bvhData,
249
236
  originalToBvh,
250
237
  triangleCount: inputTriangles.length / FPT,
251
- treeletStats: builder.splitStats
238
+ splitStats: builder.splitStats
252
239
  }, transferables );
253
240
 
254
241
  } else {
@@ -264,7 +251,7 @@ function handleFullBuild( data ) {
264
251
  triangles: reordered,
265
252
  originalToBvh,
266
253
  triangleCount,
267
- treeletStats: builder.splitStats
254
+ splitStats: builder.splitStats
268
255
  }, transferables );
269
256
 
270
257
  }
@@ -1,179 +1,11 @@
1
1
  /**
2
- * Web Worker for computing environment map CDF (Cumulative Distribution Function)
3
- * for importance sampling. Pure math — no Three.js dependencies.
2
+ * Web Worker for an environment map's sampling table (EnvironmentExactTable.js). Pure math — no Three.js dependencies.
4
3
  *
5
4
  * Input: { floatData: Float32Array, width, height }
6
- * Output: { marginalData: Float32Array, conditionalData: Float32Array, totalSum, width, height }
5
+ * Output: { width, height } and the table
7
6
  */
8
7
 
9
- function binarySearchFindClosestIndexOf( array, targetValue, offset, count ) {
10
-
11
- let lower = offset;
12
- let upper = offset + count - 1;
13
-
14
- while ( lower < upper ) {
15
-
16
- const mid = ( lower + upper ) >> 1;
17
-
18
- if ( array[ mid ] < targetValue ) {
19
-
20
- lower = mid + 1;
21
-
22
- } else {
23
-
24
- upper = mid;
25
-
26
- }
27
-
28
- }
29
-
30
- return lower - offset;
31
-
32
- }
33
-
34
- function buildCDF( floatData, width, height ) {
35
-
36
- const numPixels = width * height;
37
-
38
- // Pass 1: compute per-pixel luminance weighted by sin(theta) and raw total sum.
39
- // sin(theta) compensates for the equirectangular projection: pixels near the poles
40
- // cover less solid angle, so weighting by sin(theta) makes the CDF proportional to
41
- // luminance per solid angle rather than luminance per pixel.
42
- const pixelWeights = new Float32Array( numPixels );
43
- let rawTotalSum = 0.0;
44
-
45
- for ( let y = 0; y < height; y ++ ) {
46
-
47
- const sinTheta = Math.sin( Math.PI * ( y + 0.5 ) / height );
48
-
49
- for ( let x = 0; x < width; x ++ ) {
50
-
51
- const i = y * width + x;
52
- const r = floatData[ 4 * i ];
53
- const g = floatData[ 4 * i + 1 ];
54
- const b = floatData[ 4 * i + 2 ];
55
-
56
- // Luminance (Rec. 709) weighted by solid angle factor
57
- const w = ( 0.2126 * r + 0.7152 * g + 0.0722 * b ) * sinTheta;
58
- pixelWeights[ i ] = w;
59
- rawTotalSum += w;
60
-
61
- }
62
-
63
- }
64
-
65
- // MIS Compensation (Karlík et al. 2019, Eq. 14)
66
- // With equal sample allocation (c_I = 0.5): delta = 2*(1 - 0.5)*meanWeight = meanWeight
67
- // Subtracting mean sharpens the env map PDF, reducing oversampling
68
- // of dim regions already well-covered by BSDF sampling.
69
- const meanWeight = rawTotalSum / numPixels;
70
- let compensatedTotalSum = 0.0;
71
-
72
- for ( let i = 0; i < numPixels; i ++ ) {
73
-
74
- pixelWeights[ i ] = Math.max( 0, pixelWeights[ i ] - meanWeight );
75
- compensatedTotalSum += pixelWeights[ i ];
76
-
77
- }
78
-
79
- // Fall back to raw weights if compensation zeroed everything (uniform env map)
80
- const useCompensation = compensatedTotalSum > 0;
81
- const totalSumValue = useCompensation ? compensatedTotalSum : rawTotalSum;
82
- const compensationDelta = useCompensation ? meanWeight : 0;
83
-
84
- if ( ! useCompensation ) {
85
-
86
- // Restore raw sin-weighted luminance
87
- for ( let y = 0; y < height; y ++ ) {
88
-
89
- const sinTheta = Math.sin( Math.PI * ( y + 0.5 ) / height );
90
-
91
- for ( let x = 0; x < width; x ++ ) {
92
-
93
- const i = y * width + x;
94
- const r = floatData[ 4 * i ];
95
- const g = floatData[ 4 * i + 1 ];
96
- const b = floatData[ 4 * i + 2 ];
97
- pixelWeights[ i ] = ( 0.2126 * r + 0.7152 * g + 0.0722 * b ) * sinTheta;
98
-
99
- }
100
-
101
- }
102
-
103
- }
104
-
105
- // Pass 2: build conditional and marginal CDFs from (compensated) weights
106
- const cdfConditional = new Float32Array( numPixels );
107
- const cdfMarginal = new Float32Array( height );
108
-
109
- let cumulativeWeightMarginal = 0.0;
110
-
111
- for ( let y = 0; y < height; y ++ ) {
112
-
113
- let cumulativeRowWeight = 0.0;
114
- for ( let x = 0; x < width; x ++ ) {
115
-
116
- const i = y * width + x;
117
- cumulativeRowWeight += pixelWeights[ i ];
118
- cdfConditional[ i ] = cumulativeRowWeight;
119
-
120
- }
121
-
122
- // Normalize row CDF to [0, 1]
123
- if ( cumulativeRowWeight !== 0 ) {
124
-
125
- for ( let i = y * width, l = y * width + width; i < l; i ++ ) {
126
-
127
- cdfConditional[ i ] /= cumulativeRowWeight;
128
-
129
- }
130
-
131
- }
132
-
133
- cumulativeWeightMarginal += cumulativeRowWeight;
134
- cdfMarginal[ y ] = cumulativeWeightMarginal;
135
-
136
- }
137
-
138
- // Normalize marginal CDF to [0, 1]
139
- if ( cumulativeWeightMarginal !== 0 ) {
140
-
141
- for ( let i = 0, l = cdfMarginal.length; i < l; i ++ ) {
142
-
143
- cdfMarginal[ i ] /= cumulativeWeightMarginal;
144
-
145
- }
146
-
147
- }
148
-
149
- // Invert marginal CDF
150
- const marginalData = new Float32Array( height );
151
- for ( let i = 0; i < height; i ++ ) {
152
-
153
- const dist = ( i + 1 ) / height;
154
- const row = binarySearchFindClosestIndexOf( cdfMarginal, dist, 0, height );
155
- marginalData[ i ] = ( row + 0.5 ) / height;
156
-
157
- }
158
-
159
- // Invert conditional CDFs
160
- const conditionalData = new Float32Array( width * height );
161
- for ( let y = 0; y < height; y ++ ) {
162
-
163
- for ( let x = 0; x < width; x ++ ) {
164
-
165
- const i = y * width + x;
166
- const dist = ( x + 1 ) / width;
167
- const col = binarySearchFindClosestIndexOf( cdfConditional, dist, y * width, width );
168
- conditionalData[ i ] = ( col + 0.5 ) / width;
169
-
170
- }
171
-
172
- }
173
-
174
- return { marginalData, conditionalData, totalSum: totalSumValue, compensationDelta };
175
-
176
- }
8
+ import { buildExactEnvironmentTable } from '../EnvironmentExactTable.js';
177
9
 
178
10
  self.onmessage = function ( e ) {
179
11
 
@@ -181,19 +13,10 @@ self.onmessage = function ( e ) {
181
13
 
182
14
  try {
183
15
 
184
- const result = buildCDF( floatData, width, height );
185
-
186
- // Transfer arrays back zero-copy
16
+ const table = buildExactEnvironmentTable( floatData, width, height );
187
17
  self.postMessage(
188
- {
189
- marginalData: result.marginalData,
190
- conditionalData: result.conditionalData,
191
- totalSum: result.totalSum,
192
- compensationDelta: result.compensationDelta,
193
- width,
194
- height,
195
- },
196
- [ result.marginalData.buffer, result.conditionalData.buffer ]
18
+ { width, height, ...table },
19
+ [ table.exactConditional.buffer, table.exactMarginal.buffer, table.exactRowGuide.buffer, table.exactMarginalGuide.buffer ]
197
20
  );
198
21
 
199
22
  } catch ( error ) {
@@ -1,16 +1,114 @@
1
+ import { TEXTURE_CONSTANTS, alignBucketWidth } from '../TextureBuckets.js';
2
+
1
3
  let canvas, ctx;
2
4
 
3
5
  // Memory limits and chunking configuration
4
6
  const MEMORY_LIMITS = {
5
- MAX_BYTES_PER_TEXTURE: 256 * 1024 * 1024, // 256MB per texture array
6
- MAX_TEXTURE_DIMENSION: 8192, // Hardware ceiling (WebGPU maxTextureDimension2D guaranteed min); the per-scene maxTextureSize setting is the actual knob
7
7
  CHUNK_SIZE: 8, // Optimized: Process textures in chunks of 8 for better memory locality
8
8
  ADAPTIVE_CHUNK_SIZE: true, // Enable adaptive chunk sizing based on texture dimensions
9
9
  MEMORY_SAFETY_FACTOR: 0.8 // Use only 80% of estimated available memory
10
10
  };
11
11
 
12
+ let stream = null;
13
+
14
+ function handleStream( msg ) {
15
+
16
+ if ( msg.stream === 'begin' ) {
17
+
18
+ const { width, height, depth } = msg;
19
+ const target = new OffscreenCanvas( width, height );
20
+ const context = target.getContext( '2d', { willReadFrequently: true, alpha: true, desynchronized: true } );
21
+ stream = { width, height, depth, context, data: new Uint8Array( width * height * depth * 4 ) };
22
+ return;
23
+
24
+ }
25
+
26
+ const { width, height, depth, context, data } = stream;
27
+
28
+ if ( msg.stream === 'layer' ) {
29
+
30
+ context.clearRect( 0, 0, width, height );
31
+ context.drawImage( msg.bitmap, 0, 0 );
32
+ msg.bitmap.close();
33
+ data.set( context.getImageData( 0, 0, width, height ).data, width * height * 4 * msg.index );
34
+ self.postMessage( { stream: 'ack', index: msg.index } );
35
+ return;
36
+
37
+ }
38
+
39
+ stream = null;
40
+ self.postMessage( { data: data.buffer, width, height, depth }, [ data.buffer ] );
41
+
42
+ }
43
+
44
+ async function processIntoShared( { shared, width, height, layers } ) {
45
+
46
+ if ( canvas.width !== width || canvas.height !== height ) {
47
+
48
+ canvas.width = width;
49
+ canvas.height = height;
50
+
51
+ }
52
+
53
+ ctx.imageSmoothingEnabled = true;
54
+ ctx.imageSmoothingQuality = 'high';
55
+
56
+ const data = new Uint8Array( shared );
57
+ const bytes = width * height * 4;
58
+
59
+ for ( const { index, texture } of layers ) {
60
+
61
+ try {
62
+
63
+ await processSingleTextureOptimized( texture, data, index * bytes, width, height );
64
+
65
+ } catch ( error ) {
66
+
67
+ console.warn( `Failed to process texture ${index}:`, error );
68
+ data.fill( 0, index * bytes, ( index + 1 ) * bytes );
69
+
70
+ }
71
+
72
+ }
73
+
74
+ }
75
+
12
76
  self.onmessage = async function ( e ) {
13
77
 
78
+ if ( e.data.shared ) {
79
+
80
+ try {
81
+
82
+ if ( ! canvas ) initializeWorker( e.data.maxTextureSize );
83
+ await processIntoShared( e.data );
84
+ self.postMessage( { done: true } );
85
+
86
+ } catch ( error ) {
87
+
88
+ self.postMessage( { error: error.message } );
89
+
90
+ }
91
+
92
+ return;
93
+
94
+ }
95
+
96
+ if ( e.data.stream ) {
97
+
98
+ try {
99
+
100
+ handleStream( e.data );
101
+
102
+ } catch ( error ) {
103
+
104
+ self.postMessage( { error: error.message } );
105
+
106
+ }
107
+
108
+ return;
109
+
110
+ }
111
+
14
112
  const { textures, maxTextureSize, method = 'direct-transfer' } = e.data;
15
113
 
16
114
  try {
@@ -39,7 +137,7 @@ self.onmessage = async function ( e ) {
39
137
  function initializeWorker( maxTextureSize ) {
40
138
 
41
139
  // Initialize OffscreenCanvas with optimal settings
42
- const size = Math.min( maxTextureSize, MEMORY_LIMITS.MAX_TEXTURE_DIMENSION );
140
+ const size = Math.min( maxTextureSize, TEXTURE_CONSTANTS.MAX_TEXTURE_SIZE );
43
141
  canvas = new OffscreenCanvas( size, size );
44
142
  ctx = canvas.getContext( '2d', {
45
143
  willReadFrequently: true,
@@ -51,17 +149,6 @@ function initializeWorker( maxTextureSize ) {
51
149
 
52
150
  async function processTextures( textures, maxTextureSize, method ) {
53
151
 
54
- // Check if we need to use chunked processing
55
- const dimensions = calculateOptimalDimensions( textures, maxTextureSize );
56
- const estimatedBytes = dimensions.maxWidth * dimensions.maxHeight * textures.length * 4;
57
-
58
- if ( estimatedBytes > MEMORY_LIMITS.MAX_BYTES_PER_TEXTURE ) {
59
-
60
- console.log( `Large texture array detected (${( estimatedBytes / 1024 / 1024 ).toFixed( 2 )}MB), using chunked processing` );
61
- return await processTexturesInChunks( textures, maxTextureSize, method );
62
-
63
- }
64
-
65
152
  switch ( method ) {
66
153
 
67
154
  case 'direct-transfer':
@@ -620,7 +707,7 @@ function calculateOptimalDimensions( textures, maxTextureSize ) {
620
707
  }
621
708
 
622
709
  // Scale down proportionally only when the cap is exceeded; native res is kept below it.
623
- const cap = Math.min( maxTextureSize, MEMORY_LIMITS.MAX_TEXTURE_DIMENSION );
710
+ const cap = Math.min( maxTextureSize, TEXTURE_CONSTANTS.MAX_TEXTURE_SIZE );
624
711
  const longest = Math.max( maxWidth, maxHeight );
625
712
  if ( longest > cap ) {
626
713
 
@@ -630,9 +717,7 @@ function calculateOptimalDimensions( textures, maxTextureSize ) {
630
717
 
631
718
  }
632
719
 
633
- // An RGBA8 row upload must be a multiple of 256 bytes, so widths land on 64 texels.
634
- // Mirrors alignBucketWidth in EngineDefaults (not importable from worker context).
635
- maxWidth = Math.min( cap, Math.max( 4, Math.ceil( Math.max( 1, maxWidth ) / 64 ) * 64 ) );
720
+ maxWidth = alignBucketWidth( maxWidth, cap );
636
721
 
637
722
  return { maxWidth, maxHeight: Math.max( 1, maxHeight ) };
638
723
 
@@ -0,0 +1,7 @@
1
+ /** What the archive add-on reads, known before its code loads (rayzee/addons/archives; PathTracerApp loads it on first use). */
2
+ export const ARCHIVE_FORMATS = Object.freeze( {
3
+ 'zip': { type: 'archive', name: 'ZIP Archive' },
4
+ 'gz': { type: 'archive', name: 'Gzipped TAR Archive' },
5
+ 'tgz': { type: 'archive', name: 'Gzipped TAR Archive' },
6
+ 'tar': { type: 'archive', name: 'TAR Archive' },
7
+ } );
@@ -63,7 +63,8 @@ export function disposeMaterialTextures( material ) {
63
63
  const textures = [
64
64
  'alphaMap', 'aoMap', 'bumpMap', 'clearcoatMap', 'clearcoatNormalMap', 'clearcoatRoughnessMap', 'displacementMap',
65
65
  'emissiveMap', 'envMap', 'gradientMap', 'lightMap', 'map', 'metalnessMap', 'normalMap', 'roughnessMap', 'specularMap',
66
- 'sheenColorMap', 'sheenRoughnessMap', 'specularIntensityMap', 'specularColorMap', 'thicknessMap', 'transmissionMap'
66
+ 'sheenColorMap', 'sheenRoughnessMap', 'specularIntensityMap', 'specularColorMap', 'thicknessMap', 'transmissionMap',
67
+ 'diffuseTransmissionMap', 'diffuseTransmissionColorMap',
67
68
  ];
68
69
 
69
70
  textures.forEach( texture => {