three-gpu-pathtracer 0.0.1 → 0.0.4

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 (36) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +678 -386
  3. package/build/index.module.js +3166 -1690
  4. package/build/index.module.js.map +1 -1
  5. package/build/index.umd.cjs +3176 -1692
  6. package/build/index.umd.cjs.map +1 -1
  7. package/package.json +60 -57
  8. package/src/core/DynamicPathTracingSceneGenerator.js +106 -0
  9. package/src/core/MaterialReducer.js +256 -256
  10. package/src/core/PathTracingRenderer.js +125 -28
  11. package/src/core/PathTracingSceneGenerator.js +52 -46
  12. package/src/core/PhysicalCamera.js +28 -0
  13. package/src/index.js +25 -21
  14. package/src/materials/AlphaDisplayMaterial.js +48 -0
  15. package/src/materials/AmbientOcclusionMaterial.js +197 -197
  16. package/src/materials/BlendMaterial.js +67 -0
  17. package/src/materials/LambertPathTracingMaterial.js +285 -285
  18. package/src/materials/MaterialBase.js +56 -56
  19. package/src/materials/PhysicalPathTracingMaterial.js +684 -370
  20. package/src/shader/shaderEnvMapSampling.js +67 -0
  21. package/src/shader/shaderGGXFunctions.js +108 -107
  22. package/src/shader/shaderMaterialSampling.js +345 -333
  23. package/src/shader/shaderStructs.js +131 -30
  24. package/src/shader/shaderUtils.js +246 -140
  25. package/src/uniforms/EquirectHdrInfoUniform.js +263 -0
  26. package/src/uniforms/MaterialsTexture.js +251 -0
  27. package/src/uniforms/PhysicalCameraUniform.js +36 -0
  28. package/src/uniforms/RenderTarget2DArray.js +93 -80
  29. package/src/utils/BlurredEnvMapGenerator.js +113 -0
  30. package/src/utils/GeometryPreparationUtils.js +194 -172
  31. package/src/utils/UVUnwrapper.js +101 -101
  32. package/src/workers/PathTracingSceneWorker.js +40 -0
  33. package/src/uniforms/EquirectPdfUniform.js +0 -132
  34. package/src/uniforms/MaterialStructArrayUniform.js +0 -18
  35. package/src/uniforms/MaterialStructUniform.js +0 -94
  36. package/src/viewers/PathTracingViewer.js +0 -259
@@ -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;
11
33
 
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();
34
+ }
35
+
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;
@@ -28,12 +48,15 @@ function* renderTask() {
28
48
 
29
49
  material.cameraWorldMatrix.copy( camera.matrixWorld );
30
50
  material.invProjectionMatrix.copy( camera.projectionMatrixInverse );
51
+ // An orthographic projection matrix will always have the bottom right element == 1
52
+ // And a perspective projection matrix will always have the bottom right element == 0
53
+ material.isOrthographicCamera = camera.projectionMatrix.elements[ 15 ] > 0;
31
54
 
32
55
  const ogRenderTarget = _renderer.getRenderTarget();
33
56
  const ogAutoClear = _renderer.autoClear;
34
57
 
35
58
  // three.js renderer takes values relative to the current pixel ratio
36
- _renderer.setRenderTarget( target );
59
+ _renderer.setRenderTarget( _primaryTarget );
37
60
  _renderer.setScissorTest( true );
38
61
  _renderer.setScissor(
39
62
  dprInv * Math.ceil( x * w / tx ),
@@ -47,6 +70,17 @@ function* renderTask() {
47
70
  _renderer.setRenderTarget( ogRenderTarget );
48
71
  _renderer.autoClear = ogAutoClear;
49
72
 
73
+ if ( alpha ) {
74
+
75
+ blendMaterial.target1 = blendTarget1.texture;
76
+ blendMaterial.target2 = _primaryTarget.texture;
77
+
78
+ _renderer.setRenderTarget( blendTarget2 );
79
+ _blendQuad.render( _renderer );
80
+ _renderer.setRenderTarget( ogRenderTarget );
81
+
82
+ }
83
+
50
84
  this.samples += ( 1 / totalTiles );
51
85
 
52
86
  yield;
@@ -55,6 +89,8 @@ function* renderTask() {
55
89
 
56
90
  }
57
91
 
92
+ [ blendTarget1, blendTarget2 ] = [ blendTarget2, blendTarget1 ];
93
+
58
94
  this.samples = Math.round( this.samples );
59
95
 
60
96
  }
@@ -76,43 +112,104 @@ export class PathTracingRenderer {
76
112
 
77
113
  }
78
114
 
115
+ get target() {
116
+
117
+ return this._alpha ? this._blendTargets[ 1 ] : this._primaryTarget;
118
+
119
+ }
120
+
121
+ set alpha( v ) {
122
+
123
+ if ( ! v ) {
124
+
125
+ this._blendTargets[ 0 ].dispose();
126
+ this._blendTargets[ 1 ].dispose();
127
+
128
+ }
129
+
130
+ this._alpha = v;
131
+ this.reset();
132
+
133
+ }
134
+
135
+ get alpha() {
136
+
137
+ return this._alpha;
138
+
139
+ }
140
+
79
141
  constructor( renderer ) {
80
142
 
81
143
  this.camera = null;
82
144
  this.tiles = new Vector2( 1, 1 );
83
- this.target = new WebGLRenderTarget( 1, 1, {
84
- format: RGBAFormat,
85
- type: FloatType,
86
- } );
145
+
87
146
  this.samples = 0;
88
147
  this.stableNoise = false;
89
148
  this._renderer = renderer;
149
+ this._alpha = false;
90
150
  this._fsQuad = new FullScreenQuad( null );
151
+ this._blendQuad = new FullScreenQuad( new BlendMaterial() );
91
152
  this._task = null;
92
153
 
154
+ this._primaryTarget = new WebGLRenderTarget( 1, 1, {
155
+ format: RGBAFormat,
156
+ type: FloatType,
157
+ } );
158
+ this._blendTargets = [
159
+ new WebGLRenderTarget( 1, 1, {
160
+ format: RGBAFormat,
161
+ type: FloatType,
162
+ } ),
163
+ new WebGLRenderTarget( 1, 1, {
164
+ format: RGBAFormat,
165
+ type: FloatType,
166
+ } ),
167
+ ];
168
+
93
169
  }
94
170
 
95
171
  setSize( w, h ) {
96
172
 
97
- this.target.setSize( w, h );
173
+ this._primaryTarget.setSize( w, h );
174
+ this._blendTargets[ 0 ].setSize( w, h );
175
+ this._blendTargets[ 1 ].setSize( w, h );
98
176
  this.reset();
99
177
 
100
178
  }
101
179
 
180
+ dispose() {
181
+
182
+ this._primaryTarget.dispose();
183
+ this._blendTargets[ 0 ].dispose();
184
+ this._blendTargets[ 1 ].dispose();
185
+
186
+ this._fsQuad.dispose();
187
+ this._blendQuad.dispose();
188
+ this._task = null;
189
+
190
+ }
191
+
102
192
  reset() {
103
193
 
104
- const renderer = this._renderer;
105
- const target = this.target;
106
- const ogRenderTarget = renderer.getRenderTarget();
107
- const ogClearAlpha = renderer.getClearAlpha();
108
- renderer.getClearColor( ogClearColor );
194
+ const { _renderer, _primaryTarget, _blendTargets } = this;
195
+ const ogRenderTarget = _renderer.getRenderTarget();
196
+ const ogClearAlpha = _renderer.getClearAlpha();
197
+ _renderer.getClearColor( ogClearColor );
198
+
199
+ _renderer.setRenderTarget( _primaryTarget );
200
+ _renderer.setClearColor( 0, 0 );
201
+ _renderer.clearColor();
202
+
203
+ _renderer.setRenderTarget( _blendTargets[ 0 ] );
204
+ _renderer.setClearColor( 0, 0 );
205
+ _renderer.clearColor();
109
206
 
110
- renderer.setRenderTarget( target );
111
- renderer.setClearColor( 0, 0 );
112
- renderer.clearColor();
207
+ _renderer.setRenderTarget( _blendTargets[ 1 ] );
208
+ _renderer.setClearColor( 0, 0 );
209
+ _renderer.clearColor();
113
210
 
114
- renderer.setClearColor( ogClearColor, ogClearAlpha );
115
- renderer.setRenderTarget( ogRenderTarget );
211
+ _renderer.setClearColor( ogClearColor, ogClearAlpha );
212
+ _renderer.setRenderTarget( ogRenderTarget );
116
213
 
117
214
  this.samples = 0;
118
215
  this._task = null;
@@ -1,46 +1,52 @@
1
- import { SAH } from 'three-mesh-bvh';
2
- import { GenerateMeshBVHWorker } from 'three-mesh-bvh/src/workers/GenerateMeshBVHWorker.js';
3
- import { mergeMeshes } from '../utils/GeometryPreparationUtils.js';
4
-
5
- export class PathTracingSceneGenerator {
6
-
7
- constructor() {
8
-
9
- this.bvhGenerator = new GenerateMeshBVHWorker();
10
-
11
- }
12
-
13
- async generate( scene, options = {} ) {
14
-
15
- const { bvhGenerator } = this;
16
- const meshes = [];
17
-
18
- scene.traverse( c => {
19
-
20
- if ( c.isMesh ) {
21
-
22
- meshes.push( c );
23
-
24
- }
25
-
26
- } );
27
-
28
- const { geometry, materials, textures } = mergeMeshes( meshes, { attributes: [ 'position', 'normal', 'tangent', 'uv' ] } );
29
- const bvhPromise = bvhGenerator.generate( geometry, { strategy: SAH, ...options, maxLeafTris: 1 } );
30
-
31
- return {
32
- scene,
33
- materials,
34
- textures,
35
- bvh: await bvhPromise,
36
- };
37
-
38
- }
39
-
40
- dispose() {
41
-
42
- this.bvhGenerator.terminate();
43
-
44
- }
45
-
46
- }
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
+ }
@@ -0,0 +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
+ }
package/src/index.js CHANGED
@@ -1,21 +1,25 @@
1
- // core
2
- export * from './core/PathTracingRenderer.js';
3
- export * from './core/PathTracingSceneGenerator.js';
4
- export * from './core/MaterialReducer.js';
5
-
6
- // uniforms
7
- export * from './uniforms/MaterialStructArrayUniform.js';
8
- export * from './uniforms/MaterialStructUniform.js';
9
- export * from './uniforms/RenderTarget2DArray.js';
10
-
11
- // utils
12
- export * from './utils/GeometryPreparationUtils.js';
13
-
14
- // materials
15
- export * from './materials/MaterialBase.js';
16
- export * from './materials/PhysicalPathTracingMaterial.js';
17
-
18
- // shaders
19
- export * from './shader/shaderMaterialSampling.js';
20
- export * from './shader/shaderUtils.js';
21
- 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
+
8
+ // uniforms
9
+ export * from './uniforms/MaterialsTexture.js';
10
+ export * from './uniforms/RenderTarget2DArray.js';
11
+ export * from './uniforms/EquirectHdrInfoUniform.js';
12
+ export * from './uniforms/PhysicalCameraUniform.js';
13
+
14
+ // utils
15
+ export * from './utils/GeometryPreparationUtils.js';
16
+ export * from './utils/BlurredEnvMapGenerator.js';
17
+
18
+ // materials
19
+ export * from './materials/MaterialBase.js';
20
+ export * from './materials/PhysicalPathTracingMaterial.js';
21
+
22
+ // shaders
23
+ export * from './shader/shaderMaterialSampling.js';
24
+ export * from './shader/shaderUtils.js';
25
+ 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
+ }