Last active
October 26, 2017 19:03
-
-
Save kainino0x/7df254f5d3a2343fd1cab5f9c09e3354 to your computer and use it in GitHub Desktop.
boids glslc->spirv-opt->spirv-cross
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<style> | |
td pre { | |
overflow-x: scroll; | |
width: 31vw; | |
} | |
td { | |
border: 1px solid black; | |
vertical-align: top; | |
} | |
</style> | |
<pre> | |
$ glslc boids.comp -o boids.spv | |
$ spirv-cross boids.spv --output boids.decomp.comp | |
$ spirv-opt --strip-debug boids.spv -o boids.opt.spv | |
$ spirv-cross boids.opt.spv --output boids.opt.comp | |
</pre> | |
<table> | |
<tr> | |
<th>boids.comp</th> | |
<th>boids.decomp.comp</th> | |
<th>boids.opt.comp</th> | |
</tr> | |
<tr> | |
<td> | |
<pre> | |
#version 450 | |
// https://github.com/google/nxt-standalone/blob/master/examples/ComputeBoids.cpp | |
struct Particle { | |
vec2 pos; | |
vec2 vel; | |
}; | |
layout(std140, set = 0, binding = 0) uniform SimParams { | |
float deltaT; | |
float rule1Distance; | |
float rule2Distance; | |
float rule3Distance; | |
float rule1Scale; | |
float rule2Scale; | |
float rule3Scale; | |
int particleCount; | |
} params; | |
layout(std140, set = 0, binding = 1) buffer ParticlesA { | |
Particle particle; | |
} particlesA[1000]; | |
layout(std140, set = 0, binding = 2) buffer ParticlesB { | |
Particle particle; | |
} particlesB[1000]; | |
void main() { | |
// https://github.com/austinEng/Project6-Vulkan-Flocking/blob/master/data/shaders/computeparticles/particle.comp | |
uint index = gl_GlobalInvocationID.x; | |
if (index >= params.particleCount) { return; } | |
vec2 vPos = particlesA[index].particle.pos; | |
vec2 vVel = particlesA[index].particle.vel; | |
vec2 cMass = vec2(0.0, 0.0); | |
vec2 cVel = vec2(0.0, 0.0); | |
vec2 colVel = vec2(0.0, 0.0); | |
int cMassCount = 0; | |
int cVelCount = 0; | |
vec2 pos; | |
vec2 vel; | |
for (int i = 0; i < params.particleCount; ++i) { | |
if (i == index) { continue; } | |
pos = particlesA[i].particle.pos.xy; | |
vel = particlesA[i].particle.vel.xy; | |
if (distance(pos, vPos) < params.rule1Distance) { | |
cMass += pos; | |
cMassCount++; | |
} | |
if (distance(pos, vPos) < params.rule2Distance) { | |
colVel -= (pos - vPos); | |
} | |
if (distance(pos, vPos) < params.rule3Distance) { | |
cVel += vel; | |
cVelCount++; | |
} | |
} | |
if (cMassCount > 0) { | |
cMass = cMass / cMassCount - vPos; | |
} | |
if (cVelCount > 0) { | |
cVel = cVel / cVelCount; | |
} | |
vVel += cMass * params.rule1Scale + colVel * params.rule2Scale + cVel * params.rule3Scale; | |
// clamp velocity for a more pleasing simulation. | |
vVel = normalize(vVel) * clamp(length(vVel), 0.0, 0.1); | |
// kinematic update | |
vPos += vVel * params.deltaT; | |
// Wrap around boundary | |
if (vPos.x < -1.0) vPos.x = 1.0; | |
if (vPos.x > 1.0) vPos.x = -1.0; | |
if (vPos.y < -1.0) vPos.y = 1.0; | |
if (vPos.y > 1.0) vPos.y = -1.0; | |
particlesB[index].particle.pos = vPos; | |
// Write back | |
particlesB[index].particle.vel = vVel; | |
} | |
</pre> | |
</td><td> | |
<pre> | |
#version 450 | |
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; | |
struct Particle | |
{ | |
vec2 pos; | |
vec2 vel; | |
}; | |
layout(binding = 0, std140) uniform SimParams | |
{ | |
float deltaT; | |
float rule1Distance; | |
float rule2Distance; | |
float rule3Distance; | |
float rule1Scale; | |
float rule2Scale; | |
float rule3Scale; | |
int particleCount; | |
} params; | |
layout(binding = 1, std430) buffer ParticlesA | |
{ | |
Particle particle; | |
} particlesA[1000]; | |
layout(binding = 2, std430) buffer ParticlesB | |
{ | |
Particle particle; | |
} particlesB[1000]; | |
void main() | |
{ | |
uint index = gl_GlobalInvocationID.x; | |
if (index >= uint(params.particleCount)) | |
{ | |
return; | |
} | |
vec2 vPos = particlesA[index].particle.pos; | |
vec2 vVel = particlesA[index].particle.vel; | |
vec2 cMass = vec2(0.0); | |
vec2 cVel = vec2(0.0); | |
vec2 colVel = vec2(0.0); | |
int cMassCount = 0; | |
int cVelCount = 0; | |
for (int i = 0; i < params.particleCount; i++) | |
{ | |
vec2 vel; | |
vec2 pos; | |
if (uint(i) == index) | |
{ | |
continue; | |
} | |
pos = particlesA[i].particle.pos; | |
vel = particlesA[i].particle.vel; | |
if (distance(pos, vPos) < params.rule1Distance) | |
{ | |
cMass += pos; | |
cMassCount++; | |
} | |
if (distance(pos, vPos) < params.rule2Distance) | |
{ | |
colVel -= (pos - vPos); | |
} | |
if (distance(pos, vPos) < params.rule3Distance) | |
{ | |
cVel += vel; | |
cVelCount++; | |
} | |
} | |
if (cMassCount > 0) | |
{ | |
cMass = (cMass / vec2(float(cMassCount))) - vPos; | |
} | |
if (cVelCount > 0) | |
{ | |
cVel /= vec2(float(cVelCount)); | |
} | |
vVel += (((cMass * params.rule1Scale) + (colVel * params.rule2Scale)) + (cVel * params.rule3Scale)); | |
vVel = normalize(vVel) * clamp(length(vVel), 0.0, 0.100000001490116119384765625); | |
vPos += (vVel * params.deltaT); | |
if (vPos.x < (-1.0)) | |
{ | |
vPos.x = 1.0; | |
} | |
if (vPos.x > 1.0) | |
{ | |
vPos.x = -1.0; | |
} | |
if (vPos.y < (-1.0)) | |
{ | |
vPos.y = 1.0; | |
} | |
if (vPos.y > 1.0) | |
{ | |
vPos.y = -1.0; | |
} | |
particlesB[index].particle.pos = vPos; | |
particlesB[index].particle.vel = vVel; | |
} | |
</pre> | |
</td><td> | |
<pre> | |
#version 450 | |
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; | |
struct _35 | |
{ | |
vec2 _m0; | |
vec2 _m1; | |
}; | |
layout(binding = 0, std140) uniform _19_21 | |
{ | |
float _m0; | |
float _m1; | |
float _m2; | |
float _m3; | |
float _m4; | |
float _m5; | |
float _m6; | |
int _m7; | |
} _21; | |
layout(binding = 1, std430) buffer _36_40 | |
{ | |
_35 _m0; | |
} _40[1000]; | |
layout(binding = 2, std430) buffer _208_211 | |
{ | |
_35 _m0; | |
} _211[1000]; | |
void main() | |
{ | |
uint _8 = gl_GlobalInvocationID.x; | |
if (_8 >= uint(_21._m7)) | |
{ | |
return; | |
} | |
vec2 _34 = _40[_8]._m0._m0; | |
vec2 _46 = _40[_8]._m0._m1; | |
vec2 _51 = vec2(0.0); | |
vec2 _54 = vec2(0.0); | |
vec2 _55 = vec2(0.0); | |
int _57 = 0; | |
int _58 = 0; | |
for (int _59 = 0; _59 < _21._m7; _59++) | |
{ | |
vec2 _80; | |
vec2 _76; | |
if (uint(_59) == _8) | |
{ | |
continue; | |
} | |
_76 = _40[_59]._m0._m0; | |
_80 = _40[_59]._m0._m1; | |
if (distance(_76, _34) < _21._m1) | |
{ | |
_51 += _76; | |
_57++; | |
} | |
if (distance(_76, _34) < _21._m2) | |
{ | |
_55 -= (_76 - _34); | |
} | |
if (distance(_76, _34) < _21._m3) | |
{ | |
_54 += _80; | |
_58++; | |
} | |
} | |
if (_57 > 0) | |
{ | |
_51 = (_51 / vec2(float(_57))) - _34; | |
} | |
if (_58 > 0) | |
{ | |
_54 /= vec2(float(_58)); | |
} | |
_46 += (((_51 * _21._m4) + (_55 * _21._m5)) + (_54 * _21._m6)); | |
_46 = normalize(_46) * clamp(length(_46), 0.0, 0.100000001490116119384765625); | |
_34 += (_46 * _21._m0); | |
if (_34.x < (-1.0)) | |
{ | |
_34.x = 1.0; | |
} | |
if (_34.x > 1.0) | |
{ | |
_34.x = -1.0; | |
} | |
if (_34.y < (-1.0)) | |
{ | |
_34.y = 1.0; | |
} | |
if (_34.y > 1.0) | |
{ | |
_34.y = -1.0; | |
} | |
_211[_8]._m0._m0 = _34; | |
_211[_8]._m0._m1 = _46; | |
} | |
</pre> | |
</td> | |
</tr></table> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment