rayzee 7.10.2 → 7.11.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.
@@ -1,9 +1,10 @@
1
- import { Fn, wgslFn, float, vec2, vec3, vec4, int, If, normalize, cross, abs, mix, clamp, texture, textureSize } from 'three/tsl';
1
+ import { Fn, wgslFn, float, vec2, vec3, vec4, int, If, normalize, cross, abs, atan, mix, clamp, texture, textureSize } from 'three/tsl';
2
2
  import { DataArrayTexture, LinearFilter } from 'three';
3
3
 
4
4
  import {
5
5
  UVCache,
6
6
  MaterialSamples,
7
+ ExtMapResult,
7
8
  } from './Struct.js';
8
9
  import { TEXTURE_CONSTANTS } from '../EngineDefaults.js';
9
10
 
@@ -431,6 +432,107 @@ export const processBump = Fn( ( [ currentNormal, material, uvCache ] ) => {
431
432
 
432
433
  } );
433
434
 
435
+ // Fold the glTF anisotropyTexture (RG = tangent-space direction, B = strength) into scalar
436
+ // (strength, rotationRadians) per three.js: anisotropy · R(rotation) · (normalize(rg·2−1)·b).
437
+ // Caller guarantees anisotropyMapIndex >= 0. `uv` is pre-transformed by the caller (albedo transform).
438
+ export const processAnisotropyMap = Fn( ( [ material, uv ] ) => {
439
+
440
+ const result = vec2( material.anisotropy, material.anisotropyRotation ).toVar();
441
+
442
+ const s = sampleBucket( _linearBuckets, material.anisotropyMapIndex, uv ).toVar();
443
+ const texDir = s.rg.mul( 2.0 ).sub( 1.0 ).toVar();
444
+ const dlen = texDir.length().toVar();
445
+
446
+ If( dlen.greaterThan( 1e-4 ), () => {
447
+
448
+ const u = texDir.div( dlen ).mul( s.b ).toVar(); // unit direction × texture strength
449
+ const c = material.anisotropyRotation.cos();
450
+ const sn = material.anisotropyRotation.sin();
451
+ const vx = material.anisotropy.mul( c.mul( u.x ).sub( sn.mul( u.y ) ) );
452
+ const vy = material.anisotropy.mul( sn.mul( u.x ).add( c.mul( u.y ) ) );
453
+ result.assign( vec2( clamp( vx.mul( vx ).add( vy.mul( vy ) ).sqrt(), 0.0, 1.0 ), atan( vy, vx ) ) );
454
+
455
+ } ).Else( () => {
456
+
457
+ result.assign( vec2( 0.0, material.anisotropyRotation ) );
458
+
459
+ } );
460
+
461
+ return result;
462
+
463
+ } );
464
+
465
+ // Fold the glTF extension textures into their scalar factors, per KHR_materials_* / three.js
466
+ // channel conventions. Returns the modulated scalars (unchanged where a map is absent). `uv` is
467
+ // pre-transformed by the caller with the material's albedo KHR_texture_transform (extension maps
468
+ // share the base UV set/transform in practice). Color maps (sheenColor, specularColor) read the
469
+ // sRGB pool; data maps read the linear pool.
470
+ export const applyExtensionMaps = Fn( ( [ material, uv ] ) => {
471
+
472
+ const r = ExtMapResult( {
473
+ transmission: material.transmission,
474
+ clearcoat: material.clearcoat,
475
+ clearcoatRoughness: material.clearcoatRoughness,
476
+ sheenColor: material.sheenColor,
477
+ sheenRoughness: material.sheenRoughness,
478
+ iridescence: material.iridescence,
479
+ iridescenceThickness: material.iridescenceThicknessRange.y, // default = max (no-texture behavior)
480
+ specularIntensity: material.specularIntensity,
481
+ specularColor: material.specularColor,
482
+ } ).toVar();
483
+
484
+ If( material.transmissionMapIndex.greaterThanEqual( int( 0 ) ), () => {
485
+
486
+ r.transmission.assign( r.transmission.mul( sampleBucket( _linearBuckets, material.transmissionMapIndex, uv ).r ) );
487
+
488
+ } );
489
+ If( material.clearcoatMapIndex.greaterThanEqual( int( 0 ) ), () => {
490
+
491
+ r.clearcoat.assign( r.clearcoat.mul( sampleBucket( _linearBuckets, material.clearcoatMapIndex, uv ).r ) );
492
+
493
+ } );
494
+ If( material.clearcoatRoughnessMapIndex.greaterThanEqual( int( 0 ) ), () => {
495
+
496
+ r.clearcoatRoughness.assign( r.clearcoatRoughness.mul( sampleBucket( _linearBuckets, material.clearcoatRoughnessMapIndex, uv ).g ) );
497
+
498
+ } );
499
+ If( material.sheenColorMapIndex.greaterThanEqual( int( 0 ) ), () => {
500
+
501
+ r.sheenColor.assign( r.sheenColor.mul( sampleBucket( _srgbBuckets, material.sheenColorMapIndex, uv ).rgb ) );
502
+
503
+ } );
504
+ If( material.sheenRoughnessMapIndex.greaterThanEqual( int( 0 ) ), () => {
505
+
506
+ // clamp to [0.05,1] to keep parity with the sample/PDF floor applied in ShadeKernel
507
+ r.sheenRoughness.assign( clamp( r.sheenRoughness.mul( sampleBucket( _linearBuckets, material.sheenRoughnessMapIndex, uv ).a ), 0.05, 1.0 ) );
508
+
509
+ } );
510
+ If( material.iridescenceMapIndex.greaterThanEqual( int( 0 ) ), () => {
511
+
512
+ r.iridescence.assign( r.iridescence.mul( sampleBucket( _linearBuckets, material.iridescenceMapIndex, uv ).r ) );
513
+
514
+ } );
515
+ If( material.iridescenceThicknessMapIndex.greaterThanEqual( int( 0 ) ), () => {
516
+
517
+ const g = sampleBucket( _linearBuckets, material.iridescenceThicknessMapIndex, uv ).g;
518
+ r.iridescenceThickness.assign( mix( material.iridescenceThicknessRange.x, material.iridescenceThicknessRange.y, g ) );
519
+
520
+ } );
521
+ If( material.specularIntensityMapIndex.greaterThanEqual( int( 0 ) ), () => {
522
+
523
+ r.specularIntensity.assign( r.specularIntensity.mul( sampleBucket( _linearBuckets, material.specularIntensityMapIndex, uv ).a ) );
524
+
525
+ } );
526
+ If( material.specularColorMapIndex.greaterThanEqual( int( 0 ) ), () => {
527
+
528
+ r.specularColor.assign( r.specularColor.mul( sampleBucket( _srgbBuckets, material.specularColorMapIndex, uv ).rgb ) );
529
+
530
+ } );
531
+
532
+ return r;
533
+
534
+ } );
535
+
434
536
  export const processEmissive = Fn( ( [ material, uvCache ] ) => {
435
537
 
436
538
  const emissionBase = material.emissive.mul( material.emissiveIntensity ).toVar();
@@ -248,6 +248,9 @@ export class DenoisingManager extends EventDispatcher {
248
248
  break;
249
249
 
250
250
  case 'edgeaware':
251
+ // EdgeAware is a spatial-only SVGF à-trous — it consumes the Variance
252
+ // stage's per-pixel variance to drive its luminance edge-stop.
253
+ if ( s.variance ) s.variance.enabled = true;
251
254
  if ( s.edgeFilter ) s.edgeFilter.setFilteringEnabled( true );
252
255
  break;
253
256
 
@@ -329,6 +329,8 @@ export class MaterialDataManager {
329
329
  case 'subsurface': data[ stride + M.SUBSURFACE ] = value; break;
330
330
  case 'subsurfaceRadiusScale': data[ stride + M.SUBSURFACE_RADIUS_SCALE ] = value; break;
331
331
  case 'subsurfaceAnisotropy': data[ stride + M.SUBSURFACE_ANISOTROPY ] = value; break;
332
+ case 'anisotropy': data[ stride + M.ANISOTROPY ] = value; break;
333
+ case 'anisotropyRotation': data[ stride + M.ANISOTROPY_ROTATION ] = value; break;
332
334
  case 'subsurfaceColor':
333
335
  if ( value.r !== undefined ) {
334
336
 
@@ -521,7 +523,25 @@ export class MaterialDataManager {
521
523
  data[ stride + M.SUBSURFACE_RADIUS_SCALE ] = materialData.subsurfaceRadiusScale ?? 1;
522
524
  data[ stride + M.SUBSURFACE_ANISOTROPY ] = materialData.subsurfaceAnisotropy ?? 0;
523
525
 
524
- // Texture transformation matrices (9 floats each, identity if missing)
526
+ // Surface specular anisotropy (map index defaults to -1 = none)
527
+ data[ stride + M.ANISOTROPY ] = materialData.anisotropy ?? 0;
528
+ data[ stride + M.ANISOTROPY_ROTATION ] = materialData.anisotropyRotation ?? 0;
529
+ data[ stride + M.ANISOTROPY_MAP_INDEX ] = materialData.anisotropyMap ?? - 1;
530
+
531
+ // Extension-texture map indices (packed bucket index, -1 = none)
532
+ data[ stride + M.TRANSMISSION_MAP_INDEX ] = materialData.transmissionMap ?? - 1;
533
+ data[ stride + M.CLEARCOAT_MAP_INDEX ] = materialData.clearcoatMap ?? - 1;
534
+ data[ stride + M.CLEARCOAT_ROUGHNESS_MAP_INDEX ] = materialData.clearcoatRoughnessMap ?? - 1;
535
+ data[ stride + M.SHEEN_COLOR_MAP_INDEX ] = materialData.sheenColorMap ?? - 1;
536
+ data[ stride + M.SHEEN_ROUGHNESS_MAP_INDEX ] = materialData.sheenRoughnessMap ?? - 1;
537
+ data[ stride + M.IRIDESCENCE_MAP_INDEX ] = materialData.iridescenceMap ?? - 1;
538
+ data[ stride + M.IRIDESCENCE_THICKNESS_MAP_INDEX ] = materialData.iridescenceThicknessMap ?? - 1;
539
+ data[ stride + M.SPECULAR_INTENSITY_MAP_INDEX ] = materialData.specularIntensityMap ?? - 1;
540
+ data[ stride + M.SPECULAR_COLOR_MAP_INDEX ] = materialData.specularColorMap ?? - 1;
541
+
542
+ // Texture transformation matrices (8 floats per slot = matrix elements[0..7];
543
+ // element[8]=1 is reconstructed on the GPU by arrayToMat3, so it is NOT stored —
544
+ // writing a 9th float here would spill into the next slot / subsurfaceColor).
525
545
  const identity = [ 1, 0, 0, 0, 1, 0, 0, 0, 1 ];
526
546
  const transformEntries = [
527
547
  { key: 'mapMatrix', offset: M.ALBEDO_TRANSFORM },
@@ -536,7 +556,7 @@ export class MaterialDataManager {
536
556
  for ( const { key, offset } of transformEntries ) {
537
557
 
538
558
  const matrix = materialData[ key ] ?? identity;
539
- for ( let i = 0; i < 9; i ++ ) {
559
+ for ( let i = 0; i < 8; i ++ ) {
540
560
 
541
561
  if ( stride + offset + i < data.length ) {
542
562
 
@@ -582,6 +602,17 @@ export class MaterialDataManager {
582
602
  completeMaterialData.roughnessMap = this.getPackedTextureIndex( material.roughnessMap, false );
583
603
  completeMaterialData.metalnessMap = this.getPackedTextureIndex( material.metalnessMap, false );
584
604
  completeMaterialData.displacementMap = this.getPackedTextureIndex( material.displacementMap, false );
605
+ completeMaterialData.anisotropyMap = this.getPackedTextureIndex( material.anisotropyMap, false );
606
+ // Extension maps — color maps (sheenColor, specularColor) are sRGB; the rest are data (linear)
607
+ completeMaterialData.transmissionMap = this.getPackedTextureIndex( material.transmissionMap, false );
608
+ completeMaterialData.clearcoatMap = this.getPackedTextureIndex( material.clearcoatMap, false );
609
+ completeMaterialData.clearcoatRoughnessMap = this.getPackedTextureIndex( material.clearcoatRoughnessMap, false );
610
+ completeMaterialData.sheenColorMap = this.getPackedTextureIndex( material.sheenColorMap, true );
611
+ completeMaterialData.sheenRoughnessMap = this.getPackedTextureIndex( material.sheenRoughnessMap, false );
612
+ completeMaterialData.iridescenceMap = this.getPackedTextureIndex( material.iridescenceMap, false );
613
+ completeMaterialData.iridescenceThicknessMap = this.getPackedTextureIndex( material.iridescenceThicknessMap, false );
614
+ completeMaterialData.specularIntensityMap = this.getPackedTextureIndex( material.specularIntensityMap, false );
615
+ completeMaterialData.specularColorMap = this.getPackedTextureIndex( material.specularColorMap, true );
585
616
 
586
617
  }
587
618
 
@@ -625,7 +656,9 @@ export class MaterialDataManager {
625
656
 
626
657
  }
627
658
 
628
- for ( let i = 0; i < 9; i ++ ) {
659
+ // 8 floats per slot (matrix elements[0..7]); element[8]=1 is GPU-reconstructed.
660
+ // Writing 9 would clobber the next transform slot's first element.
661
+ for ( let i = 0; i < 8; i ++ ) {
629
662
 
630
663
  if ( stride + offset + i < data.length ) {
631
664