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
@@ -45,8 +45,10 @@ import {
45
45
  computeAnisoAlphas,
46
46
  calculateBRDFWeights,
47
47
  sheenSamplingRoughness,
48
+ diffuseTransmissionPdf,
48
49
  } from './MaterialProperties.js';
49
- import { evaluateMaterialResponseFromDots, evaluateSpecularDeltaFromDots } from './MaterialEvaluation.js';
50
+ import { evaluateMaterialResponseFromDots, evaluateSpecularDeltaFromDots, evaluateDiffuseTransmission } from './MaterialEvaluation.js';
51
+ import { materialLayers } from './SceneResources.js';
50
52
 
51
53
  import {
52
54
  ImportanceSampleCosine,
@@ -71,14 +73,16 @@ export const generateSampledDirection = Fn( ( [
71
73
  mc,
72
74
  weightsComputed, cachedBrdfWeights,
73
75
  materialCacheCached, cachedMaterialCache,
74
- ] ) => {
76
+ ], builder ) => {
75
77
 
78
+ const layers = materialLayers( builder );
76
79
  const resultDirection = vec3( 0.0 ).toVar();
77
80
  const resultValue = vec3( 0.0 ).toVar();
78
81
  const resultPdf = float( 0.0 ).toVar();
79
82
  const resultIsTransmission = tslBool( false ).toVar();
80
83
  const resultColorWeight = vec3( 1.0 ).toVar();
81
84
  const resultIsDelta = tslBool( false ).toVar();
85
+ const resultIsDiffuseTransmission = tslBool( false ).toVar();
82
86
 
83
87
  // Compute BRDF weights
84
88
  const weights = cachedBrdfWeights.toVar();
@@ -114,17 +118,42 @@ export const generateSampledDirection = Fn( ( [
114
118
  const cumulativeDiffuse = weights.diffuse.toVar();
115
119
  const cumulativeSpecular = cumulativeDiffuse.add( weights.specular ).toVar();
116
120
  const cumulativeSheen = cumulativeSpecular.add( weights.sheen ).toVar();
117
- const cumulativeClearcoat = cumulativeSheen.add( weights.clearcoat );
121
+ const cumulativeClearcoat = cumulativeSheen.add( weights.clearcoat ).toVar();
122
+ const cumulativeDiffuseTransmission = cumulativeClearcoat.add( weights.diffuseTransmission );
118
123
 
119
124
  // Chained If/ElseIf so emitted WGSL becomes a single mutually-exclusive branch
120
- // (replaces five separate If blocks gated on a `sampled` flag — divergence hotspot)
121
- If( rand.lessThan( cumulativeDiffuse ), () => {
125
+ // (replaces five separate If blocks gated on a `sampled` flag — divergence hotspot). A layer no material uses
126
+ // has weight 0, so its link could never be taken and is left out.
127
+ const isotropicSpecular = () => {
128
+
129
+ If( material.roughness.greaterThan( 0.0 ), () => {
130
+
131
+ const TBN = constructTBN( { N } );
132
+ const localV = TBN.transpose().mul( V );
133
+
134
+ // VNDF sampling
135
+ const localH = sampleGGXVNDF( { V: localV, roughness: material.roughness, Xi: xi } );
136
+ H.assign( TBN.mul( localH ) );
137
+
138
+ resultDirection.assign( reflect( V.negate(), H ) );
139
+
140
+ } ).Else( () => {
141
+
142
+ resultDirection.assign( reflect( V.negate(), N ) );
143
+ resultIsDelta.assign( true );
144
+
145
+ } );
146
+
147
+ };
148
+
149
+ let lobes = If( rand.lessThan( cumulativeDiffuse ), () => {
122
150
 
123
151
  resultDirection.assign( ImportanceSampleCosine( { N, xi } ) );
124
152
 
125
153
  } ).ElseIf( rand.lessThan( cumulativeSpecular ), () => {
126
154
 
127
- If( material.anisotropy.greaterThan( 0.0 ), () => {
155
+ if ( ! layers.anisotropy ) isotropicSpecular();
156
+ else If( material.anisotropy.greaterThan( 0.0 ), () => {
128
157
 
129
158
  // Shared frame → sampler and eval/PDF stay bit-identical (MIS consistency)
130
159
  const f = AnisoFrame.wrap( anisoTangentFrame( N, material.anisotropyRotation ) );
@@ -138,25 +167,11 @@ export const generateSampledDirection = Fn( ( [
138
167
 
139
168
  resultDirection.assign( reflect( V.negate(), H ) );
140
169
 
141
- } ).ElseIf( material.roughness.greaterThan( 0.0 ), () => {
142
-
143
- const TBN = constructTBN( { N } );
144
- const localV = TBN.transpose().mul( V );
145
-
146
- // VNDF sampling
147
- const localH = sampleGGXVNDF( { V: localV, roughness: material.roughness, Xi: xi } );
148
- H.assign( TBN.mul( localH ) );
149
-
150
- resultDirection.assign( reflect( V.negate(), H ) );
151
-
152
- } ).Else( () => {
153
-
154
- resultDirection.assign( reflect( V.negate(), N ) );
155
- resultIsDelta.assign( true );
170
+ } ).Else( isotropicSpecular );
156
171
 
157
- } );
172
+ } );
158
173
 
159
- } ).ElseIf( rand.lessThan( cumulativeSheen ), () => {
174
+ if ( layers.sheen ) lobes = lobes.ElseIf( rand.lessThan( cumulativeSheen ), () => {
160
175
 
161
176
  H.assign( ImportanceSampleGGX( { N, roughness: sheenSamplingRoughness( material.sheenRoughness ), Xi: xi } ) );
162
177
  resultDirection.assign( reflect( V.negate(), H ) );
@@ -165,7 +180,9 @@ export const generateSampledDirection = Fn( ( [
165
180
  // would add a P(reject)·cos term to the true density that calculateBSDFSamplingPDF cannot
166
181
  // model, and dividing by the smaller modelled density inflated the lobe 23 %.
167
182
 
168
- } ).ElseIf( rand.lessThan( cumulativeClearcoat ), () => {
183
+ } );
184
+
185
+ if ( layers.clearcoat ) lobes = lobes.ElseIf( rand.lessThan( cumulativeClearcoat ), () => {
169
186
 
170
187
  // VNDF, not ImportanceSampleGGX: the mixture density reports this lobe with
171
188
  // calculateVNDFPDF, and sampling the half-vector GGX distribution instead would make the
@@ -175,7 +192,16 @@ export const generateSampledDirection = Fn( ( [
175
192
  H.assign( ccTBN.mul( sampleGGXVNDF( { V: ccTBN.transpose().mul( V ), roughness: clearcoatRoughness, Xi: xi } ) ) );
176
193
  resultDirection.assign( reflect( V.negate(), H ) );
177
194
 
178
- } ).Else( () => {
195
+ } );
196
+
197
+ if ( layers.diffuseTransmission ) lobes = lobes.ElseIf( rand.lessThan( cumulativeDiffuseTransmission ), () => {
198
+
199
+ resultDirection.assign( ImportanceSampleCosine( { N: N.negate(), xi } ) );
200
+ resultIsDiffuseTransmission.assign( true );
201
+
202
+ } );
203
+
204
+ lobes.Else( () => {
179
205
 
180
206
  const entering = dot( V, N ).greaterThan( 0.0 );
181
207
  // pathWavelength=0 — the spectral lock happens downstream; colorWeight is carried out on
@@ -193,10 +219,11 @@ export const generateSampledDirection = Fn( ( [
193
219
 
194
220
  } );
195
221
 
196
- // One mixture density for every reflection lobe: any of them could have produced this
197
- // direction, so the chosen lobe's own pdf is not the density we sampled from.
198
- If( resultIsTransmission.not(), () => {
222
+ // Below the surface only the diffuse transmission lobe draws, so its own density is the mixture's.
223
+ const reflected = () => {
199
224
 
225
+ // One mixture density for every reflection lobe: any of them could have produced this
226
+ // direction, so the chosen lobe's own pdf is not the density we sampled from.
200
227
  const dotsOut = DotProducts.wrap( computeDotProductsAniso( N, V, resultDirection, material ) );
201
228
  If( resultIsDelta, () => {
202
229
 
@@ -213,7 +240,15 @@ export const generateSampledDirection = Fn( ( [
213
240
 
214
241
  } );
215
242
 
216
- } );
243
+ };
244
+
245
+ if ( ! layers.diffuseTransmission ) If( resultIsTransmission.not(), reflected );
246
+ else If( resultIsDiffuseTransmission, () => {
247
+
248
+ resultValue.assign( evaluateDiffuseTransmission( material, max( dot( N, V ), 0.001 ) ) );
249
+ resultPdf.assign( diffuseTransmissionPdf( weights.diffuseTransmission, dot( N, resultDirection ).negate() ) );
250
+
251
+ } ).ElseIf( resultIsTransmission.not(), reflected );
217
252
 
218
253
  resultPdf.assign( max( resultPdf, MIN_PDF ) );
219
254
 
@@ -223,6 +258,7 @@ export const generateSampledDirection = Fn( ( [
223
258
  pdf: resultPdf,
224
259
  isTransmission: resultIsTransmission,
225
260
  colorWeight: resultColorWeight,
261
+ isDiffuseTransmission: resultIsDiffuseTransmission,
226
262
  } );
227
263
 
228
264
  } );
package/src/TSL/Random.js CHANGED
@@ -107,7 +107,7 @@ export const RandomPointInCircle = ( rngState ) => {
107
107
  // +7 ground-catcher cosine BSDF (ShadeKernel)
108
108
  // +8 indirect-strategy direction (LightsIndirect)
109
109
  // +9 physical-sky sun disc (LightsSampling)
110
- // 1D +0 (free — was the {lights,BRDF} stochastic strategy pick)
110
+ // 1D +0 light kind for the picked shadow ray (LightsSampling lightPick, setting shadowRays)
111
111
  // +1 emissive-triangle pick (EmissiveSampling / LightBVHSampling)
112
112
  // +2 BSDF lobe selection (ShadeKernel)
113
113
  // +3 Russian roulette (PathTracerCore)
@@ -123,6 +123,8 @@ export const RandomPointInCircle = ( rngState ) => {
123
123
  // +13 clearcoat lobe (Clearcoat)
124
124
  // +14 area/spot light phi (LightsSampling)
125
125
  // +15 light uv second component (LightsSampling)
126
+ // +16 light path to connect to (ConnectKernel, bidirectional)
127
+ // +17 light vertex on that path (ConnectKernel, bidirectional)
126
128
  //
127
129
  // Stride is 32 rather than the ~16 in use so a new call site does not force a renumbering.
128
130
  // The index only keys a scramble seed, so spare slots cost nothing.
@@ -131,6 +133,8 @@ export const RandomPointInCircle = ( rngState ) => {
131
133
  // the next bounce's dimensions, so they live above AUX_BASE:
132
134
  // AUX_BASE + 0..63 env-backdrop blur taps (ShadeKernel)
133
135
  // AUX_BASE + 64.. light reservoir, one dimension per scene light (LightsSampling)
136
+ // AUX_BASE + 2048.. light subpath emission (LightGenerateKernel); light paths draw at pixels
137
+ // offset by LIGHT_PIXEL_ROW_OFFSET rows, so no camera path shares a sequence
134
138
  export const SAMPLER_DIMS_PER_BOUNCE = 32;
135
139
  export const SAMPLER_DIM_AUX_BASE = 4096;
136
140
 
@@ -0,0 +1,51 @@
1
+ /**
2
+ * A renderer's own scene resources for its shaders: material texture buckets, the albedo maps alpha-cutout
3
+ * shadow rays read, gobo and IES textures, and the alpha-shadow switch. They ride in the build context of each
4
+ * kernel that reads them: a TSL function's body runs when its kernel compiles, often at the first dispatch, so
5
+ * module-level state was read from whichever renderer — or pipeline stage — had set it last.
6
+ *
7
+ * @typedef {Object} SceneResources
8
+ * @property {Array<Node>} srgbBuckets - sRGB material bucket texture nodes (albedo, emissive, sheen, specular colour)
9
+ * @property {Array<Node>} linearBuckets - linear material bucket texture nodes
10
+ * @property {?Array<Node>} shadowAlbedoMaps - sRGB buckets alpha-cutout shadow rays sample, or null
11
+ * @property {?Node} goboMaps - spot / directional gobo texture array, or null
12
+ * @property {?Node} iesProfiles - IES profile texture array, or null
13
+ * @property {?Node} alphaShadows - int uniform, 1 = shadow rays test texture alpha; null = never
14
+ * @property {?Object<string, boolean>} materialLayers - the MATERIAL_LAYERS some material uses; null = all of them
15
+ */
16
+
17
+ import { context } from 'three/tsl';
18
+
19
+ const KEY = 'rayzeeScene';
20
+
21
+ /** Builds `node` (a kernel's root call) with these resources in its context. */
22
+ export const withSceneResources = ( node, resources ) => context( node, { [ KEY ]: resources } );
23
+
24
+ /**
25
+ * The resources of the kernel being built; call from a TSL function body with its builder.
26
+ * @returns {SceneResources}
27
+ */
28
+ export function sceneResources( builder ) {
29
+
30
+ const resources = builder.context[ KEY ];
31
+ if ( ! resources ) throw new Error( 'this kernel samples scene resources: build its root with withSceneResources()' );
32
+ return resources;
33
+
34
+ }
35
+
36
+ /** The material layers a kernel compiles only while some material in its scene has them. */
37
+ export const MATERIAL_LAYERS = Object.freeze( [ 'clearcoat', 'sheen', 'iridescence', 'anisotropy', 'subsurface', 'dispersion', 'diffuseTransmission' ] );
38
+
39
+ /** Every layer compiled in. */
40
+ export const ALL_MATERIAL_LAYERS = Object.freeze( Object.fromEntries( MATERIAL_LAYERS.map( ( layer ) => [ layer, true ] ) ) );
41
+
42
+ /**
43
+ * The material layers the kernel being built compiles; call from a TSL function body with its builder. A layer no
44
+ * material uses is left out of every function that reads it. Outside a scene kernel (a test), every layer is in.
45
+ * @returns {Object<string, boolean>}
46
+ */
47
+ export function materialLayers( builder ) {
48
+
49
+ return builder.context[ KEY ]?.materialLayers ?? ALL_MATERIAL_LAYERS;
50
+
51
+ }