rayzee 7.10.3 → 7.11.1
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 +1 -1
- package/dist/rayzee.es.js +1688 -1398
- package/dist/rayzee.es.js.map +1 -1
- package/dist/rayzee.umd.js +69 -54
- package/dist/rayzee.umd.js.map +1 -1
- package/package.json +1 -1
- package/src/EngineDefaults.js +14 -5
- package/src/Processor/AssetLoader.js +11 -0
- package/src/Processor/GeometryExtractor.js +45 -13
- package/src/Processor/SceneProcessor.js +51 -0
- package/src/Processor/ShaderBuilder.js +3 -0
- package/src/Processor/TextureCreator.js +21 -10
- package/src/Stages/PathTracer.js +22 -0
- package/src/TSL/Clearcoat.js +34 -10
- package/src/TSL/Common.js +80 -0
- package/src/TSL/EmissiveSampling.js +2 -2
- package/src/TSL/FinalWriteKernel.js +25 -6
- package/src/TSL/LightsDirect.js +3 -2
- package/src/TSL/LightsIndirect.js +4 -7
- package/src/TSL/LightsSampling.js +17 -6
- package/src/TSL/MaterialEvaluation.js +37 -9
- package/src/TSL/MaterialProperties.js +78 -2
- package/src/TSL/MaterialSampling.js +19 -0
- package/src/TSL/MaterialTransmission.js +3 -1
- package/src/TSL/PathTracerCore.js +35 -10
- package/src/TSL/ShadeKernel.js +97 -3
- package/src/TSL/Struct.js +39 -0
- package/src/TSL/TextureSampling.js +103 -1
- package/src/managers/DenoisingManager.js +6 -0
- package/src/managers/MaterialDataManager.js +36 -3
package/package.json
CHANGED
package/src/EngineDefaults.js
CHANGED
|
@@ -390,8 +390,8 @@ export const TRIANGLE_DATA_LAYOUT = {
|
|
|
390
390
|
// Shared between CPU writers (TextureCreator, MaterialDataManager) and GPU readers (Common.js getMaterial).
|
|
391
391
|
export const MATERIAL_DATA_LAYOUT = {
|
|
392
392
|
|
|
393
|
-
SLOTS_PER_MATERIAL:
|
|
394
|
-
FLOATS_PER_MATERIAL:
|
|
393
|
+
SLOTS_PER_MATERIAL: 33, // vec4 slots per material
|
|
394
|
+
FLOATS_PER_MATERIAL: 132, // total floats per material (33 × 4)
|
|
395
395
|
|
|
396
396
|
// ── Flat float offsets (CPU side) ────────────────────────────────
|
|
397
397
|
// Used as: data[ materialIndex * FLOATS_PER_MATERIAL + offset ]
|
|
@@ -438,8 +438,14 @@ export const MATERIAL_DATA_LAYOUT = {
|
|
|
438
438
|
SUBSURFACE_COLOR: 108, SUBSURFACE: 111,
|
|
439
439
|
// Slot 28: subsurfaceRadius.rgb (mean free path) + radius scale
|
|
440
440
|
SUBSURFACE_RADIUS: 112, SUBSURFACE_RADIUS_SCALE: 115,
|
|
441
|
-
// Slot 29:
|
|
442
|
-
SUBSURFACE_ANISOTROPY: 116,
|
|
441
|
+
// Slot 29: subsurfaceAnisotropy g (116) + surface anisotropy (strength 117, rotation 118, map index 119)
|
|
442
|
+
SUBSURFACE_ANISOTROPY: 116, ANISOTROPY: 117, ANISOTROPY_ROTATION: 118, ANISOTROPY_MAP_INDEX: 119,
|
|
443
|
+
// Slot 30: extension-texture map indices A (transmission, clearcoat, clearcoatRoughness, sheenColor)
|
|
444
|
+
TRANSMISSION_MAP_INDEX: 120, CLEARCOAT_MAP_INDEX: 121, CLEARCOAT_ROUGHNESS_MAP_INDEX: 122, SHEEN_COLOR_MAP_INDEX: 123,
|
|
445
|
+
// Slot 31: extension-texture map indices B (sheenRoughness, iridescence, iridescenceThickness, specularIntensity)
|
|
446
|
+
SHEEN_ROUGHNESS_MAP_INDEX: 124, IRIDESCENCE_MAP_INDEX: 125, IRIDESCENCE_THICKNESS_MAP_INDEX: 126, SPECULAR_INTENSITY_MAP_INDEX: 127,
|
|
447
|
+
// Slot 32: extension-texture map indices C (specularColor + 3 reserved)
|
|
448
|
+
SPECULAR_COLOR_MAP_INDEX: 128,
|
|
443
449
|
|
|
444
450
|
// ── Vec4 slot indices (GPU/TSL side) ─────────────────────────────
|
|
445
451
|
// Used with getDatafromStorageBuffer( buf, matIdx, int(slot), int(SLOTS_PER_MATERIAL) )
|
|
@@ -466,7 +472,10 @@ export const MATERIAL_DATA_LAYOUT = {
|
|
|
466
472
|
DISPLACEMENT_TRANSFORM_A: 25, DISPLACEMENT_TRANSFORM_B: 26,
|
|
467
473
|
SUBSURFACE_A: 27, // subsurfaceColor.rgb, subsurface weight
|
|
468
474
|
SUBSURFACE_B: 28, // subsurfaceRadius.rgb, subsurfaceRadiusScale
|
|
469
|
-
SUBSURFACE_C: 29, // subsurfaceAnisotropy,
|
|
475
|
+
SUBSURFACE_C: 29, // subsurfaceAnisotropy g, anisotropy, anisotropyRotation, anisotropyMapIndex
|
|
476
|
+
EXT_MAP_INDICES_A: 30, // transmission, clearcoat, clearcoatRoughness, sheenColor map indices
|
|
477
|
+
EXT_MAP_INDICES_B: 31, // sheenRoughness, iridescence, iridescenceThickness, specularIntensity map indices
|
|
478
|
+
EXT_MAP_INDICES_C: 32, // specularColor map index + 3 reserved
|
|
470
479
|
},
|
|
471
480
|
|
|
472
481
|
};
|
|
@@ -1590,6 +1590,17 @@ export class AssetLoader extends EventDispatcher {
|
|
|
1590
1590
|
|
|
1591
1591
|
}
|
|
1592
1592
|
|
|
1593
|
+
// glTF punctual point/spot intensity is candela (W/sr); the engine's light
|
|
1594
|
+
// model is Blender-style Power (W) that LightSerializer divides by 4π. Convert
|
|
1595
|
+
// glTF candela → Power once at import (×4π) so it nets to the correct I/d².
|
|
1596
|
+
// Directional (lux ≈ irradiance) is used directly and needs no conversion.
|
|
1597
|
+
if ( ( object.isPointLight || object.isSpotLight ) && ! userData.__candelaConverted ) {
|
|
1598
|
+
|
|
1599
|
+
object.intensity *= 4 * Math.PI;
|
|
1600
|
+
userData.__candelaConverted = true;
|
|
1601
|
+
|
|
1602
|
+
}
|
|
1603
|
+
|
|
1593
1604
|
// Process ceiling lights
|
|
1594
1605
|
if ( object.name.startsWith( 'RectAreaLightPlaceholder' ) &&
|
|
1595
1606
|
userData.name
|
|
@@ -292,7 +292,10 @@ export class GeometryExtractor {
|
|
|
292
292
|
subsurfaceColor: new Color( 0xffffff ),
|
|
293
293
|
subsurfaceRadius: [ 1.0, 0.2, 0.1 ], // skin-like: red travels furthest
|
|
294
294
|
subsurfaceRadiusScale: 1.0,
|
|
295
|
-
subsurfaceAnisotropy: 0.0
|
|
295
|
+
subsurfaceAnisotropy: 0.0,
|
|
296
|
+
// Surface specular anisotropy (native MeshPhysicalMaterial / KHR_materials_anisotropy)
|
|
297
|
+
anisotropy: 0.0,
|
|
298
|
+
anisotropyRotation: 0.0
|
|
296
299
|
};
|
|
297
300
|
|
|
298
301
|
}
|
|
@@ -399,7 +402,9 @@ export class GeometryExtractor {
|
|
|
399
402
|
emissiveIntensity: legacyMapping.emissiveIntensity ?? material.emissiveIntensity ?? defaults.emissiveIntensity,
|
|
400
403
|
|
|
401
404
|
// Surface properties
|
|
402
|
-
|
|
405
|
+
// Floor at 0.02 (the sampler's own VNDF-PDF clamp, MaterialProperties.js) rather than
|
|
406
|
+
// 0.05, so near-mirror metals stay sharp without entering a new firefly regime.
|
|
407
|
+
roughness: Math.max( 0.02, legacyMapping.roughness ?? material.roughness ?? defaults.roughness ),
|
|
403
408
|
metalness: legacyMapping.metalness ?? material.metalness ?? defaults.metalness,
|
|
404
409
|
|
|
405
410
|
// Optical properties
|
|
@@ -430,6 +435,10 @@ export class GeometryExtractor {
|
|
|
430
435
|
subsurfaceRadiusScale: material.subsurfaceRadiusScale ?? defaults.subsurfaceRadiusScale,
|
|
431
436
|
subsurfaceAnisotropy: material.subsurfaceAnisotropy ?? defaults.subsurfaceAnisotropy,
|
|
432
437
|
|
|
438
|
+
// Surface specular anisotropy (native MeshPhysicalMaterial / KHR_materials_anisotropy)
|
|
439
|
+
anisotropy: material.anisotropy ?? defaults.anisotropy,
|
|
440
|
+
anisotropyRotation: material.anisotropyRotation ?? defaults.anisotropyRotation,
|
|
441
|
+
|
|
433
442
|
// Specular properties (for compatibility)
|
|
434
443
|
specularIntensity: legacyMapping.specularIntensity ?? material.specularIntensity ?? defaults.specularIntensity,
|
|
435
444
|
specularColor: legacyMapping.specularColor ?? material.specularColor ?? defaults.specularColor,
|
|
@@ -456,18 +465,21 @@ export class GeometryExtractor {
|
|
|
456
465
|
metalnessMap: this.processTexture( material.metalnessMap, this.metalnessMaps ),
|
|
457
466
|
emissiveMap: this.processTexture( material.emissiveMap, this.emissiveMaps ),
|
|
458
467
|
displacementMap: this.processTexture( material.displacementMap, this.displacementMaps ),
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
468
|
+
anisotropyMap: this.processTexture( material.anisotropyMap, this.anisotropyMaps ),
|
|
469
|
+
|
|
470
|
+
// Advanced texture maps (MeshPhysicalMaterial only). Folded into their scalar factors
|
|
471
|
+
// in ShadeKernel (applyExtensionMaps). thicknessMap stays dropped — thickness has no
|
|
472
|
+
// render effect yet (see gap-plan Phase 4.4).
|
|
473
|
+
clearcoatMap: this.processTexture( material.clearcoatMap, this.clearcoatMaps ),
|
|
474
|
+
clearcoatRoughnessMap: this.processTexture( material.clearcoatRoughnessMap, this.clearcoatRoughnessMaps ),
|
|
475
|
+
transmissionMap: this.processTexture( material.transmissionMap, this.transmissionMaps ),
|
|
464
476
|
thicknessMap: this.processTexture( material.thicknessMap, [] ),
|
|
465
|
-
sheenColorMap: this.processTexture( material.sheenColorMap,
|
|
466
|
-
sheenRoughnessMap: this.processTexture( material.sheenRoughnessMap,
|
|
467
|
-
specularIntensityMap: this.processTexture( material.specularIntensityMap,
|
|
468
|
-
specularColorMap: this.processTexture( material.specularColorMap,
|
|
469
|
-
iridescenceMap: this.processTexture( material.iridescenceMap,
|
|
470
|
-
iridescenceThicknessMap: this.processTexture( material.iridescenceThicknessMap,
|
|
477
|
+
sheenColorMap: this.processTexture( material.sheenColorMap, this.sheenColorMaps ),
|
|
478
|
+
sheenRoughnessMap: this.processTexture( material.sheenRoughnessMap, this.sheenRoughnessMaps ),
|
|
479
|
+
specularIntensityMap: this.processTexture( material.specularIntensityMap, this.specularIntensityMaps ),
|
|
480
|
+
specularColorMap: this.processTexture( material.specularColorMap, this.specularColorMaps ),
|
|
481
|
+
iridescenceMap: this.processTexture( material.iridescenceMap, this.iridescenceMaps ),
|
|
482
|
+
iridescenceThicknessMap: this.processTexture( material.iridescenceThicknessMap, this.iridescenceThicknessMaps ),
|
|
471
483
|
|
|
472
484
|
// Texture transformation matrices
|
|
473
485
|
mapMatrix: this.getTextureMatrix( material.map ),
|
|
@@ -819,6 +831,16 @@ export class GeometryExtractor {
|
|
|
819
831
|
this.emissiveMaps = [];
|
|
820
832
|
this.roughnessMaps = [];
|
|
821
833
|
this.displacementMaps = [];
|
|
834
|
+
this.anisotropyMaps = [];
|
|
835
|
+
this.transmissionMaps = [];
|
|
836
|
+
this.clearcoatMaps = [];
|
|
837
|
+
this.clearcoatRoughnessMaps = [];
|
|
838
|
+
this.sheenColorMaps = [];
|
|
839
|
+
this.sheenRoughnessMaps = [];
|
|
840
|
+
this.iridescenceMaps = [];
|
|
841
|
+
this.iridescenceThicknessMaps = [];
|
|
842
|
+
this.specularIntensityMaps = [];
|
|
843
|
+
this.specularColorMaps = [];
|
|
822
844
|
this.directionalLights = [];
|
|
823
845
|
this.cameras = [];
|
|
824
846
|
|
|
@@ -857,6 +879,16 @@ export class GeometryExtractor {
|
|
|
857
879
|
emissiveMaps: this.emissiveMaps,
|
|
858
880
|
roughnessMaps: this.roughnessMaps,
|
|
859
881
|
displacementMaps: this.displacementMaps,
|
|
882
|
+
anisotropyMaps: this.anisotropyMaps,
|
|
883
|
+
transmissionMaps: this.transmissionMaps,
|
|
884
|
+
clearcoatMaps: this.clearcoatMaps,
|
|
885
|
+
clearcoatRoughnessMaps: this.clearcoatRoughnessMaps,
|
|
886
|
+
sheenColorMaps: this.sheenColorMaps,
|
|
887
|
+
sheenRoughnessMaps: this.sheenRoughnessMaps,
|
|
888
|
+
iridescenceMaps: this.iridescenceMaps,
|
|
889
|
+
iridescenceThicknessMaps: this.iridescenceThicknessMaps,
|
|
890
|
+
specularIntensityMaps: this.specularIntensityMaps,
|
|
891
|
+
specularColorMaps: this.specularColorMaps,
|
|
860
892
|
directionalLights: this.directionalLights,
|
|
861
893
|
cameras: this.cameras,
|
|
862
894
|
sceneFeatures: this.sceneFeatures // Scene-wide material feature flags
|
|
@@ -63,6 +63,16 @@ export class SceneProcessor {
|
|
|
63
63
|
this.metalnessMaps = [];
|
|
64
64
|
this.emissiveMaps = [];
|
|
65
65
|
this.displacementMaps = [];
|
|
66
|
+
this.anisotropyMaps = [];
|
|
67
|
+
this.transmissionMaps = [];
|
|
68
|
+
this.clearcoatMaps = [];
|
|
69
|
+
this.clearcoatRoughnessMaps = [];
|
|
70
|
+
this.sheenColorMaps = [];
|
|
71
|
+
this.sheenRoughnessMaps = [];
|
|
72
|
+
this.iridescenceMaps = [];
|
|
73
|
+
this.iridescenceThicknessMaps = [];
|
|
74
|
+
this.specularIntensityMaps = [];
|
|
75
|
+
this.specularColorMaps = [];
|
|
66
76
|
this.directionalLights = [];
|
|
67
77
|
this.cameras = [];
|
|
68
78
|
this.spheres = [];
|
|
@@ -320,6 +330,16 @@ export class SceneProcessor {
|
|
|
320
330
|
this.metalnessMaps = extractedData.metalnessMaps;
|
|
321
331
|
this.emissiveMaps = extractedData.emissiveMaps;
|
|
322
332
|
this.displacementMaps = extractedData.displacementMaps;
|
|
333
|
+
this.anisotropyMaps = extractedData.anisotropyMaps;
|
|
334
|
+
this.transmissionMaps = extractedData.transmissionMaps;
|
|
335
|
+
this.clearcoatMaps = extractedData.clearcoatMaps;
|
|
336
|
+
this.clearcoatRoughnessMaps = extractedData.clearcoatRoughnessMaps;
|
|
337
|
+
this.sheenColorMaps = extractedData.sheenColorMaps;
|
|
338
|
+
this.sheenRoughnessMaps = extractedData.sheenRoughnessMaps;
|
|
339
|
+
this.iridescenceMaps = extractedData.iridescenceMaps;
|
|
340
|
+
this.iridescenceThicknessMaps = extractedData.iridescenceThicknessMaps;
|
|
341
|
+
this.specularIntensityMaps = extractedData.specularIntensityMaps;
|
|
342
|
+
this.specularColorMaps = extractedData.specularColorMaps;
|
|
323
343
|
this.directionalLights = extractedData.directionalLights;
|
|
324
344
|
this.cameras = extractedData.cameras;
|
|
325
345
|
this.sceneFeatures = extractedData.sceneFeatures; // Store material feature flags for shader optimization
|
|
@@ -883,6 +903,17 @@ export class SceneProcessor {
|
|
|
883
903
|
roughness: remapType( this.roughnessMaps, linearLists, linearDedup, this._linearTexPacked ),
|
|
884
904
|
metalness: remapType( this.metalnessMaps, linearLists, linearDedup, this._linearTexPacked ),
|
|
885
905
|
displacement: remapType( this.displacementMaps, linearLists, linearDedup, this._linearTexPacked ),
|
|
906
|
+
anisotropy: remapType( this.anisotropyMaps, linearLists, linearDedup, this._linearTexPacked ),
|
|
907
|
+
// Extension maps — data maps → linear pool; color maps (sheenColor, specularColor) → sRGB pool.
|
|
908
|
+
transmission: remapType( this.transmissionMaps, linearLists, linearDedup, this._linearTexPacked ),
|
|
909
|
+
clearcoat: remapType( this.clearcoatMaps, linearLists, linearDedup, this._linearTexPacked ),
|
|
910
|
+
clearcoatRoughness: remapType( this.clearcoatRoughnessMaps, linearLists, linearDedup, this._linearTexPacked ),
|
|
911
|
+
sheenColor: remapType( this.sheenColorMaps, srgbLists, srgbDedup, this._srgbTexPacked ),
|
|
912
|
+
sheenRoughness: remapType( this.sheenRoughnessMaps, linearLists, linearDedup, this._linearTexPacked ),
|
|
913
|
+
iridescence: remapType( this.iridescenceMaps, linearLists, linearDedup, this._linearTexPacked ),
|
|
914
|
+
iridescenceThickness: remapType( this.iridescenceThicknessMaps, linearLists, linearDedup, this._linearTexPacked ),
|
|
915
|
+
specularIntensity: remapType( this.specularIntensityMaps, linearLists, linearDedup, this._linearTexPacked ),
|
|
916
|
+
specularColor: remapType( this.specularColorMaps, srgbLists, srgbDedup, this._srgbTexPacked ),
|
|
886
917
|
};
|
|
887
918
|
|
|
888
919
|
return { srgbLists, linearLists, remap };
|
|
@@ -907,6 +938,16 @@ export class SceneProcessor {
|
|
|
907
938
|
mat.roughnessMap = fix( mat.roughnessMap, remap.roughness );
|
|
908
939
|
mat.metalnessMap = fix( mat.metalnessMap, remap.metalness );
|
|
909
940
|
mat.displacementMap = fix( mat.displacementMap, remap.displacement );
|
|
941
|
+
mat.anisotropyMap = fix( mat.anisotropyMap, remap.anisotropy );
|
|
942
|
+
mat.transmissionMap = fix( mat.transmissionMap, remap.transmission );
|
|
943
|
+
mat.clearcoatMap = fix( mat.clearcoatMap, remap.clearcoat );
|
|
944
|
+
mat.clearcoatRoughnessMap = fix( mat.clearcoatRoughnessMap, remap.clearcoatRoughness );
|
|
945
|
+
mat.sheenColorMap = fix( mat.sheenColorMap, remap.sheenColor );
|
|
946
|
+
mat.sheenRoughnessMap = fix( mat.sheenRoughnessMap, remap.sheenRoughness );
|
|
947
|
+
mat.iridescenceMap = fix( mat.iridescenceMap, remap.iridescence );
|
|
948
|
+
mat.iridescenceThicknessMap = fix( mat.iridescenceThicknessMap, remap.iridescenceThickness );
|
|
949
|
+
mat.specularIntensityMap = fix( mat.specularIntensityMap, remap.specularIntensity );
|
|
950
|
+
mat.specularColorMap = fix( mat.specularColorMap, remap.specularColor );
|
|
910
951
|
|
|
911
952
|
}
|
|
912
953
|
|
|
@@ -984,6 +1025,16 @@ export class SceneProcessor {
|
|
|
984
1025
|
this.metalnessMaps = [];
|
|
985
1026
|
this.emissiveMaps = [];
|
|
986
1027
|
this.displacementMaps = [];
|
|
1028
|
+
this.anisotropyMaps = [];
|
|
1029
|
+
this.transmissionMaps = [];
|
|
1030
|
+
this.clearcoatMaps = [];
|
|
1031
|
+
this.clearcoatRoughnessMaps = [];
|
|
1032
|
+
this.sheenColorMaps = [];
|
|
1033
|
+
this.sheenRoughnessMaps = [];
|
|
1034
|
+
this.iridescenceMaps = [];
|
|
1035
|
+
this.iridescenceThicknessMaps = [];
|
|
1036
|
+
this.specularIntensityMaps = [];
|
|
1037
|
+
this.specularColorMaps = [];
|
|
987
1038
|
this.directionalLights = [];
|
|
988
1039
|
this.cameras = [];
|
|
989
1040
|
this.spheres = [];
|
|
@@ -19,6 +19,7 @@ export class ShaderBuilder {
|
|
|
19
19
|
// Previous-frame texture nodes (sample from MRT RenderTarget)
|
|
20
20
|
this.prevColorTexNode = null;
|
|
21
21
|
this.prevAlbedoTexNode = null;
|
|
22
|
+
this.prevNormalDepthTexNode = null;
|
|
22
23
|
|
|
23
24
|
// Scene texture nodes cache (for in-place updates on model change)
|
|
24
25
|
this._sceneTextureNodes = null;
|
|
@@ -98,6 +99,7 @@ export class ShaderBuilder {
|
|
|
98
99
|
const readTextures = storageTextures.getReadTextures();
|
|
99
100
|
this.prevColorTexNode = texture( readTextures.color );
|
|
100
101
|
this.prevAlbedoTexNode = texture( readTextures.albedo );
|
|
102
|
+
this.prevNormalDepthTexNode = texture( readTextures.normalDepth );
|
|
101
103
|
|
|
102
104
|
const createArrayPlaceholder = () => {
|
|
103
105
|
|
|
@@ -137,6 +139,7 @@ export class ShaderBuilder {
|
|
|
137
139
|
|
|
138
140
|
this.prevColorTexNode = null;
|
|
139
141
|
this.prevAlbedoTexNode = null;
|
|
142
|
+
this.prevNormalDepthTexNode = null;
|
|
140
143
|
this._sceneTextureNodes = null;
|
|
141
144
|
|
|
142
145
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DataArrayTexture, RGBAFormat, LinearFilter, UnsignedByteType, SRGBColorSpace } from "three";
|
|
1
|
+
import { DataArrayTexture, RGBAFormat, LinearFilter, UnsignedByteType, SRGBColorSpace, RepeatWrapping } from "three";
|
|
2
2
|
import { TEXTURE_CONSTANTS, MEMORY_CONSTANTS, DEFAULT_TEXTURE_MATRIX, MATERIAL_DATA_LAYOUT } from '../EngineDefaults.js';
|
|
3
3
|
import { fetchAsWorker } from './Workers/fetchAsWorker.js';
|
|
4
4
|
import TEXTURES_WORKER_URL from './Workers/TexturesWorker.js?worker&url';
|
|
@@ -983,25 +983,31 @@ export class TextureCreator {
|
|
|
983
983
|
// Slot 12: displacement
|
|
984
984
|
mat.bumpScale, mat.displacementScale, mat.displacementMap, 0,
|
|
985
985
|
mapMatrix[ 0 ], mapMatrix[ 1 ], mapMatrix[ 2 ], mapMatrix[ 3 ],
|
|
986
|
-
mapMatrix[ 4 ], mapMatrix[ 5 ], mapMatrix[ 6 ],
|
|
986
|
+
mapMatrix[ 4 ], mapMatrix[ 5 ], mapMatrix[ 6 ], mapMatrix[ 7 ],
|
|
987
987
|
normalMapMatrices[ 0 ], normalMapMatrices[ 1 ], normalMapMatrices[ 2 ], normalMapMatrices[ 3 ],
|
|
988
|
-
normalMapMatrices[ 4 ], normalMapMatrices[ 5 ], normalMapMatrices[ 6 ],
|
|
988
|
+
normalMapMatrices[ 4 ], normalMapMatrices[ 5 ], normalMapMatrices[ 6 ], normalMapMatrices[ 7 ],
|
|
989
989
|
roughnessMapMatrices[ 0 ], roughnessMapMatrices[ 1 ], roughnessMapMatrices[ 2 ], roughnessMapMatrices[ 3 ],
|
|
990
|
-
roughnessMapMatrices[ 4 ], roughnessMapMatrices[ 5 ], roughnessMapMatrices[ 6 ],
|
|
990
|
+
roughnessMapMatrices[ 4 ], roughnessMapMatrices[ 5 ], roughnessMapMatrices[ 6 ], roughnessMapMatrices[ 7 ],
|
|
991
991
|
metalnessMapMatrices[ 0 ], metalnessMapMatrices[ 1 ], metalnessMapMatrices[ 2 ], metalnessMapMatrices[ 3 ],
|
|
992
|
-
metalnessMapMatrices[ 4 ], metalnessMapMatrices[ 5 ], metalnessMapMatrices[ 6 ],
|
|
992
|
+
metalnessMapMatrices[ 4 ], metalnessMapMatrices[ 5 ], metalnessMapMatrices[ 6 ], metalnessMapMatrices[ 7 ],
|
|
993
993
|
emissiveMapMatrices[ 0 ], emissiveMapMatrices[ 1 ], emissiveMapMatrices[ 2 ], emissiveMapMatrices[ 3 ],
|
|
994
|
-
emissiveMapMatrices[ 4 ], emissiveMapMatrices[ 5 ], emissiveMapMatrices[ 6 ],
|
|
994
|
+
emissiveMapMatrices[ 4 ], emissiveMapMatrices[ 5 ], emissiveMapMatrices[ 6 ], emissiveMapMatrices[ 7 ],
|
|
995
995
|
bumpMapMatrices[ 0 ], bumpMapMatrices[ 1 ], bumpMapMatrices[ 2 ], bumpMapMatrices[ 3 ],
|
|
996
|
-
bumpMapMatrices[ 4 ], bumpMapMatrices[ 5 ], bumpMapMatrices[ 6 ],
|
|
996
|
+
bumpMapMatrices[ 4 ], bumpMapMatrices[ 5 ], bumpMapMatrices[ 6 ], bumpMapMatrices[ 7 ],
|
|
997
997
|
displacementMapMatrices[ 0 ], displacementMapMatrices[ 1 ], displacementMapMatrices[ 2 ], displacementMapMatrices[ 3 ],
|
|
998
|
-
displacementMapMatrices[ 4 ], displacementMapMatrices[ 5 ], displacementMapMatrices[ 6 ],
|
|
998
|
+
displacementMapMatrices[ 4 ], displacementMapMatrices[ 5 ], displacementMapMatrices[ 6 ], displacementMapMatrices[ 7 ],
|
|
999
999
|
// Slot 27: subsurface (subsurfaceColor.rgb, subsurface weight)
|
|
1000
1000
|
mat.subsurfaceColor?.r ?? 1, mat.subsurfaceColor?.g ?? 1, mat.subsurfaceColor?.b ?? 1, mat.subsurface ?? 0,
|
|
1001
1001
|
// Slot 28: subsurface (subsurfaceRadius.rgb, subsurfaceRadiusScale)
|
|
1002
1002
|
mat.subsurfaceRadius?.[ 0 ] ?? 1, mat.subsurfaceRadius?.[ 1 ] ?? 0.2, mat.subsurfaceRadius?.[ 2 ] ?? 0.1, mat.subsurfaceRadiusScale ?? 1,
|
|
1003
|
-
// Slot 29:
|
|
1004
|
-
mat.subsurfaceAnisotropy ?? 0, 0, 0,
|
|
1003
|
+
// Slot 29: subsurfaceAnisotropy g + surface anisotropy (strength, rotation, map index)
|
|
1004
|
+
mat.subsurfaceAnisotropy ?? 0, mat.anisotropy ?? 0, mat.anisotropyRotation ?? 0, mat.anisotropyMap ?? - 1,
|
|
1005
|
+
// Slot 30: extension map indices A (transmission, clearcoat, clearcoatRoughness, sheenColor)
|
|
1006
|
+
mat.transmissionMap ?? - 1, mat.clearcoatMap ?? - 1, mat.clearcoatRoughnessMap ?? - 1, mat.sheenColorMap ?? - 1,
|
|
1007
|
+
// Slot 31: extension map indices B (sheenRoughness, iridescence, iridescenceThickness, specularIntensity)
|
|
1008
|
+
mat.sheenRoughnessMap ?? - 1, mat.iridescenceMap ?? - 1, mat.iridescenceThicknessMap ?? - 1, mat.specularIntensityMap ?? - 1,
|
|
1009
|
+
// Slot 32: extension map indices C (specularColor + 3 reserved)
|
|
1010
|
+
mat.specularColorMap ?? - 1, 0, 0, 0,
|
|
1005
1011
|
];
|
|
1006
1012
|
|
|
1007
1013
|
data.set( materialData, stride );
|
|
@@ -1314,6 +1320,11 @@ export class TextureCreator {
|
|
|
1314
1320
|
|
|
1315
1321
|
texture.minFilter = LinearFilter;
|
|
1316
1322
|
texture.magFilter = LinearFilter;
|
|
1323
|
+
// glTF's default sampler wrap is REPEAT; array layers are independent (not an atlas),
|
|
1324
|
+
// so per-layer repeat is safe and lets tiling UVs (outside [0,1]) tile instead of
|
|
1325
|
+
// clamping. MIRRORED_REPEAT / per-texture wrap is a follow-up (not stored per-slot yet).
|
|
1326
|
+
texture.wrapS = RepeatWrapping;
|
|
1327
|
+
texture.wrapT = RepeatWrapping;
|
|
1317
1328
|
texture.format = RGBAFormat;
|
|
1318
1329
|
texture.type = UnsignedByteType;
|
|
1319
1330
|
texture.needsUpdate = true;
|
package/src/Stages/PathTracer.js
CHANGED
|
@@ -46,6 +46,11 @@ export class PathTracer extends PathTracerStage {
|
|
|
46
46
|
// uniform — NOT baked — so DenoisingManager can toggle it without a (UI-freezing) kernel rebuild.
|
|
47
47
|
this._auxGBufferEnabled = false;
|
|
48
48
|
this._auxGBufferUniform = uniform( 0, 'uint' );
|
|
49
|
+
// Clean-aux mode: temporally accumulate + renormalize the aux NORMAL (like albedo) so a clean-aux
|
|
50
|
+
// OIDN model (calb_cnrm/high, alb_nrm/balanced) gets the prefiltered-ish normal it expects instead
|
|
51
|
+
// of the point-sampled per-frame value that leaks noise. Off for fast/ASVGF (they want the bump normal).
|
|
52
|
+
this._cleanAuxNormalEnabled = false;
|
|
53
|
+
this._cleanAuxNormalUniform = uniform( 0, 'uint' );
|
|
49
54
|
|
|
50
55
|
// CPU sizes per-bounce kernels from last frame's survivor curve; kernels bound on ENTERING_COUNT so over-sizing is safe. (indirect dispatch not viable — three.js doesn't sync compute-written indirect buffers across submissions)
|
|
51
56
|
this._useDynamicDispatch = true;
|
|
@@ -220,6 +225,7 @@ export class PathTracer extends PathTracerStage {
|
|
|
220
225
|
|
|
221
226
|
this.shaderBuilder.prevColorTexNode.value = readTextures.color;
|
|
222
227
|
this.shaderBuilder.prevAlbedoTexNode.value = readTextures.albedo;
|
|
228
|
+
this.shaderBuilder.prevNormalDepthTexNode.value = readTextures.normalDepth;
|
|
223
229
|
|
|
224
230
|
}
|
|
225
231
|
|
|
@@ -410,6 +416,19 @@ export class PathTracer extends PathTracerStage {
|
|
|
410
416
|
|
|
411
417
|
}
|
|
412
418
|
|
|
419
|
+
// Clean-aux normal: when a clean-aux OIDN model is active (calb_cnrm/high, alb_nrm/balanced), FinalWrite
|
|
420
|
+
// temporally accumulates + renormalizes the aux normal so the model isn't fed per-frame point-sampled
|
|
421
|
+
// noise. DenoisingManager calls this on OIDN enable + quality change. Live uniform → value flip + reset.
|
|
422
|
+
setCleanAuxNormal( enabled ) {
|
|
423
|
+
|
|
424
|
+
enabled = !! enabled;
|
|
425
|
+
if ( this._cleanAuxNormalEnabled === enabled ) return;
|
|
426
|
+
this._cleanAuxNormalEnabled = enabled;
|
|
427
|
+
this._cleanAuxNormalUniform.value = enabled ? 1 : 0;
|
|
428
|
+
this.reset();
|
|
429
|
+
|
|
430
|
+
}
|
|
431
|
+
|
|
413
432
|
// UI-driven resize (Resolution dropdown) — parent bypasses _handleResize(), so hook here too.
|
|
414
433
|
setSize( width, height ) {
|
|
415
434
|
|
|
@@ -605,6 +624,7 @@ export class PathTracer extends PathTracerStage {
|
|
|
605
624
|
|
|
606
625
|
const prevColor = this.shaderBuilder.prevColorTexNode;
|
|
607
626
|
const prevAlbedo = this.shaderBuilder.prevAlbedoTexNode;
|
|
627
|
+
const prevNormalDepth = this.shaderBuilder.prevNormalDepthTexNode;
|
|
608
628
|
const writeTex = this.storageTextures.getWriteTextures();
|
|
609
629
|
|
|
610
630
|
const counters = qm.getCounters();
|
|
@@ -907,10 +927,12 @@ export class PathTracer extends PathTracerStage {
|
|
|
907
927
|
transparentBackground: this.transparentBackground,
|
|
908
928
|
prevAccumTexture: prevColor,
|
|
909
929
|
prevAlbedoTexture: prevAlbedo,
|
|
930
|
+
prevNormalDepthTexture: prevNormalDepth,
|
|
910
931
|
renderWidth: this._wfRenderWidth,
|
|
911
932
|
renderHeight: this._wfRenderHeight,
|
|
912
933
|
visMode: this.visMode,
|
|
913
934
|
auxGBufferEnabled: this._auxGBufferUniform,
|
|
935
|
+
cleanAuxNormalEnabled: this._cleanAuxNormalUniform,
|
|
914
936
|
} );
|
|
915
937
|
this._kernelManager.register( 'finalWrite',
|
|
916
938
|
// Per-pixel (w×h) — kernel averages the S sample-slots internally.
|
package/src/TSL/Clearcoat.js
CHANGED
|
@@ -2,6 +2,7 @@ import {
|
|
|
2
2
|
Fn,
|
|
3
3
|
vec3,
|
|
4
4
|
float,
|
|
5
|
+
dot,
|
|
5
6
|
normalize,
|
|
6
7
|
reflect,
|
|
7
8
|
max,
|
|
@@ -10,10 +11,10 @@ import {
|
|
|
10
11
|
|
|
11
12
|
import { struct } from './patches.js';
|
|
12
13
|
|
|
13
|
-
import { DotProducts } from './Struct.js';
|
|
14
|
-
import { PI, MIN_CLEARCOAT_ROUGHNESS,
|
|
15
|
-
import { DistributionGGX } from './MaterialProperties.js';
|
|
16
|
-
import { ImportanceSampleGGX, ImportanceSampleCosine } from './MaterialSampling.js';
|
|
14
|
+
import { AnisoFrame, DotProducts } from './Struct.js';
|
|
15
|
+
import { PI, MIN_CLEARCOAT_ROUGHNESS, computeDotProductsAniso, anisoTangentFrame } from './Common.js';
|
|
16
|
+
import { DistributionGGX, computeAnisoAlphas, calculateVNDFPDFAniso } from './MaterialProperties.js';
|
|
17
|
+
import { ImportanceSampleGGX, ImportanceSampleCosine, sampleGGXVNDFAniso } from './MaterialSampling.js';
|
|
17
18
|
import { evaluateLayeredBRDF } from './MaterialEvaluation.js';
|
|
18
19
|
import { RandomValue } from './Random.js';
|
|
19
20
|
|
|
@@ -62,8 +63,20 @@ export const sampleClearcoat = Fn( ( [
|
|
|
62
63
|
|
|
63
64
|
} ).ElseIf( rand.lessThan( clearcoatWeight.add( specularWeight ) ), () => {
|
|
64
65
|
|
|
65
|
-
// Sample base specular
|
|
66
|
-
|
|
66
|
+
// Sample base specular (anisotropic VNDF when anisotropy > 0)
|
|
67
|
+
If( material.anisotropy.greaterThan( 0.0 ), () => {
|
|
68
|
+
|
|
69
|
+
const f = AnisoFrame.wrap( anisoTangentFrame( N, material.anisotropyRotation ) );
|
|
70
|
+
const localV = vec3( dot( V, f.Ta ), dot( V, f.Ba ), dot( V, N ) );
|
|
71
|
+
const a = computeAnisoAlphas( material.roughness, material.anisotropy );
|
|
72
|
+
const localH = sampleGGXVNDFAniso( { V: localV, alphaX: a.x, alphaY: a.y, Xi: randomSample } );
|
|
73
|
+
H.assign( f.Ta.mul( localH.x ).add( f.Ba.mul( localH.y ) ).add( N.mul( localH.z ) ) );
|
|
74
|
+
|
|
75
|
+
} ).Else( () => {
|
|
76
|
+
|
|
77
|
+
H.assign( ImportanceSampleGGX( { N, roughness: baseRoughness, Xi: randomSample } ) );
|
|
78
|
+
|
|
79
|
+
} );
|
|
67
80
|
L.assign( reflect( V.negate(), H ) );
|
|
68
81
|
|
|
69
82
|
} ).Else( () => {
|
|
@@ -74,12 +87,23 @@ export const sampleClearcoat = Fn( ( [
|
|
|
74
87
|
|
|
75
88
|
} );
|
|
76
89
|
|
|
77
|
-
// Calculate dot products
|
|
78
|
-
const dots = DotProducts.wrap(
|
|
90
|
+
// Calculate dot products (aniso-aware: also projects onto the anisotropy frame)
|
|
91
|
+
const dots = DotProducts.wrap( computeDotProductsAniso( N, V, L, material ) );
|
|
79
92
|
|
|
80
|
-
// Calculate individual PDFs
|
|
93
|
+
// Calculate individual PDFs. Clearcoat layer is always isotropic; the base specular
|
|
94
|
+
// matches its sampler — VNDF-aniso when anisotropy>0, else the half-vector GGX pdf.
|
|
81
95
|
const clearcoatPDF = DistributionGGX( dots.NoH, clearcoatRoughness ).mul( dots.NoH ).div( float( 4.0 ).mul( dots.VoH ) ).mul( clearcoatWeight );
|
|
82
|
-
const specularPDF =
|
|
96
|
+
const specularPDF = float( 0.0 ).toVar();
|
|
97
|
+
If( material.anisotropy.greaterThan( 0.0 ), () => {
|
|
98
|
+
|
|
99
|
+
const a = computeAnisoAlphas( material.roughness, material.anisotropy );
|
|
100
|
+
specularPDF.assign( calculateVNDFPDFAniso( a.x, a.y, dots.NoH, dots.ToH, dots.BoH, dots.NoV, dots.ToV, dots.BoV ).mul( specularWeight ) );
|
|
101
|
+
|
|
102
|
+
} ).Else( () => {
|
|
103
|
+
|
|
104
|
+
specularPDF.assign( DistributionGGX( dots.NoH, baseRoughness ).mul( dots.NoH ).div( float( 4.0 ).mul( dots.VoH ) ).mul( specularWeight ) );
|
|
105
|
+
|
|
106
|
+
} );
|
|
83
107
|
const diffusePDF = dots.NoL.div( PI ).mul( diffuseWeight );
|
|
84
108
|
|
|
85
109
|
// Combined PDF using MIS
|
package/src/TSL/Common.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Fn, wgslFn, float, vec2, vec3, vec4, int, mat3, If, max, dot, clamp, bool as tslBool } from 'three/tsl';
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
|
+
AnisoFrame,
|
|
4
5
|
DotProducts,
|
|
5
6
|
MaterialClassification,
|
|
6
7
|
MISStrategy,
|
|
@@ -155,6 +156,58 @@ export const computeDotProducts = Fn( ( [ N, V, L ] ) => {
|
|
|
155
156
|
NoH: max( dot( N, H ), 0.001 ),
|
|
156
157
|
VoH: max( dot( V, H ), 0.001 ),
|
|
157
158
|
LoH: max( dot( L, H ), 0.001 ),
|
|
159
|
+
ToH: float( 0.0 ), BoH: float( 0.0 ),
|
|
160
|
+
ToV: float( 0.0 ), BoV: float( 0.0 ),
|
|
161
|
+
ToL: float( 0.0 ), BoL: float( 0.0 ),
|
|
162
|
+
} );
|
|
163
|
+
|
|
164
|
+
} );
|
|
165
|
+
|
|
166
|
+
// Anisotropy tangent frame: arbitrary ONB from N (matching constructTBN + normal mapping),
|
|
167
|
+
// rotated by anisotropyRotation. Single source of truth for sampler AND eval/PDF so their
|
|
168
|
+
// frames are bit-identical (required for MIS consistency).
|
|
169
|
+
export const anisoTangentFrame = Fn( ( [ N, rotation ] ) => {
|
|
170
|
+
|
|
171
|
+
const majorAxis = N.x.abs().lessThan( 0.999 ).select( vec3( 1.0, 0.0, 0.0 ), vec3( 0.0, 1.0, 0.0 ) );
|
|
172
|
+
const T0 = N.cross( majorAxis ).normalize();
|
|
173
|
+
const B0 = N.cross( T0 ).normalize();
|
|
174
|
+
const c = rotation.cos();
|
|
175
|
+
const s = rotation.sin();
|
|
176
|
+
return AnisoFrame( { Ta: T0.mul( c ).add( B0.mul( s ) ), Ba: B0.mul( c ).sub( T0.mul( s ) ) } );
|
|
177
|
+
|
|
178
|
+
} );
|
|
179
|
+
|
|
180
|
+
// Anisotropy-aware dot products: computeDotProducts + tangent-frame projections of H/V/L
|
|
181
|
+
// (0 for isotropic materials, so aniso branches gated on anisotropy>0 are a no-op).
|
|
182
|
+
export const computeDotProductsAniso = Fn( ( [ N, V, L, material ] ) => {
|
|
183
|
+
|
|
184
|
+
const H = V.add( L ).toVar();
|
|
185
|
+
const lenSq = dot( H, H ).toVar();
|
|
186
|
+
H.assign( lenSq.greaterThan( EPSILON ).select( H.div( lenSq.sqrt() ), vec3( 0.0, 0.0, 1.0 ) ) );
|
|
187
|
+
|
|
188
|
+
const ToH = float( 0.0 ).toVar();
|
|
189
|
+
const BoH = float( 0.0 ).toVar();
|
|
190
|
+
const ToV = float( 0.0 ).toVar();
|
|
191
|
+
const BoV = float( 0.0 ).toVar();
|
|
192
|
+
const ToL = float( 0.0 ).toVar();
|
|
193
|
+
const BoL = float( 0.0 ).toVar();
|
|
194
|
+
|
|
195
|
+
If( material.anisotropy.greaterThan( 0.0 ), () => {
|
|
196
|
+
|
|
197
|
+
const f = AnisoFrame.wrap( anisoTangentFrame( N, material.anisotropyRotation ) );
|
|
198
|
+
ToH.assign( dot( f.Ta, H ) ); BoH.assign( dot( f.Ba, H ) );
|
|
199
|
+
ToV.assign( dot( f.Ta, V ) ); BoV.assign( dot( f.Ba, V ) );
|
|
200
|
+
ToL.assign( dot( f.Ta, L ) ); BoL.assign( dot( f.Ba, L ) );
|
|
201
|
+
|
|
202
|
+
} );
|
|
203
|
+
|
|
204
|
+
return DotProducts( {
|
|
205
|
+
NoL: max( dot( N, L ), 0.001 ),
|
|
206
|
+
NoV: max( dot( N, V ), 0.001 ),
|
|
207
|
+
NoH: max( dot( N, H ), 0.001 ),
|
|
208
|
+
VoH: max( dot( V, H ), 0.001 ),
|
|
209
|
+
LoH: max( dot( L, H ), 0.001 ),
|
|
210
|
+
ToH, BoH, ToV, BoV, ToL, BoL,
|
|
158
211
|
} );
|
|
159
212
|
|
|
160
213
|
} );
|
|
@@ -345,6 +398,9 @@ export const getMaterial = Fn( ( [ materialIndex, materialBuffer ] ) => {
|
|
|
345
398
|
const data27 = getDatafromStorageBuffer( materialBuffer, materialIndex, int( S.SUBSURFACE_A ), int( MATERIAL_SLOTS ) ).toVar();
|
|
346
399
|
const data28 = getDatafromStorageBuffer( materialBuffer, materialIndex, int( S.SUBSURFACE_B ), int( MATERIAL_SLOTS ) ).toVar();
|
|
347
400
|
const data29 = getDatafromStorageBuffer( materialBuffer, materialIndex, int( S.SUBSURFACE_C ), int( MATERIAL_SLOTS ) ).toVar();
|
|
401
|
+
const data30 = getDatafromStorageBuffer( materialBuffer, materialIndex, int( S.EXT_MAP_INDICES_A ), int( MATERIAL_SLOTS ) ).toVar();
|
|
402
|
+
const data31 = getDatafromStorageBuffer( materialBuffer, materialIndex, int( S.EXT_MAP_INDICES_B ), int( MATERIAL_SLOTS ) ).toVar();
|
|
403
|
+
const data32 = getDatafromStorageBuffer( materialBuffer, materialIndex, int( S.EXT_MAP_INDICES_C ), int( MATERIAL_SLOTS ) ).toVar();
|
|
348
404
|
|
|
349
405
|
return RayTracingMaterial( {
|
|
350
406
|
color: vec4( data0.rgb, 1.0 ),
|
|
@@ -371,6 +427,18 @@ export const getMaterial = Fn( ( [ materialIndex, materialBuffer ] ) => {
|
|
|
371
427
|
subsurfaceRadius: data28.rgb,
|
|
372
428
|
subsurfaceRadiusScale: data28.a,
|
|
373
429
|
subsurfaceAnisotropy: data29.r,
|
|
430
|
+
anisotropy: data29.g,
|
|
431
|
+
anisotropyRotation: data29.b,
|
|
432
|
+
anisotropyMapIndex: int( data29.a ),
|
|
433
|
+
transmissionMapIndex: int( data30.r ),
|
|
434
|
+
clearcoatMapIndex: int( data30.g ),
|
|
435
|
+
clearcoatRoughnessMapIndex: int( data30.b ),
|
|
436
|
+
sheenColorMapIndex: int( data30.a ),
|
|
437
|
+
sheenRoughnessMapIndex: int( data31.r ),
|
|
438
|
+
iridescenceMapIndex: int( data31.g ),
|
|
439
|
+
iridescenceThicknessMapIndex: int( data31.b ),
|
|
440
|
+
specularIntensityMapIndex: int( data31.a ),
|
|
441
|
+
specularColorMapIndex: int( data32.r ),
|
|
374
442
|
albedoMapIndex: int( data8.r ),
|
|
375
443
|
normalMapIndex: int( data8.g ),
|
|
376
444
|
roughnessMapIndex: int( data8.b ),
|
|
@@ -458,6 +526,18 @@ export const diffuseGroundMaterial = Fn( () => {
|
|
|
458
526
|
subsurfaceRadius: vec3( 1.0, 0.2, 0.1 ),
|
|
459
527
|
subsurfaceRadiusScale: float( 1.0 ),
|
|
460
528
|
subsurfaceAnisotropy: float( 0.0 ),
|
|
529
|
+
anisotropy: float( 0.0 ),
|
|
530
|
+
anisotropyRotation: float( 0.0 ),
|
|
531
|
+
anisotropyMapIndex: int( - 1 ),
|
|
532
|
+
transmissionMapIndex: int( - 1 ),
|
|
533
|
+
clearcoatMapIndex: int( - 1 ),
|
|
534
|
+
clearcoatRoughnessMapIndex: int( - 1 ),
|
|
535
|
+
sheenColorMapIndex: int( - 1 ),
|
|
536
|
+
sheenRoughnessMapIndex: int( - 1 ),
|
|
537
|
+
iridescenceMapIndex: int( - 1 ),
|
|
538
|
+
iridescenceThicknessMapIndex: int( - 1 ),
|
|
539
|
+
specularIntensityMapIndex: int( - 1 ),
|
|
540
|
+
specularColorMapIndex: int( - 1 ),
|
|
461
541
|
} );
|
|
462
542
|
|
|
463
543
|
} );
|
|
@@ -26,7 +26,7 @@ import {
|
|
|
26
26
|
} from 'three/tsl';
|
|
27
27
|
|
|
28
28
|
import { struct } from './patches.js';
|
|
29
|
-
import { MIN_PDF, getDatafromStorageBuffer, powerHeuristic, MATERIAL_SLOTS, MATERIAL_SLOT,
|
|
29
|
+
import { MIN_PDF, getDatafromStorageBuffer, powerHeuristic, MATERIAL_SLOTS, MATERIAL_SLOT, computeDotProductsAniso } from './Common.js';
|
|
30
30
|
import { RandomValue } from './Random.js';
|
|
31
31
|
import { calculateMaterialPDFFromDots } from './LightsSampling.js';
|
|
32
32
|
import { evaluateMaterialResponseFromDots } from './MaterialEvaluation.js';
|
|
@@ -573,7 +573,7 @@ export const calculateEmissiveTriangleContributionDebug = Fn( ( [
|
|
|
573
573
|
|
|
574
574
|
// Share H + dot products between BRDF eval and PDF (computeDotProducts
|
|
575
575
|
// would otherwise run twice with identical inputs).
|
|
576
|
-
const dots = DotProducts.wrap(
|
|
576
|
+
const dots = DotProducts.wrap( computeDotProductsAniso( normal, viewDir, emissiveSample.direction, material ) );
|
|
577
577
|
const brdfValue = evaluateMaterialResponseFromDots( material, dots );
|
|
578
578
|
const brdfPdf = calculateMaterialPDFFromDots( material, dots );
|
|
579
579
|
|