@woosh/meep-engine 2.109.4 → 2.109.6
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/build/meep.cjs +115 -17
- package/build/meep.min.js +1 -1
- package/build/meep.module.js +115 -17
- package/package.json +1 -1
- package/src/core/collection/queue/Deque.d.ts.map +1 -1
- package/src/core/collection/queue/Deque.js +58 -4
- package/src/core/collection/queue/Deque.spec.js +29 -0
- package/src/core/geom/3d/Ray3.d.ts +23 -10
- package/src/core/geom/3d/Ray3.d.ts.map +1 -1
- package/src/core/geom/3d/Ray3.js +59 -20
- package/src/core/geom/3d/ray/ray3_interval_array_apply_matrix4.d.ts +2 -2
- package/src/core/geom/3d/ray/ray3_interval_array_apply_matrix4.d.ts.map +1 -1
- package/src/core/geom/3d/ray/ray3_interval_array_apply_matrix4.js +42 -27
- package/src/core/geom/3d/tetrahedra/triangle/prototype.js +0 -2
- package/src/core/geom/3d/tetrahedra/triangle/trace_triangular_depth_map.d.ts.map +1 -1
- package/src/core/geom/3d/tetrahedra/triangle/trace_triangular_depth_map.js +5 -2
- package/src/core/geom/vec3/v3_matrix4_rotate.d.ts +10 -0
- package/src/core/geom/vec3/v3_matrix4_rotate.d.ts.map +1 -0
- package/src/core/geom/vec3/v3_matrix4_rotate.js +27 -0
- package/src/engine/graphics/sh3/lpv/PathTracerProbeRenderer.d.ts +1 -0
- package/src/engine/graphics/sh3/lpv/PathTracerProbeRenderer.d.ts.map +1 -1
- package/src/engine/graphics/sh3/lpv/PathTracerProbeRenderer.js +5 -3
- package/src/engine/graphics/sh3/lpv/sh3_bake_depth.d.ts.map +1 -1
- package/src/engine/graphics/sh3/lpv/sh3_bake_depth.js +2 -1
- package/src/engine/graphics/sh3/path_tracer/BufferedGeometryBVH.d.ts +9 -4
- package/src/engine/graphics/sh3/path_tracer/BufferedGeometryBVH.d.ts.map +1 -1
- package/src/engine/graphics/sh3/path_tracer/BufferedGeometryBVH.js +61 -6
- package/src/engine/graphics/sh3/path_tracer/PathTracedMesh.d.ts +11 -4
- package/src/engine/graphics/sh3/path_tracer/PathTracedMesh.d.ts.map +1 -1
- package/src/engine/graphics/sh3/path_tracer/PathTracedMesh.js +28 -36
- package/src/engine/graphics/sh3/path_tracer/PathTracedScene.d.ts +17 -8
- package/src/engine/graphics/sh3/path_tracer/PathTracedScene.d.ts.map +1 -1
- package/src/engine/graphics/sh3/path_tracer/PathTracedScene.js +83 -44
- package/src/engine/graphics/sh3/path_tracer/PathTracer.d.ts +3 -3
- package/src/engine/graphics/sh3/path_tracer/PathTracer.d.ts.map +1 -1
- package/src/engine/graphics/sh3/path_tracer/PathTracer.js +40 -33
- package/src/engine/graphics/sh3/path_tracer/material/MaterialConverter.d.ts.map +1 -1
- package/src/engine/graphics/sh3/path_tracer/material/MaterialConverter.js +43 -40
- package/src/engine/graphics/sh3/path_tracer/material/StandardMaterial.d.ts +14 -0
- package/src/engine/graphics/sh3/path_tracer/material/StandardMaterial.d.ts.map +1 -1
- package/src/engine/graphics/sh3/path_tracer/material/StandardMaterial.js +34 -1
- package/src/engine/graphics/sh3/path_tracer/prepare_scene_gltf.d.ts +21 -0
- package/src/engine/graphics/sh3/path_tracer/prepare_scene_gltf.d.ts.map +1 -0
- package/src/engine/graphics/sh3/path_tracer/prepare_scene_gltf.js +107 -0
- package/src/engine/graphics/sh3/path_tracer/prototypePathTracer.js +22 -122
- package/src/engine/graphics/sh3/path_tracer/ray_hit_apply_transform.d.ts +0 -9
- package/src/engine/graphics/sh3/path_tracer/ray_hit_apply_transform.d.ts.map +1 -1
- package/src/engine/graphics/sh3/path_tracer/ray_hit_apply_transform.js +2 -28
- package/src/engine/graphics/sh3/path_tracer/sampling/getBiasedNormalSample.d.ts +0 -9
- package/src/engine/graphics/sh3/path_tracer/sampling/getBiasedNormalSample.d.ts.map +1 -1
- package/src/engine/graphics/sh3/path_tracer/sampling/getBiasedNormalSample.js +0 -39
- package/src/engine/graphics/sh3/path_tracer/sampling/getCosineDirection.d.ts +10 -0
- package/src/engine/graphics/sh3/path_tracer/sampling/getCosineDirection.d.ts.map +1 -0
- package/src/engine/graphics/sh3/path_tracer/sampling/getCosineDirection.js +41 -0
- package/src/engine/graphics/sh3/path_tracer/sampling/v3_orthonormal_matrix_from_normal.d.ts +10 -0
- package/src/engine/graphics/sh3/path_tracer/sampling/v3_orthonormal_matrix_from_normal.d.ts.map +1 -0
- package/src/engine/graphics/sh3/path_tracer/sampling/v3_orthonormal_matrix_from_normal.js +45 -0
- package/src/engine/graphics/sh3/path_tracer/texture/sample_material.d.ts.map +1 -1
- package/src/engine/graphics/sh3/path_tracer/texture/sample_material.js +28 -8
- package/src/engine/graphics/sh3/prototypeSH3Probe.js +7 -5
- package/src/engine/graphics/texture/sampler/convertTexture2Sampler2D.d.ts.map +1 -1
- package/src/engine/graphics/texture/sampler/convertTexture2Sampler2D.js +62 -13
- package/src/engine/graphics/texture/virtual/prototype.js +4 -3
- package/src/engine/graphics/three/material/iterate_three_material_textures.d.ts +10 -0
- package/src/engine/graphics/three/material/iterate_three_material_textures.d.ts.map +1 -0
- package/src/engine/graphics/three/material/iterate_three_material_textures.js +33 -0
- package/src/core/math/max4.d.ts +0 -10
- package/src/core/math/max4.d.ts.map +0 -1
- package/src/core/math/max4.js +0 -24
- package/src/core/math/min4.d.ts +0 -10
- package/src/core/math/min4.d.ts.map +0 -1
- package/src/core/math/min4.js +0 -23
|
@@ -9,6 +9,7 @@ import { strictEquals } from "../../../../core/function/strictEquals.js";
|
|
|
9
9
|
import { AABB3 } from "../../../../core/geom/3d/aabb/AABB3.js";
|
|
10
10
|
import { v3_morton_encode_bounded } from "../../../../core/geom/3d/morton/v3_morton_encode_bounded.js";
|
|
11
11
|
import { ray3_array_compose } from "../../../../core/geom/3d/ray/ray3_array_compose.js";
|
|
12
|
+
import { Ray3 } from "../../../../core/geom/3d/Ray3.js";
|
|
12
13
|
import { v3_dot } from "../../../../core/geom/vec3/v3_dot.js";
|
|
13
14
|
import { max2 } from "../../../../core/math/max2.js";
|
|
14
15
|
import { compute_geometry_polycount } from "../../geometry/compute_geometry_polycount.js";
|
|
@@ -25,24 +26,10 @@ import { sample_material } from "./texture/sample_material.js";
|
|
|
25
26
|
*/
|
|
26
27
|
const scratch_uint32_array = new Uint32Array(4096);
|
|
27
28
|
|
|
28
|
-
const _ray_1 =
|
|
29
|
-
const tmp_0 = new Float64Array(11);
|
|
30
|
-
const null_output = [];
|
|
29
|
+
const _ray_1 = new Ray3();
|
|
31
30
|
|
|
32
31
|
const DEFAULT_CONVERTER = new MaterialConverter();
|
|
33
32
|
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
*
|
|
37
|
-
* @param {Uint32Array} result
|
|
38
|
-
* @param {number} result_offset
|
|
39
|
-
* @param {number} count
|
|
40
|
-
* @param {BVH} bvh
|
|
41
|
-
*/
|
|
42
|
-
function bvh_build_query_cache(result, result_offset, count, bvh) {
|
|
43
|
-
|
|
44
|
-
}
|
|
45
|
-
|
|
46
33
|
export class PathTracedScene {
|
|
47
34
|
|
|
48
35
|
|
|
@@ -183,10 +170,6 @@ export class PathTracedScene {
|
|
|
183
170
|
this.#rebuild_bvh();
|
|
184
171
|
}
|
|
185
172
|
|
|
186
|
-
async build() {
|
|
187
|
-
|
|
188
|
-
}
|
|
189
|
-
|
|
190
173
|
/**
|
|
191
174
|
*
|
|
192
175
|
* @param {THREE.BufferGeometry} geo
|
|
@@ -289,6 +272,15 @@ export class PathTracedScene {
|
|
|
289
272
|
return true;
|
|
290
273
|
}
|
|
291
274
|
|
|
275
|
+
/**
|
|
276
|
+
* Retrieves pre-cached material or build one from scratch, caches it and returns the result
|
|
277
|
+
* @param {THREE.Material} material
|
|
278
|
+
* @returns {StandardMaterial}
|
|
279
|
+
*/
|
|
280
|
+
obtainMaterial(material) {
|
|
281
|
+
return this.#material_cache.getOrCompute(material, DEFAULT_CONVERTER.convert, DEFAULT_CONVERTER);
|
|
282
|
+
}
|
|
283
|
+
|
|
292
284
|
/**
|
|
293
285
|
*
|
|
294
286
|
* @param {THREE.BufferGeometry} geometry
|
|
@@ -296,7 +288,7 @@ export class PathTracedScene {
|
|
|
296
288
|
* @param {mat4|number[]} transform
|
|
297
289
|
*/
|
|
298
290
|
createMesh(geometry, material, transform) {
|
|
299
|
-
const standard_material = this
|
|
291
|
+
const standard_material = this.obtainMaterial(material);
|
|
300
292
|
|
|
301
293
|
const mesh = new PathTracedMesh();
|
|
302
294
|
mesh.geometry = geometry;
|
|
@@ -312,8 +304,9 @@ export class PathTracedScene {
|
|
|
312
304
|
*
|
|
313
305
|
* @param {number[]} out [color_r, color_g, color_b, normal_x, normal_y, normal_z]
|
|
314
306
|
* @param {number[]} hit
|
|
307
|
+
* @param {Ray3} incoming_ray
|
|
315
308
|
*/
|
|
316
|
-
sample_material(out, hit) {
|
|
309
|
+
sample_material(out, hit, incoming_ray) {
|
|
317
310
|
const primitive_id = hit[9];
|
|
318
311
|
const instance_id = hit[10];
|
|
319
312
|
const u = hit[7];
|
|
@@ -336,17 +329,65 @@ export class PathTracedScene {
|
|
|
336
329
|
|
|
337
330
|
sample_material(out, mesh, primitive_id, u, v);
|
|
338
331
|
|
|
332
|
+
// const pdf = mesh.material.scattering_pdf(
|
|
333
|
+
// incoming_ray[3],incoming_ray[4],incoming_ray[5],
|
|
334
|
+
// out[3],out[4],out[5],
|
|
335
|
+
// incoming_ray[3],incoming_ray[4],incoming_ray[5],
|
|
336
|
+
// );
|
|
337
|
+
|
|
338
|
+
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
/**
|
|
342
|
+
* Tests ray for occlusion
|
|
343
|
+
* @param {Ray3} ray
|
|
344
|
+
* @returns {boolean}
|
|
345
|
+
*/
|
|
346
|
+
occluded(ray) {
|
|
347
|
+
|
|
348
|
+
const bvh = this.bvh_top_level;
|
|
349
|
+
|
|
350
|
+
const ray_origin_x = ray[0];
|
|
351
|
+
const ray_origin_y = ray[1];
|
|
352
|
+
const ray_origin_z = ray[2];
|
|
353
|
+
|
|
354
|
+
const ray_direction_x = ray[3];
|
|
355
|
+
const ray_direction_y = ray[4];
|
|
356
|
+
const ray_direction_z = ray[5];
|
|
357
|
+
|
|
358
|
+
const max_distance = ray[6];
|
|
359
|
+
|
|
360
|
+
const hit_count = bvh_query_user_data_ray_segment(
|
|
361
|
+
bvh, bvh.root,
|
|
362
|
+
scratch_uint32_array, 0,
|
|
363
|
+
ray_origin_x, ray_origin_y, ray_origin_z,
|
|
364
|
+
ray_direction_x, ray_direction_y, ray_direction_z,
|
|
365
|
+
0, max_distance
|
|
366
|
+
);
|
|
367
|
+
|
|
368
|
+
|
|
369
|
+
for (let i = 0; i < hit_count; i++) {
|
|
370
|
+
|
|
371
|
+
const node_user_data = scratch_uint32_array[i];
|
|
372
|
+
|
|
373
|
+
const mesh = this.meshes.get(node_user_data);
|
|
374
|
+
|
|
375
|
+
if (mesh.occluded(ray)) {
|
|
376
|
+
return true;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
return false;
|
|
339
382
|
}
|
|
340
383
|
|
|
341
384
|
/**
|
|
342
385
|
*
|
|
343
386
|
* @param {number[]} out
|
|
344
387
|
* @param {number[]|Ray3} ray
|
|
345
|
-
* @param {number} min_distance
|
|
346
|
-
* @param {number} max_distance
|
|
347
388
|
* @return {number} distance to contact, or -1 if no contact found
|
|
348
389
|
*/
|
|
349
|
-
trace(out, ray
|
|
390
|
+
trace(out, ray) {
|
|
350
391
|
|
|
351
392
|
const bvh = this.bvh_top_level;
|
|
352
393
|
|
|
@@ -358,13 +399,14 @@ export class PathTracedScene {
|
|
|
358
399
|
const ray_direction_y = ray[4];
|
|
359
400
|
const ray_direction_z = ray[5];
|
|
360
401
|
|
|
402
|
+
const max_distance = ray[6];
|
|
361
403
|
|
|
362
404
|
const hit_count = bvh_query_user_data_ray_segment(
|
|
363
405
|
bvh, bvh.root,
|
|
364
406
|
scratch_uint32_array, 0,
|
|
365
407
|
ray_origin_x, ray_origin_y, ray_origin_z,
|
|
366
408
|
ray_direction_x, ray_direction_y, ray_direction_z,
|
|
367
|
-
|
|
409
|
+
0, max_distance
|
|
368
410
|
);
|
|
369
411
|
|
|
370
412
|
let nearest_hit_distance = max_distance;
|
|
@@ -375,7 +417,7 @@ export class PathTracedScene {
|
|
|
375
417
|
|
|
376
418
|
const mesh = this.meshes.get(node_user_data);
|
|
377
419
|
|
|
378
|
-
const distance_to_hit = mesh.hit(out, ray,
|
|
420
|
+
const distance_to_hit = mesh.hit(out, ray, nearest_hit_distance);
|
|
379
421
|
|
|
380
422
|
if (distance_to_hit >= 0) {
|
|
381
423
|
// since raycast in leaf nodes is already bound by maximum distance, any hit we get is necessarily a closer hit than before
|
|
@@ -408,11 +450,8 @@ export class PathTracedScene {
|
|
|
408
450
|
* @param {number[]} out
|
|
409
451
|
* @param {number} out_offset
|
|
410
452
|
* @param {number[]} ray
|
|
411
|
-
* @param {number} ray_address
|
|
412
|
-
* @returns {boolean}
|
|
413
453
|
*/
|
|
414
|
-
sample_lights(out, out_offset, ray
|
|
415
|
-
let lights_sampled = false;
|
|
454
|
+
sample_lights(out, out_offset, ray) {
|
|
416
455
|
|
|
417
456
|
const lights = this.__lights;
|
|
418
457
|
const light_count = lights.length;
|
|
@@ -430,9 +469,9 @@ export class PathTracedScene {
|
|
|
430
469
|
|
|
431
470
|
// see https://github.com/mrdoob/three.js/blob/f0a9e0cf90a2f1ba5017fcb7fd46f02748b920cf/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js#L172
|
|
432
471
|
|
|
433
|
-
const ray_direction_x = ray[
|
|
434
|
-
const ray_direction_y = ray[
|
|
435
|
-
const ray_direction_z = ray[
|
|
472
|
+
const ray_direction_x = ray[3];
|
|
473
|
+
const ray_direction_y = ray[4];
|
|
474
|
+
const ray_direction_z = ray[5];
|
|
436
475
|
|
|
437
476
|
const light_dir_inv_x = -dir.x;
|
|
438
477
|
const light_dir_inv_y = -dir.y;
|
|
@@ -448,33 +487,33 @@ export class PathTracedScene {
|
|
|
448
487
|
continue;
|
|
449
488
|
}
|
|
450
489
|
|
|
451
|
-
const ray_origin_x = ray[
|
|
452
|
-
const ray_origin_y = ray[
|
|
453
|
-
const ray_origin_z = ray[
|
|
490
|
+
const ray_origin_x = ray[0];
|
|
491
|
+
const ray_origin_y = ray[1];
|
|
492
|
+
const ray_origin_z = ray[2];
|
|
454
493
|
|
|
455
494
|
ray3_array_compose(_ray_1,
|
|
456
495
|
ray_origin_x, ray_origin_y, ray_origin_z,
|
|
457
496
|
light_dir_inv_x, light_dir_inv_y, light_dir_inv_z
|
|
458
497
|
);
|
|
459
498
|
|
|
499
|
+
_ray_1.tMax = Infinity;
|
|
500
|
+
|
|
460
501
|
// check if there are any obstacles in the direction of the light
|
|
461
|
-
if (this.
|
|
502
|
+
if (this.occluded(_ray_1)) {
|
|
462
503
|
// light is occluded
|
|
463
504
|
continue;
|
|
464
505
|
}
|
|
465
506
|
|
|
466
507
|
|
|
467
508
|
const intensity = dotNL * light.intensity.getValue();
|
|
509
|
+
const light_color = light.color;
|
|
510
|
+
|
|
511
|
+
out[out_offset] += light_color.r * intensity;
|
|
512
|
+
out[out_offset + 1] += light_color.g * intensity;
|
|
513
|
+
out[out_offset + 2] += light_color.b * intensity;
|
|
468
514
|
|
|
469
|
-
for (let j = 0; j < 3; j++) {
|
|
470
|
-
// irradiance
|
|
471
|
-
out[out_offset + j] += light.color[j] * intensity;
|
|
472
|
-
}
|
|
473
515
|
|
|
474
|
-
lights_sampled = true;
|
|
475
516
|
}
|
|
476
517
|
}
|
|
477
|
-
|
|
478
|
-
return lights_sampled;
|
|
479
518
|
}
|
|
480
519
|
}
|
|
@@ -2,13 +2,13 @@ export class PathTracer {
|
|
|
2
2
|
/**
|
|
3
3
|
*
|
|
4
4
|
* @param {number[]|Float32Array} out
|
|
5
|
-
* @param {number[]|Float32Array} ray
|
|
6
|
-
* @param {number} max_distance
|
|
5
|
+
* @param {number[]|Float32Array|Ray3} ray
|
|
7
6
|
* @param {number} min_bounce
|
|
8
7
|
* @param {number} max_bounce
|
|
9
8
|
* @param {function} random
|
|
10
9
|
* @param {PathTracedScene} scene
|
|
11
10
|
*/
|
|
12
|
-
path_trace(out: number[] | Float32Array, ray: number[] | Float32Array
|
|
11
|
+
path_trace(out: number[] | Float32Array, ray: number[] | Float32Array | Ray3, min_bounce: number, max_bounce: number, random: Function, scene: PathTracedScene): void;
|
|
13
12
|
}
|
|
13
|
+
import { Ray3 } from "../../../../core/geom/3d/Ray3.js";
|
|
14
14
|
//# sourceMappingURL=PathTracer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PathTracer.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/graphics/sh3/path_tracer/PathTracer.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"PathTracer.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/graphics/sh3/path_tracer/PathTracer.js"],"names":[],"mappings":"AAiCA;IAGI;;;;;;;;OAQG;IACH,gBAPW,MAAM,EAAE,GAAC,YAAY,OACrB,MAAM,EAAE,GAAC,YAAY,GAAC,IAAI,cAC1B,MAAM,cACN,MAAM,kDAkFhB;CACJ;qBA1HoB,kCAAkC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { vec3 } from "gl-matrix";
|
|
2
2
|
import { array_copy } from "../../../../core/collection/array/array_copy.js";
|
|
3
|
+
import { Ray3 } from "../../../../core/geom/3d/Ray3.js";
|
|
3
4
|
import { getBiasedNormalSample } from "./sampling/getBiasedNormalSample.js";
|
|
4
5
|
|
|
5
6
|
/*
|
|
@@ -18,21 +19,25 @@ const irradiance = [0, 0, 0];
|
|
|
18
19
|
|
|
19
20
|
const trace_result = [];
|
|
20
21
|
|
|
21
|
-
const _ray_0 =
|
|
22
|
+
const _ray_0 = new Ray3();
|
|
22
23
|
|
|
23
|
-
const tmp_0 =
|
|
24
|
-
const tmp_1 = [];
|
|
24
|
+
const tmp_0 = new Float32Array(6);
|
|
25
25
|
|
|
26
|
+
/**
|
|
27
|
+
* Normalized probability of terminating the ray
|
|
28
|
+
* @type {number}
|
|
29
|
+
*/
|
|
26
30
|
const RUSSIAN_ROULETTE_PROBABILITY = 0.5;
|
|
27
31
|
|
|
32
|
+
const color_mask = new Float32Array(3);
|
|
33
|
+
|
|
28
34
|
export class PathTracer {
|
|
29
35
|
|
|
30
36
|
|
|
31
37
|
/**
|
|
32
38
|
*
|
|
33
39
|
* @param {number[]|Float32Array} out
|
|
34
|
-
* @param {number[]|Float32Array} ray
|
|
35
|
-
* @param {number} max_distance
|
|
40
|
+
* @param {number[]|Float32Array|Ray3} ray
|
|
36
41
|
* @param {number} min_bounce
|
|
37
42
|
* @param {number} max_bounce
|
|
38
43
|
* @param {function} random
|
|
@@ -41,19 +46,21 @@ export class PathTracer {
|
|
|
41
46
|
path_trace(
|
|
42
47
|
out,
|
|
43
48
|
ray,
|
|
44
|
-
max_distance,
|
|
45
49
|
min_bounce,
|
|
46
50
|
max_bounce,
|
|
47
51
|
random = Math.random,
|
|
48
52
|
scene
|
|
49
53
|
) {
|
|
50
|
-
//TODO add importance sampling, see https://raytracing.github.io/books/RayTracingTheRestOfYourLife.html#lightscattering/thescatteringpdf
|
|
51
54
|
|
|
52
|
-
|
|
55
|
+
_ray_0.copy(ray);
|
|
56
|
+
|
|
57
|
+
irradiance[0] = 0;
|
|
58
|
+
irradiance[1] = 0;
|
|
59
|
+
irradiance[2] = 0;
|
|
53
60
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
61
|
+
color_mask[0] = 1;
|
|
62
|
+
color_mask[1] = 1;
|
|
63
|
+
color_mask[2] = 1;
|
|
57
64
|
|
|
58
65
|
let i;
|
|
59
66
|
for (i = 0; i < max_bounce; ++i) {
|
|
@@ -61,15 +68,13 @@ export class PathTracer {
|
|
|
61
68
|
if (i >= min_bounce) {
|
|
62
69
|
const russian_roulette_roll = random();
|
|
63
70
|
|
|
64
|
-
if (russian_roulette_roll
|
|
71
|
+
if (russian_roulette_roll < RUSSIAN_ROULETTE_PROBABILITY) {
|
|
65
72
|
// terminate ray
|
|
66
73
|
break;
|
|
67
74
|
}
|
|
68
75
|
}
|
|
69
76
|
|
|
70
|
-
|
|
71
|
-
const hit_distance = scene.trace(trace_result, _ray_0, 0.0001, max_distance);
|
|
72
|
-
|
|
77
|
+
const hit_distance = scene.trace(trace_result, _ray_0);
|
|
73
78
|
|
|
74
79
|
if (hit_distance < 0) {
|
|
75
80
|
// ray didn't hit anything
|
|
@@ -77,30 +82,33 @@ export class PathTracer {
|
|
|
77
82
|
break;
|
|
78
83
|
}
|
|
79
84
|
|
|
80
|
-
scene.sample_material(tmp_0, trace_result);
|
|
81
|
-
|
|
82
|
-
// adjust normal on the hit
|
|
83
|
-
array_copy(tmp_0, 3, trace_result, 3, 3);
|
|
84
|
-
array_copy(trace_result, 0, _ray_0, 0, 3);
|
|
85
|
+
scene.sample_material(tmp_0, trace_result, _ray_0);
|
|
85
86
|
|
|
86
|
-
// accumulate irradiance
|
|
87
|
-
vec3.multiply(irradiance, irradiance, tmp_0);
|
|
88
87
|
|
|
89
|
-
|
|
90
|
-
getBiasedNormalSample(_ray_0, 3, tmp_0, 3, 1, random);
|
|
88
|
+
vec3.multiply(color_mask, color_mask, tmp_0);
|
|
91
89
|
|
|
92
|
-
|
|
90
|
+
// construct new ray, aligned on the normal of the contact
|
|
91
|
+
array_copy(tmp_0, 3, _ray_0, 3, 3); // copy new direction
|
|
92
|
+
array_copy(trace_result, 0, _ray_0, 0, 3); // copy new origin
|
|
93
93
|
|
|
94
|
+
// move ray forward by a small amount to avoid self-occlusion
|
|
95
|
+
_ray_0.shiftForward(0.00001);
|
|
94
96
|
|
|
95
|
-
if (i > 0) {
|
|
96
97
|
// light sampling
|
|
97
|
-
scene.sample_lights(
|
|
98
|
+
scene.sample_lights(tmp_0, 0, _ray_0);
|
|
99
|
+
|
|
100
|
+
// sample on cosine lobe ray
|
|
101
|
+
getBiasedNormalSample(_ray_0, 3, _ray_0, 3, 1, random);
|
|
102
|
+
|
|
103
|
+
// // accumulate irradiance
|
|
104
|
+
irradiance[0] += color_mask[0] * tmp_0[0];
|
|
105
|
+
irradiance[1] += color_mask[1] * tmp_0[1];
|
|
106
|
+
irradiance[2] += color_mask[2] * tmp_0[2];
|
|
107
|
+
|
|
108
|
+
}
|
|
98
109
|
|
|
99
|
-
irradiance[0] *= tmp_1[0];
|
|
100
|
-
irradiance[1] *= tmp_1[1];
|
|
101
|
-
irradiance[2] *= tmp_1[2];
|
|
102
|
-
} else {
|
|
103
110
|
|
|
111
|
+
if (i === 0) {
|
|
104
112
|
// ray didn't hit anything on the very first bounce
|
|
105
113
|
|
|
106
114
|
// sample "environment" and terminate path as there is nothing to reflect off of
|
|
@@ -113,6 +121,5 @@ export class PathTracer {
|
|
|
113
121
|
out[1] = irradiance[1]
|
|
114
122
|
out[2] = irradiance[2]
|
|
115
123
|
|
|
116
|
-
// array_copy(irradiance, 0, out, 0, 3);
|
|
117
124
|
}
|
|
118
|
-
}
|
|
125
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MaterialConverter.d.ts","sourceRoot":"","sources":["../../../../../../../src/engine/graphics/sh3/path_tracer/material/MaterialConverter.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"MaterialConverter.d.ts","sourceRoot":"","sources":["../../../../../../../src/engine/graphics/sh3/path_tracer/material/MaterialConverter.js"],"names":[],"mappings":"AA8BA;IA4BI;;;;OAIG;IACH,kBAHW,MAAM,QAAQ,GACZ,gBAAgB,CAyC5B;;CAEJ;iCApGgC,uBAAuB"}
|
|
@@ -1,12 +1,33 @@
|
|
|
1
1
|
import { Color } from "three";
|
|
2
|
-
import {
|
|
3
|
-
TextureAttachmentsByMaterialType
|
|
4
|
-
} from "../../../../asset/loaders/material/TextureAttachmensByMaterialType.js";
|
|
5
2
|
import { convertTexture2Sampler2D } from "../../../texture/sampler/convertTexture2Sampler2D.js";
|
|
6
3
|
import { sampler_multiply_vector } from "../../../texture/sampler/sampler_multiply_vector.js";
|
|
4
|
+
import { iterate_three_material_textures } from "../../../three/material/iterate_three_material_textures.js";
|
|
7
5
|
import { StandardMaterial } from "./StandardMaterial.js";
|
|
8
6
|
import { StandardTexture } from "./StandardTexture.js";
|
|
9
7
|
|
|
8
|
+
/**
|
|
9
|
+
*
|
|
10
|
+
* @param {Map<number,StandardTexture>} cache
|
|
11
|
+
* @param {AssetManager} asset_manager
|
|
12
|
+
* @param {THREE.Material} material
|
|
13
|
+
* @returns {Promise<void>}
|
|
14
|
+
*/
|
|
15
|
+
async function precache_textures(cache, asset_manager, material) {
|
|
16
|
+
|
|
17
|
+
const textures = iterate_three_material_textures(material);
|
|
18
|
+
|
|
19
|
+
for (const { name, texture } of textures) {
|
|
20
|
+
if (cache.has(texture.id)) {
|
|
21
|
+
// already processed
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
}
|
|
30
|
+
|
|
10
31
|
export class MaterialConverter {
|
|
11
32
|
/**
|
|
12
33
|
* Maps {@link Texture.id} to relevant sampler
|
|
@@ -44,46 +65,28 @@ export class MaterialConverter {
|
|
|
44
65
|
|
|
45
66
|
const result = new StandardMaterial();
|
|
46
67
|
|
|
47
|
-
|
|
48
|
-
const materialType = material.type;
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
*
|
|
52
|
-
* @type {TextureAttachment[]}
|
|
53
|
-
*/
|
|
54
|
-
const attachments = TextureAttachmentsByMaterialType[materialType];
|
|
55
|
-
|
|
56
|
-
if (attachments !== undefined) {
|
|
57
|
-
|
|
58
|
-
for (let i = 0; i < attachments.length; i++) {
|
|
59
|
-
const attachment = attachments[i];
|
|
60
|
-
|
|
61
|
-
const texture = attachment.read(material);
|
|
62
|
-
|
|
63
|
-
if (texture === undefined || texture === null) {
|
|
64
|
-
continue;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
const sampler = this.#ensure_texture(texture);
|
|
68
|
-
|
|
69
|
-
const name = attachment.name;
|
|
70
|
-
|
|
71
|
-
if (name === "diffuse") {
|
|
72
|
-
result.diffuse = sampler;
|
|
73
|
-
} else if (name === "normal") {
|
|
74
|
-
result.normal = sampler;
|
|
75
|
-
} else if (name === "metalness") {
|
|
76
|
-
result.metalness = sampler;
|
|
77
|
-
} else if (name === "roughness") {
|
|
78
|
-
result.roughness = sampler;
|
|
79
|
-
} else if (name === "emissive") {
|
|
80
|
-
result.emissive = sampler;
|
|
81
|
-
} else {
|
|
82
|
-
// unused
|
|
83
|
-
}
|
|
68
|
+
const textures = iterate_three_material_textures(material);
|
|
84
69
|
|
|
70
|
+
//patch textures
|
|
85
71
|
|
|
72
|
+
for (const { name, texture } of textures) {
|
|
73
|
+
|
|
74
|
+
const sampler = this.#ensure_texture(texture);
|
|
75
|
+
|
|
76
|
+
if (name === "diffuse") {
|
|
77
|
+
result.diffuse = sampler;
|
|
78
|
+
} else if (name === "normal") {
|
|
79
|
+
result.normal = sampler;
|
|
80
|
+
} else if (name === "metalness") {
|
|
81
|
+
result.metalness = sampler;
|
|
82
|
+
} else if (name === "roughness") {
|
|
83
|
+
result.roughness = sampler;
|
|
84
|
+
} else if (name === "emissive") {
|
|
85
|
+
result.emissive = sampler;
|
|
86
|
+
} else {
|
|
87
|
+
// unused
|
|
86
88
|
}
|
|
89
|
+
|
|
87
90
|
}
|
|
88
91
|
|
|
89
92
|
if (material.color !== undefined && !material.color.equals(new Color(1, 1, 1))) {
|
|
@@ -5,6 +5,20 @@ export class StandardMaterial {
|
|
|
5
5
|
emissive: StandardTexture;
|
|
6
6
|
roughness: StandardTexture;
|
|
7
7
|
metalness: StandardTexture;
|
|
8
|
+
/**
|
|
9
|
+
*
|
|
10
|
+
* @param {number} incoming_direction_x
|
|
11
|
+
* @param {number} incoming_direction_y
|
|
12
|
+
* @param {number} incoming_direction_z
|
|
13
|
+
* @param {number} normal_x
|
|
14
|
+
* @param {number} normal_y
|
|
15
|
+
* @param {number} normal_z
|
|
16
|
+
* @param {number} outgoing_x
|
|
17
|
+
* @param {number} outgoing_y
|
|
18
|
+
* @param {number} outgoing_z
|
|
19
|
+
* @returns {number}
|
|
20
|
+
*/
|
|
21
|
+
scattering_pdf(incoming_direction_x: number, incoming_direction_y: number, incoming_direction_z: number, normal_x: number, normal_y: number, normal_z: number, outgoing_x: number, outgoing_y: number, outgoing_z: number): number;
|
|
8
22
|
}
|
|
9
23
|
import { StandardTexture } from "./StandardTexture.js";
|
|
10
24
|
//# sourceMappingURL=StandardMaterial.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StandardMaterial.d.ts","sourceRoot":"","sources":["../../../../../../../src/engine/graphics/sh3/path_tracer/material/StandardMaterial.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"StandardMaterial.d.ts","sourceRoot":"","sources":["../../../../../../../src/engine/graphics/sh3/path_tracer/material/StandardMaterial.js"],"names":[],"mappings":"AAaA;IACI,WAAkB;IAElB,yBAA+C;IAC/C,wBAA6C;IAC7C,0BAAiD;IACjD,2BAAmD;IACnD,2BAAmD;IAEnD;;;;;;;;;;;;OAYG;IACH,qCAXW,MAAM,wBACN,MAAM,wBACN,MAAM,YACN,MAAM,YACN,MAAM,YACN,MAAM,cACN,MAAM,cACN,MAAM,cACN,MAAM,GACJ,MAAM,CAkBlB;CACJ;gCAjD+B,sBAAsB"}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import { v3_dot } from "../../../../../core/geom/vec3/v3_dot.js";
|
|
2
|
+
import { PI_RECIPROCAL } from "../../../../../core/math/PI_RECIPROCAL.js";
|
|
1
3
|
import { one_pixel_sampler_uint8 } from "../../../texture/sampler/one_pixel_sampler_uint8.js";
|
|
2
4
|
import { StandardTexture } from "./StandardTexture.js";
|
|
3
5
|
|
|
4
6
|
const DEFAULT_DIFFUSE = one_pixel_sampler_uint8([255, 255, 255, 255]);
|
|
5
|
-
const DEFAULT_NORMAL = one_pixel_sampler_uint8([
|
|
7
|
+
const DEFAULT_NORMAL = one_pixel_sampler_uint8([127, 127, 255]);
|
|
6
8
|
const DEFAULT_EMISSIVE = one_pixel_sampler_uint8([0, 0, 0]);
|
|
7
9
|
const DEFAULT_ROUGHNESS = one_pixel_sampler_uint8([255]);
|
|
8
10
|
const DEFAULT_METALNESS = one_pixel_sampler_uint8([0]);
|
|
@@ -17,5 +19,36 @@ export class StandardMaterial {
|
|
|
17
19
|
emissive = StandardTexture.from(DEFAULT_EMISSIVE)
|
|
18
20
|
roughness = StandardTexture.from(DEFAULT_ROUGHNESS)
|
|
19
21
|
metalness = StandardTexture.from(DEFAULT_METALNESS)
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
*
|
|
25
|
+
* @param {number} incoming_direction_x
|
|
26
|
+
* @param {number} incoming_direction_y
|
|
27
|
+
* @param {number} incoming_direction_z
|
|
28
|
+
* @param {number} normal_x
|
|
29
|
+
* @param {number} normal_y
|
|
30
|
+
* @param {number} normal_z
|
|
31
|
+
* @param {number} outgoing_x
|
|
32
|
+
* @param {number} outgoing_y
|
|
33
|
+
* @param {number} outgoing_z
|
|
34
|
+
* @returns {number}
|
|
35
|
+
*/
|
|
36
|
+
scattering_pdf(
|
|
37
|
+
incoming_direction_x, incoming_direction_y, incoming_direction_z,
|
|
38
|
+
normal_x, normal_y, normal_z,
|
|
39
|
+
outgoing_x, outgoing_y, outgoing_z,
|
|
40
|
+
) {
|
|
41
|
+
const cos_theta = v3_dot(
|
|
42
|
+
normal_x, normal_y, normal_z,
|
|
43
|
+
outgoing_x, outgoing_y, outgoing_z
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
if (cos_theta < 0) {
|
|
47
|
+
// clamp rays below horizon
|
|
48
|
+
return 0;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return cos_theta * PI_RECIPROCAL;
|
|
52
|
+
}
|
|
20
53
|
}
|
|
21
54
|
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export function make_sun({ temperature, color, intensity, direction }?: {
|
|
2
|
+
temperature?: number;
|
|
3
|
+
color?: string;
|
|
4
|
+
intensity?: number;
|
|
5
|
+
direction?: Vector3;
|
|
6
|
+
}): DirectionalLight;
|
|
7
|
+
/**
|
|
8
|
+
*
|
|
9
|
+
* @param {PathTracedScene} scene
|
|
10
|
+
* @param {THREE.Camera} camera
|
|
11
|
+
* @param {string} url
|
|
12
|
+
* @param {number} [zoom]
|
|
13
|
+
* @param {number} [floor_level]
|
|
14
|
+
* @param {Object} [sun]
|
|
15
|
+
* @param {boolean} [no_materials]
|
|
16
|
+
* @return {Promise<void>}
|
|
17
|
+
*/
|
|
18
|
+
export function prepare_scene_gltf({ scene, camera, url, zoom, floor_level, sun, no_materials }: PathTracedScene): Promise<void>;
|
|
19
|
+
import Vector3 from "../../../../core/geom/Vector3.js";
|
|
20
|
+
import { DirectionalLight } from "../../render/forward_plus/model/DirectionalLight.js";
|
|
21
|
+
//# sourceMappingURL=prepare_scene_gltf.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prepare_scene_gltf.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/graphics/sh3/path_tracer/prepare_scene_gltf.js"],"names":[],"mappings":"AAaA;;;;;qBAyBC;AAaD;;;;;;;;;;GAUG;AACH,mHAFY,QAAQ,IAAI,CAAC,CA8CxB;oBAnGmB,kCAAkC;iCAErB,qDAAqD"}
|