@woosh/meep-engine 2.119.118 → 2.119.119
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/package.json +1 -1
- package/src/core/bvh2/bvh3/ebvh_build_hierarchy.d.ts.map +1 -1
- package/src/core/bvh2/bvh3/ebvh_build_hierarchy.js +24 -4
- package/src/core/bvh2/bvh3/ebvh_nodes_sort_sah_local4.d.ts +2 -1
- package/src/core/bvh2/bvh3/ebvh_nodes_sort_sah_local4.d.ts.map +1 -1
- package/src/core/bvh2/bvh3/ebvh_nodes_sort_sah_local4.js +73 -16
- package/src/engine/graphics/sh3/path_tracer/PathTracedScene.d.ts.map +1 -1
- package/src/engine/graphics/sh3/path_tracer/PathTracedScene.js +14 -10
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ebvh_build_hierarchy.d.ts","sourceRoot":"","sources":["../../../../../src/core/bvh2/bvh3/ebvh_build_hierarchy.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ebvh_build_hierarchy.d.ts","sourceRoot":"","sources":["../../../../../src/core/bvh2/bvh3/ebvh_build_hierarchy.js"],"names":[],"mappings":"AAWA;;;;;;;;;;;;GAYG;AACH,0CATW,GAAG,qBACH,MAAM,EAAE,GAAC,WAAW,oBACpB,MAAM,aACN,MAAM,EAAE,GAAC,WAAW,oBACpB,MAAM,2BACN,MAAM,0BACN,MAAM,GACJ,MAAM,CAgGlB"}
|
|
@@ -3,6 +3,12 @@ import { max2 } from "../../math/max2.js";
|
|
|
3
3
|
import { NULL_NODE } from "./BVH.js";
|
|
4
4
|
import { ebvh_nodes_sort_sah_local4 } from "./ebvh_nodes_sort_sah_local4.js";
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Somewhat arbitrary, pulled from various papers
|
|
8
|
+
* @type {number}
|
|
9
|
+
*/
|
|
10
|
+
const SAH_MERGE_FRACTION = 0.93;
|
|
11
|
+
|
|
6
12
|
/**
|
|
7
13
|
* Given a set of leaves, build intermediate node hierarchy on top, all the way up to the root
|
|
8
14
|
* Assumes nodes are spatially sorted, if not - no guarantees can be made about quality
|
|
@@ -36,6 +42,9 @@ export function ebvh_build_hierarchy(
|
|
|
36
42
|
|
|
37
43
|
let current_construction_depth = 0;
|
|
38
44
|
|
|
45
|
+
const primitive_counts = new Uint32Array(input_node_count);
|
|
46
|
+
primitive_counts.fill(1);
|
|
47
|
+
|
|
39
48
|
while (unprocessed_node_count > 1) {
|
|
40
49
|
|
|
41
50
|
const sah_optimization_cycle_count = Math.floor(sah_optimization_level + sah_optimization_bias * current_construction_depth);
|
|
@@ -48,6 +57,7 @@ export function ebvh_build_hierarchy(
|
|
|
48
57
|
ebvh_nodes_sort_sah_local4(
|
|
49
58
|
bvh,
|
|
50
59
|
unprocessed_nodes,
|
|
60
|
+
primitive_counts,
|
|
51
61
|
0,
|
|
52
62
|
swap_distance,
|
|
53
63
|
unprocessed_node_count
|
|
@@ -58,9 +68,17 @@ export function ebvh_build_hierarchy(
|
|
|
58
68
|
let added_nodes = 0;
|
|
59
69
|
let cursor = 0;
|
|
60
70
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
71
|
+
let merge_limit = unprocessed_node_count;
|
|
72
|
+
if (sah_optimization_cycle_count > 0) {
|
|
73
|
+
merge_limit = Math.ceil(unprocessed_node_count * SAH_MERGE_FRACTION);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
while (cursor + 1 < merge_limit) {
|
|
77
|
+
const child_2_index = cursor++;
|
|
78
|
+
const child_1_index = cursor++;
|
|
79
|
+
|
|
80
|
+
const child_2 = unprocessed_nodes[child_2_index];
|
|
81
|
+
const child_1 = unprocessed_nodes[child_1_index];
|
|
64
82
|
|
|
65
83
|
const parent = node_pool[used_index++];
|
|
66
84
|
|
|
@@ -79,7 +97,9 @@ export function ebvh_build_hierarchy(
|
|
|
79
97
|
)
|
|
80
98
|
);
|
|
81
99
|
|
|
82
|
-
|
|
100
|
+
const parent_index = added_nodes++;
|
|
101
|
+
unprocessed_nodes[parent_index] = parent;
|
|
102
|
+
primitive_counts[parent_index] = primitive_counts[child_1_index] + primitive_counts[child_2_index];
|
|
83
103
|
}
|
|
84
104
|
|
|
85
105
|
while (cursor < unprocessed_node_count) {
|
|
@@ -3,9 +3,10 @@
|
|
|
3
3
|
* Useful for optimizing topology for traversal.
|
|
4
4
|
* @param {BVH} bvh
|
|
5
5
|
* @param {number[]|Uint32Array} nodes
|
|
6
|
+
* @param {number[]|Uint32Array} primitive_counts
|
|
6
7
|
* @param {number} offset
|
|
7
8
|
* @param {number} distance
|
|
8
9
|
* @param {number} count
|
|
9
10
|
*/
|
|
10
|
-
export function ebvh_nodes_sort_sah_local4(bvh: BVH, nodes: number[] | Uint32Array, offset: number, distance: number, count: number): number;
|
|
11
|
+
export function ebvh_nodes_sort_sah_local4(bvh: BVH, nodes: number[] | Uint32Array, primitive_counts: number[] | Uint32Array, offset: number, distance: number, count: number): number;
|
|
11
12
|
//# sourceMappingURL=ebvh_nodes_sort_sah_local4.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ebvh_nodes_sort_sah_local4.d.ts","sourceRoot":"","sources":["../../../../../src/core/bvh2/bvh3/ebvh_nodes_sort_sah_local4.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ebvh_nodes_sort_sah_local4.d.ts","sourceRoot":"","sources":["../../../../../src/core/bvh2/bvh3/ebvh_nodes_sort_sah_local4.js"],"names":[],"mappings":"AAGA;;;;;;;;;GASG;AACH,gDAPW,GAAG,SACH,MAAM,EAAE,GAAC,WAAW,oBACpB,MAAM,EAAE,GAAC,WAAW,UACpB,MAAM,YACN,MAAM,SACN,MAAM,UAqGhB"}
|
|
@@ -1,27 +1,47 @@
|
|
|
1
|
+
import { array_swap } from "../../collection/array/array_swap.js";
|
|
2
|
+
|
|
3
|
+
|
|
1
4
|
/**
|
|
2
5
|
* Sort consequent 4 nodes to reduce SAH among each consequent pair.
|
|
3
6
|
* Useful for optimizing topology for traversal.
|
|
4
7
|
* @param {BVH} bvh
|
|
5
8
|
* @param {number[]|Uint32Array} nodes
|
|
9
|
+
* @param {number[]|Uint32Array} primitive_counts
|
|
6
10
|
* @param {number} offset
|
|
7
11
|
* @param {number} distance
|
|
8
12
|
* @param {number} count
|
|
9
13
|
*/
|
|
10
|
-
export function ebvh_nodes_sort_sah_local4(
|
|
14
|
+
export function ebvh_nodes_sort_sah_local4(
|
|
15
|
+
bvh,
|
|
16
|
+
nodes,
|
|
17
|
+
primitive_counts,
|
|
18
|
+
offset,
|
|
19
|
+
distance,
|
|
20
|
+
count
|
|
21
|
+
) {
|
|
11
22
|
|
|
12
23
|
const swap_pair_limit = Math.floor((count - (distance + 2)) / 2);
|
|
13
24
|
const end = offset + swap_pair_limit * 2;
|
|
14
25
|
|
|
15
26
|
let swap_count = 0;
|
|
16
27
|
|
|
17
|
-
for (let
|
|
18
|
-
const
|
|
28
|
+
for (let index_a = offset; index_a < end; index_a += 2) {
|
|
29
|
+
const index_c = index_a + distance;
|
|
30
|
+
|
|
31
|
+
const index_b = index_a + 1;
|
|
32
|
+
const index_d = index_c + 1;
|
|
33
|
+
|
|
34
|
+
const node_a = nodes[index_a];
|
|
35
|
+
const node_b = nodes[index_b];
|
|
36
|
+
|
|
37
|
+
const node_c = nodes[index_c];
|
|
38
|
+
const node_d = nodes[index_d];
|
|
19
39
|
|
|
20
|
-
const
|
|
21
|
-
const
|
|
40
|
+
const count_a = primitive_counts[index_a];
|
|
41
|
+
const count_b = primitive_counts[index_b];
|
|
22
42
|
|
|
23
|
-
const
|
|
24
|
-
const
|
|
43
|
+
const count_c = primitive_counts[index_c];
|
|
44
|
+
const count_d = primitive_counts[index_d];
|
|
25
45
|
|
|
26
46
|
/*
|
|
27
47
|
possible combinations:
|
|
@@ -31,25 +51,62 @@ export function ebvh_nodes_sort_sah_local4(bvh, nodes, offset, distance, count)
|
|
|
31
51
|
|
|
32
52
|
Other combinations are not of interest as order among each pair is irrelevant for traversal performance
|
|
33
53
|
*/
|
|
34
|
-
|
|
35
|
-
const
|
|
36
|
-
const
|
|
54
|
+
|
|
55
|
+
const area_ab = bvh.node_get_combined_surface_area(node_a, node_b);
|
|
56
|
+
const area_cd = bvh.node_get_combined_surface_area(node_c, node_d);
|
|
57
|
+
|
|
58
|
+
const area_ac = bvh.node_get_combined_surface_area(node_a, node_c);
|
|
59
|
+
const area_bd = bvh.node_get_combined_surface_area(node_b, node_d);
|
|
60
|
+
|
|
61
|
+
const area_ad = bvh.node_get_combined_surface_area(node_a, node_d);
|
|
62
|
+
const area_cb = bvh.node_get_combined_surface_area(node_c, node_b);
|
|
63
|
+
|
|
64
|
+
const cost_ab = area_ab * (count_a + count_b);
|
|
65
|
+
const cost_cd = area_cd * (count_c + count_d);
|
|
66
|
+
|
|
67
|
+
const cost_ac = area_ac * (count_a + count_c);
|
|
68
|
+
const cost_bd = area_bd * (count_b + count_d);
|
|
69
|
+
|
|
70
|
+
const cost_ad = area_ad * (count_a + count_d);
|
|
71
|
+
const cost_cb = area_cb * (count_c + count_b);
|
|
72
|
+
|
|
73
|
+
const cost0 = cost_ab + cost_cd;
|
|
74
|
+
const cost1 = cost_ac + cost_bd;
|
|
75
|
+
const cost2 = cost_ad + cost_cb;
|
|
76
|
+
|
|
77
|
+
let post_swap = false;
|
|
37
78
|
|
|
38
79
|
if (cost0 <= cost1 && cost0 <= cost2) {
|
|
39
80
|
// no change
|
|
40
|
-
|
|
81
|
+
post_swap = cost_cd < cost_ab;
|
|
82
|
+
|
|
41
83
|
} else if (cost1 <= cost2) {
|
|
42
84
|
// swap C and B
|
|
43
|
-
nodes[
|
|
44
|
-
nodes[
|
|
85
|
+
nodes[index_b] = node_c;
|
|
86
|
+
nodes[index_c] = node_b;
|
|
87
|
+
|
|
88
|
+
primitive_counts[index_b] = count_c;
|
|
89
|
+
primitive_counts[index_c] = count_b;
|
|
45
90
|
|
|
91
|
+
swap_count++;
|
|
92
|
+
|
|
93
|
+
post_swap = cost_bd < cost_ac;
|
|
46
94
|
} else {
|
|
47
95
|
// swap B and D
|
|
48
|
-
nodes[
|
|
49
|
-
nodes[
|
|
96
|
+
nodes[index_b] = node_d;
|
|
97
|
+
nodes[index_d] = node_b;
|
|
98
|
+
|
|
99
|
+
primitive_counts[index_b] = count_d;
|
|
100
|
+
primitive_counts[index_d] = count_b;
|
|
101
|
+
|
|
102
|
+
swap_count++;
|
|
103
|
+
|
|
104
|
+
post_swap = cost_cb < cost_ad;
|
|
50
105
|
}
|
|
51
106
|
|
|
52
|
-
|
|
107
|
+
// put node pairs in their cost order
|
|
108
|
+
array_swap(nodes, index_a, nodes, index_c, 2);
|
|
109
|
+
array_swap(primitive_counts, index_a, primitive_counts, index_c, 2);
|
|
53
110
|
}
|
|
54
111
|
|
|
55
112
|
return swap_count;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PathTracedScene.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/graphics/sh3/path_tracer/PathTracedScene.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"PathTracedScene.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/graphics/sh3/path_tracer/PathTracedScene.js"],"names":[],"mappings":"AAoDA;IAGI;;;OAGG;IACH,eAFU,GAAG,CAEa;IAG1B;;;OAGG;IACH,QAFU,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAElB;IAEnB;;;OAGG;IACH,UAFU,aAAa,EAAE,CAEX;IAEd;;;OAGG;IACH,WAFU,GAAG,CAAC,KAAK,CAAC,cAAc,EAAE,mBAAmB,CAAC,CAElC;IAmBtB;;;;OAIG;IACH,6BAA6C;IAqF7C,iBAOC;IAED;;;;OAIG;IACH,uBAHW,KAAK,CAAC,cAAc,GACnB,mBAAmB,CAmB9B;IAED;;;OAGG;IACH,gBAFW,aAAa,QAMvB;IAED;;;;OAIG;IACH,cAHW,cAAc,GACZ,OAAO,CAInB;IAED;;;;OAIG;IACH,cAHW,cAAc,GACZ,OAAO,CAiCnB;IAED;;;;OAIG;IACH,iBAHW,cAAc,GACZ,OAAO,CAgBnB;IAED;;;;OAIG;IACH,yBAHW,KAAK,CAAC,QAAQ,GACZ,gBAAgB,CAI5B;IAED;;;;;OAKG;IACH,qBAJW,KAAK,CAAC,cAAc,YACpB,KAAK,CAAC,QAAQ,aACd,IAAI,GAAC,MAAM,EAAE,QAavB;IAED;;;;;OAKG;IACH,qBAJW,MAAM,EAAE,OACR,MAAM,EAAE,gBACR,IAAI,QA0Cd;IAED;;;;OAIG;IACH,cAHW,IAAI,GACF,OAAO,CAsCnB;IAED;;;;;OAKG;IACH,WAJW,MAAM,EAAE,OACR,MAAM,EAAE,GAAC,IAAI,GACZ,MAAM,CA+CjB;IAED;;;;;;OAMG;IACH,uBALW,MAAM,EAAE,cACR,MAAM,aACN,MAAM,EAAE,oBACR,MAAM,QAIhB;IAED;;;;;OAKG;IACH,mBAJW,MAAM,EAAE,cACR,MAAM,OACN,MAAM,EAAE,QAwHlB;;CACJ;oBA7lB8B,mCAAmC;+BAqBnC,qBAAqB;8BAJtB,kDAAkD;oCAC5C,0BAA0B;qBAPzC,kCAAkC"}
|
|
@@ -23,22 +23,23 @@ import { MaterialConverter } from "./material/MaterialConverter.js";
|
|
|
23
23
|
import { PathTracedMesh } from "./PathTracedMesh.js";
|
|
24
24
|
import { sample_material } from "./texture/sample_material.js";
|
|
25
25
|
|
|
26
|
-
function light_getDistanceAttenuation(
|
|
26
|
+
function light_getDistanceAttenuation(distance, cutoff_distance, decay_exponent) {
|
|
27
27
|
|
|
28
|
-
let distanceFalloff = 1.0 / Math.max(
|
|
28
|
+
let distanceFalloff = 1.0 / Math.max(Math.pow(distance, decay_exponent), 0.01);
|
|
29
29
|
|
|
30
|
-
if (
|
|
30
|
+
if (cutoff_distance > 0.0) {
|
|
31
31
|
const b = distance / cutoff_distance;
|
|
32
|
-
const b2 = b*b;
|
|
33
|
-
const b4 = b2*b2;
|
|
32
|
+
const b2 = b * b;
|
|
33
|
+
const b4 = b2 * b2;
|
|
34
34
|
|
|
35
|
-
const c= saturate(
|
|
35
|
+
const c = saturate(1.0 - b4);
|
|
36
36
|
|
|
37
|
-
distanceFalloff *= c*c;
|
|
37
|
+
distanceFalloff *= c * c;
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
return distanceFalloff;
|
|
41
41
|
}
|
|
42
|
+
|
|
42
43
|
/**
|
|
43
44
|
*
|
|
44
45
|
* @type {number[]|Uint32Array}
|
|
@@ -170,7 +171,10 @@ export class PathTracedScene {
|
|
|
170
171
|
bvh.node_set_height(node, 0);
|
|
171
172
|
|
|
172
173
|
}
|
|
173
|
-
|
|
174
|
+
const primitive_counts = new Uint32Array(node_leaf_count);
|
|
175
|
+
primitive_counts.fill(1);
|
|
176
|
+
|
|
177
|
+
ebvh_nodes_sort_sah_local4(bvh, nodes, primitive_counts, 0, 2, node_leaf_count);
|
|
174
178
|
|
|
175
179
|
// record newly generated nodes as "unprocessed"
|
|
176
180
|
const unprocessed_nodes = new Uint32Array(node_leaf_count);
|
|
@@ -589,9 +593,9 @@ export class PathTracedScene {
|
|
|
589
593
|
continue;
|
|
590
594
|
}
|
|
591
595
|
|
|
592
|
-
const attenuation = light_getDistanceAttenuation(distance_to_light,radius,2);
|
|
596
|
+
const attenuation = light_getDistanceAttenuation(distance_to_light, radius, 2);
|
|
593
597
|
|
|
594
|
-
const intensity = dotNL * light.intensity.getValue()*attenuation;
|
|
598
|
+
const intensity = dotNL * light.intensity.getValue() * attenuation;
|
|
595
599
|
const light_color = light.color;
|
|
596
600
|
|
|
597
601
|
out[out_offset] += light_color.r * intensity;
|