rayzee 9.4.1 → 9.5.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 +226 -25
- package/dist/ActiveColor-YvuQq44O.js +13 -0
- package/dist/ArchiveImporter-xuUJiklP.js +4301 -0
- package/dist/AssetConfig-DSEntE65.js +30 -0
- package/dist/BidirectionalIntegrator-C5PKjJoT.js +934 -0
- package/dist/ColorManagement-CheBCPaW.js +1488 -0
- package/dist/EngineDefaults-DH3bI5t-.js +844 -0
- package/dist/EngineEvents-Ci8dVWCP.js +73 -0
- package/dist/EngineIssues-CIZnXHsF.js +72 -0
- package/dist/FileFormats-sPGJeCRc.js +102 -0
- package/dist/Logger-BnHghprG.js +97 -0
- package/dist/{NeuralRetouch-vkdXXyK2.js → NeuralRetouch-CW11yLZ_.js} +8 -6
- package/dist/{NeuralSuperRes-FVqRJKQV.js → NeuralSuperRes-BekaecYg.js} +55 -120
- package/dist/PathTracer-Ccl9KOuF.js +29729 -0
- package/dist/PhysicalSky-Dv2PMFGW.js +1219 -0
- package/dist/RayzeeRenderer-BQxnzCTD.js +3542 -0
- package/dist/SolarLimb-ken-JbDK.js +721 -0
- package/dist/ToneMapGPU-BHi5JzIq.js +177 -0
- package/dist/ViewTransforms-D0rTLBsX.js +255 -0
- package/dist/WorkingMatrix-C6y233hT.js +27 -0
- package/dist/ZipReader-gDSWr0I5.js +98 -0
- package/dist/addons/archives.es.js +3 -0
- package/dist/addons/bidirectional.es.js +2 -0
- package/dist/addons/color.es.js +3 -0
- package/dist/addons/formats.es.js +2 -0
- package/dist/addons/physical-sky.es.js +2 -0
- package/dist/addons/storage.es.js +3 -0
- package/dist/archiveFormats-BZw7TiDp.js +75 -0
- package/dist/identity-DrQsGT2o.js +39 -0
- package/dist/openStorage-DwcBRUj7.js +820 -0
- package/dist/rayzee-core.es.js +12 -0
- package/dist/rayzee.es.js +2266 -44125
- package/dist/rayzee.umd.js +485 -473
- package/dist/sceneCachePolicy-BmwYOYDu.js +183 -0
- package/dist/shared-BGBcSxBQ.js +17 -0
- package/package.json +23 -2
- package/src/Color/ActiveColor.js +34 -0
- package/src/Color/BasicColor.js +147 -0
- package/src/Color/ColorManagement.js +7 -31
- package/src/EngineDefaults.js +23 -14
- package/src/EngineEvents.js +2 -0
- package/src/EngineIssues.js +1 -0
- package/src/PathTracerApp.js +617 -4016
- package/src/Pipeline/PipelineContext.js +0 -4
- package/src/Platform.js +36 -0
- package/src/Processor/ArchiveCache.js +1 -1
- package/src/Processor/ArchiveImporter.js +1259 -0
- package/src/Processor/AssetLoader.js +322 -1746
- package/src/Processor/AtmosphereModel.js +1 -2
- package/src/Processor/BVHBuilder.js +4 -95
- package/src/Processor/EnvironmentExactTable.js +187 -0
- package/src/Processor/EquirectHDRInfo.js +30 -223
- package/src/Processor/FileFormats.js +116 -0
- package/src/Processor/GLTFDecoders.js +85 -0
- package/src/Processor/GLTFDiffuseTransmission.js +63 -0
- package/src/Processor/GeometryExtractor.js +12 -1
- package/src/Processor/IESParser.js +47 -35
- package/src/Processor/KernelManager.js +35 -2
- package/src/Processor/MaterialPacking.js +8 -7
- package/src/Processor/PBRT/PBRTMaterials.js +129 -41
- package/src/Processor/PBRT/PBRTParser.js +30 -17
- package/src/Processor/PBRT/PBRTSceneBuilder.js +548 -37
- package/src/Processor/PBRT/PBRTTextureBake.js +154 -0
- package/src/Processor/PBRT/PFM.js +59 -0
- package/src/Processor/PackedRayBuffer.js +116 -9
- package/src/Processor/ParallelBVHBuilder.js +3 -6
- package/src/Processor/PhysicalSky.js +5 -4
- package/src/Processor/PlatformImageLoader.js +50 -6
- package/src/Processor/QueueManager.js +12 -3
- package/src/Processor/ReinsertionOptimizer.js +2 -2
- package/src/Processor/SceneProcessor.js +15 -55
- package/src/Processor/ShaderBuilder.js +6 -16
- package/src/Processor/SimpleSky.js +1 -62
- package/src/Processor/SolarLimb.js +3 -0
- package/src/Processor/TextureCreator.js +1 -1
- package/src/Processor/Workers/BVHSubtreeWorker.js +1 -34
- package/src/Processor/Workers/BVHWorker.js +5 -18
- package/src/Processor/Workers/CDFWorker.js +6 -183
- package/src/Processor/archiveFormats.js +7 -0
- package/src/Processor/utils.js +2 -1
- package/src/RayzeeRenderer.js +3902 -0
- package/src/RenderSettings.js +49 -41
- package/src/Stages/ASVGF.js +5 -7
- package/src/Stages/AutoExposure.js +3 -12
- package/src/Stages/Compositor.js +8 -23
- package/src/Stages/NRD.js +9 -2
- package/src/Stages/NormalDepth.js +9 -6
- package/src/Stages/PathTracer.js +254 -38
- package/src/Stages/PathTracerStage.js +11 -16
- package/src/Storage/BLASCache.js +1 -1
- package/src/Storage/CDFCache.js +18 -17
- package/src/Storage/DownloadCache.js +1 -1
- package/src/Storage/SceneGraphCodec.js +46 -3
- package/src/Storage/SpillStore.js +1 -1
- package/src/Storage/StorageManager.js +2 -4
- package/src/Storage/areas.js +4 -0
- package/src/TSL/BVHTraversal.js +62 -24
- package/src/TSL/Bidirectional.js +204 -0
- package/src/TSL/BidirectionalLamps.js +132 -0
- package/src/TSL/Clearcoat.js +15 -6
- package/src/TSL/Common.js +19 -14
- package/src/TSL/ConnectKernel.js +147 -0
- package/src/TSL/Debugger.js +1 -1
- package/src/TSL/Displacement.js +4 -3
- package/src/TSL/EmissiveSampling.js +64 -17
- package/src/TSL/Environment.js +77 -106
- package/src/TSL/EnvironmentCDF.js +85 -39
- package/src/TSL/ExtendKernel.js +8 -3
- package/src/TSL/FinalWriteKernel.js +4 -4
- package/src/TSL/GenerateKernel.js +18 -4
- package/src/TSL/HitFacet.js +35 -5
- package/src/TSL/LightBVHSampling.js +40 -9
- package/src/TSL/LightGenerateKernel.js +293 -0
- package/src/TSL/LightGuide.js +198 -0
- package/src/TSL/LightSplatKernel.js +165 -0
- package/src/TSL/LightsCore.js +13 -38
- package/src/TSL/LightsDirect.js +28 -29
- package/src/TSL/LightsIndirect.js +3 -1
- package/src/TSL/LightsSampling.js +90 -38
- package/src/TSL/MaterialEvaluation.js +113 -31
- package/src/TSL/MaterialProperties.js +44 -17
- package/src/TSL/MaterialTransmission.js +52 -47
- package/src/TSL/MergeKernel.js +218 -0
- package/src/TSL/PathTracerCore.js +65 -29
- package/src/TSL/Random.js +4 -0
- package/src/TSL/SceneResources.js +51 -0
- package/src/TSL/ShadeKernel.js +881 -103
- package/src/TSL/Struct.js +10 -0
- package/src/TSL/Sun.js +1 -1
- package/src/TSL/TextureSampling.js +65 -60
- package/src/addons/archives.js +14 -0
- package/src/addons/bidirectional.js +13 -0
- package/src/addons/color.js +32 -0
- package/src/addons/formats.js +16 -0
- package/src/addons/physicalSky.js +14 -0
- package/src/addons/storage.js +19 -0
- package/src/core.js +35 -0
- package/src/index.js +3 -1
- package/src/integrators/BidirectionalIntegrator.js +832 -0
- package/src/managers/EnvironmentManager.js +94 -91
- package/src/managers/MaterialDataManager.js +42 -0
- package/src/managers/UniformManager.js +0 -1
- package/dist/ToneMapGPU-DKQM1pMd.js +0 -552
- package/dist/rolldown-runtime-CAFD8bLK.js +0 -11
- package/src/Processor/TreeletOptimizer.js +0 -574
|
@@ -65,6 +65,13 @@ export function pString( params, name, dflt ) {
|
|
|
65
65
|
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
+
export function pBool( params, name, dflt ) {
|
|
69
|
+
|
|
70
|
+
const v = params[ name ]?.value?.[ 0 ];
|
|
71
|
+
return v === undefined ? dflt : v === true || v === 'true';
|
|
72
|
+
|
|
73
|
+
}
|
|
74
|
+
|
|
68
75
|
/**
|
|
69
76
|
* Resolve a spectrum/color/float-valued parameter to an RGB triple and/or a
|
|
70
77
|
* texture. Returns `{ rgb, texture }` — exactly one is typically non-null.
|
|
@@ -144,15 +151,74 @@ function namedMetalKey( s ) {
|
|
|
144
151
|
|
|
145
152
|
}
|
|
146
153
|
|
|
147
|
-
|
|
148
|
-
function
|
|
154
|
+
// A float parameter's value, or a float texture's mean (`ctx.floatTextureMean`); null when absent or unreadable.
|
|
155
|
+
async function floatOrMean( params, name, ctx ) {
|
|
156
|
+
|
|
157
|
+
const p = params[ name ];
|
|
158
|
+
if ( ! p ) return null;
|
|
159
|
+
if ( typeof p.value[ 0 ] === 'number' ) return p.value[ 0 ];
|
|
160
|
+
if ( p.type === 'texture' ) return ( await ctx.floatTextureMean?.( p.value[ 0 ] ) ) ?? null;
|
|
161
|
+
return null;
|
|
162
|
+
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* The engine's roughness for pbrt's `roughness` or anisotropic `uroughness`/`vroughness` (their α averaged), under
|
|
167
|
+
* `prefix` for a layer (`conductor.`, `interface.`); a textured roughness counts as its mean. pbrt-v4 takes GGX
|
|
168
|
+
* α = √roughness (`remaproughness`, the default) or α = roughness; the engine's GGX takes α = roughness². Passing
|
|
169
|
+
* pbrt's number through made `remaproughness false` 0.1 an α of 0.01, a near mirror. `dflt` is the engine's.
|
|
170
|
+
*/
|
|
171
|
+
async function resolveRoughness( params, dflt, ctx, prefix = '' ) {
|
|
172
|
+
|
|
173
|
+
const remap = params.remaproughness?.value?.[ 0 ];
|
|
174
|
+
const alpha = ( r ) => ( remap === false || remap === 'false' ? r : Math.sqrt( Math.max( r, 0 ) ) );
|
|
175
|
+
let a = null;
|
|
176
|
+
const r = await floatOrMean( params, `${prefix}roughness`, ctx );
|
|
177
|
+
if ( r !== null ) a = alpha( r );
|
|
178
|
+
else {
|
|
179
|
+
|
|
180
|
+
const u = await floatOrMean( params, `${prefix}uroughness`, ctx );
|
|
181
|
+
const v = await floatOrMean( params, `${prefix}vroughness`, ctx );
|
|
182
|
+
if ( u !== null ) a = v !== null ? ( alpha( u ) + alpha( v ) ) / 2 : alpha( u );
|
|
183
|
+
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
return a === null ? dflt : Math.sqrt( Math.max( a, 0 ) );
|
|
187
|
+
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// A conductor's colour: `reflectance`, else normal-incidence Fresnel of `eta`/`k` (under `prefix` for a coated
|
|
191
|
+
// conductor). pbrt's default is copper.
|
|
192
|
+
async function applyConductorColor( mat, params, ctx, prefix, applyAlbedo, setColor ) {
|
|
193
|
+
|
|
194
|
+
const refl = await resolveSpectrum( params, 'reflectance', ctx, null );
|
|
195
|
+
const etaP = params[ `${prefix}eta` ], kP = params[ `${prefix}k` ];
|
|
196
|
+
const etaNamed = etaP && etaP.type === 'spectrum' && typeof etaP.value[ 0 ] === 'string';
|
|
197
|
+
|
|
198
|
+
if ( refl.rgb || refl.texture ) {
|
|
199
|
+
|
|
200
|
+
applyAlbedo( refl );
|
|
201
|
+
|
|
202
|
+
} else if ( etaP && kP && ! etaNamed ) {
|
|
203
|
+
|
|
204
|
+
// Normal-incidence reflectance from complex IOR: ((η-1)²+k²)/((η+1)²+k²).
|
|
205
|
+
const eta = ( await resolveSpectrum( params, `${prefix}eta`, ctx, [ 0.2, 0.92, 1.1 ] ) ).rgb;
|
|
206
|
+
const k = ( await resolveSpectrum( params, `${prefix}k`, ctx, [ 3.9, 2.45, 2.14 ] ) ).rgb;
|
|
207
|
+
const fr = ( n, kk ) => ( ( n - 1 ) ** 2 + kk ** 2 ) / ( ( n + 1 ) ** 2 + kk ** 2 );
|
|
208
|
+
setColor( [ fr( eta[ 0 ], k[ 0 ] ), fr( eta[ 1 ], k[ 1 ] ), fr( eta[ 2 ], k[ 2 ] ) ] );
|
|
209
|
+
|
|
210
|
+
} else if ( etaP ) {
|
|
149
211
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
212
|
+
// Named conductor spectrum → metal albedo table.
|
|
213
|
+
setColor( ( await resolveSpectrum( params, `${prefix}eta`, ctx, DEFAULT_METAL ) ).rgb || DEFAULT_METAL );
|
|
214
|
+
|
|
215
|
+
} else {
|
|
216
|
+
|
|
217
|
+
setColor( METAL_ALBEDO.cu ); // pbrt-v4 default conductor is copper
|
|
218
|
+
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
mat.metalness = 1;
|
|
156
222
|
|
|
157
223
|
}
|
|
158
224
|
|
|
@@ -193,9 +259,11 @@ export async function buildMaterial( def, ctx ) {
|
|
|
193
259
|
|
|
194
260
|
case 'diffuse': {
|
|
195
261
|
|
|
262
|
+
// Lambertian: no dielectric specular layer, which MeshPhysicalMaterial has by default.
|
|
196
263
|
applyAlbedo( await resolveSpectrum( params, 'reflectance', ctx, [ 0.5, 0.5, 0.5 ] ) );
|
|
197
264
|
mat.roughness = 1;
|
|
198
265
|
mat.metalness = 0;
|
|
266
|
+
mat.specularIntensity = 0;
|
|
199
267
|
break;
|
|
200
268
|
|
|
201
269
|
}
|
|
@@ -203,35 +271,19 @@ export async function buildMaterial( def, ctx ) {
|
|
|
203
271
|
case 'conductor':
|
|
204
272
|
case 'metal': {
|
|
205
273
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
if ( refl.rgb || refl.texture ) {
|
|
211
|
-
|
|
212
|
-
applyAlbedo( refl );
|
|
213
|
-
|
|
214
|
-
} else if ( etaP && kP && ! etaNamed ) {
|
|
215
|
-
|
|
216
|
-
// Normal-incidence reflectance from complex IOR: ((η-1)²+k²)/((η+1)²+k²).
|
|
217
|
-
const eta = ( await resolveSpectrum( params, 'eta', ctx, [ 0.2, 0.92, 1.1 ] ) ).rgb;
|
|
218
|
-
const k = ( await resolveSpectrum( params, 'k', ctx, [ 3.9, 2.45, 2.14 ] ) ).rgb;
|
|
219
|
-
const fr = ( n, kk ) => ( ( n - 1 ) ** 2 + kk ** 2 ) / ( ( n + 1 ) ** 2 + kk ** 2 );
|
|
220
|
-
setColor( [ fr( eta[ 0 ], k[ 0 ] ), fr( eta[ 1 ], k[ 1 ] ), fr( eta[ 2 ], k[ 2 ] ) ] );
|
|
221
|
-
|
|
222
|
-
} else if ( etaP ) {
|
|
223
|
-
|
|
224
|
-
// Named conductor spectrum → metal albedo table.
|
|
225
|
-
setColor( ( await resolveSpectrum( params, 'eta', ctx, DEFAULT_METAL ) ).rgb || DEFAULT_METAL );
|
|
226
|
-
|
|
227
|
-
} else {
|
|
274
|
+
await applyConductorColor( mat, params, ctx, '', applyAlbedo, setColor );
|
|
275
|
+
mat.roughness = await resolveRoughness( params, 0.1, ctx );
|
|
276
|
+
break;
|
|
228
277
|
|
|
229
|
-
|
|
278
|
+
}
|
|
230
279
|
|
|
231
|
-
|
|
280
|
+
case 'coatedconductor': {
|
|
232
281
|
|
|
233
|
-
|
|
234
|
-
|
|
282
|
+
// A conductor under a dielectric coat; pbrt's roughnesses default to 0 for both.
|
|
283
|
+
await applyConductorColor( mat, params, ctx, 'conductor.', applyAlbedo, setColor );
|
|
284
|
+
mat.roughness = await resolveRoughness( params, 0, ctx, 'conductor.' );
|
|
285
|
+
mat.clearcoat = 1;
|
|
286
|
+
mat.clearcoatRoughness = await resolveRoughness( params, 0, ctx, 'interface.' );
|
|
235
287
|
break;
|
|
236
288
|
|
|
237
289
|
}
|
|
@@ -243,7 +295,7 @@ export async function buildMaterial( def, ctx ) {
|
|
|
243
295
|
mat.metalness = 0;
|
|
244
296
|
mat.color.setRGB( 1, 1, 1 );
|
|
245
297
|
mat.ior = pFloat( params, 'eta', 1.5 );
|
|
246
|
-
mat.roughness = resolveRoughness( params, 0 );
|
|
298
|
+
mat.roughness = await resolveRoughness( params, 0, ctx );
|
|
247
299
|
mat.thickness = type === 'thindielectric' ? 0 : pFloat( params, 'thickness', 0 );
|
|
248
300
|
break;
|
|
249
301
|
|
|
@@ -255,18 +307,30 @@ export async function buildMaterial( def, ctx ) {
|
|
|
255
307
|
mat.roughness = 0.6;
|
|
256
308
|
mat.metalness = 0;
|
|
257
309
|
mat.clearcoat = 1;
|
|
258
|
-
mat.clearcoatRoughness = resolveRoughness( params, 0 );
|
|
310
|
+
mat.clearcoatRoughness = await resolveRoughness( params, 0, ctx );
|
|
259
311
|
break;
|
|
260
312
|
|
|
261
313
|
}
|
|
262
314
|
|
|
263
315
|
case 'diffusetransmission': {
|
|
264
316
|
|
|
317
|
+
// pbrt reflects R and transmits T, both diffusely and both × `scale`, clamped to [0, 1]; no specular layer.
|
|
318
|
+
// The engine splits its diffuse lobe by `diffuseTransmission`: reflecting (1 − dt) · base, transmitting
|
|
319
|
+
// dt · colour. dt = max(T) makes both exact whenever max(R) + max(T) ≤ 1.
|
|
320
|
+
const scale = pFloat( params, 'scale', 1 );
|
|
321
|
+
const unit = ( v ) => Math.min( 1, Math.max( 0, scale * v ) );
|
|
265
322
|
const trans = await resolveSpectrum( params, 'transmittance', ctx, [ 0.25, 0.25, 0.25 ] );
|
|
266
|
-
|
|
267
|
-
|
|
323
|
+
const T = trans.rgb ? trans.rgb.map( unit ) : [ 0.5, 0.5, 0.5 ];
|
|
324
|
+
const dt = Math.min( 0.99, Math.max( ...T ) );
|
|
325
|
+
const refl = await resolveSpectrum( params, 'reflectance', ctx, [ 0.25, 0.25, 0.25 ] );
|
|
326
|
+
const base = ( v ) => Math.min( 1, unit( v ) / ( 1 - dt ) );
|
|
327
|
+
applyAlbedo( { texture: refl.texture, rgb: refl.rgb ? refl.rgb.map( base ) : ( refl.texture ? [ 1, 1, 1 ].map( base ) : null ) } );
|
|
328
|
+
if ( trans.texture ) ctx.warn( 'diffusetransmission: a textured "transmittance" is not supported — using 0.5' );
|
|
329
|
+
mat.diffuseTransmission = dt;
|
|
330
|
+
mat.diffuseTransmissionColor = new Color().setRGB( ...T.map( ( v ) => ( dt > 0 ? Math.min( 1, v / dt ) : 1 ) ) );
|
|
268
331
|
mat.roughness = 1;
|
|
269
|
-
mat.
|
|
332
|
+
mat.metalness = 0;
|
|
333
|
+
mat.specularIntensity = 0;
|
|
270
334
|
break;
|
|
271
335
|
|
|
272
336
|
}
|
|
@@ -292,13 +356,18 @@ export async function buildMaterial( def, ctx ) {
|
|
|
292
356
|
// instead of warning per shape. Recursive: mix-in-mix terminates as the
|
|
293
357
|
// chain bottoms out at a non-mix.
|
|
294
358
|
const matNames = params.materials?.value || [];
|
|
295
|
-
|
|
359
|
+
let t = Math.max( 0, Math.min( 1, pFloat( params, 'amount', 0.5 ) ) );
|
|
296
360
|
const defA = matNames[ 0 ] ? ctx.namedMaterials?.get( matNames[ 0 ] ) : null;
|
|
297
361
|
const defB = matNames[ 1 ] ? ctx.namedMaterials?.get( matNames[ 1 ] ) : null;
|
|
298
362
|
|
|
299
363
|
if ( defA && defB ) {
|
|
300
364
|
|
|
301
365
|
const [ matA, matB ] = await Promise.all( [ buildMaterial( defA, ctx ), buildMaterial( defB, ctx ) ] );
|
|
366
|
+
// pbrt picks the second material where a texture amount says so; its colours are baked by that
|
|
367
|
+
// texture (`ctx.bakeMaterialMix`) and the rest is weighed by the texture's mean.
|
|
368
|
+
const amountP = params.amount;
|
|
369
|
+
const baked = amountP?.type === 'texture' ? await ctx.bakeMaterialMix?.( matA, matB, amountP.value[ 0 ] ) : null;
|
|
370
|
+
if ( baked ) t = baked.mean;
|
|
302
371
|
const lerp = ( a, b ) => a * ( 1 - t ) + b * t;
|
|
303
372
|
mat.color.lerpColors( matA.color, matB.color, t );
|
|
304
373
|
mat.roughness = lerp( matA.roughness, matB.roughness );
|
|
@@ -309,9 +378,25 @@ export async function buildMaterial( def, ctx ) {
|
|
|
309
378
|
mat.clearcoat = lerp( matA.clearcoat ?? 0, matB.clearcoat ?? 0 );
|
|
310
379
|
mat.clearcoatRoughness = lerp( matA.clearcoatRoughness ?? 0, matB.clearcoatRoughness ?? 0 );
|
|
311
380
|
mat.emissive.lerpColors( matA.emissive, matB.emissive, t );
|
|
381
|
+
const dtA = matA.diffuseTransmission ?? 0, dtB = matB.diffuseTransmission ?? 0;
|
|
382
|
+
if ( dtA > 0 || dtB > 0 ) {
|
|
383
|
+
|
|
384
|
+
mat.diffuseTransmission = lerp( dtA, dtB );
|
|
385
|
+
mat.diffuseTransmissionColor = new Color().lerpColors( matA.diffuseTransmissionColor ?? new Color( 1, 1, 1 ), matB.diffuseTransmissionColor ?? new Color( 1, 1, 1 ), t );
|
|
386
|
+
|
|
387
|
+
}
|
|
388
|
+
|
|
312
389
|
mat.emissiveIntensity = lerp( matA.emissiveIntensity ?? 0, matB.emissiveIntensity ?? 0 );
|
|
313
|
-
// Maps can't be lerped — pick the dominant side.
|
|
390
|
+
// Maps can't be lerped — pick the dominant side, unless the amount's own texture baked them together.
|
|
314
391
|
mat.map = ( t < 0.5 ? matA.map : matB.map ) || null;
|
|
392
|
+
mat.normalMap = ( t < 0.5 ? matA.normalMap : matB.normalMap ) || null;
|
|
393
|
+
if ( baked?.texture ) {
|
|
394
|
+
|
|
395
|
+
mat.map = baked.texture;
|
|
396
|
+
mat.color.setRGB( 1, 1, 1 );
|
|
397
|
+
|
|
398
|
+
}
|
|
399
|
+
|
|
315
400
|
break;
|
|
316
401
|
|
|
317
402
|
}
|
|
@@ -344,6 +429,9 @@ export async function buildMaterial( def, ctx ) {
|
|
|
344
429
|
|
|
345
430
|
}
|
|
346
431
|
|
|
432
|
+
const normalMap = pString( params, 'normalmap', null );
|
|
433
|
+
if ( normalMap && ctx.resolveNormalMap ) mat.normalMap = await ctx.resolveNormalMap( normalMap );
|
|
434
|
+
|
|
347
435
|
mat.roughness = Math.max( 0, Math.min( 1, mat.roughness ) );
|
|
348
436
|
return mat;
|
|
349
437
|
|
|
@@ -111,6 +111,7 @@ export class PBRTParser {
|
|
|
111
111
|
instanceCount: 0,
|
|
112
112
|
skippedInstances: 0,
|
|
113
113
|
objects: new Map(),
|
|
114
|
+
media: new Map(),
|
|
114
115
|
transformTimes: { start: 0, end: 1 },
|
|
115
116
|
hasMotion: false,
|
|
116
117
|
warnings: []
|
|
@@ -122,14 +123,13 @@ export class PBRTParser {
|
|
|
122
123
|
this.activeTransform = BOTH;
|
|
123
124
|
this._ctmSource = null;
|
|
124
125
|
this._ctmValue = null;
|
|
125
|
-
this.state = { material: null, areaLight: null, reverseOrientation: false };
|
|
126
|
+
this.state = { material: null, areaLight: null, reverseOrientation: false, interior: null };
|
|
126
127
|
this.attributeStack = [];
|
|
127
128
|
this.transformStack = [];
|
|
128
129
|
this.coordSystems = new Map();
|
|
129
130
|
|
|
130
131
|
// Object capture (ObjectBegin/End)
|
|
131
132
|
this.currentObject = null; // name being captured, or null
|
|
132
|
-
this.objectBeginCTM = null; // CTM frame at ObjectBegin
|
|
133
133
|
|
|
134
134
|
// Directory stack for resolving nested Includes
|
|
135
135
|
this.dirStack = [ '' ];
|
|
@@ -275,7 +275,8 @@ export class PBRTParser {
|
|
|
275
275
|
activeTransform: this.activeTransform,
|
|
276
276
|
material: this.state.material,
|
|
277
277
|
areaLight: this.state.areaLight,
|
|
278
|
-
reverseOrientation: this.state.reverseOrientation
|
|
278
|
+
reverseOrientation: this.state.reverseOrientation,
|
|
279
|
+
interior: this.state.interior
|
|
279
280
|
} );
|
|
280
281
|
|
|
281
282
|
}
|
|
@@ -287,7 +288,7 @@ export class PBRTParser {
|
|
|
287
288
|
this.ctm = s.ctm;
|
|
288
289
|
this.ctmEnd = s.ctmEnd;
|
|
289
290
|
this.activeTransform = s.activeTransform;
|
|
290
|
-
this.state = { material: s.material, areaLight: s.areaLight, reverseOrientation: s.reverseOrientation };
|
|
291
|
+
this.state = { material: s.material, areaLight: s.areaLight, reverseOrientation: s.reverseOrientation, interior: s.interior };
|
|
291
292
|
|
|
292
293
|
}
|
|
293
294
|
|
|
@@ -624,7 +625,7 @@ export class PBRTParser {
|
|
|
624
625
|
this.ctm = M.identity();
|
|
625
626
|
this.ctmEnd = null;
|
|
626
627
|
this.activeTransform = BOTH;
|
|
627
|
-
this.state = { material: null, areaLight: null, reverseOrientation: false };
|
|
628
|
+
this.state = { material: null, areaLight: null, reverseOrientation: false, interior: null };
|
|
628
629
|
break;
|
|
629
630
|
case 'WorldEnd': break; // legacy v3
|
|
630
631
|
|
|
@@ -673,14 +674,21 @@ export class PBRTParser {
|
|
|
673
674
|
|
|
674
675
|
case 'MediumInterface': {
|
|
675
676
|
|
|
676
|
-
//
|
|
677
|
-
|
|
678
|
-
if ( this._peek()
|
|
677
|
+
// "interior" "exterior"; a single name is both. Only the interior colours a shape.
|
|
678
|
+
const interior = this._peek()?.type === TokenType.STRING ? this._next().value : '';
|
|
679
|
+
if ( this._peek()?.type === TokenType.STRING ) this._next();
|
|
680
|
+
this.state.interior = interior || null;
|
|
679
681
|
break;
|
|
680
682
|
|
|
681
683
|
}
|
|
682
684
|
|
|
683
|
-
case 'MakeNamedMedium':
|
|
685
|
+
case 'MakeNamedMedium': {
|
|
686
|
+
|
|
687
|
+
const mediumName = this._expectString( 'MakeNamedMedium name' );
|
|
688
|
+
this.ir.media.set( mediumName, this._parseParams() );
|
|
689
|
+
break;
|
|
690
|
+
|
|
691
|
+
}
|
|
684
692
|
|
|
685
693
|
// ── materials ──
|
|
686
694
|
case 'Material': {
|
|
@@ -748,13 +756,18 @@ export class PBRTParser {
|
|
|
748
756
|
|
|
749
757
|
const type = this._expectString( 'Shape type' );
|
|
750
758
|
const params = this._parseParams();
|
|
759
|
+
// pbrt: a shape of alpha 0 is never hit, and an area light on it emits nothing.
|
|
760
|
+
const alpha = params.alpha;
|
|
761
|
+
if ( alpha?.type === 'float' && alpha.value[ 0 ] <= 0 ) break;
|
|
762
|
+
if ( alpha && ! ( alpha.type === 'float' && alpha.value[ 0 ] >= 1 ) ) this._warnOnce( 'alpha', 'shape "alpha" between 0 and 1, or as a texture, is not supported — drawn opaque' );
|
|
751
763
|
const shape = {
|
|
752
764
|
type,
|
|
753
765
|
params,
|
|
754
766
|
ctm: this._ctmSnapshot(),
|
|
755
767
|
material: this.state.material,
|
|
756
768
|
areaLight: this.state.areaLight,
|
|
757
|
-
reverseOrientation: this.state.reverseOrientation
|
|
769
|
+
reverseOrientation: this.state.reverseOrientation,
|
|
770
|
+
interior: this.state.interior
|
|
758
771
|
};
|
|
759
772
|
const end = this.currentObject === null ? this._ctmEndSnapshot() : null;
|
|
760
773
|
if ( end ) shape.ctmEnd = end;
|
|
@@ -776,7 +789,6 @@ export class PBRTParser {
|
|
|
776
789
|
// pbrt implicitly pushes graphics state.
|
|
777
790
|
this._pushGraphicsState();
|
|
778
791
|
this.currentObject = objName;
|
|
779
|
-
this.objectBeginCTM = this.ctm.slice();
|
|
780
792
|
if ( ! this.ir.objects.has( objName ) ) this.ir.objects.set( objName, [] );
|
|
781
793
|
break;
|
|
782
794
|
|
|
@@ -785,7 +797,6 @@ export class PBRTParser {
|
|
|
785
797
|
case 'ObjectEnd': {
|
|
786
798
|
|
|
787
799
|
this.currentObject = null;
|
|
788
|
-
this.objectBeginCTM = null;
|
|
789
800
|
this._popGraphicsState();
|
|
790
801
|
break;
|
|
791
802
|
|
|
@@ -824,8 +835,8 @@ export class PBRTParser {
|
|
|
824
835
|
|
|
825
836
|
if ( this.currentObject !== null ) {
|
|
826
837
|
|
|
827
|
-
//
|
|
828
|
-
|
|
838
|
+
// pbrt keeps a template shape's whole transform and puts each placement's on top of it,
|
|
839
|
+
// whatever the transform was at ObjectBegin (kroken defines under one and places at Identity).
|
|
829
840
|
this.ir.objects.get( this.currentObject ).push( shape );
|
|
830
841
|
|
|
831
842
|
} else {
|
|
@@ -880,7 +891,7 @@ export class PBRTParser {
|
|
|
880
891
|
|
|
881
892
|
if ( ! this.instanceIncludes || this.currentObject !== null ) return null;
|
|
882
893
|
if ( this.ctmEnd !== null || this.activeTransform !== BOTH || this.state.areaLight ) return null;
|
|
883
|
-
return `${dir}\0${path}\0${this._stateId( this.state.material )}\0${this.state.reverseOrientation}`;
|
|
894
|
+
return `${dir}\0${path}\0${this._stateId( this.state.material )}\0${this.state.reverseOrientation}\0${this.state.interior}`;
|
|
884
895
|
|
|
885
896
|
}
|
|
886
897
|
|
|
@@ -902,7 +913,8 @@ export class PBRTParser {
|
|
|
902
913
|
attributes: this.attributeStack.length,
|
|
903
914
|
transforms: this.transformStack.length,
|
|
904
915
|
material: this.state.material,
|
|
905
|
-
reverseOrientation: this.state.reverseOrientation
|
|
916
|
+
reverseOrientation: this.state.reverseOrientation,
|
|
917
|
+
interior: this.state.interior
|
|
906
918
|
};
|
|
907
919
|
|
|
908
920
|
}
|
|
@@ -912,7 +924,8 @@ export class PBRTParser {
|
|
|
912
924
|
return this._effects === before.effects && this.ctmEnd === null && this.activeTransform === BOTH &&
|
|
913
925
|
sameMatrix( this.ctm, before.ctm ) && this.attributeStack.length === before.attributes &&
|
|
914
926
|
this.transformStack.length === before.transforms && this.state.material === before.material &&
|
|
915
|
-
this.state.areaLight === null && this.state.reverseOrientation === before.reverseOrientation
|
|
927
|
+
this.state.areaLight === null && this.state.reverseOrientation === before.reverseOrientation &&
|
|
928
|
+
this.state.interior === before.interior;
|
|
916
929
|
|
|
917
930
|
}
|
|
918
931
|
|