three-gpu-pathtracer 0.0.24 → 0.0.25

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 (73) hide show
  1. package/README.md +53 -530
  2. package/build/index.module.js +262 -50
  3. package/build/index.module.js.map +1 -1
  4. package/build/index.umd.cjs +261 -48
  5. package/build/index.umd.cjs.map +1 -1
  6. package/package.json +28 -11
  7. package/src/core/WebGLPathTracer.js +8 -0
  8. package/src/core/utils/sceneUpdateUtils.js +8 -12
  9. package/src/detectors/PrecisionMaterial.js +9 -9
  10. package/src/index.js +1 -0
  11. package/src/objects/PhysicalSpotLight.js +2 -0
  12. package/src/shader/bsdf/bsdf_functions.glsl.js +0 -1
  13. package/src/textures/BlueNoiseTexture.js +6 -6
  14. package/src/textures/ProceduralEquirectTexture.js +8 -7
  15. package/src/textures/turquinMetal.png +0 -0
  16. package/src/uniforms/EquirectHdrInfoUniform.js +9 -4
  17. package/src/uniforms/FloatAttributeTextureArray.js +11 -11
  18. package/src/uniforms/MaterialsTexture.js +9 -9
  19. package/src/webgpu/API.md +762 -0
  20. package/src/webgpu/AtlasTexture.js +471 -0
  21. package/src/webgpu/BlurredEnvMapGenerator.js +129 -0
  22. package/src/webgpu/EquirectBackgroundInfo.js +97 -0
  23. package/src/webgpu/EquirectHdrInfoNode.js +151 -0
  24. package/src/webgpu/LightsInfoNode.js +224 -0
  25. package/src/webgpu/MegaKernelPathTracer.js +277 -0
  26. package/src/webgpu/PathTracerBackend.js +216 -0
  27. package/src/webgpu/TurquinTexture.js +169 -0
  28. package/src/webgpu/WaveFrontPathTracer.js +586 -0
  29. package/src/webgpu/WebGPUPathTracer.js +1302 -0
  30. package/src/webgpu/compute/ComputeKernel.js +92 -0
  31. package/src/webgpu/compute/CopyBufferKernel.js +40 -0
  32. package/src/webgpu/compute/PathTracerMegaKernel.js +470 -0
  33. package/src/webgpu/compute/SampleDebugKernel.js +51 -0
  34. package/src/webgpu/compute/TallySampleCountsKernel.js +111 -0
  35. package/src/webgpu/compute/ZeroOutBufferKernel.js +35 -0
  36. package/src/webgpu/compute/ZeroOutKernel.js +31 -0
  37. package/src/webgpu/compute/wavefront/LogicKernel.js +349 -0
  38. package/src/webgpu/compute/wavefront/MaterialKernel.js +371 -0
  39. package/src/webgpu/compute/wavefront/PopulatePixelIndicesKernel.js +72 -0
  40. package/src/webgpu/compute/wavefront/QueueLengthToDispatchKernel.js +38 -0
  41. package/src/webgpu/compute/wavefront/ResetSlotsKernel.js +66 -0
  42. package/src/webgpu/compute/wavefront/TraceRayKernel.js +71 -0
  43. package/src/webgpu/compute/wavefront/TraceShadowRayKernel.js +67 -0
  44. package/src/webgpu/compute/wavefront/structs.js +155 -0
  45. package/src/webgpu/constants.js +62 -0
  46. package/src/webgpu/denoise/OIDNDenoiser.js +431 -0
  47. package/src/webgpu/index.d.ts +176 -0
  48. package/src/webgpu/index.js +11 -0
  49. package/src/webgpu/materials/GltfCompliantMaterial.js +608 -0
  50. package/src/webgpu/materials/GraphMaterial.js +331 -0
  51. package/src/webgpu/materials/PathtracingMaterial.js +89 -0
  52. package/src/webgpu/materials/RenderToScreenMaterial.js +150 -0
  53. package/src/webgpu/materials/debug/AtlasDebugMaterial.js +41 -0
  54. package/src/webgpu/materials/debug/SampleDensityMaterial.js +61 -0
  55. package/src/webgpu/nodes/PathtracerBVHComputeData.js +1037 -0
  56. package/src/webgpu/nodes/debugBounds.wgsl.js +228 -0
  57. package/src/webgpu/nodes/eon.wgsl.js +262 -0
  58. package/src/webgpu/nodes/ggx.wgsl.js +190 -0
  59. package/src/webgpu/nodes/lights.wgsl.js +203 -0
  60. package/src/webgpu/nodes/material.wgsl.js +990 -0
  61. package/src/webgpu/nodes/rand/bluedither.wgsl.js +92 -0
  62. package/src/webgpu/nodes/rand/pcg.wgsl.js +81 -0
  63. package/src/webgpu/nodes/rand/sobol.wgsl.js +287 -0
  64. package/src/webgpu/nodes/random.wgsl.js +20 -0
  65. package/src/webgpu/nodes/reset.wgsl.js +21 -0
  66. package/src/webgpu/nodes/sampling.wgsl.js +193 -0
  67. package/src/webgpu/nodes/sheen.wgsl.js +148 -0
  68. package/src/webgpu/nodes/structs.wgsl.js +272 -0
  69. package/src/webgpu/nodes/utils.wgsl.js +366 -0
  70. package/src/webgpu/shims/ArrayCameraShim.js +74 -0
  71. package/src/webgpu/shims/EquirectCameraShim.js +37 -0
  72. package/src/webgpu/shims/PhysicalCameraShim.js +151 -0
  73. package/src/webgpu/upscale/FSRUpscaler.js +108 -0
@@ -1,4 +1,4 @@
1
- import { BufferAttribute, BufferGeometry, Matrix4, Vector3, Vector4, Matrix3, MeshBasicMaterial, Mesh, ShaderMaterial, NoBlending, Vector2, WebGLRenderTarget, FloatType, RGBAFormat, NearestFilter, PerspectiveCamera, DataUtils, HalfFloatType, Source, DataTexture, LinearFilter, RepeatWrapping, RedFormat, ClampToEdgeWrapping, Quaternion, DataArrayTexture, DoubleSide, BackSide, FrontSide, Color, WebGLArrayRenderTarget, UnsignedByteType, NoToneMapping, RGFormat, NormalBlending, Spherical, EquirectangularReflectionMapping, LinearMipMapLinearFilter, Clock, Scene, AdditiveBlending, Camera, SpotLight, RectAreaLight, PMREMGenerator, MeshStandardMaterial } from 'three';
1
+ import { BufferAttribute, BufferGeometry, Matrix4, Vector3, Vector4, Matrix3, MeshBasicMaterial, Mesh, ShaderMaterial, NoBlending, Vector2, WebGLRenderTarget, FloatType, RGBAFormat, NearestFilter, PerspectiveCamera, DataUtils, HalfFloatType, Source, DataTexture, LinearFilter, RepeatWrapping, RedFormat, ClampToEdgeWrapping, Quaternion, DataArrayTexture, DoubleSide, BackSide, FrontSide, Color, WebGLArrayRenderTarget, UnsignedByteType, NoToneMapping, RGFormat, NormalBlending, Spherical, EquirectangularReflectionMapping, LinearMipMapLinearFilter, Clock, Scene, AdditiveBlending, Camera, SpotLight, RectAreaLight, PMREMGenerator, MeshStandardMaterial, TangentSpaceNormalMap } from 'three';
2
2
  import { SAH, MeshBVH, FloatVertexAttributeTexture, MeshBVHUniformStruct, UIntVertexAttributeTexture, BVHShaderGLSL } from 'three-mesh-bvh';
3
3
  import { FullScreenQuad } from 'three/examples/jsm/postprocessing/Pass.js';
4
4
 
@@ -2246,6 +2246,12 @@ class EquirectHdrInfoUniform {
2246
2246
 
2247
2247
  }
2248
2248
 
2249
+ getPixelWeight( r, g, b ) {
2250
+
2251
+ return colorToLuminance( r, g, b );
2252
+
2253
+ }
2254
+
2249
2255
  dispose() {
2250
2256
 
2251
2257
  this.marginalWeights.dispose();
@@ -2286,10 +2292,9 @@ class EquirectHdrInfoUniform {
2286
2292
  const g = DataUtils.fromHalfFloat( data[ 4 * i + 1 ] );
2287
2293
  const b = DataUtils.fromHalfFloat( data[ 4 * i + 2 ] );
2288
2294
 
2289
- // the probability of the pixel being selected in this row is the
2290
- // scale of the luminance relative to the rest of the pixels.
2291
- // TODO: this should also account for the solid angle of the pixel when sampling
2292
- const weight = colorToLuminance( r, g, b );
2295
+ // the probability of the pixel being selected in its row is proportional
2296
+ // to its luminance relative to the other pixels.
2297
+ const weight = this.getPixelWeight( r, g, b, y, height );
2293
2298
  cumulativeRowWeight += weight;
2294
2299
  totalSumValue += weight;
2295
2300
 
@@ -2620,17 +2625,17 @@ function copyArrayToArray( fromArray, fromStride, toArray, toStride, offset ) {
2620
2625
  let maxValue = 1.0;
2621
2626
  switch ( fromArray.constructor ) {
2622
2627
 
2623
- case Uint8Array:
2624
- case Uint16Array:
2625
- case Uint32Array:
2626
- maxValue = 2 ** bpe - 1;
2627
- break;
2628
+ case Uint8Array:
2629
+ case Uint16Array:
2630
+ case Uint32Array:
2631
+ maxValue = 2 ** bpe - 1;
2632
+ break;
2628
2633
 
2629
- case Int8Array:
2630
- case Int16Array:
2631
- case Int32Array:
2632
- maxValue = 2 ** ( bpe - 1 ) - 1;
2633
- break;
2634
+ case Int8Array:
2635
+ case Int16Array:
2636
+ case Int32Array:
2637
+ maxValue = 2 ** ( bpe - 1 ) - 1;
2638
+ break;
2634
2639
 
2635
2640
  }
2636
2641
 
@@ -2881,20 +2886,16 @@ function getTextures( materials ) {
2881
2886
  function getLights( scene ) {
2882
2887
 
2883
2888
  const lights = [];
2884
- scene.traverse( c => {
2885
-
2886
- if ( c.visible ) {
2889
+ scene.traverseVisible( c => {
2887
2890
 
2888
- if (
2889
- c.isRectAreaLight ||
2890
- c.isSpotLight ||
2891
- c.isPointLight ||
2892
- c.isDirectionalLight
2893
- ) {
2894
-
2895
- lights.push( c );
2891
+ if (
2892
+ c.isRectAreaLight ||
2893
+ c.isSpotLight ||
2894
+ c.isPointLight ||
2895
+ c.isDirectionalLight
2896
+ ) {
2896
2897
 
2897
- }
2898
+ lights.push( c );
2898
2899
 
2899
2900
  }
2900
2901
 
@@ -3264,15 +3265,15 @@ class MaterialsTexture extends DataTexture {
3264
3265
 
3265
3266
  switch ( m.side ) {
3266
3267
 
3267
- case FrontSide:
3268
- floatArray[ index ++ ] = 1;
3269
- break;
3270
- case BackSide:
3271
- floatArray[ index ++ ] = - 1;
3272
- break;
3273
- case DoubleSide:
3274
- floatArray[ index ++ ] = 0;
3275
- break;
3268
+ case FrontSide:
3269
+ floatArray[ index ++ ] = 1;
3270
+ break;
3271
+ case BackSide:
3272
+ floatArray[ index ++ ] = - 1;
3273
+ break;
3274
+ case DoubleSide:
3275
+ floatArray[ index ++ ] = 0;
3276
+ break;
3276
3277
 
3277
3278
  }
3278
3279
 
@@ -4145,12 +4146,12 @@ function getFormat( channels ) {
4145
4146
 
4146
4147
  switch ( channels ) {
4147
4148
 
4148
- case 1:
4149
- return RedFormat;
4150
- case 2:
4151
- return RGFormat;
4152
- default:
4153
- return RGBAFormat;
4149
+ case 1:
4150
+ return RedFormat;
4151
+ case 2:
4152
+ return RGFormat;
4153
+ default:
4154
+ return RGBAFormat;
4154
4155
 
4155
4156
  }
4156
4157
 
@@ -5712,7 +5713,6 @@ const bsdf_functions = /* glsl */`
5712
5713
  // See equation (1) in http://www.aconty.com/pdf/s2017_pbs_imageworks_sheen.pdf
5713
5714
  vec3 color = surf.sheenColor;
5714
5715
  color *= D * G / ( 4.0 * abs( cosThetaO * cosThetaI ) );
5715
- color *= wi.z;
5716
5716
 
5717
5717
  return color;
5718
5718
 
@@ -8193,8 +8193,8 @@ class ProceduralEquirectTexture extends DataTexture {
8193
8193
  constructor( width = 512, height = 512 ) {
8194
8194
 
8195
8195
  super(
8196
- new Float32Array( width * height * 4 ),
8197
- width, height, RGBAFormat, FloatType, EquirectangularReflectionMapping,
8196
+ new Uint16Array( width * height * 4 ),
8197
+ width, height, RGBAFormat, HalfFloatType, EquirectangularReflectionMapping,
8198
8198
  RepeatWrapping, ClampToEdgeWrapping, LinearFilter, LinearFilter,
8199
8199
  );
8200
8200
 
@@ -8226,10 +8226,10 @@ class ProceduralEquirectTexture extends DataTexture {
8226
8226
 
8227
8227
  const i = y * width + x;
8228
8228
  const i4 = 4 * i;
8229
- data[ i4 + 0 ] = ( _color.r );
8230
- data[ i4 + 1 ] = ( _color.g );
8231
- data[ i4 + 2 ] = ( _color.b );
8232
- data[ i4 + 3 ] = ( 1.0 );
8229
+ data[ i4 + 0 ] = DataUtils.toHalfFloat( _color.r );
8230
+ data[ i4 + 1 ] = DataUtils.toHalfFloat( _color.g );
8231
+ data[ i4 + 2 ] = DataUtils.toHalfFloat( _color.b );
8232
+ data[ i4 + 3 ] = DataUtils.toHalfFloat( 1.0 );
8233
8233
 
8234
8234
  }
8235
8235
 
@@ -8630,6 +8630,8 @@ class WebGLPathTracer {
8630
8630
 
8631
8631
  constructor( renderer ) {
8632
8632
 
8633
+ console.warn( 'WebGLPathTracer: This class has been deprecated and will be removed in a future release. Use "WebGPUPathTracer" instead.' );
8634
+
8633
8635
  // members
8634
8636
  this._renderer = renderer;
8635
8637
  this._generator = new PathTracingSceneGenerator();
@@ -9052,6 +9054,12 @@ class WebGLPathTracer {
9052
9054
 
9053
9055
  }
9054
9056
 
9057
+ getRenderTime() {
9058
+
9059
+ return this._clock.getElapsedTime() * 1e3;
9060
+
9061
+ }
9062
+
9055
9063
  }
9056
9064
 
9057
9065
  class EquirectCamera extends Camera {
@@ -9066,6 +9074,8 @@ class EquirectCamera extends Camera {
9066
9074
 
9067
9075
  }
9068
9076
 
9077
+ // TODO: this should extend IESSpotLight, but the class is only exported from "three/webgpu" and
9078
+ // the node library resolves light nodes by exact constructor so a subclass would not rasterize
9069
9079
  class PhysicalSpotLight extends SpotLight {
9070
9080
 
9071
9081
  constructor( ...args ) {
@@ -9396,7 +9406,209 @@ class FogVolumeMaterial extends MeshStandardMaterial {
9396
9406
 
9397
9407
  }
9398
9408
 
9409
+ class AmbientOcclusionMaterial extends MaterialBase {
9410
+
9411
+ get normalMap() {
9412
+
9413
+ return this.uniforms.normalMap.value;
9414
+
9415
+ }
9416
+
9417
+ set normalMap( v ) {
9418
+
9419
+ this.uniforms.normalMap.value = v;
9420
+ this.setDefine( 'USE_NORMALMAP', v ? null : '' );
9421
+
9422
+ }
9423
+
9424
+ get normalMapType() {
9425
+
9426
+ return TangentSpaceNormalMap;
9427
+
9428
+ }
9429
+
9430
+ set normalMapType( v ) {
9431
+
9432
+ if ( v !== TangentSpaceNormalMap ) {
9433
+
9434
+ throw new Error( 'AmbientOcclusionMaterial: Only tangent space normal map are supported' );
9435
+
9436
+ }
9437
+
9438
+ }
9439
+
9440
+ constructor( parameters ) {
9441
+
9442
+ super( {
9443
+
9444
+ defines: {
9445
+ SAMPLES: 10,
9446
+ MATERIAL_PIXELS: MATERIAL_PIXELS,
9447
+ },
9448
+
9449
+ uniforms: {
9450
+ bvh: { value: new MeshBVHUniformStruct() },
9451
+ radius: { value: 1.0 },
9452
+ seed: { value: 0 },
9453
+
9454
+ normalMap: { value: null },
9455
+ normalScale: { value: new Vector2( 1, 1 ) },
9456
+ },
9457
+
9458
+ vertexShader: /* glsl */`
9459
+
9460
+ varying vec3 vNorm;
9461
+ varying vec3 vPos;
9462
+
9463
+ #if defined( USE_NORMALMAP ) && defined( USE_TANGENT )
9464
+
9465
+ varying vec2 vUv;
9466
+ varying vec4 vTan;
9467
+
9468
+ #endif
9469
+
9470
+ void main() {
9471
+
9472
+ vec4 mvPosition = vec4( position, 1.0 );
9473
+ mvPosition = modelViewMatrix * mvPosition;
9474
+ gl_Position = projectionMatrix * mvPosition;
9475
+
9476
+ mat3 modelNormalMatrix = transpose( inverse( mat3( modelMatrix ) ) );
9477
+ vNorm = normalize( modelNormalMatrix * normal );
9478
+ vPos = ( modelMatrix * vec4( position, 1.0 ) ).xyz;
9479
+
9480
+ #if defined( USE_NORMALMAP ) && defined( USE_TANGENT )
9481
+
9482
+ vUv = uv;
9483
+ vTan = tangent;
9484
+
9485
+ #endif
9486
+
9487
+ }
9488
+
9489
+ `,
9490
+
9491
+ fragmentShader: /* glsl */`
9492
+ #define RAY_OFFSET 1e-4
9493
+
9494
+ precision highp isampler2D;
9495
+ precision highp usampler2D;
9496
+ precision highp sampler2DArray;
9497
+ #include <common>
9498
+ #include <cube_uv_reflection_fragment>
9499
+
9500
+ // bvh
9501
+ ${ BVHShaderGLSL.common_functions }
9502
+ ${ BVHShaderGLSL.bvh_struct_definitions }
9503
+ ${ BVHShaderGLSL.bvh_ray_functions }
9504
+
9505
+ // uniform structs
9506
+ ${ material_struct }
9507
+
9508
+ // rand
9509
+ ${ pcg_functions }
9510
+
9511
+ // common
9512
+ ${ shape_sampling_functions }
9513
+
9514
+ uniform BVH bvh;
9515
+ uniform int seed;
9516
+ uniform float radius;
9517
+
9518
+ varying vec3 vNorm;
9519
+ varying vec3 vPos;
9520
+
9521
+ #if defined(USE_NORMALMAP) && defined(USE_TANGENT)
9522
+
9523
+ uniform sampler2D normalMap;
9524
+ uniform vec2 normalScale;
9525
+ varying vec2 vUv;
9526
+ varying vec4 vTan;
9527
+
9528
+ #endif
9529
+
9530
+ void main() {
9531
+
9532
+ rng_initialize( gl_FragCoord.xy, seed );
9533
+
9534
+ // compute the flat face surface normal
9535
+ vec3 fdx = vec3( dFdx( vPos.x ), dFdx( vPos.y ), dFdx( vPos.z ) );
9536
+ vec3 fdy = vec3( dFdy( vPos.x ), dFdy( vPos.y ), dFdy( vPos.z ) );
9537
+ vec3 faceNormal = normalize( cross( fdx, fdy ) );
9538
+
9539
+ // find the max component to scale the offset to account for floating point error
9540
+ vec3 absPoint = abs( vPos );
9541
+ float maxPoint = max( absPoint.x, max( absPoint.y, absPoint.z ) );
9542
+ vec3 normal = vNorm;
9543
+
9544
+ #if defined( USE_NORMALMAP ) && defined( USE_TANGENT )
9545
+
9546
+ // some provided tangents can be malformed (0, 0, 0) causing the normal to be degenerate
9547
+ // resulting in NaNs and slow path tracing.
9548
+ if ( length( vTan.xyz ) > 0.0 ) {
9549
+
9550
+ vec2 uv = vUv;
9551
+ vec3 tangent = normalize( vTan.xyz );
9552
+ vec3 bitangent = normalize( cross( normal, tangent ) * vTan.w );
9553
+ mat3 vTBN = mat3( tangent, bitangent, normal );
9554
+
9555
+ vec3 texNormal = texture2D( normalMap, uv ).xyz * 2.0 - 1.0;
9556
+ texNormal.xy *= normalScale;
9557
+ normal = vTBN * texNormal;
9558
+
9559
+ }
9560
+
9561
+ #endif
9562
+
9563
+ normal *= gl_FrontFacing ? 1.0 : - 1.0;
9564
+
9565
+ vec3 rayOrigin = vPos + faceNormal * ( maxPoint + 1.0 ) * RAY_OFFSET;
9566
+ float accumulated = 0.0;
9567
+ for ( int i = 0; i < SAMPLES; i ++ ) {
9568
+
9569
+ // sample the cosine weighted hemisphere and discard the sample if it's below
9570
+ // the geometric surface
9571
+ vec3 rayDirection = sampleHemisphere( normalize( normal ), pcgRand4().xy );
9572
+
9573
+ // check if we hit the mesh and its within the specified radius
9574
+ float side = 1.0;
9575
+ float dist = 0.0;
9576
+ vec3 barycoord = vec3( 0.0 );
9577
+ vec3 outNormal = vec3( 0.0 );
9578
+ uvec4 faceIndices = uvec4( 0u );
9579
+
9580
+ // if the ray is above the geometry surface, and it doesn't hit another surface within the specified radius then
9581
+ // we consider it lit
9582
+ if (
9583
+ dot( rayDirection, faceNormal ) > 0.0 &&
9584
+ (
9585
+ ! bvhIntersectFirstHit( bvh, rayOrigin, rayDirection, faceIndices, outNormal, barycoord, side, dist ) ||
9586
+ dist >= radius
9587
+ )
9588
+ ) {
9589
+
9590
+ accumulated += 1.0;
9591
+
9592
+ }
9593
+
9594
+ }
9595
+
9596
+ gl_FragColor.rgb = vec3( accumulated / float( SAMPLES ) );
9597
+ gl_FragColor.a = 1.0;
9598
+
9599
+ }
9600
+
9601
+ `
9602
+
9603
+ } );
9604
+
9605
+ this.setValues( parameters );
9606
+
9607
+ }
9608
+
9609
+ }
9610
+
9399
9611
  // core
9400
9612
 
9401
- export { BlurredEnvMapGenerator, DenoiseMaterial, DynamicPathTracingSceneGenerator, EquirectCamera, FogVolumeMaterial, GradientEquirectTexture, PathTracingRenderer, PathTracingSceneGenerator, PathTracingSceneWorker, PhysicalCamera, PhysicalPathTracingMaterial, PhysicalSpotLight, ProceduralEquirectTexture, ShapedAreaLight, WebGLPathTracer };
9613
+ export { AmbientOcclusionMaterial, BlurredEnvMapGenerator, DenoiseMaterial, DynamicPathTracingSceneGenerator, EquirectCamera, FogVolumeMaterial, GradientEquirectTexture, PathTracingRenderer, PathTracingSceneGenerator, PathTracingSceneWorker, PhysicalCamera, PhysicalPathTracingMaterial, PhysicalSpotLight, ProceduralEquirectTexture, ShapedAreaLight, WebGLPathTracer };
9402
9614
  //# sourceMappingURL=index.module.js.map