-
-
Notifications
You must be signed in to change notification settings - Fork 164
Expand file tree
/
Copy pathWebGPUPathTracer.js
More file actions
157 lines (96 loc) · 3.12 KB
/
WebGPUPathTracer.js
File metadata and controls
157 lines (96 loc) · 3.12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
import { Vector2, Scene, PerspectiveCamera } from 'three/webgpu';
import { MeshBVH, SAH } from 'three-mesh-bvh';
import { FullScreenQuad } from 'three/examples/jsm/postprocessing/Pass.js';
import { RenderToScreenNodeMaterial } from './materials/RenderToScreenMaterial.js';
import { MegaKernelPathTracer } from './MegaKernelPathTracer.js';
import { WaveFrontPathTracer } from './WaveFrontPathTracer.js';
import { ObjectBVH } from './lib/ObjectBVH.js';
import { PathtracerBVHComputeData } from './lib/PathtracerBVHComputeData.js';
const _resolution = new Vector2();
export class WebGPUPathTracer {
get bounces() {
return this._pathTracer.bounces;
}
set bounces( v ) {
this._pathTracer.bounces = v;
}
useMegakernel( value ) {
this._pathTracer.dispose();
this._pathTracer = value ? new MegaKernelPathTracer( this._renderer ) : new WaveFrontPathTracer( this._renderer );
this._pathTracer.setBVHData( this._bvhData );
this.setCamera( this.camera );
}
constructor( renderer ) {
// members
this._renderer = renderer;
this._pathTracer = new MegaKernelPathTracer( renderer );
// options
this.renderScale = 1;
this.synchronizeRenderSize = true;
this.renderToCanvas = true;
this._blitQuad = new FullScreenQuad( new RenderToScreenNodeMaterial() );
// initialize the scene so it doesn't fail
this.setScene( new Scene(), new PerspectiveCamera() );
}
setScene( scene, camera ) {
scene.updateMatrixWorld( true );
camera.updateMatrixWorld();
// Build BVH for each mesh geometry
scene.traverse( child => {
if ( child.isMesh && ! child.geometry.boundsTree ) {
child.geometry.boundsTree = new MeshBVH( child.geometry, { strategy: SAH, maxLeafSize: 5 } );
}
} );
// Build TLAS and compute functions
const objectBVH = new ObjectBVH( scene, { strategy: SAH } );
const bvhData = new PathtracerBVHComputeData( objectBVH );
bvhData.update();
this._bvhData = bvhData;
this._pathTracer.setBVHData( bvhData );
this.setCamera( camera );
}
setCamera( camera ) {
this.camera = camera;
this.updateCamera();
}
updateCamera() {
const camera = this.camera;
camera.updateMatrixWorld();
this._pathTracer.setCamera( camera );
this.reset();
}
reset() {
this._pathTracer.reset();
}
renderSample() {
if ( ! this._renderer._initialized ) {
return;
}
this._updateScale();
this._pathTracer.update();
const blitQuad = this._blitQuad;
blitQuad.material.texture = this._pathTracer.outputTarget;
blitQuad.render( this._renderer );
}
dispose() {
this._pathTracer.dispose();
}
_updateScale() {
// update the path tracer scale if it has changed
if ( this.synchronizeRenderSize ) {
this._renderer.getDrawingBufferSize( _resolution );
const w = Math.floor( this.renderScale * _resolution.x );
const h = Math.floor( this.renderScale * _resolution.y );
this._pathTracer.getSize( _resolution );
if ( _resolution.x !== w || _resolution.y !== h ) {
this._pathTracer.setSize( w, h );
}
}
}
getSampleCount() {
return this._pathTracer.samples;
}
async getLatestSampleTimestamp() {
return await this._pathTracer.getLatestSampleTimestamp();
}
}