载入中...
搜索中...
未找到
ParticleGpuKernel.h
浏览该文件的文档.
1#pragma once
2
3namespace eve::particles {
4
23inline const char *kParticleGpuKernel = R"GLSL(
24#version 450
25layout(local_size_x = 64) in;
26
27layout(set = 0, binding = 0) buffer Particles {
28 float data[];
29} p;
30
31layout(push_constant) uniform PC {
32 float d[32];
33} pc;
34
35float hashNoise(int ix, int iy) {
36 uint h = uint(ix) * 374761393u + uint(iy) * 668265263u;
37 h = (h ^ (h >> 13u)) * 1274126177u;
38 return (float((h ^ (h >> 16u)) & 0xFFFFFFu) / float(0x1000000)) * 2.0 - 1.0;
39}
40
41float valueNoise(float x, float y) {
42 int ix = int(floor(x));
43 int iy = int(floor(y));
44 float fx = x - float(ix);
45 float fy = y - float(iy);
46 float sx = fx * fx * (3.0 - 2.0 * fx);
47 float sy = fy * fy * (3.0 - 2.0 * fy);
48 float n00 = hashNoise(ix, iy);
49 float n10 = hashNoise(ix + 1, iy);
50 float n01 = hashNoise(ix, iy + 1);
51 float n11 = hashNoise(ix + 1, iy + 1);
52 float a = mix(n00, n10, sx);
53 float b = mix(n01, n11, sx);
54 return mix(a, b, sy);
55}
56
57void main() {
58 uint i = gl_GlobalInvocationID.x;
59 uint alive = uint(pc.d[0]);
60 if (i >= alive) return;
61
62 float dt = pc.d[1];
63 float ex = pc.d[2];
64 float ey = pc.d[3];
65 float gx = pc.d[4];
66 float gy = pc.d[5];
67 float damp = pc.d[6];
68 float limit = pc.d[7];
69 float nstr = pc.d[8];
70 float nfreq = pc.d[9];
71 float nspeed = pc.d[10];
72 float time = pc.d[11];
73 float frameRate = pc.d[12];
74
75 uint b = i * 16u;
76 float x = p.data[b + 0u];
77 float y = p.data[b + 1u];
78 float vx = p.data[b + 2u];
79 float vy = p.data[b + 3u];
80 float life = p.data[b + 4u];
81 float rot = p.data[b + 7u];
82 float spin = p.data[b + 8u];
83 float frame = p.data[b + 9u];
84 float radial = p.data[b + 10u];
85 float tangential = p.data[b + 11u];
86 float ax0 = p.data[b + 12u];
87 float ay0 = p.data[b + 13u];
88 float nphase = p.data[b + 14u];
89
90 life -= dt;
91 if (life <= 0.0) {
92 p.data[b + 4u] = life;
93 return;
94 }
95
96 float ax = ax0 + gx;
97 float ay = ay0 + gy;
98
99 // Radial / tangential acceleration relative to the emitter.
100 float dx = x - ex;
101 float dy = y - ey;
102 float len2 = dx * dx + dy * dy;
103 if (len2 > 1e-6) {
104 float inv = inversesqrt(len2);
105 ax += dx * inv * radial - dy * inv * tangential;
106 ay += dy * inv * radial + dx * inv * tangential;
107 }
108
109 // Turbulence noise.
110 if (nstr != 0.0) {
111 float t = time * nspeed;
112 ax += valueNoise(x * nfreq + t, y * nfreq + nphase) * nstr;
113 ay += valueNoise(y * nfreq + t, x * nfreq - nphase) * nstr;
114 }
115
116 vx += ax * dt;
117 vy += ay * dt;
118
119 // Damping.
120 if (damp > 0.0) {
121 float f = max(0.0, 1.0 - damp * dt);
122 vx *= f;
123 vy *= f;
124 }
125 // Limit velocity.
126 if (limit > 0.0) {
127 float sp2 = vx * vx + vy * vy;
128 float m2 = limit * limit;
129 if (sp2 > m2) {
130 float s = sqrt(m2 / sp2);
131 vx *= s;
132 vy *= s;
133 }
134 }
135
136 x += vx * dt;
137 y += vy * dt;
138 rot += spin * dt;
139 frame += frameRate * dt;
140
141 p.data[b + 0u] = x;
142 p.data[b + 1u] = y;
143 p.data[b + 2u] = vx;
144 p.data[b + 3u] = vy;
145 p.data[b + 4u] = life;
146 p.data[b + 7u] = rot;
147 p.data[b + 9u] = frame;
148}
149)GLSL";
150
151} // namespace eve::particles
const char * kParticleGpuKernel
GLSL compute kernel for GPU-accelerated particle integration.