@woosh/meep-engine 3.19.0 → 3.20.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-terrain.js +1 -1
- package/editor/view/particles/effect/ParticleGraphEditorView.js +2 -2
- package/editor/view/particles/effect/ParticleNodeParametersView.d.ts.map +1 -1
- package/editor/view/particles/effect/ParticleNodeParametersView.js +7 -48
- package/package.json +1 -1
- package/src/core/collection/array/array_group_by.d.ts.map +1 -1
- package/src/core/collection/array/array_group_by.js +2 -11
- package/src/core/geom/3d/shape/HeightMapShape3D.d.ts.map +1 -1
- package/src/core/geom/3d/shape/HeightMapShape3D.js +4 -9
- package/src/core/model/object/optional_clone.d.ts +7 -0
- package/src/core/model/object/optional_clone.d.ts.map +1 -0
- package/src/core/model/object/optional_equality.d.ts +10 -0
- package/src/core/model/object/optional_equality.d.ts.map +1 -0
- package/src/{shade/descriptor/util → core/model/object}/optional_equality.js +2 -2
- package/src/core/model/object/optional_hash.d.ts +9 -0
- package/src/core/model/object/optional_hash.d.ts.map +1 -0
- package/src/{shade/descriptor/util → core/model/object}/optional_hash.js +3 -3
- package/src/engine/asset/Asset.d.ts +1 -1
- package/src/engine/asset/Asset.d.ts.map +1 -1
- package/src/engine/asset/Asset.js +3 -1
- package/src/engine/ecs/gui/hud/HeadsUpDisplaySystem.d.ts.map +1 -1
- package/src/engine/ecs/gui/hud/HeadsUpDisplaySystem.js +9 -10
- package/src/engine/graphics/ecs/particles/ParticleEffect.d.ts.map +1 -1
- package/src/engine/graphics/ecs/particles/ParticleEffect.js +6 -22
- package/src/shade/descriptor/binding/BindGroupLayoutDescriptor.js +1 -1
- package/src/shade/descriptor/binding/BindGroupLayoutEntry.js +3 -3
- package/src/shade/descriptor/pipeline/PipelineDescriptorBase.js +1 -1
- package/src/shade/descriptor/pipeline/PipelineLayoutDescriptor.js +1 -1
- package/src/shade/descriptor/pipeline/render/ColorTargetState.js +3 -3
- package/src/shade/descriptor/pipeline/render/FragmentState.js +1 -1
- package/src/shade/descriptor/pipeline/render/RenderPipelineDescriptor.js +3 -3
- package/src/shade/playground/particle_editor/README.md +1 -1
- package/src/shade/playground/particle_system/particle_prototype.d.ts +7 -9
- package/src/shade/playground/particle_system/particle_prototype.d.ts.map +1 -1
- package/src/shade/playground/particle_system/particle_prototype.js +7 -9
- package/src/shade/playground/ssr_motion/README.md +22 -0
- package/src/shade/playground/ssr_motion/index.html +18 -0
- package/src/shade/playground/ssr_motion/main.d.ts +2 -0
- package/src/shade/playground/ssr_motion/main.d.ts.map +1 -0
- package/src/shade/playground/ssr_motion/main.js +149 -0
- package/src/shade/playground/ssr_variance/index.html +1 -0
- package/src/shade/renderer/geometry/Geometry.d.ts.map +1 -1
- package/src/shade/renderer/geometry/Geometry.js +4 -7
- package/src/shade/renderer/material/StandardShadeMaterial.js +2 -2
- package/src/shade/renderer/particles/DESIGN.md +9 -11
- package/src/shade/renderer/particles/GPUParticleSystem.d.ts.map +1 -1
- package/src/shade/renderer/particles/GPUParticleSystem.js +3 -1
- package/src/shade/renderer/particles/graph/ParticleGroupBuilder.d.ts +1 -1
- package/src/shade/renderer/particles/graph/ParticleGroupBuilder.js +1 -1
- package/src/shade/renderer/particles/graph/ParticleNodeRegistry.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph/ParticleNodeRegistry.js +9 -15
- package/src/shade/renderer/particles/graph/particle_group_library.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph/particle_group_library.js +8 -3
- package/src/shade/renderer/particles/graph/particle_node_parameters.d.ts +0 -2
- package/src/shade/renderer/particles/graph/particle_node_parameters.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph/particle_node_parameters.js +0 -9
- package/src/shade/renderer/particles/graph/particle_node_presentation.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph/particle_node_presentation.js +0 -10
- package/src/shade/renderer/particles/graph/particle_ramp.d.ts +2 -8
- package/src/shade/renderer/particles/graph/particle_ramp.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph/particle_ramp.js +2 -8
- package/src/shade/renderer/particles/graph/validate_particle_graph.js +0 -6
- package/src/shade/renderer/particles/graph_particles_avboit.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph_particles_avboit.js +13 -4
- package/src/shade/renderer/particles/isa/InstructionStream.d.ts +1 -12
- package/src/shade/renderer/particles/isa/InstructionStream.d.ts.map +1 -1
- package/src/shade/renderer/particles/isa/InstructionStream.js +1 -12
- package/src/shade/renderer/particles/isa/ParticleVMISA.d.ts +54 -60
- package/src/shade/renderer/particles/isa/ParticleVMISA.d.ts.map +1 -1
- package/src/shade/renderer/particles/isa/ParticleVMISA.js +9 -17
- package/src/shade/renderer/particles/isa/particle_assembly.d.ts +0 -1
- package/src/shade/renderer/particles/isa/particle_assembly.d.ts.map +1 -1
- package/src/shade/renderer/particles/isa/particle_assembly.js +2 -16
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_graph.d.ts +1 -1
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_graph.js +1 -1
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_lift.js +0 -14
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_pack.js +3 -17
- package/src/shade/renderer/particles/optimizer/particle_program_analysis.d.ts.map +1 -1
- package/src/shade/renderer/particles/optimizer/particle_program_analysis.js +15 -36
- package/src/shade/renderer/particles/optimizer/particle_program_equivalence.d.ts.map +1 -1
- package/src/shade/renderer/particles/optimizer/particle_program_equivalence.js +1 -5
- package/src/shade/renderer/particles/optimizer/particle_program_fuzz.d.ts.map +1 -1
- package/src/shade/renderer/particles/optimizer/particle_program_fuzz.js +1 -8
- package/src/shade/renderer/particles/optimizer/particle_vm_semantics.d.ts +2 -11
- package/src/shade/renderer/particles/optimizer/particle_vm_semantics.d.ts.map +1 -1
- package/src/shade/renderer/particles/optimizer/particle_vm_semantics.js +2 -11
- package/src/shade/renderer/particles/shaders/chunk_particle_avboit_contribution.d.ts.map +1 -1
- package/src/shade/renderer/particles/shaders/chunk_particle_avboit_contribution.js +13 -0
- package/src/shade/renderer/particles/shaders/shader_particle_avboit_draw.d.ts +3 -6
- package/src/shade/renderer/particles/shaders/shader_particle_avboit_draw.d.ts.map +1 -1
- package/src/shade/renderer/particles/shaders/shader_particle_avboit_draw.js +49 -17
- package/src/shade/renderer/particles/shaders/shader_particle_emit.d.ts.map +1 -1
- package/src/shade/renderer/particles/shaders/shader_particle_emit.js +0 -2
- package/src/shade/renderer/particles/shaders/shader_particle_emit_wide.d.ts.map +1 -1
- package/src/shade/renderer/particles/shaders/shader_particle_emit_wide.js +0 -2
- package/src/shade/renderer/particles/shaders/shader_particle_simulate.d.ts.map +1 -1
- package/src/shade/renderer/particles/shaders/shader_particle_simulate.js +1 -5
- package/src/shade/renderer/particles/shaders/shader_particle_simulate_wide.d.ts.map +1 -1
- package/src/shade/renderer/particles/shaders/shader_particle_simulate_wide.js +0 -2
- package/src/shade/renderer/particles/vm/ParticleVMReference.d.ts +1 -3
- package/src/shade/renderer/particles/vm/ParticleVMReference.d.ts.map +1 -1
- package/src/shade/renderer/particles/vm/ParticleVMReference.js +4 -20
- package/src/shade/renderer/particles/vm/chunk_particle_vm.d.ts.map +1 -1
- package/src/shade/renderer/particles/vm/chunk_particle_vm.js +2 -5
- package/src/shade/renderer/particles/warmup/shader_particle_warmup_advance.d.ts.map +1 -1
- package/src/shade/renderer/particles/warmup/shader_particle_warmup_advance.js +0 -2
- package/src/shade/renderer/particles/warmup/shader_particle_warmup_advance_wide.d.ts.map +1 -1
- package/src/shade/renderer/particles/warmup/shader_particle_warmup_advance_wide.js +0 -2
- package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_reprojection.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_reprojection.js +21 -0
- package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_temporal_accumulate.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_temporal_accumulate.js +4 -0
- package/src/shade/renderer/postprocess/ssr/ssr_reproject_shader.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/ssr/ssr_reproject_shader.js +2 -1
- package/src/shade/renderer/scene/Mesh.js +1 -1
- package/src/shade/renderer/texture/ShadeTexture.js +1 -1
- package/src/shade/renderer/particles/shaders/chunk_particle_curve_animation.d.ts +0 -19
- package/src/shade/renderer/particles/shaders/chunk_particle_curve_animation.d.ts.map +0 -1
- package/src/shade/renderer/particles/shaders/chunk_particle_curve_animation.js +0 -30
- package/src/shade/renderer/particles/shaders/chunk_particle_curve_disabled.d.ts +0 -11
- package/src/shade/renderer/particles/shaders/chunk_particle_curve_disabled.d.ts.map +0 -1
- package/src/shade/renderer/particles/shaders/chunk_particle_curve_disabled.js +0 -13
- /package/src/{shade/descriptor/util → core/model/object}/optional_clone.js +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"particle_program_fuzz.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/optimizer/particle_program_fuzz.js"],"names":[],"mappings":"AAkDA;;;;;;;;;;;;;GAaG;AACH,oDAXuB,MAAM;IAED,WAAW,GAA5B,MAAM;IACY,IAAI,GAAtB,OAAO;IACW,MAAM,GAAxB,OAAO;IACU,cAAc,GAA/B,MAAM;oBAqHhB;
|
|
1
|
+
{"version":3,"file":"particle_program_fuzz.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/optimizer/particle_program_fuzz.js"],"names":[],"mappings":"AAkDA;;;;;;;;;;;;;GAaG;AACH,oDAXuB,MAAM;IAED,WAAW,GAA5B,MAAM;IACY,IAAI,GAAtB,OAAO;IACW,MAAM,GAAxB,OAAO;IACU,cAAc,GAA/B,MAAM;oBAqHhB;AAuED;;;;;;;;;;;;;;;;;;GAkBG;AACH,yDALuB,MAAM;IAED,MAAM,GAAvB,MAAM;oBAmEhB"}
|
|
@@ -41,7 +41,7 @@ const FUZZ_OPS = [
|
|
|
41
41
|
VM_OP.SMOOTHSTEP, VM_OP.RSQRT, VM_OP.TAN, VM_OP.ASIN, VM_OP.ACOS, VM_OP.ATAN2,
|
|
42
42
|
VM_OP.DOT, VM_OP.CROSS, VM_OP.LENGTH, VM_OP.NORMALIZE, VM_OP.DISTANCE,
|
|
43
43
|
VM_OP.CMP_LT, VM_OP.CMP_LE, VM_OP.CMP_GT, VM_OP.CMP_GE, VM_OP.CMP_EQ,
|
|
44
|
-
VM_OP.SELECT, VM_OP.RANDOM, VM_OP.
|
|
44
|
+
VM_OP.SELECT, VM_OP.RANDOM, VM_OP.LOAD_CONST, VM_OP.LOAD_ATTR, VM_OP.LOAD_BUILTIN,
|
|
45
45
|
VM_OP.NOP,
|
|
46
46
|
];
|
|
47
47
|
|
|
@@ -222,13 +222,6 @@ function emit_random_instruction(stream, assembler, rand, pool) {
|
|
|
222
222
|
return;
|
|
223
223
|
}
|
|
224
224
|
|
|
225
|
-
case VM_OP.CURVE: {
|
|
226
|
-
const handle = Math.floor(rand() * 4);
|
|
227
|
-
|
|
228
|
-
stream.curve(dst, handle, source(group), width);
|
|
229
|
-
return;
|
|
230
|
-
}
|
|
231
|
-
|
|
232
225
|
default: {
|
|
233
226
|
// A `SELECT` whose condition is a constant is the shape the folding pass exists for, and
|
|
234
227
|
// random registers hold one about never — so it is worth steering into deliberately.
|
|
@@ -13,7 +13,7 @@ export function vm_semantics_of(op: number): ParticleOpSemantics;
|
|
|
13
13
|
* it — whether it can be deleted when its result is unread, narrowed when its high lanes are dead,
|
|
14
14
|
* evaluated at compile time, or recognised as a recomputation of something already in a register.
|
|
15
15
|
* Those are four different questions and an opcode can answer them differently: `LOAD_ATTR` is
|
|
16
|
-
* removable but not shareable across a store, `RANDOM` is neither, and `
|
|
16
|
+
* removable but not shareable across a store, `RANDOM` is neither, and `LOAD_BUILTIN` is both.
|
|
17
17
|
*
|
|
18
18
|
* Every opcode has to appear in {@link VM_SEMANTICS} — the spec asserts it — because the safe
|
|
19
19
|
* default for a new one is "assume nothing", and a table that silently omitted it would instead have
|
|
@@ -22,7 +22,7 @@ export function vm_semantics_of(op: number): ParticleOpSemantics;
|
|
|
22
22
|
* Which lane of a source feeds which lane of the result is not a property of the opcode any more:
|
|
23
23
|
* every register operand carries a swizzle, and `vm_operand_slot` in the ISA answers it per operand.
|
|
24
24
|
* What is left here is per-opcode: whether lane `i` of the result depends on lane `i` of the
|
|
25
|
-
* sources alone (`lanewise`)
|
|
25
|
+
* sources alone (`lanewise`).
|
|
26
26
|
*/
|
|
27
27
|
/**
|
|
28
28
|
* @typedef {object} ParticleOpSemantics
|
|
@@ -37,9 +37,6 @@ export function vm_semantics_of(op: number): ParticleOpSemantics;
|
|
|
37
37
|
* @property {boolean} shareable two executions with equal operand values produce equal results, so a
|
|
38
38
|
* second one can read the first one's register instead. False for anything reading the record or
|
|
39
39
|
* the RNG.
|
|
40
|
-
* @property {boolean} broadcasts every lane of the destination holds the same value, by construction
|
|
41
|
-
* rather than by what the operands happen to be. Lane `i` is then a copy of lane 0 and may be read
|
|
42
|
-
* as one.
|
|
43
40
|
* @property {boolean} foldable the JS reference and the WGSL interpreter are both obliged to produce
|
|
44
41
|
* the *same bits* for this operation, so evaluating it here and baking a constant changes nothing
|
|
45
42
|
* on either. Correctly-rounded IEEE arithmetic qualifies; a transcendental does not — JS
|
|
@@ -79,12 +76,6 @@ export type ParticleOpSemantics = {
|
|
|
79
76
|
* the RNG.
|
|
80
77
|
*/
|
|
81
78
|
shareable: boolean;
|
|
82
|
-
/**
|
|
83
|
-
* every lane of the destination holds the same value, by construction
|
|
84
|
-
* rather than by what the operands happen to be. Lane `i` is then a copy of lane 0 and may be read
|
|
85
|
-
* as one.
|
|
86
|
-
*/
|
|
87
|
-
broadcasts: boolean;
|
|
88
79
|
/**
|
|
89
80
|
* the JS reference and the WGSL interpreter are both obliged to produce
|
|
90
81
|
* the *same bits* for this operation, so evaluating it here and baking a constant changes nothing
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"particle_vm_semantics.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/optimizer/particle_vm_semantics.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"particle_vm_semantics.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/optimizer/particle_vm_semantics.js"],"names":[],"mappings":"AA4IA;;;;;;GAMG;AACH,oCAHW,MAAM,GACJ,mBAAmB,CAW/B;AA1JD;;;;;;;;;;;;;;;;;GAiBG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,+CAA+C;AAC/C,2BADW,IAAI,MAAM,EAAE,mBAAmB,CAAC,CACL;;;;;;;kBA1BxB,OAAO;;;;;cAGP,OAAO;;;;;;gBAEP,OAAO;;;;;;eAGP,OAAO;;;;;;;;cAGP,OAAO;;;;;;;;;;sBAKP,OAAO"}
|
|
@@ -7,7 +7,7 @@ import { VM_OP } from "../isa/ParticleVMISA.js";
|
|
|
7
7
|
* it — whether it can be deleted when its result is unread, narrowed when its high lanes are dead,
|
|
8
8
|
* evaluated at compile time, or recognised as a recomputation of something already in a register.
|
|
9
9
|
* Those are four different questions and an opcode can answer them differently: `LOAD_ATTR` is
|
|
10
|
-
* removable but not shareable across a store, `RANDOM` is neither, and `
|
|
10
|
+
* removable but not shareable across a store, `RANDOM` is neither, and `LOAD_BUILTIN` is both.
|
|
11
11
|
*
|
|
12
12
|
* Every opcode has to appear in {@link VM_SEMANTICS} — the spec asserts it — because the safe
|
|
13
13
|
* default for a new one is "assume nothing", and a table that silently omitted it would instead have
|
|
@@ -16,7 +16,7 @@ import { VM_OP } from "../isa/ParticleVMISA.js";
|
|
|
16
16
|
* Which lane of a source feeds which lane of the result is not a property of the opcode any more:
|
|
17
17
|
* every register operand carries a swizzle, and `vm_operand_slot` in the ISA answers it per operand.
|
|
18
18
|
* What is left here is per-opcode: whether lane `i` of the result depends on lane `i` of the
|
|
19
|
-
* sources alone (`lanewise`)
|
|
19
|
+
* sources alone (`lanewise`).
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
22
|
/**
|
|
@@ -32,9 +32,6 @@ import { VM_OP } from "../isa/ParticleVMISA.js";
|
|
|
32
32
|
* @property {boolean} shareable two executions with equal operand values produce equal results, so a
|
|
33
33
|
* second one can read the first one's register instead. False for anything reading the record or
|
|
34
34
|
* the RNG.
|
|
35
|
-
* @property {boolean} broadcasts every lane of the destination holds the same value, by construction
|
|
36
|
-
* rather than by what the operands happen to be. Lane `i` is then a copy of lane 0 and may be read
|
|
37
|
-
* as one.
|
|
38
35
|
* @property {boolean} foldable the JS reference and the WGSL interpreter are both obliged to produce
|
|
39
36
|
* the *same bits* for this operation, so evaluating it here and baking a constant changes nothing
|
|
40
37
|
* on either. Correctly-rounded IEEE arithmetic qualifies; a transcendental does not — JS
|
|
@@ -62,7 +59,6 @@ function semantics(op, flags) {
|
|
|
62
59
|
lanewise: false,
|
|
63
60
|
narrowable: false,
|
|
64
61
|
shareable: false,
|
|
65
|
-
broadcasts: false,
|
|
66
62
|
foldable: false,
|
|
67
63
|
foldable_inexact: false,
|
|
68
64
|
...flags,
|
|
@@ -141,10 +137,6 @@ semantics(VM_OP.SELECT, EXACT);
|
|
|
141
137
|
// Ordered and side-effecting: it advances the shared RNG, and its width IS the number of draws it
|
|
142
138
|
// takes. Removing, duplicating, reordering or narrowing one moves every value drawn after it.
|
|
143
139
|
semantics(VM_OP.RANDOM, { side_effects: true });
|
|
144
|
-
// An external WGSL symbol, but a pure function of (handle, t) — so a dead one goes and a repeated
|
|
145
|
-
// one is shared. Every lane of the result is the same sample, which is what makes it narrowable —
|
|
146
|
-
// and what makes it a broadcast, so a consumer reading it wide is a consumer that wants `.xxxx`.
|
|
147
|
-
semantics(VM_OP.CURVE, { lanewise: true, narrowable: true, shareable: true, broadcasts: true });
|
|
148
140
|
|
|
149
141
|
/**
|
|
150
142
|
* What may be assumed about an opcode. An unknown one is assumed to do everything, so a new opcode
|
|
@@ -159,7 +151,6 @@ export function vm_semantics_of(op) {
|
|
|
159
151
|
lanewise: false,
|
|
160
152
|
narrowable: false,
|
|
161
153
|
shareable: false,
|
|
162
|
-
broadcasts: false,
|
|
163
154
|
foldable: false,
|
|
164
155
|
foldable_inexact: false,
|
|
165
156
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chunk_particle_avboit_contribution.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/shaders/chunk_particle_avboit_contribution.js"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;GAaG;AACH,iDAFU,SAAS,
|
|
1
|
+
{"version":3,"file":"chunk_particle_avboit_contribution.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/shaders/chunk_particle_avboit_contribution.js"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;GAaG;AACH,iDAFU,SAAS,CAuEc;0BAvFP,oCAAoC"}
|
|
@@ -24,6 +24,19 @@ struct ParticleAVBOITContribution {
|
|
|
24
24
|
emission : vec4<f32>,
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
+
// Black covering fragments still contribute extinction; zero-alpha premultiplied RGB still emits.
|
|
28
|
+
fn particle_avboit_is_empty(color : vec4<f32>, blend : u32) -> bool {
|
|
29
|
+
return all(particle_premultiply(color, blend) == vec4<f32>(0.0));
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// The atlas is unorm, so non-negative straight alpha cannot produce emission. Signed alpha and
|
|
33
|
+
// premultiplied sprites keep all four outputs: either can emit without positive coverage.
|
|
34
|
+
fn particle_avboit_draw_blend(color : vec4<f32>, blend : u32) -> u32 {
|
|
35
|
+
if (blend == PARTICLE_BLEND_ADDITIVE) { return PARTICLE_BLEND_ADDITIVE; }
|
|
36
|
+
if (blend == PARTICLE_BLEND_ALPHA && color.a >= 0.0) { return PARTICLE_BLEND_ALPHA; }
|
|
37
|
+
return PARTICLE_BLEND_PREMULTIPLIED;
|
|
38
|
+
}
|
|
39
|
+
|
|
27
40
|
fn particle_avboit_contribution(
|
|
28
41
|
shaded : vec4<f32>,
|
|
29
42
|
blend : u32,
|
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
* @type {RenderPipelineDescriptor}
|
|
5
|
-
*/
|
|
6
|
-
export const PARTICLE_AVBOIT_DRAW_PIPELINE: RenderPipelineDescriptor;
|
|
1
|
+
export const PARTICLE_AVBOIT_DRAW_ALPHA_PIPELINE: RenderPipelineDescriptor;
|
|
2
|
+
export const PARTICLE_AVBOIT_DRAW_ADDITIVE_PIPELINE: RenderPipelineDescriptor;
|
|
3
|
+
export const PARTICLE_AVBOIT_DRAW_GENERAL_PIPELINE: RenderPipelineDescriptor;
|
|
7
4
|
/** The draw shader's resource set, for building its bind group. */
|
|
8
5
|
export const PARTICLE_AVBOIT_DRAW_RESOURCES: ShaderResourceSetDescriptor;
|
|
9
6
|
/** The assembled shader, for the validity tier. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shader_particle_avboit_draw.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/shaders/shader_particle_avboit_draw.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"shader_particle_avboit_draw.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/shaders/shader_particle_avboit_draw.js"],"names":[],"mappings":"AAgLA,2EAAsI;AACtI,8EAA2I;AAC3I,6EAA8I;AAE9I,mEAAmE;AACnE,yEAAwD;AAExD,mDAAmD;AACnD,2DAAsD;yCAxLb,iEAAiE;4CAW9D,sDAAsD;iCAFjE,kCAAkC"}
|
|
@@ -77,9 +77,28 @@ struct ParticleAVBOITDrawOutput {
|
|
|
77
77
|
@location(3) emission : vec4<f32>,
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
+
// Each draw uses the same GPU-owned alive list. Clip the other modes before rasterization.
|
|
81
|
+
fn particle_avboit_vertex(vi : u32, ii : u32, blend : u32) -> ParticleVertexOut {
|
|
82
|
+
var out = particle_billboard_vertex(vi, ii);
|
|
83
|
+
if (particle_avboit_draw_blend(out.color, out.blend) != blend) {
|
|
84
|
+
out.clip = vec4<f32>(2.0, 2.0, 2.0, 1.0);
|
|
85
|
+
}
|
|
86
|
+
return out;
|
|
87
|
+
}
|
|
88
|
+
|
|
80
89
|
@vertex
|
|
81
|
-
fn
|
|
82
|
-
return
|
|
90
|
+
fn vs_alpha(@builtin(vertex_index) vi : u32, @builtin(instance_index) ii : u32) -> ParticleVertexOut {
|
|
91
|
+
return particle_avboit_vertex(vi, ii, PARTICLE_BLEND_ALPHA);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
@vertex
|
|
95
|
+
fn vs_additive(@builtin(vertex_index) vi : u32, @builtin(instance_index) ii : u32) -> ParticleVertexOut {
|
|
96
|
+
return particle_avboit_vertex(vi, ii, PARTICLE_BLEND_ADDITIVE);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
@vertex
|
|
100
|
+
fn vs_general(@builtin(vertex_index) vi : u32, @builtin(instance_index) ii : u32) -> ParticleVertexOut {
|
|
101
|
+
return particle_avboit_vertex(vi, ii, PARTICLE_BLEND_PREMULTIPLIED);
|
|
83
102
|
}
|
|
84
103
|
|
|
85
104
|
@fragment
|
|
@@ -104,6 +123,10 @@ fn fs_main(in : ParticleVertexOut) -> ParticleAVBOITDrawOutput {
|
|
|
104
123
|
color = particle_apply_lighting(color, in.world_position, normalize(in.normal));
|
|
105
124
|
}
|
|
106
125
|
|
|
126
|
+
if (particle_avboit_is_empty(color, in.blend)) {
|
|
127
|
+
discard;
|
|
128
|
+
}
|
|
129
|
+
|
|
107
130
|
let volumetrics = sample_volumetrics(in.view_depth, screen_uv, in.clip.xy);
|
|
108
131
|
|
|
109
132
|
let contribution = particle_avboit_contribution(color, in.blend, transmittance, volumetrics);
|
|
@@ -129,22 +152,31 @@ fn fs_main(in : ParticleVertexOut) -> ParticleAVBOITDrawOutput {
|
|
|
129
152
|
const descriptor = ShaderDescriptor.from({ label: "Particle AVBOIT Draw", body, resources });
|
|
130
153
|
|
|
131
154
|
/**
|
|
132
|
-
* The
|
|
133
|
-
*
|
|
134
|
-
* @
|
|
155
|
+
* The variants share WGSL, bindings and attachments; only the vertex entry point and target writes
|
|
156
|
+
* differ. Disabling unused targets avoids blending zeros over every billboard pixel.
|
|
157
|
+
* @param {string} label
|
|
158
|
+
* @param {string} entryPoint
|
|
159
|
+
* @param {number[]} writeMasks
|
|
160
|
+
* @returns {RenderPipelineDescriptor}
|
|
135
161
|
*/
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
}
|
|
162
|
+
function create_draw_pipeline(label, entryPoint, writeMasks) {
|
|
163
|
+
return RenderPipelineDescriptor.from({
|
|
164
|
+
label,
|
|
165
|
+
layout: resources.generatePipelineLayout(GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT),
|
|
166
|
+
vertex: { module: { code: descriptor.source }, entryPoint },
|
|
167
|
+
fragment: {
|
|
168
|
+
module: { code: descriptor.source },
|
|
169
|
+
entryPoint: "fs_main",
|
|
170
|
+
targets: AVBOIT_DRAW_TARGETS.map((target, i) => ({ ...target, writeMask: writeMasks[i] })),
|
|
171
|
+
},
|
|
172
|
+
depthStencil: DepthStencilState.from({ format: "depth32float", depthWriteEnabled: false, depthCompare: "greater" }),
|
|
173
|
+
primitive: { topology: "triangle-list", cullMode: "none" },
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
export const PARTICLE_AVBOIT_DRAW_ALPHA_PIPELINE = create_draw_pipeline("Particle AVBOIT Draw Alpha", "vs_alpha", [0xF, 0xF, 0xF, 0]);
|
|
178
|
+
export const PARTICLE_AVBOIT_DRAW_ADDITIVE_PIPELINE = create_draw_pipeline("Particle AVBOIT Draw Additive", "vs_additive", [0, 0, 0, 0xF]);
|
|
179
|
+
export const PARTICLE_AVBOIT_DRAW_GENERAL_PIPELINE = create_draw_pipeline("Particle AVBOIT Draw General", "vs_general", [0xF, 0xF, 0xF, 0xF]);
|
|
148
180
|
|
|
149
181
|
/** The draw shader's resource set, for building its bind group. */
|
|
150
182
|
export const PARTICLE_AVBOIT_DRAW_RESOURCES = resources;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shader_particle_emit.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/shaders/shader_particle_emit.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"shader_particle_emit.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/shaders/shader_particle_emit.js"],"names":[],"mappings":"AAYA;;;;;;;;;;;;;;;;GAgBG;AAEH;;;GAGG;AACH,kDAA8E;AAE9E;;;;;;;;GAQG;AACH,4BAFU,YAAY,CAOK;AAoD3B,iDAIG;6BAxG0B,mCAAmC;8BAGlC,+BAA+B"}
|
|
@@ -8,7 +8,6 @@ import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
|
|
|
8
8
|
import { ShaderResourceSetDescriptor } from "../../shader/resource/ShaderResourceSetDescriptor.js";
|
|
9
9
|
import { PARTICLE_COUNTER } from "../data/PARTICLE_COUNTERS.js";
|
|
10
10
|
import { chunk_particle_vm_registers_fast } from "../vm/chunk_particle_vm_registers_fast.js";
|
|
11
|
-
import { chunk_particle_curve_disabled } from "./chunk_particle_curve_disabled.js";
|
|
12
11
|
import { chunk_particle_emit_step } from "./chunk_particle_emit_step.js";
|
|
13
12
|
|
|
14
13
|
/**
|
|
@@ -99,7 +98,6 @@ fn main(@builtin(global_invocation_id) gid : vec3<u32>) {
|
|
|
99
98
|
`, [
|
|
100
99
|
chunk_particle_emit_step,
|
|
101
100
|
chunk_particle_vm_registers_fast,
|
|
102
|
-
chunk_particle_curve_disabled,
|
|
103
101
|
]);
|
|
104
102
|
|
|
105
103
|
export const shader_particle_emit = ComputeShader.from({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shader_particle_emit_wide.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/shaders/shader_particle_emit_wide.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"shader_particle_emit_wide.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/shaders/shader_particle_emit_wide.js"],"names":[],"mappings":"AAYA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH;;;;GAIG;AACH,iDAFU,MAAM,CAGiD;AAgEjE,sDAIG;8BA5G2B,+BAA+B"}
|
|
@@ -7,7 +7,6 @@ import { ShaderResourceSetDescriptor } from "../../shader/resource/ShaderResourc
|
|
|
7
7
|
import { PARTICLE_VM_WIDE_LAUNCH_LANES } from "../ParticleConstants.js";
|
|
8
8
|
import { PARTICLE_COUNTER } from "../data/PARTICLE_COUNTERS.js";
|
|
9
9
|
import { chunk_particle_vm_registers_wide } from "../vm/chunk_particle_vm_registers_wide.js";
|
|
10
|
-
import { chunk_particle_curve_disabled } from "./chunk_particle_curve_disabled.js";
|
|
11
10
|
import { chunk_particle_emit_step } from "./chunk_particle_emit_step.js";
|
|
12
11
|
import { EMIT_SETTINGS, PARTICLE_EMIT_WORKGROUP_SIZE } from "./shader_particle_emit.js";
|
|
13
12
|
|
|
@@ -104,7 +103,6 @@ fn main(@builtin(global_invocation_id) gid : vec3<u32>) {
|
|
|
104
103
|
`, [
|
|
105
104
|
chunk_particle_emit_step,
|
|
106
105
|
chunk_particle_vm_registers_wide,
|
|
107
|
-
chunk_particle_curve_disabled,
|
|
108
106
|
]);
|
|
109
107
|
|
|
110
108
|
export const shader_particle_emit_wide = ComputeShader.from({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shader_particle_simulate.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/shaders/shader_particle_simulate.js"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"shader_particle_simulate.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/shaders/shader_particle_simulate.js"],"names":[],"mappings":";AAuDA;;;;;GAKG;AACH,gCAFU,YAAY,CAMS;AAsD/B,qDAIG;iDApH8C,yBAAyB;6BAJ7C,mCAAmC;8BAClC,+BAA+B"}
|
|
@@ -8,7 +8,6 @@ import { ShaderResourceSetDescriptor } from "../../shader/resource/ShaderResourc
|
|
|
8
8
|
import { PARTICLE_SIMULATE_WORKGROUP_SIZE } from "../ParticleConstants.js";
|
|
9
9
|
import { PARTICLE_COUNTER } from "../data/PARTICLE_COUNTERS.js";
|
|
10
10
|
import { chunk_particle_vm_registers_fast } from "../vm/chunk_particle_vm_registers_fast.js";
|
|
11
|
-
import { chunk_particle_curve_disabled } from "./chunk_particle_curve_disabled.js";
|
|
12
11
|
import { chunk_particle_simulate_step } from "./chunk_particle_simulate_step.js";
|
|
13
12
|
|
|
14
13
|
/**
|
|
@@ -47,9 +46,7 @@ import { chunk_particle_simulate_step } from "./chunk_particle_simulate_step.js"
|
|
|
47
46
|
* frame from that same value, so thread count and bound agree by construction — and, because the
|
|
48
47
|
* padded length is a whole number of workgroups, agree exactly.
|
|
49
48
|
*
|
|
50
|
-
* All structured reads go through `array<u32>` for emulator-testability.
|
|
51
|
-
* pluggable `particle_vm_sample_curve` — here the no-op provider; the feature swaps in the
|
|
52
|
-
* animation-database-backed one.
|
|
49
|
+
* All structured reads go through `array<u32>` for emulator-testability.
|
|
53
50
|
*
|
|
54
51
|
* @type {ComputeShader}
|
|
55
52
|
*/
|
|
@@ -116,7 +113,6 @@ fn main(@builtin(global_invocation_id) gid : vec3<u32>) {
|
|
|
116
113
|
`, [
|
|
117
114
|
chunk_particle_simulate_step,
|
|
118
115
|
chunk_particle_vm_registers_fast,
|
|
119
|
-
chunk_particle_curve_disabled,
|
|
120
116
|
]);
|
|
121
117
|
|
|
122
118
|
body.addExtension(WebGPUExtensionType.Subgroups);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shader_particle_simulate_wide.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/shaders/shader_particle_simulate_wide.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"shader_particle_simulate_wide.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/shaders/shader_particle_simulate_wide.js"],"names":[],"mappings":"AAYA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAEH;;;GAGG;AACH,qDAFU,MAAM,CAGqD;AA6DrE,0DAIG;8BArH2B,+BAA+B"}
|
|
@@ -7,7 +7,6 @@ import { ShaderResourceSetDescriptor } from "../../shader/resource/ShaderResourc
|
|
|
7
7
|
import { PARTICLE_SIMULATE_WORKGROUP_SIZE, PARTICLE_VM_WIDE_LAUNCH_LANES } from "../ParticleConstants.js";
|
|
8
8
|
import { PARTICLE_COUNTER } from "../data/PARTICLE_COUNTERS.js";
|
|
9
9
|
import { chunk_particle_vm_registers_wide } from "../vm/chunk_particle_vm_registers_wide.js";
|
|
10
|
-
import { chunk_particle_curve_disabled } from "./chunk_particle_curve_disabled.js";
|
|
11
10
|
import { chunk_particle_simulate_step } from "./chunk_particle_simulate_step.js";
|
|
12
11
|
import { SIMULATE_SETTINGS } from "./shader_particle_simulate.js";
|
|
13
12
|
|
|
@@ -111,7 +110,6 @@ fn main(@builtin(global_invocation_id) gid : vec3<u32>) {
|
|
|
111
110
|
`, [
|
|
112
111
|
chunk_particle_simulate_step,
|
|
113
112
|
chunk_particle_vm_registers_wide,
|
|
114
|
-
chunk_particle_curve_disabled,
|
|
115
113
|
]);
|
|
116
114
|
|
|
117
115
|
body.addExtension(WebGPUExtensionType.Subgroups);
|
|
@@ -36,17 +36,15 @@ export function u32_to_unit_f32(u: number): number;
|
|
|
36
36
|
* @param {Uint32Array} params.record particle record words (mutated in place); attributes are f32 bits
|
|
37
37
|
* @param {number[][]} [params.builtins] builtin values indexed by {@link VM_BUILTIN} id, each a 4-array
|
|
38
38
|
* @param {number} [params.rng_state] initial RNG state (u32)
|
|
39
|
-
* @param {(handle: number, t: number) => number} [params.sampleCurve] curve evaluator for the CURVE op
|
|
40
39
|
* @returns {{ killed: boolean, rng_state: number }}
|
|
41
40
|
*/
|
|
42
|
-
export function execute_particle_vm({ words, constants, register_count, record, builtins, rng_state,
|
|
41
|
+
export function execute_particle_vm({ words, constants, register_count, record, builtins, rng_state, }: {
|
|
43
42
|
words: Uint32Array;
|
|
44
43
|
constants: Float32Array;
|
|
45
44
|
register_count: number;
|
|
46
45
|
record: Uint32Array;
|
|
47
46
|
builtins?: number[][];
|
|
48
47
|
rng_state?: number;
|
|
49
|
-
sampleCurve?: (handle: number, t: number) => number;
|
|
50
48
|
}): {
|
|
51
49
|
killed: boolean;
|
|
52
50
|
rng_state: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ParticleVMReference.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/vm/ParticleVMReference.js"],"names":[],"mappings":"AA0BA;;;;;;;GAOG;AACH,gCAHW,MAAM;WACK,MAAM;WAAS,MAAM;EAW1C;AAED;;;;;GAKG;AACH,mCAHW,MAAM,GACJ,MAAM,CAIlB;
|
|
1
|
+
{"version":3,"file":"ParticleVMReference.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/vm/ParticleVMReference.js"],"names":[],"mappings":"AA0BA;;;;;;;GAOG;AACH,gCAHW,MAAM;WACK,MAAM;WAAS,MAAM;EAW1C;AAED;;;;;GAKG;AACH,mCAHW,MAAM,GACJ,MAAM,CAIlB;AA8DD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH;IAR+B,KAAK,EAAzB,WAAW;IACU,SAAS,EAA9B,YAAY;IACG,cAAc,EAA7B,MAAM;IACc,MAAM,EAA1B,WAAW;IACS,QAAQ,GAA5B,MAAM,EAAE,EAAE;IACM,SAAS,GAAzB,MAAM;;YACM,OAAO;eAAa,MAAM;EAuRhD"}
|
|
@@ -72,17 +72,10 @@ const OP_WIDTH = new Int8Array(OP_COUNT);
|
|
|
72
72
|
/** The lanes the opcode always writes, or `-1` for as many as it operates on. @type {Int8Array} */
|
|
73
73
|
const OP_DEST = new Int8Array(OP_COUNT);
|
|
74
74
|
|
|
75
|
-
/** Bit `n` set where source slot `n` is read one lane whatever the width. @type {Uint8Array} */
|
|
76
|
-
const OP_SCALAR = new Uint8Array(OP_COUNT);
|
|
77
|
-
|
|
78
75
|
for (const [op, meta] of VM_ISA) {
|
|
79
76
|
OP_DEFINED[op] = 1;
|
|
80
77
|
OP_WIDTH[op] = meta.width === VM_WIDTH.VARIABLE ? -1 : vm_operation_width(op, 0);
|
|
81
78
|
OP_DEST[op] = meta.dest === VM_DEST.WIDTH ? -1 : vm_dest_width(op, 0);
|
|
82
|
-
|
|
83
|
-
for (const slot of meta.scalar_operands) {
|
|
84
|
-
OP_SCALAR[op] |= 1 << slot;
|
|
85
|
-
}
|
|
86
79
|
}
|
|
87
80
|
|
|
88
81
|
// --- module-local copies of what the loop reads per instruction ----------------------------------
|
|
@@ -92,7 +85,7 @@ for (const [op, meta] of VM_ISA) {
|
|
|
92
85
|
// constants to the JIT, and the opcode switch can be a jump table.
|
|
93
86
|
|
|
94
87
|
const {
|
|
95
|
-
ABS, ACOS, ADD, ASIN, ATAN2, CLAMP, CMP_EQ, CMP_GE, CMP_GT, CMP_LE, CMP_LT, COS, CROSS,
|
|
88
|
+
ABS, ACOS, ADD, ASIN, ATAN2, CLAMP, CMP_EQ, CMP_GE, CMP_GT, CMP_LE, CMP_LT, COS, CROSS,
|
|
96
89
|
DISTANCE, DIV, DOT, EXP, FLOOR, FRACT, HALT, KILL, LENGTH, LOAD_ATTR, LOAD_BUILTIN, LOAD_CONST,
|
|
97
90
|
LOG, MAD, MAX, MIN, MIX, MOV, MUL, NEG, NOP, NORMALIZE, POW, RANDOM, RSQRT, SELECT, SIN,
|
|
98
91
|
SMOOTHSTEP, SQRT, STEP, STORE_ATTR, SUB, TAN,
|
|
@@ -139,7 +132,6 @@ const LITERAL_U32 = new Uint32Array(LITERAL_F32.buffer);
|
|
|
139
132
|
* @param {Uint32Array} params.record particle record words (mutated in place); attributes are f32 bits
|
|
140
133
|
* @param {number[][]} [params.builtins] builtin values indexed by {@link VM_BUILTIN} id, each a 4-array
|
|
141
134
|
* @param {number} [params.rng_state] initial RNG state (u32)
|
|
142
|
-
* @param {(handle: number, t: number) => number} [params.sampleCurve] curve evaluator for the CURVE op
|
|
143
135
|
* @returns {{ killed: boolean, rng_state: number }}
|
|
144
136
|
*/
|
|
145
137
|
export function execute_particle_vm({
|
|
@@ -149,7 +141,6 @@ export function execute_particle_vm({
|
|
|
149
141
|
record,
|
|
150
142
|
builtins = [],
|
|
151
143
|
rng_state = 0,
|
|
152
|
-
sampleCurve = () => 0,
|
|
153
144
|
}) {
|
|
154
145
|
// Register file: one f32 per slot. A value of width w occupies w consecutive slots.
|
|
155
146
|
const reg = new Float32Array(register_count);
|
|
@@ -217,14 +208,13 @@ export function execute_particle_vm({
|
|
|
217
208
|
const w = fixed_width < 0 ? (word0 >>> WIDTH_SHIFT) & WIDTH_MASK : fixed_width;
|
|
218
209
|
const dst = (word0 >>> DST_SHIFT) & DST_MASK;
|
|
219
210
|
const kinds = word0 >>> KIND_SHIFT;
|
|
220
|
-
const scalar = OP_SCALAR[op];
|
|
221
211
|
const s0 = words[base + 1];
|
|
222
212
|
const s1 = words[base + 2];
|
|
223
213
|
const s2 = words[base + 3];
|
|
224
214
|
|
|
225
|
-
gather(a, kinds & KIND_MASK, s0,
|
|
226
|
-
gather(b, (kinds >>> KIND_BITS) & KIND_MASK, s1,
|
|
227
|
-
gather(c, (kinds >>> (2 * KIND_BITS)) & KIND_MASK, s2,
|
|
215
|
+
gather(a, kinds & KIND_MASK, s0, w);
|
|
216
|
+
gather(b, (kinds >>> KIND_BITS) & KIND_MASK, s1, w);
|
|
217
|
+
gather(c, (kinds >>> (2 * KIND_BITS)) & KIND_MASK, s2, w);
|
|
228
218
|
|
|
229
219
|
switch (op) {
|
|
230
220
|
case HALT:
|
|
@@ -408,12 +398,6 @@ export function execute_particle_vm({
|
|
|
408
398
|
for (let i = 0; i < w; i++) d[i] = draw_unit();
|
|
409
399
|
break;
|
|
410
400
|
|
|
411
|
-
case CURVE: {
|
|
412
|
-
const v = sampleCurve(s0, b[0]);
|
|
413
|
-
for (let i = 0; i < w; i++) d[i] = v;
|
|
414
|
-
break;
|
|
415
|
-
}
|
|
416
|
-
|
|
417
401
|
default:
|
|
418
402
|
throw new Error(`ParticleVMReference: unhandled opcode ${op} at pc ${pc}`);
|
|
419
403
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chunk_particle_vm.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/vm/chunk_particle_vm.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"chunk_particle_vm.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/vm/chunk_particle_vm.js"],"names":[],"mappings":"AA0UA;;;GAGG;AACH,gCAFU,SAAS,CAEmG;0BA7U5F,oCAAoC"}
|
|
@@ -66,8 +66,8 @@ import { PARTICLE_VM_CONTEXT_STRUCT } from "./PARTICLE_VM_CONTEXT_STRUCT.js";
|
|
|
66
66
|
* VGPRs on RDNA2 and held the shader to 10 waves against a cap of 16.
|
|
67
67
|
*
|
|
68
68
|
* Where those slots LIVE is not this chunk's business. The interpreter reads and writes them through
|
|
69
|
-
* `vm_reg_read` and `vm_reg_write`, which a backing chunk supplies
|
|
70
|
-
*
|
|
69
|
+
* `vm_reg_read` and `vm_reg_write`, which a backing chunk supplies. There are two backings and they
|
|
70
|
+
* are the two interpreters:
|
|
71
71
|
*
|
|
72
72
|
* - {@link ./chunk_particle_vm_registers_fast.js} — a `var<private>` array of
|
|
73
73
|
* {@link ../ParticleConstants.js PARTICLE_VM_FAST_REGISTER_SLOTS}. Dynamically indexed, so it
|
|
@@ -128,8 +128,6 @@ import { PARTICLE_VM_CONTEXT_STRUCT } from "./PARTICLE_VM_CONTEXT_STRUCT.js";
|
|
|
128
128
|
* driver then fetches the instruction words through the scalar unit, branches the switch on a
|
|
129
129
|
* scalar and indexes `vm_reg` through M0 without the per-lane waterfall. Emit cannot: its waves
|
|
130
130
|
* span emitters.
|
|
131
|
-
* - The `CURVE` opcode calls the external symbol `particle_vm_sample_curve(handle: u32, t: f32) ->
|
|
132
|
-
* f32`. The enclosing shader must define it (production: animation-curve backed; tests: a stub).
|
|
133
131
|
*/
|
|
134
132
|
|
|
135
133
|
const source = /* language=wgsl */ `
|
|
@@ -318,7 +316,6 @@ fn particle_vm_execute(
|
|
|
318
316
|
if (w > 2u) { d.z = random(); }
|
|
319
317
|
if (w > 3u) { d.w = random(); }
|
|
320
318
|
}
|
|
321
|
-
case ${VM_OP.CURVE}u: { d = vec4<f32>(particle_vm_sample_curve(s0, b.x)); }
|
|
322
319
|
|
|
323
320
|
default: { lanes = 0u; }
|
|
324
321
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shader_particle_warmup_advance.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/warmup/shader_particle_warmup_advance.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"shader_particle_warmup_advance.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/warmup/shader_particle_warmup_advance.js"],"names":[],"mappings":"AAYA;;;;;;;;;;;;;;;;GAgBG;AAEH;;;;GAIG;AACH,sCAFU,YAAY,CAMc;AAgBpC;;;;GAIG;AACH,kCAFU,MAAM,CA6Bd;AAEF,2DAcG;;6BArG0B,mCAAmC;8BAClC,+BAA+B;gDAOb,6BAA6B"}
|
|
@@ -6,7 +6,6 @@ import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
|
|
|
6
6
|
import { ShaderResourceSetDescriptor } from "../../shader/resource/ShaderResourceSetDescriptor.js";
|
|
7
7
|
import { PARTICLE_WARMUP_LAUNCH_LANES, PARTICLE_WARMUP_WORKGROUP_SIZE } from "../ParticleConstants.js";
|
|
8
8
|
import { PARTICLE_COUNTER } from "../data/PARTICLE_COUNTERS.js";
|
|
9
|
-
import { chunk_particle_curve_disabled } from "../shaders/chunk_particle_curve_disabled.js";
|
|
10
9
|
import { chunk_particle_vm_registers_fast } from "../vm/chunk_particle_vm_registers_fast.js";
|
|
11
10
|
import { chunk_particle_warmup_step } from "./chunk_particle_warmup_step.js";
|
|
12
11
|
import { PARTICLE_WARMUP_WORKGROUP_COUNT } from "./shader_particle_warmup.js";
|
|
@@ -101,7 +100,6 @@ fn main(@builtin(global_invocation_id) gid : vec3<u32>) {
|
|
|
101
100
|
`, [
|
|
102
101
|
chunk_particle_warmup_step,
|
|
103
102
|
chunk_particle_vm_registers_fast,
|
|
104
|
-
chunk_particle_curve_disabled,
|
|
105
103
|
]),
|
|
106
104
|
});
|
|
107
105
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shader_particle_warmup_advance_wide.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/warmup/shader_particle_warmup_advance_wide.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"shader_particle_warmup_advance_wide.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/warmup/shader_particle_warmup_advance_wide.js"],"names":[],"mappings":"AAiDA,gEAkBG;8BAhE2B,+BAA+B"}
|
|
@@ -9,7 +9,6 @@ import {
|
|
|
9
9
|
PARTICLE_WARMUP_LAUNCH_LANES,
|
|
10
10
|
PARTICLE_WARMUP_WORKGROUP_SIZE,
|
|
11
11
|
} from "../ParticleConstants.js";
|
|
12
|
-
import { chunk_particle_curve_disabled } from "../shaders/chunk_particle_curve_disabled.js";
|
|
13
12
|
import { chunk_particle_vm_registers_wide } from "../vm/chunk_particle_vm_registers_wide.js";
|
|
14
13
|
import { chunk_particle_warmup_step } from "./chunk_particle_warmup_step.js";
|
|
15
14
|
import { WARMUP_ADVANCE_BODY, WARMUP_ADVANCE_SETTINGS } from "./shader_particle_warmup_advance.js";
|
|
@@ -65,6 +64,5 @@ fn main(@builtin(global_invocation_id) gid : vec3<u32>) {
|
|
|
65
64
|
`, [
|
|
66
65
|
chunk_particle_warmup_step,
|
|
67
66
|
chunk_particle_vm_registers_wide,
|
|
68
|
-
chunk_particle_curve_disabled,
|
|
69
67
|
]),
|
|
70
68
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chunk_ssr_reprojection.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_reprojection.js"],"names":[],"mappings":"AAIA,+
|
|
1
|
+
{"version":3,"file":"chunk_ssr_reprojection.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_reprojection.js"],"names":[],"mappings":"AAIA,+CAwCuC;0BA5Cb,uCAAuC"}
|
|
@@ -21,4 +21,25 @@ fn ssr_surface_history_uv(pixel: vec2f, velocity: vec2f, jitter_delta: vec2f, si
|
|
|
21
21
|
return (pixel - velocity + jitter_delta) / size;
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
+
// Surface motion does not include reflection parallax. Bound the expected lag of
|
|
25
|
+
// an exponential history to one internal pixel when this correspondence is used.
|
|
26
|
+
// Rotation and raster jitter cancel between the two projections; translation does not.
|
|
27
|
+
fn ssr_surface_parallax_confidence(camera_position: vec3f, position: vec3f, distance: f32,
|
|
28
|
+
previous_view_projection: mat4x4f, size: vec2f) -> f32 {
|
|
29
|
+
let surface_uv = ssr_history_uv(position, previous_view_projection);
|
|
30
|
+
var reflected_uv: vec2f;
|
|
31
|
+
if (is_finite(distance) && distance > 0.0) {
|
|
32
|
+
reflected_uv = ssr_history_uv(ssr_virtual_position(camera_position,position,distance),previous_view_projection);
|
|
33
|
+
} else {
|
|
34
|
+
// A miss has no finite reflected depth. Infinity bounds the parallax of
|
|
35
|
+
// a stale finite reflection that can still be present in this history.
|
|
36
|
+
let clip = previous_view_projection * vec4f(position-camera_position,0.0);
|
|
37
|
+
if (!is_finite(clip.w) || clip.w <= 1e-6) { return 0.0; }
|
|
38
|
+
reflected_uv = ndc_to_uv(clip.xy/clip.w);
|
|
39
|
+
}
|
|
40
|
+
let displacement = length((reflected_uv-surface_uv)*size);
|
|
41
|
+
if (!is_finite(displacement)) { return 0.0; }
|
|
42
|
+
return 1.0/(1.0+displacement);
|
|
43
|
+
}
|
|
44
|
+
|
|
24
45
|
`, [chunk_ndc_to_uv, chunk_is_finite]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chunk_ssr_temporal_accumulate.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_temporal_accumulate.js"],"names":[],"mappings":"AAUA,gGAAgG;AAChG,
|
|
1
|
+
{"version":3,"file":"chunk_ssr_temporal_accumulate.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_temporal_accumulate.js"],"names":[],"mappings":"AAUA,gGAAgG;AAChG,sDA6HuH;0BAxI7F,uCAAuC"}
|
|
@@ -119,6 +119,10 @@ fn ssr_temporal_accumulate(current: vec4f, previous: vec4f, previous_age: f32,
|
|
|
119
119
|
// well-supported long-term estimate. Do not leave it pinned to a clipped edge.
|
|
120
120
|
let rectified = any(abs(previous.rgb-clipped) > vec3f(1e-5));
|
|
121
121
|
if (rectified) { age = min(age, 2.0); }
|
|
122
|
+
// Confidence can force a much larger current contribution than 1/age.
|
|
123
|
+
// Carry that actual update rate into the age/variance pair too; otherwise a
|
|
124
|
+
// half-current blend can claim the uncertainty of a 65-frame accumulation.
|
|
125
|
+
age = min(age, 1.0 / max(1e-6, 1.0-saturate(confidence)));
|
|
122
126
|
let weight = min(saturate(confidence), 1.0 - 1.0/age);
|
|
123
127
|
let color = mix(current.rgb, clipped, weight);
|
|
124
128
|
var result: SSRAccumulation;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ssr_reproject_shader.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/postprocess/ssr/ssr_reproject_shader.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ssr_reproject_shader.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/postprocess/ssr/ssr_reproject_shader.js"],"names":[],"mappings":"AAqGA,+CAGG;4BAlGyB,6BAA6B"}
|
|
@@ -65,7 +65,7 @@ fn main(@builtin(position) coord: vec4f) -> SSRTemporalOutput {
|
|
|
65
65
|
var confidence = 0.0;
|
|
66
66
|
var motion_confidence = 1.0;
|
|
67
67
|
var history_uv = vec2f(0.0);
|
|
68
|
-
let virtual_eligible = settings.reprojection_mode != 1u && metadata.y >= 0.
|
|
68
|
+
let virtual_eligible = settings.reprojection_mode != 1u && metadata.y >= 0.5 && metadata.x > 0.0 && is_finite(metadata.x) && roughness <= 0.2;
|
|
69
69
|
if (virtual_eligible) {
|
|
70
70
|
let uv = ssr_history_uv(virtual_position, camera_previous.view_projection_matrix);
|
|
71
71
|
history_uv = uv;
|
|
@@ -81,6 +81,7 @@ fn main(@builtin(position) coord: vec4f) -> SSRTemporalOutput {
|
|
|
81
81
|
history_uv = uv;
|
|
82
82
|
history = ssr_sample_history(uv, position, normal, roughness, metadata, virtual_position, false, plane_tolerance);
|
|
83
83
|
confidence = history.confidence * surface_confidence;
|
|
84
|
+
confidence *= ssr_surface_parallax_confidence(camera_position,position,metadata.x,camera_previous.view_projection_matrix,size);
|
|
84
85
|
// Surface correspondence alone cannot justify a long history for a smooth finite reflection.
|
|
85
86
|
if (virtual_eligible) { confidence *= 0.25; }
|
|
86
87
|
}
|