/ proof-of-concept / cymbalsim
Sign in
proof-of-concept / cymbalsim
cymbalsim / src / sim / shaders / common.wgsl
91 lines · 3.7 KBCodeBlameHistory
5778036cymbalsim: scripted plate and cymbal designer with a modal linear model and a von Karman GPU modelJeremy Magland 1// Shared declarations, prepended to every kernel of the full simulation.
3struct Params {
4 nx: u32,
5 ny: u32,
6 n: u32,
7 histLen: u32,
8 hx: f32,
9 hy: f32,
10 dt: f32,
11 nu: f32,
12 Db: f32, // E / (12 (1 - nu^2)): bending stiffness per h^3 [Pa]
13 Cm: f32, // E / (1 - nu^2): membrane stiffness per h [Pa]
14 Gm: f32, // E / (2 (1 + nu)): membrane shear stiffness per h [Pa]
15 rho: f32, // density [kg/m^3]
16 mass: f32, // total mass [kg]
17 Ix: f32, // sum m y^2
18 Iy: f32, // sum m x^2
19 fs: f32, // audio sample rate [Hz]
20 strikeX: f32, // drumstick contact point [m]
21 strikeY: f32,
22 strikeR2: f32, // squared contact radius [m^2]
23 patchMass: f32, // mass of the contact patch [kg]
24 strikeNode: u32, // plate node nearest the contact point
25 K: f32, // Hertz contact stiffness [N/m^alpha]
26 alpha: f32, // Hertz exponent
27 stickMass: f32, // [kg]
28 patchI0: u32, // index box enclosing the contact patch (inclusive)
29 patchI1: u32,
30 patchJ0: u32,
31 patchJ1: u32,
32 patchCX: f32, // mass-weighted center of the contact patch [m]
33 patchCY: f32,
34 standOn: u32, // 1 when the plate sits on a stand, 0 when it is free
35 liftoff: u32, // 1 when the pads push only while compressed
36 preloadTop: f32, // compression of the top pad at rest [m] (0 without a top pad)
37 preloadBottom: f32, // compression of the bottom pad at rest [m]
18b1b86Model the felt as a Maxwell chain so that the full model has the loss factor of the linear oneJeremy Magland 38 kInf: f32, // relaxed stiffness of the felt, per unit of its stiffness at the bounce frequency
18b1b86Model the felt as a Maxwell chain so that the full model has the loss factor of the linear oneJeremy Magland 40 nArms: u32, // arms of the felt's chain (at most MAX_ARMS)
42 pad2: u32,
43 pad3: u32,
18b1b86Model the felt as a Maxwell chain so that the full model has the loss factor of the linear oneJeremy Magland 44 // The chain of the felt (felt.ts), four arms per vec4: decay factors
45 // exp(-dt / tau) in [0..2], growth factors (tau / dt)(1 - decay) in
46 // [3..5], and arm stiffnesses per unit of pad stiffness in [6..8].
47 chain: array<vec4f, 9>,
50fn armDecay(a: u32) -> f32 { return P.chain[a >> 2u][a & 3u]; }
51fn armGrowth(a: u32) -> f32 { return P.chain[3u + (a >> 2u)][a & 3u]; }
52fn armK(a: u32) -> f32 { return P.chain[6u + (a >> 2u)][a & 3u]; }
54// Per-step parameters, addressed with a dynamic uniform offset.
55struct StepParams {
56 step: u32,
57 flags: u32, // bit 0: drumstick active
58 audioSlot: i32, // ring-buffer slot to record the velocity into (-1: none)
59 audioOut: i32, // index of this sample within the batch's output
60 sigma0: f32,
61 sigma1: f32,
62 sigmaIn: f32, // additional frequency-independent loss of the in-plane motion
63 parity: u32, // which of the two stick-state slots holds the current state
64 pad0: u32,
65 pad1: u32,
66 pad2: u32,
67 pad3: u32,
68};
70fn nodeX(i: i32) -> f32 { return (f32(i) - 0.5 * f32(P.nx - 1u)) * P.hx; }
71fn nodeY(j: i32) -> f32 { return (f32(j) - 0.5 * f32(P.ny - 1u)) * P.hy; }
73// Static per-node data, written once by the host: x = stress-free shape w0 [m],
74// y = quadrature and lumped-mass weight (the fraction of the node's four cells
75// that belong to the plate; zero outside), z = thickness [m], w = bottom-pad
76// stiffness at the node [N/m] (zero away from the pads; the top pad, when
77// present, has the same rate).
78@group(0) @binding(8) var<storage, read> nd: array<vec4f>;
18b1b86Model the felt as a Maxwell chain so that the full model has the loss factor of the linear oneJeremy Magland 79// Extensions of the arms of the felt's chain: padQ[(field * nArms + arm) * n + k]
80// with field 0, 1, 2 for u, v, w; zero is the relaxed felt.
81@group(0) @binding(9) var<storage, read_write> padQ: array<f32>;
83 if (i < 0 || i >= i32(P.nx) || j < 0 || j >= i32(P.ny)) { return 0.0; }
84 return nd[u32(j) * P.nx + u32(i)].y;
86// Lumped mass of a node [kg].
87fn nodeMass(i: i32, j: i32) -> f32 {
88 if (i < 0 || i >= i32(P.nx) || j < 0 || j >= i32(P.ny)) { return 0.0; }
89 let k = u32(j) * P.nx + u32(i);
90 return P.rho * nd[k].z * P.hx * P.hy * nd[k].y;
↑↓ move↵openescclose