three-gpu-pathtracer 0.0.23 → 0.0.24
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.
- package/README.md +6 -4
- package/build/index.module.js +57 -16
- package/build/index.module.js.map +1 -1
- package/build/index.umd.cjs +57 -16
- package/build/index.umd.cjs.map +1 -1
- package/package.json +13 -13
- package/src/core/PathTracingSceneGenerator.js +21 -2
- package/src/core/WebGLPathTracer.js +8 -7
- package/src/core/utils/mergeGeometries.js +14 -1
- package/src/index.d.ts +2 -1
- package/src/materials/pathtracing/PhysicalPathTracingMaterial.js +2 -1
- package/src/materials/pathtracing/glsl/attenuate_hit_function.glsl.js +2 -1
- package/src/materials/pathtracing/glsl/camera_util_functions.glsl.js +1 -1
- package/src/materials/pathtracing/glsl/get_surface_record_function.glsl.js +2 -1
- package/src/materials/surface/AmbientOcclusionMaterial.js +2 -0
- package/src/shader/bvh/inside_fog_volume_function.glsl.js +1 -1
- package/src/shader/structs/material_struct.glsl.js +3 -1
- package/src/uniforms/MaterialsTexture.js +4 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "three-gpu-pathtracer",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.24",
|
|
4
4
|
"description": "Path tracing renderer and utilities for three.js built on top of three-mesh-bvh.",
|
|
5
5
|
"module": "src/index.js",
|
|
6
6
|
"main": "build/index.umd.cjs",
|
|
@@ -30,35 +30,35 @@
|
|
|
30
30
|
"tracer"
|
|
31
31
|
],
|
|
32
32
|
"devDependencies": {
|
|
33
|
-
"@lookingglass/webxr": "^0.
|
|
33
|
+
"@lookingglass/webxr": "^0.6.0",
|
|
34
34
|
"@monogrid/gainmap-js": "^3.0.5",
|
|
35
|
-
"@types/node": "^
|
|
36
|
-
"@types/three": "^0.
|
|
37
|
-
"@typescript-eslint/
|
|
35
|
+
"@types/node": "^24.3.1",
|
|
36
|
+
"@types/three": "^0.181.0",
|
|
37
|
+
"@typescript-eslint/eslint-plugin": "^8.40.0",
|
|
38
38
|
"canvas-capture": "^2.0.5",
|
|
39
|
-
"eslint": "^
|
|
39
|
+
"eslint": "^8.56.0",
|
|
40
40
|
"eslint-config-mdcs": "^5.0.0",
|
|
41
41
|
"node-fetch": "^3.2.9",
|
|
42
|
-
"parcel": "^2.12.0",
|
|
43
42
|
"pixelmatch": "^5.3.0",
|
|
44
43
|
"pngjs": "^6.0.0",
|
|
45
44
|
"process": "^0.11.10",
|
|
46
45
|
"puppeteer": "^15.4.0",
|
|
47
46
|
"rollup": "^2.70.0",
|
|
48
47
|
"simple-git": "^3.10.0",
|
|
49
|
-
"three": "^0.
|
|
50
|
-
"three-mesh-bvh": "^0.
|
|
51
|
-
"typescript": "5.
|
|
48
|
+
"three": "^0.181.1",
|
|
49
|
+
"three-mesh-bvh": "^0.9.5",
|
|
50
|
+
"typescript": "^5.9.2",
|
|
51
|
+
"vite": "^6.2.2",
|
|
52
52
|
"yargs": "^17.5.1"
|
|
53
53
|
},
|
|
54
54
|
"peerDependencies": {
|
|
55
|
-
"three": ">=0.
|
|
55
|
+
"three": ">=0.180.0",
|
|
56
56
|
"three-mesh-bvh": ">=0.7.4",
|
|
57
57
|
"xatlas-web": "^0.1.0"
|
|
58
58
|
},
|
|
59
59
|
"scripts": {
|
|
60
|
-
"start": "
|
|
61
|
-
"build-examples": "
|
|
60
|
+
"start": "vite --config ./vite.config.js",
|
|
61
|
+
"build-examples": "vite build --config ./vite.config.js",
|
|
62
62
|
"update-screenshots": "node ./scripts/push-screenshots.js",
|
|
63
63
|
"screenshot-diff": "node ./scripts/regression-test.js",
|
|
64
64
|
"build": "rollup -c",
|
|
@@ -95,6 +95,7 @@ export class PathTracingSceneGenerator {
|
|
|
95
95
|
this._bvhWorker = null;
|
|
96
96
|
this._pendingGenerate = null;
|
|
97
97
|
this._buildAsync = false;
|
|
98
|
+
this._materialUuids = null;
|
|
98
99
|
|
|
99
100
|
}
|
|
100
101
|
|
|
@@ -176,12 +177,29 @@ export class PathTracingSceneGenerator {
|
|
|
176
177
|
// generate the geometry
|
|
177
178
|
const result = staticGeometryGenerator.generate( geometry );
|
|
178
179
|
const materials = result.materials;
|
|
180
|
+
let needsMaterialIndexUpdate = result.changeType !== NO_CHANGE || this._materialUuids === null || this._materialUuids.length !== length;
|
|
181
|
+
if ( ! needsMaterialIndexUpdate ) {
|
|
182
|
+
|
|
183
|
+
for ( let i = 0, length = materials.length; i < length; i ++ ) {
|
|
184
|
+
|
|
185
|
+
const material = materials[ i ];
|
|
186
|
+
if ( material.uuid !== this._materialUuids[ i ] ) {
|
|
187
|
+
|
|
188
|
+
needsMaterialIndexUpdate = true;
|
|
189
|
+
break;
|
|
190
|
+
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
}
|
|
196
|
+
|
|
179
197
|
const textures = getTextures( materials );
|
|
180
198
|
const { lights, iesTextures } = getLights( objects );
|
|
181
|
-
|
|
182
|
-
if ( result.changeType !== NO_CHANGE ) {
|
|
199
|
+
if ( needsMaterialIndexUpdate ) {
|
|
183
200
|
|
|
184
201
|
updateMaterialIndexAttribute( geometry, materials, materials );
|
|
202
|
+
this._materialUuids = materials.map( material => material.uuid );
|
|
185
203
|
|
|
186
204
|
}
|
|
187
205
|
|
|
@@ -225,6 +243,7 @@ export class PathTracingSceneGenerator {
|
|
|
225
243
|
return {
|
|
226
244
|
bvhChanged: result.changeType !== NO_CHANGE,
|
|
227
245
|
bvh: this.bvh,
|
|
246
|
+
needsMaterialIndexUpdate,
|
|
228
247
|
lights,
|
|
229
248
|
iesTextures,
|
|
230
249
|
geometry,
|
|
@@ -306,7 +306,7 @@ export class WebGLPathTracer {
|
|
|
306
306
|
}
|
|
307
307
|
|
|
308
308
|
// update scene environment
|
|
309
|
-
material.environmentIntensity = scene.environmentIntensity ?? 1;
|
|
309
|
+
material.environmentIntensity = scene.environment !== null ? ( scene.environmentIntensity ?? 1 ) : 0;
|
|
310
310
|
material.environmentRotation.makeRotationFromEuler( scene.environmentRotation ).invert();
|
|
311
311
|
if ( this._previousEnvironment !== scene.environment ) {
|
|
312
312
|
|
|
@@ -326,10 +326,6 @@ export class WebGLPathTracer {
|
|
|
326
326
|
|
|
327
327
|
}
|
|
328
328
|
|
|
329
|
-
} else {
|
|
330
|
-
|
|
331
|
-
material.environmentIntensity = 0;
|
|
332
|
-
|
|
333
329
|
}
|
|
334
330
|
|
|
335
331
|
}
|
|
@@ -347,6 +343,7 @@ export class WebGLPathTracer {
|
|
|
347
343
|
geometry,
|
|
348
344
|
bvh,
|
|
349
345
|
bvhChanged,
|
|
346
|
+
needsMaterialIndexUpdate,
|
|
350
347
|
} = results;
|
|
351
348
|
|
|
352
349
|
this._materials = materials;
|
|
@@ -364,6 +361,10 @@ export class WebGLPathTracer {
|
|
|
364
361
|
geometry.attributes.color,
|
|
365
362
|
);
|
|
366
363
|
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
if ( needsMaterialIndexUpdate ) {
|
|
367
|
+
|
|
367
368
|
material.materialIndexAttribute.updateFrom( geometry.attributes.materialIndex );
|
|
368
369
|
|
|
369
370
|
}
|
|
@@ -494,8 +495,8 @@ export class WebGLPathTracer {
|
|
|
494
495
|
|
|
495
496
|
dispose() {
|
|
496
497
|
|
|
497
|
-
this.
|
|
498
|
-
this.
|
|
498
|
+
this._quad.dispose();
|
|
499
|
+
this._quad.material.dispose();
|
|
499
500
|
this._pathTracer.dispose();
|
|
500
501
|
|
|
501
502
|
}
|
|
@@ -205,7 +205,20 @@ export function mergeGeometries( geometries, options = {}, targetGeometry = new
|
|
|
205
205
|
const attr = geometry.getAttribute( key );
|
|
206
206
|
if ( ! skip ) {
|
|
207
207
|
|
|
208
|
-
|
|
208
|
+
if ( key === 'color' && targetAttribute.itemSize !== attr.itemSize ) {
|
|
209
|
+
|
|
210
|
+
// make sure the color attribute is aligned with itemSize 3 to 4
|
|
211
|
+
for ( let index = offset, l = attr.count; index < l; index ++ ) {
|
|
212
|
+
|
|
213
|
+
attr.setXYZW( index, targetAttribute.getX( index ), targetAttribute.getY( index ), targetAttribute.getZ( index ), 1.0 );
|
|
214
|
+
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
} else {
|
|
218
|
+
|
|
219
|
+
copyAttributeContents( attr, targetAttribute, offset );
|
|
220
|
+
|
|
221
|
+
}
|
|
209
222
|
|
|
210
223
|
}
|
|
211
224
|
|
package/src/index.d.ts
CHANGED
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
Scene,
|
|
22
22
|
PMREMGenerator
|
|
23
23
|
} from 'three';
|
|
24
|
-
import { FullScreenQuad } from 'three/examples/jsm/postprocessing/Pass';
|
|
24
|
+
import { FullScreenQuad } from 'three/examples/jsm/postprocessing/Pass.js';
|
|
25
25
|
import { MeshBVH, MeshBVHOptions } from 'three-mesh-bvh';
|
|
26
26
|
|
|
27
27
|
// three.js type augmentation
|
|
@@ -57,6 +57,7 @@ export interface PathTracingSceneGeneratorResult {
|
|
|
57
57
|
lights: Array<Light>;
|
|
58
58
|
iesTextures: Array<DataTexture>;
|
|
59
59
|
geometry: BufferGeometry;
|
|
60
|
+
needsMaterialIndexUpdate: boolean;
|
|
60
61
|
materials: Array<Material>;
|
|
61
62
|
textures: Array<Texture>;
|
|
62
63
|
objects: Array<Object3D>;
|
|
@@ -10,7 +10,7 @@ import { PhysicalCameraUniform } from '../../uniforms/PhysicalCameraUniform.js';
|
|
|
10
10
|
import { EquirectHdrInfoUniform } from '../../uniforms/EquirectHdrInfoUniform.js';
|
|
11
11
|
import { LightsInfoUniformStruct } from '../../uniforms/LightsInfoUniformStruct.js';
|
|
12
12
|
import { AttributesTextureArray } from '../../uniforms/AttributesTextureArray.js';
|
|
13
|
-
import { MaterialsTexture } from '../../uniforms/MaterialsTexture.js';
|
|
13
|
+
import { MaterialsTexture, MATERIAL_PIXELS } from '../../uniforms/MaterialsTexture.js';
|
|
14
14
|
import { RenderTarget2DArray } from '../../uniforms/RenderTarget2DArray.js';
|
|
15
15
|
import { StratifiedSamplesTexture } from '../../uniforms/StratifiedSamplesTexture.js';
|
|
16
16
|
import { BlueNoiseTexture } from '../../textures/BlueNoiseTexture.js';
|
|
@@ -66,6 +66,7 @@ export class PhysicalPathTracingMaterial extends MaterialBase {
|
|
|
66
66
|
ATTR_TANGENT: 1,
|
|
67
67
|
ATTR_UV: 2,
|
|
68
68
|
ATTR_COLOR: 3,
|
|
69
|
+
MATERIAL_PIXELS: MATERIAL_PIXELS,
|
|
69
70
|
},
|
|
70
71
|
|
|
71
72
|
uniforms: {
|
|
@@ -97,7 +97,8 @@ export const attenuate_hit_function = /* glsl */`
|
|
|
97
97
|
// alphaMap
|
|
98
98
|
if ( material.alphaMap != - 1 ) {
|
|
99
99
|
|
|
100
|
-
|
|
100
|
+
vec3 uvPrime = material.alphaMapTransform * vec3( uv, 1 );
|
|
101
|
+
albedo.a *= texture2D( textures, vec3( uvPrime.xy, material.alphaMap ) ).x;
|
|
101
102
|
|
|
102
103
|
}
|
|
103
104
|
|
|
@@ -60,7 +60,7 @@ export const camera_util_functions = /* glsl */`
|
|
|
60
60
|
vec3 shapeUVW= rand3( 1 );
|
|
61
61
|
int blades = physicalCamera.apertureBlades;
|
|
62
62
|
float anamorphicRatio = physicalCamera.anamorphicRatio;
|
|
63
|
-
vec2 apertureSample =
|
|
63
|
+
vec2 apertureSample = sampleAperture( blades, shapeUVW );
|
|
64
64
|
apertureSample *= physicalCamera.bokehSize * 0.5 * 1e-3;
|
|
65
65
|
|
|
66
66
|
// rotate the aperture shape
|
|
@@ -48,7 +48,8 @@ export const get_surface_record_function = /* glsl */`
|
|
|
48
48
|
// alphaMap
|
|
49
49
|
if ( material.alphaMap != - 1 ) {
|
|
50
50
|
|
|
51
|
-
|
|
51
|
+
vec3 uvPrime = material.alphaMapTransform * vec3( uv, 1 );
|
|
52
|
+
albedo.a *= texture2D( textures, vec3( uvPrime.xy, material.alphaMap ) ).x;
|
|
52
53
|
|
|
53
54
|
}
|
|
54
55
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { TangentSpaceNormalMap, Vector2 } from 'three';
|
|
2
2
|
import { MaterialBase } from '../MaterialBase.js';
|
|
3
3
|
import { MeshBVHUniformStruct, BVHShaderGLSL } from 'three-mesh-bvh';
|
|
4
|
+
import { MATERIAL_PIXELS } from '../../uniforms/MaterialsTexture.js';
|
|
4
5
|
|
|
5
6
|
import * as StructsGLSL from '../../shader/structs/index.js';
|
|
6
7
|
import * as SamplingGLSL from '../../shader/sampling/index.js';
|
|
@@ -43,6 +44,7 @@ export class AmbientOcclusionMaterial extends MaterialBase {
|
|
|
43
44
|
|
|
44
45
|
defines: {
|
|
45
46
|
SAMPLES: 10,
|
|
47
|
+
MATERIAL_PIXELS: MATERIAL_PIXELS,
|
|
46
48
|
},
|
|
47
49
|
|
|
48
50
|
uniforms: {
|
|
@@ -7,7 +7,7 @@ export const inside_fog_volume_function = /* glsl */`
|
|
|
7
7
|
// returns whether the given material is a fog material or not
|
|
8
8
|
bool isMaterialFogVolume( sampler2D materials, uint materialIndex ) {
|
|
9
9
|
|
|
10
|
-
uint i = materialIndex *
|
|
10
|
+
uint i = materialIndex * uint( MATERIAL_PIXELS );
|
|
11
11
|
vec4 s14 = texelFetch1D( materials, i + 14u );
|
|
12
12
|
return bool( int( s14.b ) & 4 );
|
|
13
13
|
|
|
@@ -81,6 +81,7 @@ export const material_struct = /* glsl */ `
|
|
|
81
81
|
mat3 iridescenceThicknessMapTransform;
|
|
82
82
|
mat3 specularColorMapTransform;
|
|
83
83
|
mat3 specularIntensityMapTransform;
|
|
84
|
+
mat3 alphaMapTransform;
|
|
84
85
|
|
|
85
86
|
};
|
|
86
87
|
|
|
@@ -101,7 +102,7 @@ export const material_struct = /* glsl */ `
|
|
|
101
102
|
|
|
102
103
|
Material readMaterialInfo( sampler2D tex, uint index ) {
|
|
103
104
|
|
|
104
|
-
uint i = index *
|
|
105
|
+
uint i = index * uint( MATERIAL_PIXELS );
|
|
105
106
|
|
|
106
107
|
vec4 s0 = texelFetch1D( tex, i + 0u );
|
|
107
108
|
vec4 s1 = texelFetch1D( tex, i + 1u );
|
|
@@ -200,6 +201,7 @@ export const material_struct = /* glsl */ `
|
|
|
200
201
|
m.iridescenceThicknessMapTransform = m.iridescenceThicknessMap == - 1 ? mat3( 1.0 ) : readTextureTransform( tex, firstTextureTransformIdx + 24u );
|
|
201
202
|
m.specularColorMapTransform = m.specularColorMap == - 1 ? mat3( 1.0 ) : readTextureTransform( tex, firstTextureTransformIdx + 26u );
|
|
202
203
|
m.specularIntensityMapTransform = m.specularIntensityMap == - 1 ? mat3( 1.0 ) : readTextureTransform( tex, firstTextureTransformIdx + 28u );
|
|
204
|
+
m.alphaMapTransform = m.alphaMap == - 1 ? mat3( 1.0 ) : readTextureTransform( tex, firstTextureTransformIdx + 30u );
|
|
203
205
|
|
|
204
206
|
return m;
|
|
205
207
|
|
|
@@ -2,7 +2,7 @@ import { DataTexture, RGBAFormat, ClampToEdgeWrapping, FloatType, FrontSide, Bac
|
|
|
2
2
|
import { getTextureHash } from '../core/utils/sceneUpdateUtils.js';
|
|
3
3
|
import { bufferToHash } from '../utils/bufferToHash.js';
|
|
4
4
|
|
|
5
|
-
const MATERIAL_PIXELS =
|
|
5
|
+
export const MATERIAL_PIXELS = 47;
|
|
6
6
|
const MATERIAL_STRIDE = MATERIAL_PIXELS * 4;
|
|
7
7
|
|
|
8
8
|
class MaterialFeatures {
|
|
@@ -427,6 +427,9 @@ export class MaterialsTexture extends DataTexture {
|
|
|
427
427
|
// specularIntensityMap transform 43
|
|
428
428
|
index += writeTextureMatrixToArray( m, 'specularIntensityMap', floatArray, index );
|
|
429
429
|
|
|
430
|
+
// alphaMap transform 45
|
|
431
|
+
index += writeTextureMatrixToArray( m, 'alphaMap', floatArray, index );
|
|
432
|
+
|
|
430
433
|
}
|
|
431
434
|
|
|
432
435
|
// check if the contents have changed
|