From c2e4a92d04b210bb4f507d097f8d5632b797d585 Mon Sep 17 00:00:00 2001
From: Alexander Gauggel <agauggel@uni-koblenz.de>
Date: Fri, 25 Jun 2021 22:41:54 +0200
Subject: [PATCH] [#69] Additively blend particles and make them look rounded

---
 include/vkcv/PipelineConfig.hpp               |   5 +++++
 .../shaders/frag_space.spv                    | Bin 2092 -> 2700 bytes
 .../shaders/frag_water.spv                    | Bin 2168 -> 2760 bytes
 .../shaders/particleShading.inc               |   6 ++++++
 .../particle_simulation/shaders/shader.vert   |   7 ++++++-
 .../shaders/shader_space.frag                 |  10 ++++++++++
 .../shaders/shader_water.frag                 |   9 +++++++++
 projects/particle_simulation/shaders/vert.spv | Bin 2652 -> 2956 bytes
 projects/particle_simulation/src/main.cpp     |   9 +++++----
 src/vkcv/PipelineManager.cpp                  |   5 ++++-
 10 files changed, 45 insertions(+), 6 deletions(-)
 create mode 100644 projects/particle_simulation/shaders/particleShading.inc

diff --git a/include/vkcv/PipelineConfig.hpp b/include/vkcv/PipelineConfig.hpp
index 1e00c520..45539769 100644
--- a/include/vkcv/PipelineConfig.hpp
+++ b/include/vkcv/PipelineConfig.hpp
@@ -15,6 +15,10 @@ namespace vkcv {
 
     enum class PrimitiveTopology{PointList, LineList, TriangleList };
 
+    // add more as needed
+    // alternatively we could expose the blend factors directly
+    enum class BlendMode{ None, Additive };
+
     struct PipelineConfig {
         ShaderProgram                         m_ShaderProgram;
         uint32_t                              m_Width;
@@ -25,6 +29,7 @@ namespace vkcv {
         bool                                  m_UseDynamicViewport;
         bool                                  m_UseConservativeRasterization = false;
         PrimitiveTopology                     m_PrimitiveTopology = PrimitiveTopology::TriangleList;
+        BlendMode                             m_blendMode = BlendMode::None;
     };
 
 }
\ No newline at end of file
diff --git a/projects/particle_simulation/shaders/frag_space.spv b/projects/particle_simulation/shaders/frag_space.spv
index f05bab5cddababb06332586007586fee842e51c2..8acf8a4295ba661f1b7a893d3c8dd508a4b168b6 100644
GIT binary patch
literal 2700
zcmZQ(Qf6mhU}WH8;AO~UfB-=TCI&_Z1_o{hHZbk(6YQf`T#}+^Vrl?V!N<T1qQG+e
z44e!s3=CkLo0ypglF(sbV9;Y=V2Ea5U`S<PU=Uzn2FtTEFfcGPFf%YQFfbfq1nJ>q
zaQBIK404JuPAy0*N-Rl@FV09zNiB-cPs&P7E-417;R2~~_xE@Aag9$dD2OjEsmw`@
z&&kY7jZeueN=+`wEK3Ec<3LiEnU|bXnu4r=m4OB92ACUJ8Q2-P85kInGmDaQQr!}h
zOY(~}%F>Li85kHqa$F1y3?)UGiFxTcsm}TNMJbtii6yDU46F>y415d>3<Y3yEDX{N
z3=FyXrNtnBvNEtT$S^Q4lm_G%XO?8<g93w%fekDM3YP+eFat=f90LObl2Wi3DD3h}
zOPup_@{2%vSQ*&BVOfw^T%41cmKu_o3$luVm4O2sz98`stnOrChyl4Xu_!SY>{d2#
zT!7SvrRL-(XO>h#%x7Up1GyP$BO3!Nm=BUmhB^Wib{Px|3{WKu9#DUR)F^`p1_lOq
z24=87L2>KOz`_9Xn-W|O!dGMfr8JOQ76y<%L25usK<Yv11;mHx2c;blA0`j-G>8vM
zmmvE=ZU)IA+Yb_h=?A$N*?tfoWIsrcFar}f4Jv|DBLkQ%#=y+L#=yX!z`(#D&cMO|
zN~<6~$UFrG76uLm2Cx`NT#<o=fs=s&tR5r|lIMlWgY;-Kuz=<G85kJOo;hO&<BNbS
zXJBA}@kPP>275VZ*n!LjnI+2raT6#lSu?OOfcPN4gWMv@z``I8btfn+KxV=CAmc#t
zAb*1V0pf$?L3~(PfXoMl8OSV{TS4+_(6|BlT?^_rP`(DK*9PZX1_qEg$UPuFDE>gD
z07zaJsuyG)NFKxo#V5#pA`DCnph823fgP;hn1O)-<ZloLg$D?O+z8TZ268Y1g9D6j
z58>Ox_?}?Cf&<K~aHv@zGhi6xo+zk$K;a2;4~P#+PayYz{Fe;%AI$wJQ1u{jka`dw
zl-@w<L2(00S0KNG%ua{K4M+^67Q_doEl_xxF|dNu5-8k2P6e6&gMo>Gm4Sf)q!yG`
zK;;F@T_8RvkAnD)3~UUbcu`?s0OuW0{DI=k7Mhk+85kHqaxiu3Na{dw2UDlPz`y{K
z3jmj53=EnK3=AN>AaOeeW^j205`(GNhnCel7+AsaWXQn401^Ym&q@YR>BYcc#K6D+
z5(kNa!nu!u6&#l)3=9mQ_yozr%riwZ&zymQ0VD>B+wTm_43?mPVPIhR#lXS<lCxl7
z0E>ab3B-n(V+A#57t~##av3BBa>GvsCb%Aud0!dW!EU!<U;vv532z1lka;ja*fKCM
zfaF2?L4JVQV+XaTl>t=JGB7wWFff3`Kxr=knr0oL=?o+X(hI_{FmPgEU;xR3%x{E-
zi!%cQ11M}jaxi;bp!V#8`p1=lfdM223m12!Z~@7=fy-0|22i+w*f4WEpyt5h%Zq`5
z0VD>>8=!CjnFG=TqG93U&A`9_G7}V5AoU>gVBzA!z`y{KM-LZYs6DW7@nc|M0EvOZ
z1?CoiG&KPX3=AMKkQ!Ln1u`%&fb@doK;Z_$u&@haU|;~rgWLcMyI@c~!@$4*l7rb3
z0<{MgcA*Rm3?MO(pJDz8V_;waiNpK>vm=6mfdN!bfaGCzL^3cifb0Ruf${{XECY#w
z>;vV+SZLb?BnQf$AigCueZ+y=MGWA&6{H?iF2pl1fa^1uoe2yK3?MO(T96qa^Fd-T
z^@(WelNcBnKw_Y9gQ*9J{bgWeuwY<h0F^7C@)6Wt0VNYq-DA$c46c(v?G#Xa^FYfO
zP(1`{pMd-UvJXTHFfcHH)bT*`vmms*1Eo)pTr<>fLJSNHpgIdA-vJd9W?*1|iSsaU
zfa^6esD4mA0FnpADJa}QZU@;7k_Xuha<e!C1Gv2evs(hH7gT3~<o+=*F@VHC{saKM
CM%|bI

literal 2092
zcmZQ(Qf6mhU}WH8;AIG4fB-=TCI&_Z1_o{hHZbk(6YQf`T#}+^Vrl?V!N<T1qQG+e
z3>*wB3=CkLo0ypgl8|CxV31*8VDMpJU=Uzn2FtNCFfcGPFf%YQFfbfq1gYm_aQBIK
z404JuPAy0*N-Rl@FV09zNiB-cPs&P7E-417;R2~~_xE@Aag9$dD2OjEsmw`@&&kY7
zjZeueN=+`wEK3Ec<3LiEnU|bXnu4r=m4OB92AKOmd`<=ihTQzp;#39(237`E1}+8$
zhSGri;>?oFe2^#D7}&sKApaB~gu!Zg7#J9kl!C=Te$Fo~an8@lF9PXdWncq`K|x}1
zaZYAhYDi`-$SMYqI4E2|;$f*d`N^3jl@RqT489;YKuus{U<LC*a>-CbLGJcvU|@hM
zVeo*u8>B`VL@+QgxHB+=-3<z7cLo*)kXx1DauB{E11QEpYFQXS?v_K62gMtR57Q5F
zD~JzD4<P$MZUiYuwhtr*Qx9?<vV9;v$UcxBVFo5}{40V}0t1*W#=y+L#=yX!z`(#D
z&cMO|N+%#b$UFrG76uLm2Cx`NTn_3t5E~@N%>Xe26nEAPEDRt%$iE=Hq6{nyyijvN
zZr6tL`9Ka~U|;~r^F!r9LLhk%UjW1bi?c8YLd^%c2PQ894LguqB^VgMZU?1*kb5M-
zX`F!pBo1;9hz|;1P;LRqOGEX7%mc}T_@MBHxep``3Tp<2273_(CI)#11_qG5AaPh2
z>M*c_%?E`)NG%A1<UkmvRt@3@2N+);!ncR<Ex~*R2bfvz3=9m&=77us`OgdLKbZTy
zq3#EXgWM0|gVG1c{h+u3r2~-PL4Ngvh8;)@q!z>nr3Fyjm@%+|;~o@lAg6%L|G~h-
zz{<eD08$Hzb5Q;S#j_&=8#o?>7#P5585Dn@II?A60f)UX0|Ns{4yH~NNgXJzVCuxc
zan8UHz`zPlPvQ&=3?RKAaXSWP29SLqF_?N;Xc@MHffXDNp!5k61BKH{22kn1zyM0;
zAaRfwD9rj8Siy0l!oa`)iXV_X%sf>z^VAs_7(im6xcbh(%%BMh2nGg*Ukoe^AUO>N
z2Cx_?TtIA?Ia*M2c0t{x&A`9_5(By6Cj%2)56HZ)4D4XH>o72Y%>;!nNIl3rm>+Z*
z7#KkEApIae!0ge3+S3Xyu^1RY1wTj(l$HXZY0wawZa{J%y&wz=10x0o29P|+{6=WF
z7&9<1fWihO2eZcnYR^8Xe@qz|7(imMa4|;;7m%D80|Ns{3=}RPHq0Cgs5!9svSMIh
z0EvOpIw)LVdO$QRT&x)w7(ix%!V07wWF9PBY`|#|kuPBO*h1}rg^L{n0|Q756fQ6|
z_GoGx7#J8pVjwlJuybT!U;ya_$$`QRgkfRl#K6D+k_Wi~7Iw}I3=E*~1IfYcae>+c
z3p-Z^1_qEA$j>l;xG^v=fW%?(3$w!mTvsqKfaGCzc!KH{1_lO@94JqK$}W)DUj{}7
I3kF6808EIT6951J

diff --git a/projects/particle_simulation/shaders/frag_water.spv b/projects/particle_simulation/shaders/frag_water.spv
index 0ce71df61bc127c7d057d290b78871593ee4f78e..406e44df35757621d0688d37bd93cb83f5f04c24 100644
GIT binary patch
literal 2760
zcmZQ(Qf6mhU}WH8;AO~WfB-=TCI&_Z1_o{hHZbk(6YQf`T#}+^Vrl?V!N<T1qQG+e
z44e!s3=CkLo0ypgl8|L!U@&4}V2EX4U`S_RU=Uzn2FtTEFfcGPFf%YQFfbfq1nJ>q
zaQBIK404JuPAy0*N-Rl@FV09zNiB-cPs&P7E-417;R2~~_xE@Aag9$dD2OjEsmw`@
z&&kY7jZeueN=+`wEK3Ec<3LiEnU|bXnu4r=m4OB92ACUJ8Q2-P85kInGmDaQQr!}h
zOY(~}%F>Li85kHqa$F1y3?)UGiFxTcsm}TNMJbtii6yDU46F>y415d>3<Y3yEDX{N
z3=DbsMY%a8Abo5MAiozR78mDarlp2t=B9$e17x=%0|P^DerYjCfR%xjL5YEZp)?@B
zII|=(9~5Y83~XRAkop3IFat=f3IhWJl2Wi3D17rvOPup_@{2%vSQ$9L;SI7o1gpDQ
z7~(+gPAp2y1-qRM95*2KVW~O!$(bdU5OY`<GC*#Fn#{()3g(04lA)G?{FBANzyMXk
z;LgAT_O~1Z12}Fyp#B5tQ3eqV3=HlJ%wYe4;vS?P<R?%VfTUr3P#A&I9f%L|AILnI
zJSZ(8^Fiqf#0RMd*#~knNG-B`ATgMIAon8M2jYY51L+ZFU;?{a5u7?9eh_0|W?*Ar
zU{GLSU=U|uVF0CF5Fcco0s{*J2Ll6G3?#0|z{0@EzyMYc5(mliLghhvv>8~ya{LSo
z3}?@rv4inNK$bHwFu?etV19!=NWTmNC|5$vv}Ryo0P#U-3*=upXjp>m2B`)48RRaI
z|3GR%d{Fp;#6%fb7*wJD0O<wU1>&oL?P6d6$*V)<K|&yT5MKkt0gJORXhP!^<`<B>
z4%B_1umKecAURMu0CJBZIG-~xfW$%W0r5fc2`V*27?>DLko;^84ig`Em{>sUwbx-_
z2kW<FU|;~L0f~dc2NY%?H-hZ5fv9zW@m&}g7-r3!2{+4?fq}u;*cfh>8v_FaNDW9F
z-7G(_Sq*Trf*2SW($do4dV?7l7(i|SiNo~5+!)EgzyK46$$`Ql1{y}7cmjn3h!0A~
zpm+d<8>lP*`2!R#AoXcb^&oMOdJrF!&Oz!yaSlq)pfClg&4k7YNDQPF#0RBmP@J1F
zu!7SwC_X^m0-67Vfr){Yfq?;}7L+zY<rd6cpfn503&?y>SpnkPLenlNuYuAZ4+E&A
zVqlPmx)l_bAh~7+R&W{z<rh#GfaL8Mn8D>ENX(Ie4V;d&7#J8pX%m$GKxqtSzBU5`
z14s_0P8UfXD6PTN=`k=cfaC(er8EPBJ~%BgFo48C_JRBX5`(EXW?%r9O*<G^!RgKv
zlqMKJ>7IdMCDbow3=9k)age(~>8p={6`c007#J8p=?^3iGY?chfWiT0o-H^`85lrm
z@jC-EgFPs~85kITF|aUz<m?z2z+#~A2eD!1I6&RC3+gUM1_lO@7|0Dj8JOUDK<0gA
zU<bS1iGcxZCMX_3>Otng{NT*MzyOj5=|}d1I|Bm)DBXkP8=?O4U|?VX`3)oobB`y~
zJ^P^U@nT?L0Exl;<%8rekeoLI0|Q75<S!5#W{xk^99a1HGcYiK#6bBA<S&>W5DoKJ
z00RR9$V`x5LFz%~!Tc2ns{5evh3u~o1_lODo&?Fm{1wW;zyR_aNDk(nFsOTA{t9Pc
zU;v4M+yk>Cf`NenB#s_-Q49<Wpu7!|huIO$z`y{q2P6kdZ=iAwBnGk%lwabZ?H-UE
zC=Y@7me9PB0B%z;fa_t9dQe_YgtnDnX)cL@fdM22QVTKzWIjj?ral=>eF~@z11+0i
z>Oo?E85kKX7#JBqWdW#+0kw5NQ3$H1%o&)$^%tm(1ByQ$a2jS|0F?`%whhQ1Ap1bH
z00RR9NF6NS3qtcfD6N6yVEJB%fq?;3zk%dCp#BwRU|@iW^DuCL%Lg&2eo%e~$%En)
p6z(9mgX{*$gX{*mS)73Z+}48GEdkXFDqBEu{}`AUKw=<&0su+{=)V8}

literal 2168
zcmZQ(Qf6mhU}WH8;AIGAfB-=TCI&_Z1_o{hHZbk(6YQf`T#}+^Vrl?V!N<T1qQG+e
z3>*wB3=CkLo0ypglHg`wU{GRUVDM*PU=Uzn2FtNCFfcGPFf%YQFfbfq1gYm_aQBIK
z404JuPAy0*N-Rl@FV09zNiB-cPs&P7E-417;R2~~_xE@Aag9$dD2OjEsmw`@&&kY7
zjZeueN=+`wEK3Ec<3LiEnU|bXnu4r=m4OB92AKOmd=3T%hP?cu+?)~y237_(29TQz
z5{rv-GSgB+GILWw{s5^HWME*(%`Ytm39vG-G6*p+Fq8)57iX4a=7T)T#=r&^1F0`S
z2s41xiZC!RASnflfx;!fw8S|-C%*`!2V^%WoIrMmrRL-(XO>h##90^uKz2b@vN5oN
z`5?JusAiD+f*2SWph_6r8CbynkYiu~hqDLNy&yfxAcBE`!JUB_>|RhjfYgKB2yzoh
z8pc;-0Hp|!S{86Tg3N=-gWL+@gVG1ce2^PKa>(X`#9-!w+=pyFhz~L!q(_*63G7Zq
zaLRzVS&V_1fsKKIK>>_e7(nR;gh6833@l(dPLO7X273ht76vY;TS4;HP(COwLGBZ0
zU}4~AU;yg@xd)_PfPn#QCP-Wk8WtcnNKP0UZlE{@nFZp5!Uv>Rl!1jo6znEQ*nr#u
z;){XZ!oUEM7l+D&gh28jz66K^7H46Qgqja>D@<Mn>VA-0L4F3wf$|f`J)m#`<us5u
z$UPuFC@eu@A`DCnDhvz^Aag)^)S&jj_!<lh3}?^y*unUk5P5qY26k}RYB4Y{fYgA*
zLE#C~4^yiPQR@KXn=&vk%$hk9Zk8DX1B0=#G2AS31_lO@8jv`;S@vMF8sKI*GcYiu
zrKQ33x-c*>fZPBQhv|j6(F>He85kHq;vfuiBPg7Fp>YZd2T(ZqLBkLv4hkm_ACyi(
zX#f<*p!5g|Ly+1)XdHmVKx#pJP?`kAu^9s^I6Z>GALMM1`9Bz#7+4t?7(i-4=@3+I
zfM^gOl$Jo{1Bh=6O`AO6a+869hXGVFFfi~!-R8;w5@TR!2A4Jr417?3f#mHNm>EFk
zg2Wsd*ud#Tih+Rvl=eXB3zUXn=1Vg$Fo5J>>SU4BfzlF89Vm~2<N_F2!FfQQfq?;}
z7bFg{59Dr;7)(7V|AO+(4hB|mx>99eU;v4M!hI#wFX{{o3?Olk7$`3K7+Aq+Nt=Oz
z0hFFV@-Xvspy2>BPmh6t0VD=WTi+R&8Nd|@0|Ub^1{Ma8oIV2sSPT^2AU4b#L#R2s
zpzbnaU|;}=f!y$ufeEe$WZqW>cCg!x85qE3g5nLN9%LTO4<?|r3k`c@KUgp@Fo4oA
zNWKy3FH3O#VqgHt!Q5j7b<aMid#o847(ik$f7yZ(4%A;DIU5EB29OxYUl2B=46}op
z0}CGq1_lO@7%0Dh`~}kkqGA4W1gAqtIDyoI%!B#MiGhIuBo7J~WPgFu9Vm~1<YE4D
zV_;wa`3)oo^Orl+JurWHfa?kd29SGTc6c%{Fo49-?eJz`U;yP+kUY!|9|i^nkUbzd
TP<jKETOhH&42%pG42%o_9#^OA

diff --git a/projects/particle_simulation/shaders/particleShading.inc b/projects/particle_simulation/shaders/particleShading.inc
new file mode 100644
index 00000000..b2d1832b
--- /dev/null
+++ b/projects/particle_simulation/shaders/particleShading.inc
@@ -0,0 +1,6 @@
+float circleFactor(vec2 triangleCoordinates){
+    // percentage of distance from center to circle edge
+    float p = clamp((0.4 - length(triangleCoordinates)) / 0.4, 0, 1);
+    // remapping for nice falloff
+    return sqrt(p);
+}
\ No newline at end of file
diff --git a/projects/particle_simulation/shaders/shader.vert b/projects/particle_simulation/shaders/shader.vert
index 7884d094..ad80a4e1 100644
--- a/projects/particle_simulation/shaders/shader.vert
+++ b/projects/particle_simulation/shaders/shader.vert
@@ -23,6 +23,7 @@ layout( push_constant ) uniform constants{
     mat4 projection;
 };
 
+layout(location = 0) out vec2 passTriangleCoordinates;
 layout(location = 1) out vec3 passVelocity;
 layout(location = 2) out float passlifeTime;
 
@@ -36,5 +37,9 @@ void main()
     // by adding the triangle position in view space the mesh is always camera facing
     positionView.xyz += particle;
     // multiply with projection matrix for final position
-	gl_Position =   projection * positionView;
+	gl_Position = projection * positionView;
+    
+    // 0.01 corresponds to vertex position size in main
+    float normalizationDivider  = 0.01;
+    passTriangleCoordinates     = particle.xy / normalizationDivider;
 }
\ No newline at end of file
diff --git a/projects/particle_simulation/shaders/shader_space.frag b/projects/particle_simulation/shaders/shader_space.frag
index 79c80c3b..a1da5403 100644
--- a/projects/particle_simulation/shaders/shader_space.frag
+++ b/projects/particle_simulation/shaders/shader_space.frag
@@ -1,6 +1,10 @@
 #version 450
 #extension GL_ARB_separate_shader_objects : enable
+#extension GL_GOOGLE_include_directive : enable
 
+#include "particleShading.inc"
+
+layout(location = 0) in vec2 passTriangleCoordinates;
 layout(location = 1) in vec3 passVelocity;
 layout(location = 2) in float passlifeTime;
 
@@ -14,6 +18,7 @@ layout(set=0,binding=1) uniform uPosition{
 	vec2 position;
 } Position;
 
+
 void main()
 {
 	vec2 mouse = vec2(Position.position.x, Position.position.y);
@@ -21,4 +26,9 @@ void main()
 				   float(passlifeTime < 2 && passlifeTime > 1) * vec4(1,passlifeTime * 0.5,0,0) +
 				   float(passlifeTime >= 2 && passlifeTime < 2.5f) * vec4(passlifeTime * 0.5,passlifeTime * 0.5,0,0) +
 				   float(passlifeTime >= 2.5f) * vec4(1,0,0,0);
+   
+   // make the triangle look like a circle
+   outColor *= circleFactor(passTriangleCoordinates);
+   // full color is achieved by additively blending many particles
+   outColor *= 0.5; 
 }
\ No newline at end of file
diff --git a/projects/particle_simulation/shaders/shader_water.frag b/projects/particle_simulation/shaders/shader_water.frag
index 3f817c1c..b0b4cc70 100644
--- a/projects/particle_simulation/shaders/shader_water.frag
+++ b/projects/particle_simulation/shaders/shader_water.frag
@@ -1,6 +1,10 @@
 #version 450
 #extension GL_ARB_separate_shader_objects : enable
+#extension GL_GOOGLE_include_directive : enable
 
+#include "particleShading.inc"
+
+layout(location = 0) in vec2 passTriangleCoordinates;
 layout(location = 1) in vec3 passVelocity;
 layout(location = 2) in float passlifeTime;
 
@@ -22,4 +26,9 @@ void main()
 	float(passlifeTime < 2 && passlifeTime > 1) * vec4(0.3, 0.7,1,0) +
 	float(passlifeTime >= 2 && passlifeTime < 4.f) * vec4(0.5,0.9,1,0) +
 	float(passlifeTime >= 4.f) * vec4(0.9,1,1,0);
+    
+    // make the triangle look like a circle
+   outColor *= circleFactor(passTriangleCoordinates);
+   // full color is achieved by additively blending many particles
+   outColor *= 0.5; 
 }
diff --git a/projects/particle_simulation/shaders/vert.spv b/projects/particle_simulation/shaders/vert.spv
index 0387f48623f02789d7b0cce0a06128996c0b3cb6..e5a23d663612f70bbbafca156f9a49215dc2fd72 100644
GIT binary patch
delta 351
zcmca3(j(5x%%sfDz`)4B#lXuDGLhGmk$a-EDx=@V)XPlvtPC6sUJMKjdHF@Ti8+~7
zi6xo&c`lh{nJKA73=9kmAbCFq28M#f;^L5^%*4F(oK)xh{Gyc1yu^~!;?3sF9~pVw
z8CV!VisV2#HmkB0Gx;hourPQsFfgz)Ffi~iFfeE{uz+cA1_lPM>&iCb3@i*jP&p<B
z1_qFNUj_ySW(EeZxHSU{1BeeYmU;42c6&~c2*^aQ&1c!$nd<Ern86MQ8EDJE!obVG
zz~Iloz+eWZ*};YcfY}gnkkc3$7#KimK@JLJU;yh6U|<ES4Pszm0EvNc2UIMWfq?;J
W21pKMAILEvvA+zAtPB<mj0^xZRxk<x

delta 58
zcmeAXzazrS%%sfDz`)4B#lXwpIg!_tk!zx}>c*T4Oq*+%KQL~tVJ%>qY{Ox*xr3vD
OiQ_K=BZCD4BLe_~aShi1

diff --git a/projects/particle_simulation/src/main.cpp b/projects/particle_simulation/src/main.cpp
index f2608036..b2eb5bc5 100644
--- a/projects/particle_simulation/src/main.cpp
+++ b/projects/particle_simulation/src/main.cpp
@@ -95,7 +95,7 @@ int main(int argc, const char **argv) {
 
     const vkcv::VertexLayout particleLayout(bindings);
 
-    const vkcv::PipelineConfig particlePipelineDefinition{
+    vkcv::PipelineConfig particlePipelineDefinition{
             particleShaderProgram,
             UINT32_MAX,
             UINT32_MAX,
@@ -103,10 +103,11 @@ int main(int argc, const char **argv) {
             {particleLayout},
             {core.getDescriptorSet(descriptorSet).layout},
             true};
+    particlePipelineDefinition.m_blendMode = vkcv::BlendMode::Additive;
 
-    const std::vector<glm::vec3> vertices = {glm::vec3(-0.005, 0.005, 0),
-                                             glm::vec3(0.005, 0.005, 0),
-                                             glm::vec3(0, -0.005, 0)};
+    const std::vector<glm::vec3> vertices = {glm::vec3(-0.01, 0.01, 0),
+                                             glm::vec3(0.01, 0.01, 0),
+                                             glm::vec3(0, -0.01, 0)};
 
     vertexBuffer.fill(vertices);
 
diff --git a/src/vkcv/PipelineManager.cpp b/src/vkcv/PipelineManager.cpp
index df36442e..47694ab6 100644
--- a/src/vkcv/PipelineManager.cpp
+++ b/src/vkcv/PipelineManager.cpp
@@ -182,8 +182,11 @@ namespace vkcv
                                                VK_COLOR_COMPONENT_G_BIT |
                                                VK_COLOR_COMPONENT_B_BIT |
                                                VK_COLOR_COMPONENT_A_BIT);
+
+        // currently set to additive, if not disabled
+        // BlendFactors must be set as soon as additional BlendModes are added
         vk::PipelineColorBlendAttachmentState colorBlendAttachmentState(
-                false,
+                config.m_blendMode != BlendMode::None,
                 vk::BlendFactor::eOne,
                 vk::BlendFactor::eOne,
                 vk::BlendOp::eAdd,
-- 
GitLab