three-gpu-pathtracer 0.0.2 → 0.0.5

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 (38) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +728 -597
  3. package/build/index.module.js +3585 -1739
  4. package/build/index.module.js.map +1 -1
  5. package/build/index.umd.cjs +3589 -1739
  6. package/build/index.umd.cjs.map +1 -1
  7. package/package.json +60 -61
  8. package/src/core/DynamicPathTracingSceneGenerator.js +17 -11
  9. package/src/core/EquirectCamera.js +13 -0
  10. package/src/core/MaterialReducer.js +256 -256
  11. package/src/core/PathTracingRenderer.js +143 -28
  12. package/src/core/PathTracingSceneGenerator.js +68 -52
  13. package/src/core/PhysicalCamera.js +28 -28
  14. package/src/index.js +26 -23
  15. package/src/materials/AlphaDisplayMaterial.js +48 -0
  16. package/src/materials/AmbientOcclusionMaterial.js +197 -197
  17. package/src/materials/BlendMaterial.js +67 -0
  18. package/src/materials/LambertPathTracingMaterial.js +285 -285
  19. package/src/materials/MaterialBase.js +56 -56
  20. package/src/materials/PhysicalPathTracingMaterial.js +848 -420
  21. package/src/shader/shaderEnvMapSampling.js +59 -0
  22. package/src/shader/shaderGGXFunctions.js +108 -107
  23. package/src/shader/shaderLightSampling.js +87 -0
  24. package/src/shader/shaderMaterialSampling.js +501 -333
  25. package/src/shader/shaderStructs.js +191 -42
  26. package/src/shader/shaderUtils.js +287 -191
  27. package/src/uniforms/EquirectHdrInfoUniform.js +263 -0
  28. package/src/uniforms/LightsTexture.js +83 -0
  29. package/src/uniforms/MaterialsTexture.js +319 -0
  30. package/src/uniforms/PhysicalCameraUniform.js +36 -36
  31. package/src/uniforms/RenderTarget2DArray.js +93 -80
  32. package/src/utils/BlurredEnvMapGenerator.js +113 -0
  33. package/src/utils/GeometryPreparationUtils.js +2 -8
  34. package/src/utils/UVUnwrapper.js +101 -101
  35. package/src/workers/PathTracingSceneWorker.js +41 -40
  36. package/src/uniforms/EquirectPdfUniform.js +0 -132
  37. package/src/uniforms/MaterialStructArrayUniform.js +0 -18
  38. package/src/uniforms/MaterialStructUniform.js +0 -114
@@ -1,22 +1,42 @@
1
- import { RGBAFormat, FloatType, Color, Vector2, WebGLRenderTarget } from 'three';
1
+ import { RGBAFormat, FloatType, Color, Vector2, WebGLRenderTarget, NoBlending, NormalBlending } from 'three';
2
2
  import { FullScreenQuad } from 'three/examples/jsm/postprocessing/Pass.js';
3
+ import { BlendMaterial } from '../materials/BlendMaterial.js';
3
4
 
4
5
  function* renderTask() {
5
6
 
6
- const { _fsQuad, _renderer, target, camera, material } = this;
7
+ const {
8
+ _renderer,
9
+ _fsQuad,
10
+ _blendQuad,
11
+ _primaryTarget,
12
+ _blendTargets,
13
+ alpha,
14
+ camera,
15
+ material,
16
+ } = this;
17
+
18
+ const blendMaterial = _blendQuad.material;
19
+ let [ blendTarget1, blendTarget2 ] = _blendTargets;
20
+
7
21
  while ( true ) {
8
22
 
9
- material.opacity = 1 / ( this.samples + 1 );
10
- material.seed ++;
23
+ if ( alpha ) {
24
+
25
+ blendMaterial.opacity = 1 / ( this.samples + 1 );
26
+ material.blending = NoBlending;
27
+ material.opacity = 1;
28
+
29
+ } else {
30
+
31
+ material.opacity = 1 / ( this.samples + 1 );
32
+ material.blending = NormalBlending;
33
+
34
+ }
11
35
 
12
- const w = target.width;
13
- const h = target.height;
14
- camera.setViewOffset(
15
- w, h,
16
- Math.random() - 0.5, Math.random() - 0.5,
17
- w, h,
18
- );
19
- camera.updateProjectionMatrix();
36
+ const w = _primaryTarget.width;
37
+ const h = _primaryTarget.height;
38
+ material.resolution.set( w, h );
39
+ material.seed ++;
20
40
 
21
41
  const tx = this.tiles.x || 1;
22
42
  const ty = this.tiles.y || 1;
@@ -29,11 +49,32 @@ function* renderTask() {
29
49
  material.cameraWorldMatrix.copy( camera.matrixWorld );
30
50
  material.invProjectionMatrix.copy( camera.projectionMatrixInverse );
31
51
 
52
+ // Perspective camera (default)
53
+ let cameraType = 0;
54
+
55
+ // An orthographic projection matrix will always have the bottom right element == 1
56
+ // And a perspective projection matrix will always have the bottom right element == 0
57
+ if ( camera.projectionMatrix.elements[ 15 ] > 0 ) {
58
+
59
+ // Orthographic
60
+ cameraType = 1;
61
+
62
+ }
63
+
64
+ if ( camera.isEquirectCamera ) {
65
+
66
+ // Equirectangular
67
+ cameraType = 2;
68
+
69
+ }
70
+
71
+ material.setDefine( 'CAMERA_TYPE', cameraType );
72
+
32
73
  const ogRenderTarget = _renderer.getRenderTarget();
33
74
  const ogAutoClear = _renderer.autoClear;
34
75
 
35
76
  // three.js renderer takes values relative to the current pixel ratio
36
- _renderer.setRenderTarget( target );
77
+ _renderer.setRenderTarget( _primaryTarget );
37
78
  _renderer.setScissorTest( true );
38
79
  _renderer.setScissor(
39
80
  dprInv * Math.ceil( x * w / tx ),
@@ -47,6 +88,17 @@ function* renderTask() {
47
88
  _renderer.setRenderTarget( ogRenderTarget );
48
89
  _renderer.autoClear = ogAutoClear;
49
90
 
91
+ if ( alpha ) {
92
+
93
+ blendMaterial.target1 = blendTarget1.texture;
94
+ blendMaterial.target2 = _primaryTarget.texture;
95
+
96
+ _renderer.setRenderTarget( blendTarget2 );
97
+ _blendQuad.render( _renderer );
98
+ _renderer.setRenderTarget( ogRenderTarget );
99
+
100
+ }
101
+
50
102
  this.samples += ( 1 / totalTiles );
51
103
 
52
104
  yield;
@@ -55,6 +107,8 @@ function* renderTask() {
55
107
 
56
108
  }
57
109
 
110
+ [ blendTarget1, blendTarget2 ] = [ blendTarget2, blendTarget1 ];
111
+
58
112
  this.samples = Math.round( this.samples );
59
113
 
60
114
  }
@@ -76,43 +130,104 @@ export class PathTracingRenderer {
76
130
 
77
131
  }
78
132
 
133
+ get target() {
134
+
135
+ return this._alpha ? this._blendTargets[ 1 ] : this._primaryTarget;
136
+
137
+ }
138
+
139
+ set alpha( v ) {
140
+
141
+ if ( ! v ) {
142
+
143
+ this._blendTargets[ 0 ].dispose();
144
+ this._blendTargets[ 1 ].dispose();
145
+
146
+ }
147
+
148
+ this._alpha = v;
149
+ this.reset();
150
+
151
+ }
152
+
153
+ get alpha() {
154
+
155
+ return this._alpha;
156
+
157
+ }
158
+
79
159
  constructor( renderer ) {
80
160
 
81
161
  this.camera = null;
82
162
  this.tiles = new Vector2( 1, 1 );
83
- this.target = new WebGLRenderTarget( 1, 1, {
84
- format: RGBAFormat,
85
- type: FloatType,
86
- } );
163
+
87
164
  this.samples = 0;
88
165
  this.stableNoise = false;
89
166
  this._renderer = renderer;
167
+ this._alpha = false;
90
168
  this._fsQuad = new FullScreenQuad( null );
169
+ this._blendQuad = new FullScreenQuad( new BlendMaterial() );
91
170
  this._task = null;
92
171
 
172
+ this._primaryTarget = new WebGLRenderTarget( 1, 1, {
173
+ format: RGBAFormat,
174
+ type: FloatType,
175
+ } );
176
+ this._blendTargets = [
177
+ new WebGLRenderTarget( 1, 1, {
178
+ format: RGBAFormat,
179
+ type: FloatType,
180
+ } ),
181
+ new WebGLRenderTarget( 1, 1, {
182
+ format: RGBAFormat,
183
+ type: FloatType,
184
+ } ),
185
+ ];
186
+
93
187
  }
94
188
 
95
189
  setSize( w, h ) {
96
190
 
97
- this.target.setSize( w, h );
191
+ this._primaryTarget.setSize( w, h );
192
+ this._blendTargets[ 0 ].setSize( w, h );
193
+ this._blendTargets[ 1 ].setSize( w, h );
98
194
  this.reset();
99
195
 
100
196
  }
101
197
 
198
+ dispose() {
199
+
200
+ this._primaryTarget.dispose();
201
+ this._blendTargets[ 0 ].dispose();
202
+ this._blendTargets[ 1 ].dispose();
203
+
204
+ this._fsQuad.dispose();
205
+ this._blendQuad.dispose();
206
+ this._task = null;
207
+
208
+ }
209
+
102
210
  reset() {
103
211
 
104
- const renderer = this._renderer;
105
- const target = this.target;
106
- const ogRenderTarget = renderer.getRenderTarget();
107
- const ogClearAlpha = renderer.getClearAlpha();
108
- renderer.getClearColor( ogClearColor );
212
+ const { _renderer, _primaryTarget, _blendTargets } = this;
213
+ const ogRenderTarget = _renderer.getRenderTarget();
214
+ const ogClearAlpha = _renderer.getClearAlpha();
215
+ _renderer.getClearColor( ogClearColor );
216
+
217
+ _renderer.setRenderTarget( _primaryTarget );
218
+ _renderer.setClearColor( 0, 0 );
219
+ _renderer.clearColor();
220
+
221
+ _renderer.setRenderTarget( _blendTargets[ 0 ] );
222
+ _renderer.setClearColor( 0, 0 );
223
+ _renderer.clearColor();
109
224
 
110
- renderer.setRenderTarget( target );
111
- renderer.setClearColor( 0, 0 );
112
- renderer.clearColor();
225
+ _renderer.setRenderTarget( _blendTargets[ 1 ] );
226
+ _renderer.setClearColor( 0, 0 );
227
+ _renderer.clearColor();
113
228
 
114
- renderer.setClearColor( ogClearColor, ogClearAlpha );
115
- renderer.setRenderTarget( ogRenderTarget );
229
+ _renderer.setClearColor( ogClearColor, ogClearAlpha );
230
+ _renderer.setRenderTarget( ogRenderTarget );
116
231
 
117
232
  this.samples = 0;
118
233
  this._task = null;
@@ -1,52 +1,68 @@
1
- import { Mesh } from 'three';
2
- import { SAH, MeshBVH, StaticGeometryGenerator } from 'three-mesh-bvh';
3
- import { mergeMeshes } from '../utils/GeometryPreparationUtils.js';
4
-
5
- export class PathTracingSceneGenerator {
6
-
7
- prepScene( scene ) {
8
-
9
- const meshes = [];
10
- scene.traverse( c => {
11
-
12
- if ( c.isSkinnedMesh || c.isMesh && c.morphTargetInfluences ) {
13
-
14
- const generator = new StaticGeometryGenerator( c );
15
- generator.applyWorldTransforms = false;
16
- const mesh = new Mesh(
17
- generator.generate(),
18
- c.material,
19
- );
20
- mesh.matrixWorld.copy( c.matrixWorld );
21
- mesh.matrix.copy( c.matrixWorld );
22
- mesh.matrix.decompose( mesh.position, mesh.quaternion, mesh.scale );
23
- meshes.push( mesh );
24
-
25
- } else if ( c.isMesh ) {
26
-
27
- meshes.push( c );
28
-
29
- }
30
-
31
- } );
32
-
33
- return mergeMeshes( meshes, {
34
- attributes: [ 'position', 'normal', 'tangent', 'uv' ],
35
- } );
36
-
37
- }
38
-
39
- generate( scene, options = {} ) {
40
-
41
- const { materials, textures, geometry } = this.prepScene( scene );
42
- const bvhOptions = { strategy: SAH, ...options, maxLeafTris: 1 };
43
- return {
44
- scene,
45
- materials,
46
- textures,
47
- bvh: new MeshBVH( geometry, bvhOptions ),
48
- };
49
-
50
- }
51
-
52
- }
1
+ import { Mesh } from 'three';
2
+ import { SAH, MeshBVH, StaticGeometryGenerator } from 'three-mesh-bvh';
3
+ import { mergeMeshes } from '../utils/GeometryPreparationUtils.js';
4
+
5
+ export class PathTracingSceneGenerator {
6
+
7
+ prepScene( scene ) {
8
+
9
+ scene = Array.isArray( scene ) ? scene : [ scene ];
10
+
11
+ const meshes = [];
12
+ const lights = [];
13
+
14
+ for ( let i = 0, l = scene.length; i < l; i ++ ) {
15
+
16
+ scene[ i ].traverse( c => {
17
+
18
+ if ( c.isSkinnedMesh || c.isMesh && c.morphTargetInfluences ) {
19
+
20
+ const generator = new StaticGeometryGenerator( c );
21
+ generator.applyWorldTransforms = false;
22
+ const mesh = new Mesh(
23
+ generator.generate(),
24
+ c.material,
25
+ );
26
+ mesh.matrixWorld.copy( c.matrixWorld );
27
+ mesh.matrix.copy( c.matrixWorld );
28
+ mesh.matrix.decompose( mesh.position, mesh.quaternion, mesh.scale );
29
+ meshes.push( mesh );
30
+
31
+ } else if ( c.isMesh ) {
32
+
33
+ meshes.push( c );
34
+
35
+ } else if ( c.isRectAreaLight ) {
36
+
37
+ lights.push( c );
38
+
39
+ }
40
+
41
+ } );
42
+
43
+ }
44
+
45
+ return {
46
+ ...mergeMeshes( meshes, {
47
+ attributes: [ 'position', 'normal', 'tangent', 'uv' ],
48
+ } ),
49
+ lights
50
+ };
51
+
52
+ }
53
+
54
+ generate( scene, options = {} ) {
55
+
56
+ const { materials, textures, geometry, lights } = this.prepScene( scene );
57
+ const bvhOptions = { strategy: SAH, ...options, maxLeafTris: 1 };
58
+ return {
59
+ scene,
60
+ materials,
61
+ textures,
62
+ lights,
63
+ bvh: new MeshBVH( geometry, bvhOptions ),
64
+ };
65
+
66
+ }
67
+
68
+ }
@@ -1,28 +1,28 @@
1
- import { PerspectiveCamera } from 'three';
2
-
3
- export class PhysicalCamera extends PerspectiveCamera {
4
-
5
- set bokehSize( size ) {
6
-
7
- this.fStop = this.getFocalLength() / size;
8
-
9
- }
10
-
11
- get bokehSize() {
12
-
13
- return this.getFocalLength() / this.fStop;
14
-
15
- }
16
-
17
- constructor( ...args ) {
18
-
19
- super( ...args );
20
- this.fStop = 1.4;
21
- this.apertureBlades = 0;
22
- this.apertureRotation = 0;
23
- this.focusDistance = 25;
24
- this.anamorphicRatio = 1;
25
-
26
- }
27
-
28
- }
1
+ import { PerspectiveCamera } from 'three';
2
+
3
+ export class PhysicalCamera extends PerspectiveCamera {
4
+
5
+ set bokehSize( size ) {
6
+
7
+ this.fStop = this.getFocalLength() / size;
8
+
9
+ }
10
+
11
+ get bokehSize() {
12
+
13
+ return this.getFocalLength() / this.fStop;
14
+
15
+ }
16
+
17
+ constructor( ...args ) {
18
+
19
+ super( ...args );
20
+ this.fStop = 1.4;
21
+ this.apertureBlades = 0;
22
+ this.apertureRotation = 0;
23
+ this.focusDistance = 25;
24
+ this.anamorphicRatio = 1;
25
+
26
+ }
27
+
28
+ }
package/src/index.js CHANGED
@@ -1,23 +1,26 @@
1
- // core
2
- export * from './core/PathTracingRenderer.js';
3
- export * from './core/PathTracingSceneGenerator.js';
4
- export * from './core/DynamicPathTracingSceneGenerator.js';
5
- export * from './core/MaterialReducer.js';
6
- export * from './core/PhysicalCamera.js';
7
-
8
- // uniforms
9
- export * from './uniforms/MaterialStructArrayUniform.js';
10
- export * from './uniforms/MaterialStructUniform.js';
11
- export * from './uniforms/RenderTarget2DArray.js';
12
-
13
- // utils
14
- export * from './utils/GeometryPreparationUtils.js';
15
-
16
- // materials
17
- export * from './materials/MaterialBase.js';
18
- export * from './materials/PhysicalPathTracingMaterial.js';
19
-
20
- // shaders
21
- export * from './shader/shaderMaterialSampling.js';
22
- export * from './shader/shaderUtils.js';
23
- export * from './shader/shaderStructs.js';
1
+ // core
2
+ export * from './core/PathTracingRenderer.js';
3
+ export * from './core/PathTracingSceneGenerator.js';
4
+ export * from './core/DynamicPathTracingSceneGenerator.js';
5
+ export * from './core/MaterialReducer.js';
6
+ export * from './core/PhysicalCamera.js';
7
+ export * from './core/EquirectCamera.js';
8
+
9
+ // uniforms
10
+ export * from './uniforms/MaterialsTexture.js';
11
+ export * from './uniforms/RenderTarget2DArray.js';
12
+ export * from './uniforms/EquirectHdrInfoUniform.js';
13
+ export * from './uniforms/PhysicalCameraUniform.js';
14
+
15
+ // utils
16
+ export * from './utils/GeometryPreparationUtils.js';
17
+ export * from './utils/BlurredEnvMapGenerator.js';
18
+
19
+ // materials
20
+ export * from './materials/MaterialBase.js';
21
+ export * from './materials/PhysicalPathTracingMaterial.js';
22
+
23
+ // shaders
24
+ export * from './shader/shaderMaterialSampling.js';
25
+ export * from './shader/shaderUtils.js';
26
+ export * from './shader/shaderStructs.js';
@@ -0,0 +1,48 @@
1
+ import { NoBlending } from 'three';
2
+ import { MaterialBase } from './MaterialBase.js';
3
+
4
+ export class AlphaDisplayMaterial extends MaterialBase {
5
+
6
+ constructor( parameters ) {
7
+
8
+ super( {
9
+
10
+ uniforms: {
11
+
12
+ map: { value: null },
13
+
14
+ },
15
+
16
+ blending: NoBlending,
17
+
18
+ vertexShader: /* glsl */`
19
+
20
+ varying vec2 vUv;
21
+
22
+ void main() {
23
+
24
+ vUv = uv;
25
+ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
26
+
27
+ }`,
28
+
29
+ fragmentShader: /* glsl */`
30
+
31
+ uniform sampler2D map;
32
+
33
+ varying vec2 vUv;
34
+
35
+ void main() {
36
+
37
+ gl_FragColor = vec4( texture( map, vUv ).a );
38
+ gl_FragColor.a = 1.0;
39
+
40
+ }`
41
+
42
+ } );
43
+
44
+ this.setValues( parameters );
45
+
46
+ }
47
+
48
+ }