@woosh/meep-engine 2.73.0 → 2.74.0
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/bundle-worker-image-decoder.js +1 -1
- package/build/meep.cjs +4 -4
- package/build/meep.min.js +1 -1
- package/build/meep.module.js +4 -4
- package/package.json +1 -1
- package/src/engine/asset/loaders/image/codec/NativeImageDecoder.js +2 -1
- package/src/engine/asset/loaders/image/codec/ThreadedImageDecoder.js +4 -5
- package/src/engine/asset/loaders/image/png/PNGReader.js +23 -19
- package/src/engine/graphics/generate_halton_jitter.js +21 -0
- package/src/engine/graphics/render/buffer/simple-fx/taa/TemporalSupersamplingRenderPlugin.js +3 -20
- package/src/engine/graphics/texture/virtual/v2/SparseTexture.js +129 -20
- package/src/engine/graphics/texture/virtual/v2/TileLoader.js +24 -7
- package/src/engine/graphics/texture/virtual/v2/UsageMetadata.js +73 -21
- package/src/engine/graphics/texture/virtual/v2/VirtualTextureManager.js +60 -5
- package/src/engine/graphics/texture/virtual/v2/debug/ResidencyDebugView.js +58 -0
- package/src/engine/graphics/texture/virtual/v2/debug/UsageDebugView.js +63 -0
- package/src/engine/graphics/texture/virtual/v2/{UsagePyramidDebugView.js → debug/UsagePyramidDebugView.js} +30 -39
- package/src/engine/graphics/texture/virtual/v2/prototype.js +46 -21
- package/src/engine/graphics/texture/virtual/v2/{TextureTile.js → tile/TextureTile.js} +1 -1
- package/src/engine/graphics/texture/virtual/v2/tile/compose_finger_print.js +23 -0
- package/src/engine/graphics/texture/virtual/v2/tile/compose_tile_address.js +22 -0
- package/src/engine/graphics/texture/virtual/v2/tile/decompose_finger_print.js +12 -0
- package/src/engine/graphics/texture/virtual/v2/tile/finger_print_to_tile_address.js +16 -0
- package/src/engine/graphics/texture/virtual/v2/{tile_index_to_finger_print.js → tile/tile_address_to_finger_print.js} +7 -3
- package/src/view/CSS_ABSOLUTE_POSITIONING.js +5 -0
- package/src/engine/graphics/texture/virtual/v2/UsageDebugView.js +0 -64
- package/src/engine/graphics/texture/virtual/v2/compose_finger_print.js +0 -13
- package/src/engine/graphics/texture/virtual/v2/finger_print_to_tile_index.js +0 -37
|
@@ -1,9 +1,27 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { arrayQuickSort } from "../../../../../core/collection/array/arrayQuickSort.js";
|
|
2
|
+
import { compose_finger_print } from "./tile/compose_finger_print.js";
|
|
3
|
+
import { finger_print_to_tile_address } from "./tile/finger_print_to_tile_address.js";
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
function compose_tile_address(mip, x, y) {
|
|
7
|
+
const finger_print = compose_finger_print(mip, x, y);
|
|
8
|
+
|
|
9
|
+
return finger_print_to_tile_address(finger_print);
|
|
10
|
+
}
|
|
3
11
|
|
|
4
12
|
export class UsageMetadata {
|
|
5
13
|
|
|
6
14
|
#counts_intrinsic = new Uint32Array(0);
|
|
15
|
+
/**
|
|
16
|
+
* Stores indices of tiles with usage > 0
|
|
17
|
+
* @type {Uint32Array}
|
|
18
|
+
*/
|
|
19
|
+
#occupancy = new Uint32Array(0);
|
|
20
|
+
/**
|
|
21
|
+
* Points at the end of the occupancy list
|
|
22
|
+
* @type {number}
|
|
23
|
+
*/
|
|
24
|
+
#occupancy_cursor = 0;
|
|
7
25
|
|
|
8
26
|
get counts() {
|
|
9
27
|
return this.#counts_intrinsic;
|
|
@@ -11,6 +29,7 @@ export class UsageMetadata {
|
|
|
11
29
|
|
|
12
30
|
#max_mip_level = 0;
|
|
13
31
|
|
|
32
|
+
|
|
14
33
|
set max_mip_level(v) {
|
|
15
34
|
this.#max_mip_level = v;
|
|
16
35
|
|
|
@@ -21,14 +40,21 @@ export class UsageMetadata {
|
|
|
21
40
|
return this.#max_mip_level;
|
|
22
41
|
}
|
|
23
42
|
|
|
43
|
+
|
|
44
|
+
get occupancy() {
|
|
45
|
+
return this.#occupancy;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
get occupancy_count() {
|
|
49
|
+
return this.#occupancy_cursor;
|
|
50
|
+
}
|
|
51
|
+
|
|
24
52
|
/**
|
|
25
53
|
*
|
|
26
54
|
*/
|
|
27
55
|
#ensureCapacity() {
|
|
28
56
|
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
const size = finger_print_to_tile_index(finger_print);
|
|
57
|
+
const size = compose_tile_address(this.#max_mip_level + 1, 0, 0);
|
|
32
58
|
|
|
33
59
|
if (this.#counts_intrinsic.length >= size) {
|
|
34
60
|
// already large enough
|
|
@@ -36,12 +62,7 @@ export class UsageMetadata {
|
|
|
36
62
|
}
|
|
37
63
|
|
|
38
64
|
this.#counts_intrinsic = new Uint32Array(size);
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
#getIndexBy(mip, x, y) {
|
|
42
|
-
const finger_print = compose_finger_print(mip, x, y);
|
|
43
|
-
|
|
44
|
-
return finger_print_to_tile_index(finger_print);
|
|
65
|
+
this.#occupancy = new Uint32Array(size);
|
|
45
66
|
}
|
|
46
67
|
|
|
47
68
|
/**
|
|
@@ -50,8 +71,7 @@ export class UsageMetadata {
|
|
|
50
71
|
* @returns {number}
|
|
51
72
|
*/
|
|
52
73
|
getCountByFingerprint(fingerprint) {
|
|
53
|
-
const index =
|
|
54
|
-
|
|
74
|
+
const index = finger_print_to_tile_address(fingerprint);
|
|
55
75
|
|
|
56
76
|
return this.#counts_intrinsic[index];
|
|
57
77
|
}
|
|
@@ -64,13 +84,14 @@ export class UsageMetadata {
|
|
|
64
84
|
* @returns {number}
|
|
65
85
|
*/
|
|
66
86
|
getCountBy(mip, x, y) {
|
|
67
|
-
const
|
|
87
|
+
const address = compose_tile_address(mip, x, y);
|
|
68
88
|
|
|
69
|
-
return this
|
|
89
|
+
return this.#counts_intrinsic[address];
|
|
70
90
|
}
|
|
71
91
|
|
|
72
92
|
clear() {
|
|
73
93
|
this.#counts_intrinsic.fill(0);
|
|
94
|
+
this.#occupancy_cursor = 0;
|
|
74
95
|
}
|
|
75
96
|
|
|
76
97
|
/**
|
|
@@ -81,7 +102,7 @@ export class UsageMetadata {
|
|
|
81
102
|
promoteAncestors(bias = 1) {
|
|
82
103
|
|
|
83
104
|
// traverse mip pyramid in reverse, so we can push counts to parents one level at a time
|
|
84
|
-
for (let mip = this.#max_mip_level
|
|
105
|
+
for (let mip = this.#max_mip_level; mip > 0; mip--) {
|
|
85
106
|
|
|
86
107
|
const mip_resolution = 1 << mip;
|
|
87
108
|
|
|
@@ -99,7 +120,7 @@ export class UsageMetadata {
|
|
|
99
120
|
const parent_x = x >>> 1;
|
|
100
121
|
const parent_y = y >>> 1;
|
|
101
122
|
|
|
102
|
-
const parent_index =
|
|
123
|
+
const parent_index = compose_tile_address(parent_level, parent_x, parent_y);
|
|
103
124
|
|
|
104
125
|
const parent_count = this.#counts_intrinsic[parent_index];
|
|
105
126
|
|
|
@@ -107,6 +128,10 @@ export class UsageMetadata {
|
|
|
107
128
|
|
|
108
129
|
if (parent_count < expected_count) {
|
|
109
130
|
this.#counts_intrinsic[parent_index] = expected_count;
|
|
131
|
+
|
|
132
|
+
if (parent_count === 0) {
|
|
133
|
+
this.#append_to_occupancy(parent_index);
|
|
134
|
+
}
|
|
110
135
|
}
|
|
111
136
|
|
|
112
137
|
}
|
|
@@ -115,6 +140,26 @@ export class UsageMetadata {
|
|
|
115
140
|
}
|
|
116
141
|
}
|
|
117
142
|
|
|
143
|
+
/**
|
|
144
|
+
*
|
|
145
|
+
* @param {number} address
|
|
146
|
+
*/
|
|
147
|
+
#append_to_occupancy(address) {
|
|
148
|
+
this.#occupancy[this.#occupancy_cursor] = address;
|
|
149
|
+
this.#occupancy_cursor++;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Sort occupancy list in descending order
|
|
154
|
+
*/
|
|
155
|
+
sortOccupancy() {
|
|
156
|
+
arrayQuickSort(
|
|
157
|
+
this.#occupancy,
|
|
158
|
+
(index) => -this.#counts_intrinsic[index], null,
|
|
159
|
+
0, this.#occupancy_cursor - 1
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
|
|
118
163
|
|
|
119
164
|
/**
|
|
120
165
|
*
|
|
@@ -125,7 +170,9 @@ export class UsageMetadata {
|
|
|
125
170
|
|
|
126
171
|
const data_size = data.length;
|
|
127
172
|
|
|
128
|
-
this.#ensureCapacity(
|
|
173
|
+
this.#ensureCapacity();
|
|
174
|
+
|
|
175
|
+
const counts = this.#counts_intrinsic;
|
|
129
176
|
|
|
130
177
|
for (let offset = 0; offset < data_size; offset += 4) {
|
|
131
178
|
|
|
@@ -142,11 +189,16 @@ export class UsageMetadata {
|
|
|
142
189
|
const tile_x = data[offset + 1] & max_tile_value;
|
|
143
190
|
const tile_y = data[offset + 2] & max_tile_value;
|
|
144
191
|
|
|
145
|
-
const
|
|
192
|
+
const tile_address = compose_tile_address(mip_level, tile_x, tile_y);
|
|
146
193
|
|
|
147
|
-
const
|
|
194
|
+
const previous_count = counts[tile_address];
|
|
195
|
+
|
|
196
|
+
if (previous_count === 0) {
|
|
197
|
+
// first occurrence, mark occupancy
|
|
198
|
+
this.#append_to_occupancy(tile_address);
|
|
199
|
+
}
|
|
148
200
|
|
|
149
|
-
|
|
201
|
+
counts[tile_address] = previous_count + 1;
|
|
150
202
|
}
|
|
151
203
|
|
|
152
204
|
}
|
|
@@ -12,8 +12,10 @@ import {
|
|
|
12
12
|
WebGLRenderTarget
|
|
13
13
|
} from "three";
|
|
14
14
|
import { assert } from "../../../../../core/assert.js";
|
|
15
|
+
import { array_copy } from "../../../../../core/collection/array/array_copy.js";
|
|
15
16
|
import { clamp } from "../../../../../core/math/clamp.js";
|
|
16
17
|
import { max2 } from "../../../../../core/math/max2.js";
|
|
18
|
+
import { generate_halton_jitter } from "../../../generate_halton_jitter.js";
|
|
17
19
|
import { renderScreenSpace } from "../../../render/utils/renderScreenSpace.js";
|
|
18
20
|
import { Sampler2D } from "../../sampler/Sampler2D.js";
|
|
19
21
|
import { fragment, vertex } from "./ShaderUsage.js";
|
|
@@ -65,8 +67,25 @@ const clear_usage_material = new RawShaderMaterial({
|
|
|
65
67
|
glslVersion: GLSL3
|
|
66
68
|
});
|
|
67
69
|
|
|
70
|
+
const scratch_matrix = new Float32Array(16);
|
|
71
|
+
|
|
68
72
|
export class VirtualTextureManager {
|
|
69
73
|
|
|
74
|
+
#frame_index = 0;
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* In order to avoid aliasing due to the fact that we render at a lower resolution, we move the camera slightly each frame to sweep across texels in-between
|
|
78
|
+
* @type {Float32Array}
|
|
79
|
+
*/
|
|
80
|
+
#frame_jitter_offsets = new Float32Array([0, 0]);
|
|
81
|
+
#frame_jitter_samples = 1;
|
|
82
|
+
#frame_jitter_enabled = true;
|
|
83
|
+
|
|
84
|
+
#initialize_frame_jitter() {
|
|
85
|
+
this.#frame_jitter_samples = this.#usage_resolution_scale;
|
|
86
|
+
this.#frame_jitter_offsets = generate_halton_jitter(this.#frame_jitter_samples);
|
|
87
|
+
}
|
|
88
|
+
|
|
70
89
|
#usage_buffer = new WebGLRenderTarget(1, 1, {
|
|
71
90
|
wrapT: ClampToEdgeWrapping,
|
|
72
91
|
wrapS: ClampToEdgeWrapping,
|
|
@@ -115,6 +134,7 @@ export class VirtualTextureManager {
|
|
|
115
134
|
*/
|
|
116
135
|
#usage_texture_bias = 0.1;
|
|
117
136
|
|
|
137
|
+
|
|
118
138
|
/**
|
|
119
139
|
*
|
|
120
140
|
* @param {number} resolution
|
|
@@ -150,6 +170,7 @@ export class VirtualTextureManager {
|
|
|
150
170
|
|
|
151
171
|
constructor() {
|
|
152
172
|
this.#initialize_usage_uniforms();
|
|
173
|
+
this.#initialize_frame_jitter();
|
|
153
174
|
}
|
|
154
175
|
|
|
155
176
|
#initialize_usage_uniforms() {
|
|
@@ -208,6 +229,28 @@ export class VirtualTextureManager {
|
|
|
208
229
|
|
|
209
230
|
}
|
|
210
231
|
|
|
232
|
+
#prepareUsageUniforms(camera) {
|
|
233
|
+
|
|
234
|
+
const uniforms = usage_material.uniforms;
|
|
235
|
+
const usage_buffer = this.#usage_buffer;
|
|
236
|
+
const camera_projection_matrix = camera.projectionMatrix.elements;
|
|
237
|
+
|
|
238
|
+
if (this.#frame_jitter_enabled) {
|
|
239
|
+
// apply jitter to projection matrix
|
|
240
|
+
const jitter_index = this.#frame_index % this.#frame_jitter_samples;
|
|
241
|
+
|
|
242
|
+
const jitter_offset_x = this.#frame_jitter_offsets[jitter_index * 2];
|
|
243
|
+
const jitter_offset_y = this.#frame_jitter_offsets[jitter_index * 2 + 1];
|
|
244
|
+
|
|
245
|
+
camera_projection_matrix[8] = jitter_offset_x / usage_buffer.width;
|
|
246
|
+
camera_projection_matrix[9] = jitter_offset_y / usage_buffer.height;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
uniforms.modelViewMatrix.value.multiplyMatrices(camera.matrixWorldInverse, camera.matrixWorld);
|
|
251
|
+
uniforms.projectionMatrix.value.copy(camera.projectionMatrix);
|
|
252
|
+
}
|
|
253
|
+
|
|
211
254
|
/**
|
|
212
255
|
*
|
|
213
256
|
* @param {WebGLRenderer} renderer
|
|
@@ -218,37 +261,49 @@ export class VirtualTextureManager {
|
|
|
218
261
|
|
|
219
262
|
const usage_buffer = this.#usage_buffer;
|
|
220
263
|
|
|
221
|
-
const uniforms = usage_material.uniforms;
|
|
222
264
|
|
|
223
|
-
|
|
224
|
-
uniforms.projectionMatrix.value.copy(camera.projectionMatrix);
|
|
265
|
+
const camera_projection_matrix = camera.projectionMatrix.elements;
|
|
225
266
|
|
|
226
267
|
// remember existing state
|
|
227
268
|
const _old_render_target = renderer.getRenderTarget();
|
|
228
269
|
const _auto_clear = renderer.autoClear;
|
|
229
|
-
|
|
270
|
+
array_copy(camera_projection_matrix, 0, scratch_matrix, 0, 16);
|
|
230
271
|
const _old_material = scene.overrideMaterial;
|
|
272
|
+
const _old_camera_matrix_update = camera.matrixAutoUpdate;
|
|
273
|
+
|
|
274
|
+
camera.matrixAutoUpdate = false;
|
|
231
275
|
|
|
232
276
|
renderer.autoClear = false;
|
|
233
277
|
renderer.setRenderTarget(usage_buffer);
|
|
234
|
-
scene.overrideMaterial = usage_material;
|
|
235
278
|
|
|
236
279
|
// clear out usage texture
|
|
237
280
|
renderScreenSpace(renderer, clear_usage_material);
|
|
238
281
|
|
|
239
282
|
renderer.clearDepth();
|
|
240
283
|
|
|
284
|
+
scene.overrideMaterial = usage_material;
|
|
285
|
+
|
|
286
|
+
this.#prepareUsageUniforms(camera);
|
|
287
|
+
|
|
241
288
|
renderer.render(scene, camera);
|
|
242
289
|
|
|
243
290
|
scene.overrideMaterial = _old_material;
|
|
244
291
|
|
|
245
292
|
renderer.readRenderTargetPixels(usage_buffer, 0, 0, usage_buffer.width, usage_buffer.height, this.#usage_pixel_data.data);
|
|
246
293
|
|
|
294
|
+
// restore state
|
|
247
295
|
renderer.setRenderTarget(_old_render_target);
|
|
248
296
|
renderer.autoClear = _auto_clear;
|
|
297
|
+
array_copy(scratch_matrix, 0, camera_projection_matrix, 0, 16);
|
|
249
298
|
|
|
299
|
+
camera.matrixAutoUpdate = _old_camera_matrix_update;
|
|
300
|
+
|
|
301
|
+
//
|
|
250
302
|
this.#usage_metadata.fromTexture(this.#usage_pixel_data.data);
|
|
251
303
|
this.#usage_metadata.promoteAncestors(1);
|
|
304
|
+
this.#usage_metadata.sortOccupancy();
|
|
305
|
+
|
|
306
|
+
this.#frame_index++;
|
|
252
307
|
}
|
|
253
308
|
|
|
254
309
|
dispose() {
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { CSS_ABSOLUTE_POSITIONING } from "../../../../../../view/CSS_ABSOLUTE_POSITIONING.js";
|
|
2
|
+
import { CanvasView } from "../../../../../../view/elements/CanvasView.js";
|
|
3
|
+
import EmptyView from "../../../../../../view/elements/EmptyView.js";
|
|
4
|
+
import { sampler2d_write_to_canvas_raw } from "../../../sampler/sampler2d_write_to_canvas_raw.js";
|
|
5
|
+
|
|
6
|
+
export class ResidencyDebugView extends EmptyView {
|
|
7
|
+
/**
|
|
8
|
+
*
|
|
9
|
+
* @type {SparseTexture|null}
|
|
10
|
+
*/
|
|
11
|
+
texture = null;
|
|
12
|
+
|
|
13
|
+
#canvas = new CanvasView();
|
|
14
|
+
|
|
15
|
+
constructor() {
|
|
16
|
+
super({
|
|
17
|
+
css: {
|
|
18
|
+
position: "absolute"
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
this.#canvas.css(CSS_ABSOLUTE_POSITIONING);
|
|
23
|
+
|
|
24
|
+
this.addChild(this.#canvas);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
update() {
|
|
28
|
+
|
|
29
|
+
const t = this.texture;
|
|
30
|
+
if (t === null) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const canvas = this.#canvas;
|
|
35
|
+
canvas.size.readFromArray(t.page_texture_resolution);
|
|
36
|
+
|
|
37
|
+
this.size.copy(canvas.size);
|
|
38
|
+
|
|
39
|
+
const residentTiles = t.resident_tiles;
|
|
40
|
+
|
|
41
|
+
const temp = new CanvasView();
|
|
42
|
+
const tile_resolution = t.tile_resolution;
|
|
43
|
+
temp.size.setScalar(tile_resolution);
|
|
44
|
+
|
|
45
|
+
const tile_columns = t.page_texture_resolution[0] / tile_resolution;
|
|
46
|
+
|
|
47
|
+
for (let i = 0; i < residentTiles.length; i++) {
|
|
48
|
+
const tile = residentTiles[i];
|
|
49
|
+
|
|
50
|
+
sampler2d_write_to_canvas_raw(tile.data, temp.el);
|
|
51
|
+
|
|
52
|
+
const column = tile.page_slot % tile_columns;
|
|
53
|
+
const row = (tile.page_slot / tile_columns) | 0;
|
|
54
|
+
|
|
55
|
+
canvas.context2d.drawImage(temp.el, 0, 0, tile_resolution, tile_resolution, tile_resolution * column, tile_resolution * row, tile_resolution, tile_resolution);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import LabelView from "../../../../../../view/common/LabelView.js";
|
|
2
|
+
import EmptyView from "../../../../../../view/elements/EmptyView.js";
|
|
3
|
+
import { decompose_finger_print } from "../tile/decompose_finger_print.js";
|
|
4
|
+
import { tile_address_to_finger_print } from "../tile/tile_address_to_finger_print.js";
|
|
5
|
+
|
|
6
|
+
export class UsageDebugView extends EmptyView {
|
|
7
|
+
#tileCount = new LabelView("")
|
|
8
|
+
#tiles = new EmptyView();
|
|
9
|
+
#mip_levels = 0;
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
constructor(opt) {
|
|
13
|
+
super(opt);
|
|
14
|
+
|
|
15
|
+
this.addChild(this.#tileCount);
|
|
16
|
+
this.addChild(this.#tiles);
|
|
17
|
+
|
|
18
|
+
this.css({
|
|
19
|
+
position: "absolute",
|
|
20
|
+
left: "0",
|
|
21
|
+
top: "0",
|
|
22
|
+
background: "rgba(255,255,255,0.5)",
|
|
23
|
+
fontFamily: "monospace",
|
|
24
|
+
fontSize: "10px"
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
set mip_levels(v) {
|
|
29
|
+
this.#mip_levels = v;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
*
|
|
34
|
+
* @param {UsageMetadata} usage
|
|
35
|
+
*/
|
|
36
|
+
set usage(usage) {
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
this.#tiles.removeAllChildren();
|
|
40
|
+
|
|
41
|
+
const occupancy = usage.occupancy;
|
|
42
|
+
const occupancyCount = usage.occupancy_count;
|
|
43
|
+
|
|
44
|
+
for (let i = 0; i < occupancyCount; i++) {
|
|
45
|
+
const occupancy_index = occupancy[i];
|
|
46
|
+
const fingerPrint = tile_address_to_finger_print(occupancy_index);
|
|
47
|
+
|
|
48
|
+
const count = usage.getCountByFingerprint(fingerPrint);
|
|
49
|
+
|
|
50
|
+
if (count <= 0) {
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const { mip, x, y } = decompose_finger_print(fingerPrint);
|
|
55
|
+
|
|
56
|
+
this.#tiles.addChild(new LabelView(`ID: ${0} Level: ${mip} X: ${x} Y: ${y} USAGE: ${count}`));
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
this.#tileCount.updateText(`Tile Count: ${occupancyCount}`);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
}
|
|
@@ -1,12 +1,9 @@
|
|
|
1
|
-
import { assert } from "
|
|
2
|
-
import LabelView from "
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
top: 0,
|
|
8
|
-
left: 0
|
|
9
|
-
};
|
|
1
|
+
import { assert } from "../../../../../../core/assert.js";
|
|
2
|
+
import LabelView from "../../../../../../view/common/LabelView.js";
|
|
3
|
+
import { CSS_ABSOLUTE_POSITIONING } from "../../../../../../view/CSS_ABSOLUTE_POSITIONING.js";
|
|
4
|
+
import EmptyView from "../../../../../../view/elements/EmptyView.js";
|
|
5
|
+
import { decompose_finger_print } from "../tile/decompose_finger_print.js";
|
|
6
|
+
import { tile_address_to_finger_print } from "../tile/tile_address_to_finger_print.js";
|
|
10
7
|
|
|
11
8
|
class TextureLODView extends EmptyView {
|
|
12
9
|
|
|
@@ -22,7 +19,7 @@ class TextureLODView extends EmptyView {
|
|
|
22
19
|
resolution = [1, 1],
|
|
23
20
|
tile_size = 8
|
|
24
21
|
}) {
|
|
25
|
-
super({ css:
|
|
22
|
+
super({ css: CSS_ABSOLUTE_POSITIONING });
|
|
26
23
|
|
|
27
24
|
this.css({
|
|
28
25
|
background: "rgba(255,255,255,0.05)"
|
|
@@ -38,10 +35,11 @@ class TextureLODView extends EmptyView {
|
|
|
38
35
|
|
|
39
36
|
for (let j = 0; j < height; j++) {
|
|
40
37
|
for (let i = 0; i < width; i++) {
|
|
41
|
-
const tileView = new EmptyView({ css:
|
|
38
|
+
const tileView = new EmptyView({ css: CSS_ABSOLUTE_POSITIONING });
|
|
42
39
|
|
|
43
40
|
// const flipped_y = height - j - 1;
|
|
44
41
|
tileView.position.set(i * tile_size, j * tile_size);
|
|
42
|
+
// tileView.position.set(i * tile_size, flipped_y * tile_size);
|
|
45
43
|
tileView.size.set(tile_size, tile_size);
|
|
46
44
|
|
|
47
45
|
this.clearTile(tileView);
|
|
@@ -57,7 +55,7 @@ class TextureLODView extends EmptyView {
|
|
|
57
55
|
|
|
58
56
|
const label = new LabelView(`${width} x ${height}`, {
|
|
59
57
|
css: {
|
|
60
|
-
...
|
|
58
|
+
...CSS_ABSOLUTE_POSITIONING,
|
|
61
59
|
color: '#FFFFFF',
|
|
62
60
|
textShadow: '0 0 2px black',
|
|
63
61
|
whiteSpace: "pre"
|
|
@@ -200,10 +198,7 @@ export class UsagePyramidDebugView extends EmptyView {
|
|
|
200
198
|
for (let i = 0; i < this.#used_set_size; i++) {
|
|
201
199
|
const finger_print = this.#used_set[i];
|
|
202
200
|
|
|
203
|
-
|
|
204
|
-
const mip = (finger_print >> 24) & 0xFF;
|
|
205
|
-
const x = (finger_print >> 16) & 0xFF;
|
|
206
|
-
const y = (finger_print >> 8) & 0xFF;
|
|
201
|
+
const { mip, x, y } = decompose_finger_print(finger_print);
|
|
207
202
|
|
|
208
203
|
const mipView = this.#levels[mip];
|
|
209
204
|
|
|
@@ -214,38 +209,34 @@ export class UsagePyramidDebugView extends EmptyView {
|
|
|
214
209
|
this.#used_set_size = 0;
|
|
215
210
|
|
|
216
211
|
|
|
217
|
-
const
|
|
212
|
+
const occupancy = usage.occupancy;
|
|
213
|
+
const occupancyCount = usage.occupancy_count;
|
|
218
214
|
|
|
219
|
-
for (let
|
|
220
|
-
const
|
|
215
|
+
for (let i = 0; i < occupancyCount; i++) {
|
|
216
|
+
const occupancy_index = occupancy[i];
|
|
217
|
+
const fingerPrint = tile_address_to_finger_print(occupancy_index);
|
|
221
218
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
219
|
+
const count = usage.getCountByFingerprint(fingerPrint);
|
|
220
|
+
|
|
221
|
+
if (count <= 0) {
|
|
222
|
+
continue;
|
|
223
|
+
}
|
|
225
224
|
|
|
226
|
-
|
|
227
|
-
continue;
|
|
228
|
-
}
|
|
225
|
+
const { mip, x, y } = decompose_finger_print(fingerPrint);
|
|
229
226
|
|
|
230
|
-
const mipView = this.#levels[mip];
|
|
231
227
|
|
|
232
|
-
|
|
228
|
+
const mipView = this.#levels[mip];
|
|
233
229
|
|
|
234
|
-
|
|
235
|
-
background: "rgba(255,0,0,0.8)"
|
|
236
|
-
});
|
|
230
|
+
const tile = mipView.getTile(x, y);
|
|
237
231
|
|
|
238
|
-
|
|
232
|
+
tile.css({
|
|
233
|
+
background: "rgba(255,0,0,0.8)"
|
|
234
|
+
});
|
|
239
235
|
|
|
240
|
-
|
|
241
|
-
| (x << 16)
|
|
242
|
-
| (y << 8)
|
|
243
|
-
;
|
|
236
|
+
tile.visible = true;
|
|
244
237
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
}
|
|
248
|
-
}
|
|
238
|
+
this.#used_set[this.#used_set_size] = fingerPrint;
|
|
239
|
+
this.#used_set_size++;
|
|
249
240
|
}
|
|
250
241
|
|
|
251
242
|
}
|
|
@@ -18,8 +18,10 @@ import EmptyView from "../../../../../view/elements/EmptyView.js";
|
|
|
18
18
|
import { AssetManager } from "../../../../asset/AssetManager.js";
|
|
19
19
|
import { GameAssetType } from "../../../../asset/GameAssetType.js";
|
|
20
20
|
import { ImageRGBADataLoader } from "../../../../asset/loaders/image/ImageRGBADataLoader.js";
|
|
21
|
+
import { ResidencyDebugView } from "./debug/ResidencyDebugView.js";
|
|
22
|
+
import { UsageDebugView } from "./debug/UsageDebugView.js";
|
|
23
|
+
import { UsagePyramidDebugView } from "./debug/UsagePyramidDebugView.js";
|
|
21
24
|
import { SparseTexture } from "./SparseTexture.js";
|
|
22
|
-
import { UsageDebugView } from "./UsageDebugView.js";
|
|
23
25
|
import { VirtualTextureManager } from "./VirtualTextureManager.js";
|
|
24
26
|
|
|
25
27
|
let camera,
|
|
@@ -41,36 +43,45 @@ am.startup();
|
|
|
41
43
|
|
|
42
44
|
const virtualTextureManager = new VirtualTextureManager();
|
|
43
45
|
virtualTextureManager.setTextureParameters(
|
|
44
|
-
|
|
45
|
-
16384,
|
|
46
|
-
|
|
46
|
+
4096,
|
|
47
|
+
// 16384,
|
|
48
|
+
32,
|
|
47
49
|
3
|
|
48
50
|
);
|
|
49
51
|
|
|
50
52
|
const sparseTexture = new SparseTexture();
|
|
51
|
-
sparseTexture.
|
|
53
|
+
sparseTexture.path = "data/textures/utility/vt/TexelDensity1";
|
|
54
|
+
sparseTexture.page_texture_size = [512, 512];
|
|
52
55
|
sparseTexture.tile_resolution = virtualTextureManager.tile_resolution;
|
|
53
56
|
sparseTexture.asset_manager = am;
|
|
54
57
|
|
|
58
|
+
|
|
55
59
|
console.log(sparseTexture);
|
|
56
60
|
|
|
57
61
|
// const TEXTURE_URL = "data/textures/utility/uv_map_reference.png";
|
|
58
|
-
|
|
62
|
+
const TEXTURE_URL = "data/textures/utility/4096x4096TexelDensityTexture1.png";
|
|
59
63
|
// const TEXTURE_URL = "data/textures/utility/Lenna.png";
|
|
60
64
|
// const TEXTURE_URL = "data/textures/utility/TESTIMAGES/SAMPLING/8BIT/RGB/2448x2448/SRC/img_2448x2448_3x8bit_SRC_RGB_cards_a.png";
|
|
61
|
-
const TEXTURE_URL = "data/models/LowPolyTownshipSet/Town_Hall//diffuse_2048.png";
|
|
65
|
+
// const TEXTURE_URL = "data/models/LowPolyTownshipSet/Town_Hall//diffuse_2048.png";
|
|
62
66
|
|
|
63
67
|
const container_view = new EmptyView();
|
|
64
68
|
//
|
|
65
69
|
const usageDebugView = new UsageDebugView();
|
|
66
70
|
usageDebugView.mip_levels = virtualTextureManager.max_mip_level;
|
|
67
|
-
container_view.addChild(usageDebugView);
|
|
71
|
+
// container_view.addChild(usageDebugView);
|
|
68
72
|
|
|
69
73
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
+
const usagePyramidDebugView = new UsagePyramidDebugView();
|
|
75
|
+
usagePyramidDebugView.setImageURL(TEXTURE_URL);
|
|
76
|
+
container_view.addChild(usagePyramidDebugView);
|
|
77
|
+
|
|
78
|
+
const residencyDebugView = new ResidencyDebugView();
|
|
79
|
+
residencyDebugView.texture = sparseTexture;
|
|
80
|
+
residencyDebugView.css({
|
|
81
|
+
bottom: 0,
|
|
82
|
+
right: 0
|
|
83
|
+
});
|
|
84
|
+
container_view.addChild(residencyDebugView);
|
|
74
85
|
|
|
75
86
|
const options = {
|
|
76
87
|
spin: true
|
|
@@ -82,11 +93,27 @@ animate();
|
|
|
82
93
|
|
|
83
94
|
function makeTorus() {
|
|
84
95
|
const size = 0.65;
|
|
96
|
+
|
|
97
|
+
const map = new TextureLoader().load(TEXTURE_URL);
|
|
98
|
+
map.flipY = false;
|
|
99
|
+
|
|
85
100
|
mesh = new Mesh(new TorusGeometry(size, 0.3, 30, 30), new MeshStandardMaterial({
|
|
86
101
|
roughness: 0.4,
|
|
87
|
-
map
|
|
102
|
+
map
|
|
88
103
|
}));
|
|
89
104
|
mesh.rotation.x = 0.3;
|
|
105
|
+
|
|
106
|
+
scene.add(mesh);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function makeGLTF(path) {
|
|
110
|
+
|
|
111
|
+
new GLTFLoader().load(path, (gltf) => {
|
|
112
|
+
|
|
113
|
+
mesh = gltf.scene;
|
|
114
|
+
scene.add(mesh);
|
|
115
|
+
|
|
116
|
+
});
|
|
90
117
|
}
|
|
91
118
|
|
|
92
119
|
function init() {
|
|
@@ -105,13 +132,9 @@ function init() {
|
|
|
105
132
|
|
|
106
133
|
clock = new Clock();
|
|
107
134
|
|
|
135
|
+
makeTorus();
|
|
108
136
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
mesh = gltf.scene;
|
|
112
|
-
scene.add(mesh);
|
|
113
|
-
|
|
114
|
-
});
|
|
137
|
+
// makeGLTF("data/models/LowPolyTownshipSet/Town_Hall/model.gltf");
|
|
115
138
|
|
|
116
139
|
scene.add(new DirectionalLight(0xFFFFFF, 0.7));
|
|
117
140
|
scene.add(new AmbientLight(0xFFFFFF, 0.2));
|
|
@@ -187,6 +210,8 @@ function render() {
|
|
|
187
210
|
|
|
188
211
|
usageDebugView.usage = virtualTextureManager.usage_metadata;
|
|
189
212
|
|
|
190
|
-
|
|
191
|
-
|
|
213
|
+
usagePyramidDebugView.setTextureParameters(virtualTextureManager.texture_resolution, virtualTextureManager.tile_resolution);
|
|
214
|
+
usagePyramidDebugView.usage = virtualTextureManager.usage_metadata;
|
|
215
|
+
|
|
216
|
+
residencyDebugView.update();
|
|
192
217
|
}
|