@woosh/meep-engine 2.39.37 → 2.39.38

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.
Files changed (70) hide show
  1. package/LICENSE +13 -0
  2. package/core/assert.js +14 -5
  3. package/core/bvh2/aabb3/AABB3.js +2 -2
  4. package/core/bvh2/aabb3/aabb3_detailed_volume_intersection.js +3 -2
  5. package/core/bvh2/aabb3/aabb3_intersects_frustum_array.js +2 -2
  6. package/core/bvh2/bvh3/ExplicitBinaryBoundingVolumeHierarchy.js +7 -0
  7. package/core/bvh2/bvh3/query/compute_tight_near_far_clipping_planes.js +149 -6
  8. package/core/bvh2/bvh3/query/compute_tight_near_far_clipping_planes.spec.js +41 -0
  9. package/core/bvh2/traversal/ThreeClippingPlaneComputingBVHVisitor.js +2 -2
  10. package/core/bvh2/traversal/__process_point_if_within_planes.js +2 -2
  11. package/core/bvh2/traversal/aabb3_detailed_volume_intersection_callback_based.js +3 -0
  12. package/core/geom/3d/aabb/aabb3_computeDistanceAbovePlane_max.spec.js +8 -0
  13. package/core/geom/3d/aabb/{aabb3_computeDistanceAbovePlane.js → aabb3_compute_distance_above_plane_max.js} +3 -2
  14. package/core/geom/3d/aabb/computeAABB3PlaneSide.js +3 -3
  15. package/core/geom/3d/frustum/frustum3_computeNearestPointToPoint.js +3 -2
  16. package/core/geom/3d/plane/is_point_within_planes.js +2 -2
  17. package/core/geom/3d/plane/plane3_projectPoint.js +2 -2
  18. package/core/geom/3d/plane/plane3_projectPoint.spec.js +54 -0
  19. package/core/geom/Plane.js +0 -19
  20. package/core/geom/v3_distance_above_plane.js +20 -0
  21. package/core/geom/v3_distance_above_plane.spec.js +40 -0
  22. package/core/math/statistics/halton_sequence.js +26 -0
  23. package/engine/asset/loaders/ArrayBufferLoader.js +76 -16
  24. package/engine/ecs/EntityComponentDataset.js +18 -28
  25. package/engine/graphics/GraphicsEngine.d.ts +2 -2
  26. package/engine/graphics/GraphicsEngine.js +11 -15
  27. package/engine/graphics/composit/LayerCompositer.js +1 -0
  28. package/engine/graphics/ecs/camera/Camera.js +2 -2
  29. package/engine/graphics/ecs/camera/CameraSystem.js +6 -0
  30. package/engine/graphics/ecs/light/binding/three/ThreeLightBinding.js +1 -1
  31. package/engine/graphics/ecs/mesh-v2/aggregate/prototypeSGMesh.js +17 -20
  32. package/engine/graphics/filter/FlipArrayInPlace.js +11 -6
  33. package/engine/graphics/geometry/clipping/ClippedGeometry.js +4 -4
  34. package/engine/graphics/micron/prototypeVirtualGeometry.js +3 -1
  35. package/engine/graphics/render/buffer/simple-fx/ao/AmbientOcclusionPostProcessEffect.js +2 -0
  36. package/engine/graphics/render/buffer/simple-fx/taa/TemporalSupersamplingRenderPlugin.js +95 -0
  37. package/engine/graphics/render/buffer/simple-fx/taa/prototypeTAA.js +61 -0
  38. package/engine/graphics/render/forward_plus/LightManager.js +4 -4
  39. package/engine/graphics/render/forward_plus/plugin/ForwardPlusRenderingPlugin.js +6 -7
  40. package/engine/graphics/render/forward_plus/plugin/MaterialTransformer.js +6 -2
  41. package/engine/graphics/render/forward_plus/query/query_bvh_frustum_from_objects.js +4 -2
  42. package/engine/graphics/render/forward_plus/query/query_bvh_frustum_from_texture.js +4 -2
  43. package/engine/graphics/render/frame_graph/GraphNode.js +22 -0
  44. package/engine/graphics/render/frame_graph/RenderGraph.js +405 -0
  45. package/engine/graphics/render/frame_graph/RenderGraphBuilder.js +77 -0
  46. package/engine/graphics/render/frame_graph/RenderPass.js +30 -12
  47. package/engine/graphics/render/frame_graph/RenderPassNode.js +103 -0
  48. package/engine/graphics/render/frame_graph/RenderPassResources.js +54 -4
  49. package/engine/graphics/render/frame_graph/ResourceEntry.js +77 -0
  50. package/engine/graphics/render/frame_graph/ResourceNode.js +23 -0
  51. package/engine/graphics/render/frame_graph/TextureDescriptor.js +38 -4
  52. package/engine/graphics/render/frame_graph/sample/deferred/GBufferDrawPass.js +11 -5
  53. package/engine/graphics/render/frame_graph/sample/deferred/LightingPass.js +24 -0
  54. package/engine/graphics/render/frame_graph/sample/deferred/run.js +31 -0
  55. package/engine/graphics/render/frame_graph/sample/meep-v1/ColorDepthPass.js +38 -0
  56. package/engine/graphics/render/frame_graph/sample/meep-v1/OutlinePass.js +9 -0
  57. package/engine/graphics/render/frame_graph/sample/meep-v1/SSAOPass.js +5 -0
  58. package/engine/graphics/render/frame_graph/sample/meep-v1/render.js +7 -0
  59. package/engine/graphics/render/frame_graph/webgl/WebGLRenderContext.js +5 -0
  60. package/engine/graphics/render/layers/RenderLayerUtils.js +5 -3
  61. package/engine/graphics/render/view/CameraView.js +38 -0
  62. package/engine/knowledge/database/DATABASE_SERIALIZATION_IGNORE_PROPERTY.js +1 -0
  63. package/engine/knowledge/database/StaticKnowledgeDataTable.js +5 -4
  64. package/package.json +1 -1
  65. package/core/geom/Plane.spec.js +0 -12
  66. package/engine/graphics/render/frame_graph/FrameGraphBuilder.js +0 -36
  67. package/engine/graphics/render/frame_graph/Resource.js +0 -21
  68. package/engine/graphics/render/frame_graph/ResourceReference.js +0 -14
  69. package/engine/graphics/render/frame_graph/UsageModeType.js +0 -5
  70. package/engine/graphics/render/frame_graph/sample/deferred/PresentPass.js +0 -17
@@ -20,15 +20,13 @@ export class ForwardPlusRenderingPlugin extends EnginePlugin {
20
20
 
21
21
  /**
22
22
  *
23
- * @param {WebGLRenderer} renderer
24
- * @param {Camera} camera
25
- * @param {Scene} scene
23
+ * @param {CameraView} view
26
24
  * @private
27
25
  */
28
- __prepare_for_render(renderer, camera, scene) {
29
- this.__material_transformer.updateCamera(camera);
26
+ __prepare_for_render(view) {
27
+ this.__material_transformer.updateCamera(view);
30
28
 
31
- this.__light_manager.buildTiles(camera);
29
+ this.__light_manager.buildTiles(view.camera);
32
30
  }
33
31
 
34
32
  updateResolution() {
@@ -49,7 +47,8 @@ export class ForwardPlusRenderingPlugin extends EnginePlugin {
49
47
  graphics.viewport.size.onChanged.add(this.updateResolution, this);
50
48
  graphics.pixelRatio.onChanged.add(this.updateResolution, this);
51
49
 
52
- graphics.on.preRender.add(this.__prepare_for_render, this);
50
+
51
+ graphics.main_view.on.preRender.add(this.__prepare_for_render, this);
53
52
 
54
53
  this.updateResolution();
55
54
 
@@ -62,9 +62,13 @@ export class MaterialTransformer extends AbstractMaterialTransformer {
62
62
  };
63
63
  }
64
64
 
65
+ /**
66
+ *
67
+ * @param {CameraView} c
68
+ */
65
69
  updateCamera(c) {
66
- this.__common_uniforms.fp_f_camera_far.value = c.far;
67
- this.__common_uniforms.fp_f_camera_near.value = c.near;
70
+ this.__common_uniforms.fp_f_camera_far.value = c.camera.far;
71
+ this.__common_uniforms.fp_f_camera_near.value = c.camera.near;
68
72
  }
69
73
 
70
74
  transform(source) {
@@ -1,4 +1,6 @@
1
- import { aabb3_computeDistanceAbovePlane } from "../../../../../core/geom/3d/aabb/aabb3_computeDistanceAbovePlane.js";
1
+ import {
2
+ aabb3_computeDistanceAbovePlane_max
3
+ } from "../../../../../core/geom/3d/aabb/aabb3_compute_distance_above_plane_max.js";
2
4
  import { point_light_inside_volume } from "./point_light_inside_volume.js";
3
5
  import { spot_light_inside_volume } from "./spot_light_inside_volume.js";
4
6
 
@@ -50,7 +52,7 @@ export function query_bvh_frustum_from_objects(
50
52
  const plane_normal_z = planes[plane_address + 2];
51
53
  const plane_constant = planes[plane_address + 3];
52
54
 
53
- const distanceAbovePlane = aabb3_computeDistanceAbovePlane(
55
+ const distanceAbovePlane = aabb3_computeDistanceAbovePlane_max(
54
56
  plane_normal_x, plane_normal_y, plane_normal_z, plane_constant,
55
57
  n.x0, n.y0, n.z0,
56
58
  n.x1, n.y1, n.z1
@@ -1,4 +1,6 @@
1
- import { aabb3_computeDistanceAbovePlane } from "../../../../../core/geom/3d/aabb/aabb3_computeDistanceAbovePlane.js";
1
+ import {
2
+ aabb3_computeDistanceAbovePlane_max
3
+ } from "../../../../../core/geom/3d/aabb/aabb3_compute_distance_above_plane_max.js";
2
4
  import { point_light_inside_volume } from "./point_light_inside_volume.js";
3
5
  import { BVH_BINARY_NODE_SIZE, BVH_LEAF_NODE_SIZE } from "../../../../../core/bvh2/binary/2/BinaryUint32BVH.js";
4
6
 
@@ -69,7 +71,7 @@ export function query_bvh_frustum_from_texture(
69
71
  const plane_normal_z = planes[plane_address + 2];
70
72
  const plane_constant = planes[plane_address + 3];
71
73
 
72
- const distanceAbovePlane = aabb3_computeDistanceAbovePlane(
74
+ const distanceAbovePlane = aabb3_computeDistanceAbovePlane_max(
73
75
  plane_normal_x, plane_normal_y, plane_normal_z, plane_constant,
74
76
  n_x0, n_y0, n_z0,
75
77
  n_x1, n_y1, n_z1
@@ -0,0 +1,22 @@
1
+ export class GraphNode {
2
+ /**
3
+ *
4
+ * @type {string}
5
+ */
6
+ name = "";
7
+ /**
8
+ *
9
+ * @type {number}
10
+ */
11
+ id = 0;
12
+ /**
13
+ *
14
+ * @type {number}
15
+ */
16
+ version = 0;
17
+ /**
18
+ *
19
+ * @type {number}
20
+ */
21
+ ref_count = 0;
22
+ }
@@ -0,0 +1,405 @@
1
+ import { RenderGraphBuilder } from "./RenderGraphBuilder.js";
2
+ import { RenderPassNode } from "./RenderPassNode.js";
3
+ import { ResourceNode } from "./ResourceNode.js";
4
+ import { assert } from "../../../../core/assert.js";
5
+ import LineBuilder from "../../../../core/codegen/LineBuilder.js";
6
+ import { RenderPassResources } from "./RenderPassResources.js";
7
+ import { ResourceEntry } from "./ResourceEntry.js";
8
+
9
+ /**
10
+ * Based on the Frostbite's GDC paper "FrameGraph: Extensible Rendering Architecture in Frostbite" by Yuriy O'Donnell
11
+ * @see https://github.com/skaarj1989/FrameGraph
12
+ */
13
+ export class RenderGraph {
14
+ /**
15
+ *
16
+ * @type {RenderPass[]}
17
+ * @private
18
+ */
19
+ __passes = [];
20
+
21
+ /**
22
+ *
23
+ * @type {RenderPassNode[]}
24
+ * @private
25
+ */
26
+ __pass_nodes = [];
27
+
28
+ /**
29
+ *
30
+ * @type {ResourceNode[]}
31
+ * @private
32
+ */
33
+ __resource_nodes = [];
34
+
35
+ /**
36
+ *
37
+ * @type {ResourceEntry[]}
38
+ * @private
39
+ */
40
+ __resource_registry = [];
41
+
42
+ /**
43
+ *
44
+ * @param {number} id Resource Node ID
45
+ * @returns {ResourceEntry}
46
+ */
47
+ getResourceEntry(id) {
48
+ const node = this.getResourceNode(id);
49
+
50
+ return this.__resource_registry[node.resource_id];
51
+ }
52
+
53
+ /**
54
+ *
55
+ * @param {number} id
56
+ * @returns {ResourceNode}
57
+ */
58
+ getResourceNode(id) {
59
+ assert.isNonNegativeInteger(id, 'id');
60
+
61
+ const nodes = this.__resource_nodes;
62
+ const node_count = nodes.length;
63
+ for (let i = 0; i < node_count; i++) {
64
+ const node = nodes[i];
65
+ if (node.id === id) {
66
+ return node;
67
+ }
68
+ }
69
+
70
+ throw new Error(`Resource Node ${id} not found`);
71
+ }
72
+
73
+ /**
74
+ * @template T
75
+ * @param {number} id resource ID
76
+ * @returns {T}
77
+ */
78
+ getDescriptor(id) {
79
+ return this.getResourceEntry(id).resource_descriptor;
80
+ }
81
+
82
+ /**
83
+ * @template T
84
+ * @param {string} name
85
+ * @param {T} descriptor
86
+ */
87
+ create_resource(name, descriptor) {
88
+ const resource = this._createResourceEntry(descriptor);
89
+
90
+ return this._createResourceNode(name, resource.resource_id).id;
91
+ }
92
+
93
+ /**
94
+ * @template T
95
+ * @param {T} descriptor
96
+ * @return {ResourceEntry}
97
+ * @private
98
+ */
99
+ _createResourceEntry(descriptor) {
100
+
101
+ const entry = new ResourceEntry();
102
+
103
+ entry.resource_id = this.__resource_registry.length;
104
+ entry.resource_descriptor = descriptor;
105
+
106
+ this.__resource_registry.push(entry);
107
+
108
+ return entry;
109
+ }
110
+
111
+ /**
112
+ *
113
+ * @param {string} name
114
+ * @param {number} resource_id
115
+ * @return {ResourceNode}
116
+ * @private
117
+ */
118
+ _createResourceNode(name, resource_id) {
119
+ assert.isNonNegativeInteger(resource_id, 'resource_id');
120
+
121
+ const n = new ResourceNode();
122
+
123
+ const id = this.__resource_nodes.length;
124
+
125
+ n.id = id;
126
+ n.name = name;
127
+ n.resource_id = resource_id;
128
+
129
+ this.__resource_nodes[id] = n;
130
+
131
+ return n;
132
+ }
133
+
134
+ /**
135
+ *
136
+ * @param {number} res
137
+ * @returns {number}
138
+ */
139
+ clone_resource(res) {
140
+ const node = this.getResourceNode(res);
141
+
142
+ const entry = this.__resource_registry[node.resource_id];
143
+
144
+ entry.resource_version++;
145
+
146
+ const clone_node = new ResourceNode();
147
+ clone_node.id = this.__resource_nodes.length;
148
+ clone_node.name = node.name;
149
+ clone_node.resource_id = node.resource_id;
150
+ clone_node.version = entry.resource_version;
151
+
152
+ this.__resource_nodes.push(clone_node);
153
+
154
+ return clone_node.id;
155
+ }
156
+
157
+ /**
158
+ * @template T
159
+ * @param {string} name
160
+ * @param {TextureDescriptor} description
161
+ * @param {T} resource
162
+ * @returns {number}
163
+ */
164
+ import_resource(name, description, resource) {
165
+ const record = this._createResourceEntry(description);
166
+
167
+ record.resource = resource;
168
+
169
+ record.imported = true;
170
+
171
+ return this._createResourceNode(name, record.resource_id).id;
172
+ }
173
+
174
+ /**
175
+ * @returns {boolean}
176
+ * @param id
177
+ */
178
+ is_valid_resource(id) {
179
+ const node = this.getResourceNode(id);
180
+ const record = this.getResourceEntry(id);
181
+
182
+ return node.version === record.resource_version;
183
+ }
184
+
185
+ /**
186
+ * @template T
187
+ * @param {RenderPass} pass
188
+ * @returns {T} resources/handles returned by {@link RenderPass#setup}
189
+ */
190
+ add(pass) {
191
+
192
+ const pass_nodes = this.__pass_nodes;
193
+
194
+ const builder = new RenderGraphBuilder();
195
+ const node = new RenderPassNode();
196
+
197
+ node.id = pass_nodes.length;
198
+ node.name = pass.name;
199
+ node.pass = pass;
200
+
201
+ pass_nodes.push(node);
202
+
203
+ builder.init(this, node);
204
+
205
+ const result = pass.setup(builder, pass.inputs);
206
+
207
+ this.__passes.push(pass);
208
+
209
+ node.data = result;
210
+
211
+ return result;
212
+ }
213
+
214
+ compile() {
215
+ const pass_nodes = this.__pass_nodes;
216
+
217
+ // wire resources of passes
218
+ const pass_node_count = pass_nodes.length;
219
+ const resource_nodes = this.__resource_nodes;
220
+
221
+ for (let i = 0; i < pass_node_count; i++) {
222
+ const pass = pass_nodes[i];
223
+
224
+ // mask pass as having number of references equal to number of resources it writes to
225
+ pass.ref_count = pass.resource_writes.length;
226
+
227
+ for (const id of pass.resource_reads) {
228
+ const read_node = resource_nodes[id];
229
+
230
+ read_node.ref_count++;
231
+ }
232
+
233
+ for (const id of pass.resource_writes) {
234
+ const written_node = resource_nodes[id];
235
+
236
+ written_node.producer = pass;
237
+ }
238
+ }
239
+
240
+ // perform culling
241
+ /**
242
+ *
243
+ * @type {ResourceNode[]}
244
+ */
245
+ const unreferenced_resources = [];
246
+
247
+ for (const node of resource_nodes) {
248
+ if (node.ref_count === 0) {
249
+ unreferenced_resources.push(node);
250
+ }
251
+ }
252
+
253
+ while (unreferenced_resources.length > 0) {
254
+ const unreferenced_resource = unreferenced_resources.pop();
255
+
256
+ const producer = unreferenced_resource.producer;
257
+
258
+ if (producer === null || producer.has_side_effects) {
259
+ continue;
260
+ }
261
+
262
+ assert.greaterThanOrEqual(producer.ref_count, 1, 'must have at least one reference'); // Why?
263
+
264
+ // disconnect unreferenced resource from producer
265
+ producer.ref_count--;
266
+
267
+ if (producer.ref_count === 0) {
268
+
269
+ // producer is no longer referenced
270
+
271
+ for (const id of producer.resource_reads) {
272
+ const node = resource_nodes[id];
273
+
274
+ // disconnect producer from all its reads (upstream)
275
+ node.ref_count--;
276
+
277
+ if (node.ref_count === 0) {
278
+ // resource is no longer referenced
279
+ unreferenced_resources.push(node);
280
+ }
281
+ }
282
+ }
283
+ }
284
+
285
+ // calculate lifetimes
286
+ for (const pass of pass_nodes) {
287
+ if (pass.ref_count === 0) {
288
+ // unused pass
289
+ continue;
290
+ }
291
+
292
+ for (const id of pass.resource_creates) {
293
+ this.getResourceEntry(id).producer = pass;
294
+ }
295
+
296
+ for (const id of pass.resource_writes) {
297
+ this.getResourceEntry(id).last = pass;
298
+ }
299
+
300
+ for (const id of pass.resource_reads) {
301
+ this.getResourceEntry(id).last = pass;
302
+ }
303
+ }
304
+ }
305
+
306
+ /**
307
+ *
308
+ * @param {IRenderContext} context
309
+ */
310
+ execute(context) {
311
+ const pass_nodes = this.__pass_nodes;
312
+ const pass_node_count = pass_nodes.length;
313
+ for (let i = 0; i < pass_node_count; i++) {
314
+ const node = pass_nodes[i];
315
+
316
+ if (!node.can_execute()) {
317
+ continue;
318
+ }
319
+
320
+ for (const id of node.resource_creates) {
321
+ // allocate resource
322
+ this.getResourceEntry(id).create();
323
+ }
324
+
325
+ const resources = new RenderPassResources();
326
+ resources.init(this, node);
327
+
328
+ // execute pass
329
+ node.pass.execute(node.data, resources, context);
330
+
331
+ for (const entry of this.__resource_registry) {
332
+ if (entry.last === node && entry.isTransient()) {
333
+ // this was the last user of the resource and the resource is transient (no external usage)
334
+ entry.destroy();
335
+ }
336
+ }
337
+
338
+ }
339
+ }
340
+
341
+ exportToDot() {
342
+ const out = new LineBuilder();
343
+
344
+ out.add("digraph FrameGraph {");
345
+ out.indent();
346
+ out.add("graph [style=invis, rankdir=\"TB\" ordering=out, splines=spline]");
347
+ out.add("node [shape=record, fontname=\"helvetica\", fontsize=10, margin=\"0.2,0.03\"]");
348
+
349
+
350
+ // -- Define pass nodes
351
+
352
+ out.add("");
353
+ out.add("# Pass Nodes");
354
+ for (const node of this.__pass_nodes) {
355
+ out.add(`P${node.id} [label=<{ {<B>${node.name}</B>} | {${(node.has_side_effects ? "&#x2605; " : "")} Refs: ${node.ref_count}<BR/> Index: ${node.id}} }> style=\"rounded,filled\", fillcolor=${(node.ref_count > 0 || node.has_side_effects) ? "orange" : "lightgray"}]`);
356
+ }
357
+
358
+ // -- Define resource nodes
359
+
360
+ out.add("");
361
+ out.add("# Resource Nodes");
362
+ for (const node of this.__resource_nodes) {
363
+ const entry = this.__resource_registry[node.resource_id];
364
+ out.add(`R${entry.resource_id}_${node.version} [label=<{ {<B>${node.name}</B>${node.version > 0 ? `<FONT>v${node.version}</FONT>` : ""}<BR/>${entry.toString()}} | {Index: ${entry.resource_id}<BR/> Refs : ${node.ref_count} } }> style=filled, fillcolor=${entry.isImported() ? "lightsteelblue" : "skyblue"}]`);
365
+ }
366
+
367
+ // -- Each pass node points to resource that it writes
368
+
369
+ out.add("");
370
+ out.add("# Resource Writes");
371
+ for (const node of this.__pass_nodes) {
372
+ out.add(`P${node.id} -> {`);
373
+ out.indent();
374
+ for (const id of node.resource_writes) {
375
+ const written = this.__resource_nodes[id];
376
+ out.add(`R${written.resource_id}_${written.version} `);
377
+ }
378
+ out.dedent();
379
+ out.add("} [color=orangered]");
380
+ }
381
+
382
+ // -- Each resource node points to pass where it's consumed
383
+
384
+ out.add("");
385
+ out.add("# Resource Reads");
386
+
387
+ for (const node of this.__resource_nodes) {
388
+ out.add(`R${node.resource_id}_${node.version} -> {`);
389
+ out.indent();
390
+ // find all readers of this resource node
391
+ for (const pass of this.__pass_nodes) {
392
+ for (const id of pass.resource_reads)
393
+ if (id === node.id) {
394
+ out.add(`P${pass.id} `);
395
+ }
396
+ }
397
+ out.dedent();
398
+ out.add("} [color=olivedrab3]");
399
+ }
400
+ out.dedent();
401
+ out.add("}");
402
+ // -- Clusters:
403
+ return out.build();
404
+ }
405
+ }
@@ -0,0 +1,77 @@
1
+ import { assert } from "../../../../core/assert.js";
2
+
3
+ export class RenderGraphBuilder {
4
+ /**
5
+ *
6
+ * @type {RenderGraph}
7
+ * @private
8
+ */
9
+ __graph = null;
10
+ /**
11
+ *
12
+ * @type {RenderPassNode}
13
+ * @private
14
+ */
15
+ __node = null;
16
+
17
+ /**
18
+ *
19
+ * @param {RenderGraph} graph
20
+ * @param {RenderPassNode} node
21
+ */
22
+ init(graph, node) {
23
+ this.__graph = graph;
24
+ this.__node = node;
25
+ }
26
+
27
+ /**
28
+ *
29
+ * @param {string} name
30
+ * @param {TextureDescriptor} descriptor
31
+ * @returns {number} resource ID
32
+ */
33
+ create(name, descriptor) {
34
+ const node = this.__graph.create_resource(name, descriptor);
35
+
36
+ // remember resource
37
+ this.__node.resource_creates.push(node);
38
+
39
+ return node;
40
+ }
41
+
42
+ /**
43
+ *
44
+ * @param {number} resource
45
+ * @returns {number}
46
+ */
47
+ read(resource) {
48
+ assert.isNonNegativeInteger(resource, 'resource');
49
+
50
+ return this.__node.read(resource);
51
+ }
52
+
53
+ /**
54
+ *
55
+ * @param {number} resource
56
+ * @returns {number}
57
+ */
58
+ write(resource) {
59
+ const graph = this.__graph;
60
+ const node = this.__node;
61
+
62
+ if (graph.getResourceEntry(resource).isImported()) {
63
+ // comes from outside the graph, and we write to it. That's a side effect
64
+ node.has_side_effects = true;
65
+ }
66
+
67
+ if (node.creates(resource)) {
68
+ return node.write(resource);
69
+ } else {
70
+ // writing to a resource produces a renamed handle
71
+ node.read(resource);
72
+
73
+ return node.write(graph.clone_resource(resource));
74
+ }
75
+
76
+ }
77
+ }
@@ -1,32 +1,50 @@
1
1
  const DEFAULT_FLAGS = 0;
2
2
 
3
+ /**
4
+ * @template DATA
5
+ */
3
6
  export class RenderPass {
4
7
 
5
- constructor() {
6
- this.ref_count = 0;
7
- /**
8
- *
9
- * @type {number|RenderPassFlags}
10
- */
11
- this.flags = DEFAULT_FLAGS;
8
+ /**
9
+ * Used for debug and visualisation
10
+ * @type {string}
11
+ */
12
+ name = "Render Pass";
13
+
14
+ /**
15
+ *
16
+ * @type {number|RenderPassFlags}
17
+ */
18
+ flags = DEFAULT_FLAGS;
19
+
20
+
21
+ /**
22
+ * Arbitrary dictionary of data
23
+ * @type {Object<number>}
24
+ */
25
+ inputs = {};
26
+
27
+ constructor(inputs = {}) {
28
+ this.inputs = inputs;
12
29
  }
13
30
 
31
+
14
32
  /**
15
33
  *
16
- * @param {FrameGraphBuilder} builder
17
- * @param {Object<Resource>} inputs
18
- * @returns {Object<Resource>}
34
+ * @param {RenderGraphBuilder} builder
35
+ * @param {Object<number>} inputs
36
+ * @returns {Object<number>}
19
37
  */
20
38
  setup(builder, inputs) {
21
39
  throw new Error('Not Implemented');
22
40
  }
23
41
 
24
42
  /**
25
- *
43
+ * @param {DATA} data
26
44
  * @param {RenderPassResources} resources
27
45
  * @param {IRenderContext} render_context
28
46
  */
29
- execute(resources, render_context) {
47
+ execute(data, resources, render_context) {
30
48
  throw new Error('Not Implemented');
31
49
  }
32
50
  }