dan sinclair | 42e873c | 2021-01-12 18:13:28 +0000 | [diff] [blame] | 1 | // Copyright 2020 The Tint Authors. |
| 2 | // |
| 3 | // Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | // you may not use this file except in compliance with the License. |
| 5 | // You may obtain a copy of the License at |
| 6 | // |
| 7 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | // |
| 9 | // Unless required by applicable law or agreed to in writing, software |
| 10 | // distributed under the License is distributed on an "AS IS" BASIS, |
| 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 | // See the License for the specific language governing permissions and |
| 13 | // limitations under the License. |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 14 | |
dan sinclair | 42e873c | 2021-01-12 18:13:28 +0000 | [diff] [blame] | 15 | // vertex shader |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 16 | |
dan sinclair | b29892b | 2022-06-07 13:55:34 +0000 | [diff] [blame] | 17 | @vertex |
Ben Clayton | 01e4b6f | 2022-01-19 22:46:57 +0000 | [diff] [blame] | 18 | fn vert_main(@location(0) a_particlePos : vec2<f32>, |
| 19 | @location(1) a_particleVel : vec2<f32>, |
| 20 | @location(2) a_pos : vec2<f32>) |
| 21 | -> @builtin(position) vec4<f32> { |
dan sinclair | b4fee2f | 2020-09-22 19:42:13 +0000 | [diff] [blame] | 22 | var angle : f32 = -atan2(a_particleVel.x, a_particleVel.y); |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 23 | var pos : vec2<f32> = vec2<f32>( |
dan sinclair | b4fee2f | 2020-09-22 19:42:13 +0000 | [diff] [blame] | 24 | (a_pos.x * cos(angle)) - (a_pos.y * sin(angle)), |
| 25 | (a_pos.x * sin(angle)) + (a_pos.y * cos(angle))); |
James Price | a2239c6 | 2021-04-06 18:08:47 +0000 | [diff] [blame] | 26 | return vec4<f32>(pos + a_particlePos, 0.0, 1.0); |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 27 | } |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 28 | |
dan sinclair | 42e873c | 2021-01-12 18:13:28 +0000 | [diff] [blame] | 29 | // fragment shader |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 30 | |
dan sinclair | b29892b | 2022-06-07 13:55:34 +0000 | [diff] [blame] | 31 | @fragment |
Ben Clayton | 01e4b6f | 2022-01-19 22:46:57 +0000 | [diff] [blame] | 32 | fn frag_main() -> @location(0) vec4<f32> { |
James Price | a2239c6 | 2021-04-06 18:08:47 +0000 | [diff] [blame] | 33 | return vec4<f32>(1.0, 1.0, 1.0, 1.0); |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 34 | } |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 35 | |
dan sinclair | 42e873c | 2021-01-12 18:13:28 +0000 | [diff] [blame] | 36 | // compute shader |
Ben Clayton | 8db8188 | 2021-04-21 16:45:02 +0000 | [diff] [blame] | 37 | struct Particle { |
James Price | 3b671cb | 2022-03-28 14:31:22 +0000 | [diff] [blame] | 38 | pos : vec2<f32>, |
| 39 | vel : vec2<f32>, |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 40 | }; |
| 41 | |
James Price | a5d3986 | 2021-12-09 15:45:03 +0000 | [diff] [blame] | 42 | struct SimParams { |
James Price | 3b671cb | 2022-03-28 14:31:22 +0000 | [diff] [blame] | 43 | deltaT : f32, |
| 44 | rule1Distance : f32, |
| 45 | rule2Distance : f32, |
| 46 | rule3Distance : f32, |
| 47 | rule1Scale : f32, |
| 48 | rule2Scale : f32, |
| 49 | rule3Scale : f32, |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 50 | }; |
| 51 | |
James Price | a5d3986 | 2021-12-09 15:45:03 +0000 | [diff] [blame] | 52 | struct Particles { |
James Price | 3b671cb | 2022-03-28 14:31:22 +0000 | [diff] [blame] | 53 | particles : array<Particle, 5>, |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 54 | }; |
| 55 | |
Ben Clayton | 01e4b6f | 2022-01-19 22:46:57 +0000 | [diff] [blame] | 56 | @binding(0) @group(0) var<uniform> params : SimParams; |
| 57 | @binding(1) @group(0) var<storage, read_write> particlesA : Particles; |
| 58 | @binding(2) @group(0) var<storage, read_write> particlesB : Particles; |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 59 | |
dan sinclair | 42e873c | 2021-01-12 18:13:28 +0000 | [diff] [blame] | 60 | // https://github.com/austinEng/Project6-Vulkan-Flocking/blob/master/data/shaders/computeparticles/particle.comp |
dan sinclair | b29892b | 2022-06-07 13:55:34 +0000 | [diff] [blame] | 61 | @compute @workgroup_size(1) |
James Price | a2239c6 | 2021-04-06 18:08:47 +0000 | [diff] [blame] | 62 | fn comp_main( |
Ben Clayton | 01e4b6f | 2022-01-19 22:46:57 +0000 | [diff] [blame] | 63 | @builtin(global_invocation_id) gl_GlobalInvocationID : vec3<u32>) { |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 64 | var index : u32 = gl_GlobalInvocationID.x; |
dan sinclair | d7abd76 | 2020-09-23 14:40:54 +0000 | [diff] [blame] | 65 | if (index >= 5u) { |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 66 | return; |
| 67 | } |
| 68 | |
| 69 | var vPos : vec2<f32> = particlesA.particles[index].pos; |
| 70 | var vVel : vec2<f32> = particlesA.particles[index].vel; |
| 71 | |
David Neto | ac47807 | 2020-05-01 19:02:35 +0000 | [diff] [blame] | 72 | var cMass : vec2<f32> = vec2<f32>(0.0, 0.0); |
| 73 | var cVel : vec2<f32> = vec2<f32>(0.0, 0.0); |
| 74 | var colVel : vec2<f32> = vec2<f32>(0.0, 0.0); |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 75 | var cMassCount : i32 = 0; |
| 76 | var cVelCount : i32 = 0; |
| 77 | |
| 78 | var pos : vec2<f32>; |
| 79 | var vel : vec2<f32>; |
Ben Clayton | 7862da9 | 2021-03-17 18:43:53 +0000 | [diff] [blame] | 80 | for(var i : u32 = 0u; i < 5u; i = i + 1u) { |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 81 | if (i == index) { |
| 82 | continue; |
| 83 | } |
| 84 | |
| 85 | pos = particlesA.particles[i].pos.xy; |
| 86 | vel = particlesA.particles[i].vel.xy; |
| 87 | |
dan sinclair | b4fee2f | 2020-09-22 19:42:13 +0000 | [diff] [blame] | 88 | if (distance(pos, vPos) < params.rule1Distance) { |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 89 | cMass = cMass + pos; |
| 90 | cMassCount = cMassCount + 1; |
| 91 | } |
dan sinclair | b4fee2f | 2020-09-22 19:42:13 +0000 | [diff] [blame] | 92 | if (distance(pos, vPos) < params.rule2Distance) { |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 93 | colVel = colVel - (pos - vPos); |
| 94 | } |
dan sinclair | b4fee2f | 2020-09-22 19:42:13 +0000 | [diff] [blame] | 95 | if (distance(pos, vPos) < params.rule3Distance) { |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 96 | cVel = cVel + vel; |
| 97 | cVelCount = cVelCount + 1; |
| 98 | } |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 99 | } |
| 100 | if (cMassCount > 0) { |
dan sinclair | 64db1d9 | 2020-05-01 19:05:43 +0000 | [diff] [blame] | 101 | cMass = |
dan sinclair | d2d7ce6 | 2020-09-30 14:00:10 +0000 | [diff] [blame] | 102 | (cMass / vec2<f32>(f32(cMassCount), f32(cMassCount))) - vPos; |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 103 | } |
| 104 | if (cVelCount > 0) { |
dan sinclair | d2d7ce6 | 2020-09-30 14:00:10 +0000 | [diff] [blame] | 105 | cVel = cVel / vec2<f32>(f32(cVelCount), f32(cVelCount)); |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 106 | } |
| 107 | |
| 108 | vVel = vVel + (cMass * params.rule1Scale) + (colVel * params.rule2Scale) + |
| 109 | (cVel * params.rule3Scale); |
| 110 | |
dan sinclair | 42e873c | 2021-01-12 18:13:28 +0000 | [diff] [blame] | 111 | // clamp velocity for a more pleasing simulation |
dan sinclair | b4fee2f | 2020-09-22 19:42:13 +0000 | [diff] [blame] | 112 | vVel = normalize(vVel) * clamp(length(vVel), 0.0, 0.1); |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 113 | |
dan sinclair | 42e873c | 2021-01-12 18:13:28 +0000 | [diff] [blame] | 114 | // kinematic update |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 115 | vPos = vPos + (vVel * params.deltaT); |
| 116 | |
dan sinclair | 42e873c | 2021-01-12 18:13:28 +0000 | [diff] [blame] | 117 | // Wrap around boundary |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 118 | if (vPos.x < -1.0) { |
| 119 | vPos.x = 1.0; |
| 120 | } |
| 121 | if (vPos.x > 1.0) { |
| 122 | vPos.x = -1.0; |
| 123 | } |
| 124 | if (vPos.y < -1.0) { |
| 125 | vPos.y = 1.0; |
| 126 | } |
| 127 | if (vPos.y > 1.0) { |
| 128 | vPos.y = -1.0; |
| 129 | } |
| 130 | |
dan sinclair | 42e873c | 2021-01-12 18:13:28 +0000 | [diff] [blame] | 131 | // Write back |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 132 | particlesB.particles[index].pos = vPos; |
| 133 | particlesB.particles[index].vel = vVel; |
Dan Sinclair | 6e58189 | 2020-03-02 15:47:43 -0500 | [diff] [blame] | 134 | } |