From 5f0cf958cc41188b4cee1177dbb4c87c7d4da1fe Mon Sep 17 00:00:00 2001 From: Xueyin Date: Sun, 13 Nov 2016 20:26:30 -0500 Subject: [PATCH 1/4] Finish All --- data/shaders/computeparticles/particle.comp | 44 +++++++++++++++++- .../computeparticles/particle.comp.spv | Bin 3132 -> 5644 bytes showcase.gif | Bin 0 -> 10898247 bytes vulkanBoids/vulkanBoids.cpp | 30 ++++++++++-- 4 files changed, 70 insertions(+), 4 deletions(-) create mode 100644 showcase.gif diff --git a/data/shaders/computeparticles/particle.comp b/data/shaders/computeparticles/particle.comp index b7dc2f7..4870a22 100644 --- a/data/shaders/computeparticles/particle.comp +++ b/data/shaders/computeparticles/particle.comp @@ -50,14 +50,56 @@ void main() // Current SSBO index uint index = gl_GlobalInvocationID.x; - // Don't try to write beyond particle count + // Don't try to write beyond particle count if (index >= ubo.particleCount) return; + vec2 centerOfMass = vec2(0.0, 0.0); // Rule 1 + vec2 seperation = vec2(0.0, 0.0); // Rule 2 + vec2 alignment = vec2(0.0, 0.0); // Rule 3 + float neighborOfCountRule1 = 0.0; + float neighborOfCountRule3 = 0.0; + float distanceBetweenTwoBoids = 0.0; + // Read position and velocity vec2 vPos = particlesA[index].pos.xy; vec2 vVel = particlesA[index].vel.xy; + for (int i = 0; i < ubo.particleCount; ++i) { + if (i == index) { + continue; + } + distanceBetweenTwoBoids = distance(particlesA[i].pos, vPos); + if (distanceBetweenTwoBoids < ubo.rule1Distance) { + centerOfMass += particlesA[i].pos.xy; + neighborOfCountRule1 += 1.0; + } + + if (distanceBetweenTwoBoids < ubo.rule2Distance) { + seperation -= particlesA[i].pos.xy - vPos; + } + + if (distanceBetweenTwoBoids < ubo.rule3Distance) { + alignment += particlesA[i].vel.xy; + neighborOfCountRule3 += 1.0; + } + } + + if (neighborOfCountRule1 > 0.0) { + centerOfMass /= neighborOfCountRule1; + vVel += (centerOfMass - vPos) * ubo.rule1Scale; + } + +// Refer to project 1 feedback, maybe we do not need to subtract this time? + + if(neighborOfCountRule3 > 0.0) { + alignment /= neighborOfCountRule3; + vVel += alignment * ubo.rule3Scale; + } + + vVel += seperation * ubo.rule2Scale; + + // clamp velocity for a more pleasing simulation. vVel = normalize(vVel) * clamp(length(vVel), 0.0, 0.1); diff --git a/data/shaders/computeparticles/particle.comp.spv b/data/shaders/computeparticles/particle.comp.spv index 059ab599d41ce7153cc2508dcfae81d358f32589..0389cf5e6ab4ce16af4986c2ae41885947579a1c 100644 GIT binary patch literal 5644 zcmZ{niI-H>5r-en!WhQ|6*U?;4MY$@!T=&hQD(%9Bp48ISH_;1=g``8Po{eYV~m1J z;vSc5W;O2Oz9p`am}oYPWKaH)ES}>z`M%e$#>X6UJ$33=zp7ieZryr4*tXx?=}9t; z|GJWYCapCi*$+EO4oEsP-M?A>=(OGe8>S8;y(KIdz9aYm&!oL-IYz_O;1>Og zwsuYCZ%YnCpVzlOyN%d2oK~CV%?aG}%y0c;2|M}E^X+MtZwlWTxhDBmZ9HN^3!9apYIr3{;^x7XtCf-3Ha28&UCHt2T3Q*|I#?$| zcFIQE0Zo>!WWmS#mxccXz;NEWzO=bLO>3LC*Zb;~;RgHLlZE&vHqgKMC+439CQrYyOq$MrO&w8=+>TA9(~dK zMa)GB`_nlm@1FT+_ZT}1+u14QaxC|CM&xFJods?8eFp8ha^6APc_`kY2is-*GIXoX zkM6hS~SqfKDrt;?RMw;)Nf^p}20NC$Q z+x)wb_x9{r752;6ocETt`*tJNYhRr8=!-M0?LFT|Ta%o9(RQw*PV@X7IRsfmR_D+; zms55lE2zqNYj=64|G-$QIqj3*uv&XIdd?KvzZ*sWyn;O+?B9#w@tg3s(meA2=8Rcr*9XMwI~I|%m*Nk3O|hIc*+ah%vHc5d?*iL5za3-j zSz!Amj{7VHx9&4NoBie3OAx;aeQIM%=#vor=Cse+k>_M^G0!R3kw>53P~`b6SigCE zA8oO3<9Yw(uB*`AS^Y20KLfoQap~_x>sOoCzV{*Kh_^WtJoRnXz{x+Kzr|T#_sQFT z?b8v@Gru_Ue-3Q^c-MZgT=d{t3xl`XYApR$uXr)?@2;Zwb8t@vXX<`WfhRk!grMFjl|4cP{j~&$x|O8lSbL#Q&R#@)>gYusTVgg+3 z#dhrIg}#+}YzcieqCf8WW$-*CX5<>MoN?Y$pIqGQE8qo4%*eH1xtI}sa`q)^RTsbC z)!0${SHaf4gSR*oeH|ia&7QAM&i$*<-re7ysONgHbNL$kk3sK1u~b%4ZQ)DGmo|W9PP3eeQzRi)*_DFZ-I-oXnP-PiFkFy|00jyjgDI0 z2FpiZehHR~zPtl=S&P13A#&Ctj@<8ptz|c2U$nO%))MjRi2pS>;-i+|z{y8nehZc} zkA3+)+GQ>Jeuv0ei#T%c0Y`3Y(T=`EyxMa+(SJm`a=V276XO0}{=K&h{byt^(t{YQ lHm|&~k>@YqVxGTZx8}c<=Wp1N$JmvKdE|}t|4~*V{{x4m91{Ql literal 3132 zcmZ{k+j3M@5QY~_P6&d?$rGtbP!k0aLO>J&6QUC|N+f`1Cp(idjE*xDGf8>jg}#7~ z;VW%sjwv);R#tvB!2yK7%I8~xtS973(mM!lVNHa4@3W_@<%%)PAf74?U9 z)Yl)QMys>l{02RYXHOgLdad1E%i7mFTir(1Z*@D@7xH)|9YWupzmcCt+qK?o_p@6G zY&4JC|NYH&^Xx*a*UvhQCVs>`ld+lqh(v8Ojz^eg6y`r^aPd8&Z1htf;fTX!H~S^IPJHqU&)Bj(!X0hebrM^mc7 z;~bS|kVT>~tLQs0dlvJ419L`VzKy^tCAMz>bB}qx*~oJqVuuGXXCd~)0OlOT?5{@e z_GevtcNUX~EBpy;_~yhEYh2*}Wd0E1@*VvF zGK`kfzQ+)?{semRA>VJ7@i}(+p7tZYIp5i3_IREHi1-yM$fqAM`xA4&Z^7?`@5MJ_ zj_<<%i1@c9-%};_BYS)=en;dH|D77+XxCrl8#|7Oc{c68xm|6s=;H5 zVvWls9-LS3-6tMASFydb@5{PxV2ha>_bFzbIke|6Ki-pdu9f&t_t1c?_k@D+}?|R z+)L!EBmV>J$d6t=1QU;Y`3PGq?&T9~m%SMK7!k7_MI;e)0Ybo-goM5%-(x|5_e#bN$9#ME(I_ C2Ji*| diff --git a/showcase.gif b/showcase.gif new file mode 100644 index 0000000000000000000000000000000000000000..59c8902acbdcc16c43c4c26080bb786ea081f488 GIT binary patch literal 10898247 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