From 32ef4d8c554e818d805323adc9004ed66d247832 Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Wed, 15 Mar 2023 21:09:55 +0800 Subject: [PATCH] Updated particle interfaces and added more barriers --- Assets/Scenes/Scene2.shade | 19 ++-- Assets/Shaders/ParticleEmit_CS.glsl | 26 ++++-- Assets/Shaders/ParticleEmit_CS.shshaderb | Bin 7685 -> 9957 bytes Assets/Shaders/ParticleUpdate_CS.glsl | 10 +-- Assets/Shaders/ParticleUpdate_CS.shshaderb | Bin 6229 -> 6541 bytes Assets/Shaders/Particle_VS.glsl | 24 +++-- Assets/Shaders/Particle_VS.shshaderb | Bin 5761 -> 6357 bytes .../Inspector/SHEditorComponentView.hpp | 37 +++----- .../Particles/SHParticleEmitterComponent.cpp | 34 +++---- .../Particles/SHParticleEmitterComponent.h | 55 ++++++------ .../Particles/SHParticleSubSystem.cpp | 84 +++++++----------- .../MiddleEnd/Particles/SHParticleSubSystem.h | 4 +- .../src/Serialization/SHYAMLConverters.h | 32 +++---- 13 files changed, 145 insertions(+), 180 deletions(-) diff --git a/Assets/Scenes/Scene2.shade b/Assets/Scenes/Scene2.shade index 2cfa3fb7..76595523 100644 --- a/Assets/Scenes/Scene2.shade +++ b/Assets/Scenes/Scene2.shade @@ -158,15 +158,14 @@ IsActive: true classSHADE::SHParticleEmitterComponent: Emission Count: 1 - Is Passive: false - Emission Interval: 3 - Min Life: 7 - Max Life: 20 - Angular Min: {x: 2.29999995, y: 1.70000005, z: 2.9000001} - Angular Max: {x: 0, y: 0, z: 0} - Minimum Velocity: {x: 1, y: 1, z: 0} - Maximum Velocity: {x: 2, y: 2, z: 0} - Minimum Size: 1 - Maximum Size: 3 + Is Passive: true + Emission Interval: 0.200000003 + Min Life: 2 + Max Life: 3 + Minimum Speed: 3 + Maximum Speed: 6 + Minimum Size: 0 + Maximum Size: 0.5 + Angular Ranges And Offset: {x: 0, y: 0, z: 0, w: 0} IsActive: true Scripts: ~ \ No newline at end of file diff --git a/Assets/Shaders/ParticleEmit_CS.glsl b/Assets/Shaders/ParticleEmit_CS.glsl index 6c65ff83..1e2a0882 100644 --- a/Assets/Shaders/ParticleEmit_CS.glsl +++ b/Assets/Shaders/ParticleEmit_CS.glsl @@ -4,10 +4,10 @@ layout(local_size_x = 128) in; struct EmitterParameters { - vec4 angularMin; - vec4 angularMax; - vec4 minVel; - vec4 maxVel; + vec4 angularRangesAndOffsets; + float minSpeed; + float maxSpeed; + float padding[2]; vec4 lifeAndSizeRange; // min life, max life, min size, max size }; @@ -107,6 +107,9 @@ void main() { uint emitterInvocationIndex = gl_GlobalInvocationID.x; vec4 emitterPosition = emitterPushConstant.emitterPosition; + vec4 angularRangesAndOffsets = emitterParams.data.angularRangesAndOffsets; + float minSpeed = emitterParams.data.minSpeed; + float maxSpeed = emitterParams.data.maxSpeed; if (emitterInvocationIndex >= emitterPushConstant.emissionCount) return; @@ -127,15 +130,24 @@ void main() // emit particle from emitter position particle.position = vec4 (emitterPosition.xyz, 1.0f); + vec2 eulerAngles = vec2 (rand(seed) * angularRangesAndOffsets.x + angularRangesAndOffsets.z, + rand(seed) * angularRangesAndOffsets.y + angularRangesAndOffsets.w); + // Set its velocity - particle.velocity = emitterParams.data.minVel; + particle.velocity.xyz = vec3 (cos(eulerAngles.x) * cos(eulerAngles.y), + sin(eulerAngles.x) * cos(eulerAngles.y), + sin(eulerAngles.y)); + + particle.velocity *= map (rand (seed), 0.0f, 1.0f, minSpeed.x, maxSpeed.x); // randomize life value that ranges from minLife to maxLife particle.life = map (rand(seed), 0.0f, 1.0f, emitterParams.data.lifeAndSizeRange.x, emitterParams.data.lifeAndSizeRange.y); + float particleSize = map (rand(seed), 0.0f, 1.0f, emitterParams.data.lifeAndSizeRange.z, emitterParams.data.lifeAndSizeRange.w); + // Set size of particle - particle.scaleAndDecay.x = emitterParams.data.lifeAndSizeRange.z; - particle.scaleAndDecay.z = emitterParams.data.lifeAndSizeRange.z; + particle.scaleAndDecay.x = particleSize; + particle.scaleAndDecay.z = particleSize; particle.rotation = vec4 (5.0f); particle.acceleration = vec4 (0.01f); diff --git a/Assets/Shaders/ParticleEmit_CS.shshaderb b/Assets/Shaders/ParticleEmit_CS.shshaderb index 898baf45d9f8cfbeb4c6f34f99c06f4751117f51..125d56214d9838b6209164686b53572e48083b69 100644 GIT binary patch literal 9957 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 bANXBqJr_tP7q-h%u2(wa!p2;Jnak$@c})kQ literal 7685 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 0.0f) { // update position from velocity - // particle.position += particle.velocity * genericDataBuffer.data.dt; - // particle.life -= genericDataBuffer.data.dt; + particle.position += particle.velocity * genericDataBuffer.data.dt; + particle.life -= genericDataBuffer.data.dt; if (particle.life < 0.0f || particle.scaleAndDecay.x < 0.0f || particle.scaleAndDecay.y < 0.0f) { particle.life = 0.0f; - particle.position.x = 99999.0f; + particle.position.x = 9999.0f; outputParticles.data[index] = particle; freelist.freeIndices[atomicAdd(freelist.freeCount, 1)] = int (index); return; } - outputParticles.data[index] = particle; uint drawIndex = atomicAdd (indirectArgs.instanceCount, 1); indices[drawIndex] = index; - // indirectArgs.instanceCount = 1; } + + outputParticles.data[index] = particle; } \ No newline at end of file diff --git a/Assets/Shaders/ParticleUpdate_CS.shshaderb b/Assets/Shaders/ParticleUpdate_CS.shshaderb index 53c89d01ec7756fe8677723c7f5996f0278f6b8d..8f0de701474344fe7efab5fe56b8a95f552c3305 100644 GIT binary patch literal 6541 zcmZ{m`*&Pb6~}LrOj2nJrId$AYx>YC&|0)0O2MSBv|4PDDn1F*nVa;|$;>!2Nm~UC zEk0JQ6%^m^HzGdpCzn6^=lHwJ$6BuC=X3AflS@`OUAt%R@7dqI_u1#%Gnst;%}G8+ zM|Mpl$-3l*WK;5&0!nU9MnIBeLo%MvGbbNExvxKH?mKY*eqC-%MsrVnZo;R=JccaP zv$hKxkj>y?HzUi4zRD>7MwtJOF-F#zle06YPR*P=I@{=WXZwRot#r1PwbR*V)=L|M zY$?@meZ?3gG&WIk;k`d^+qFY zrM(KLShN0qquxrV+sz|sqb||TT9^H8Wpi{wtneR4AEXxti@o$jxlR0P$yV@gxexto zFm7dDYj5I?)q4|PYj5If?M?iR_U76f?aj5-dlOrGZ|jrWS&M!2Pqe#>gF}mRb7>Da z@0IJ0W_f<@-D{rdIwYF2mV5wwCT*v^tdSqLw^hv192jprx9vmPs(1To^Gvpof==Xk z-iIu`(CzdFPh`!(Is9VHUM!Vs$J1>79Pw)KrobyXhsAr&t~pj}pGXd2&#%-t^!Gkz ztPQtxYH?6)hVfi?ti&5n&SQ6S*C7+n^~o~$5INRM(^l4x*4hWx9dj%l?ku+14rqbf zA8{^W)=2xrt0k99%rK}qc9pr=t6zxAYTmDb9RZu}_3D>6(BhMy?#=g$^K{+O80MVF zIp)mT{XxCmsMJ%-*G5>I%X)cY&%+p=$Ju(H8Ve34HBBVfm?LXZhnb6Wbj^{yt}1z> z$@O9>-`6+Mjltf_dsIur9CC}Ej3zG?P|kT3{cwGOS0Jb4y%cl2{#&di;_i2;`)IxB zdx5!6@0h6Pt)Khs_Bv0Cc@BTXZdCHP=RbiRUC0K5w0C;3f9`N6?};&rHI|dKT#qL& z*79#*A?x>f2jdGp z7jM`~KjICEeuQ20W95yh=F`WzjCY>dd?OXxd|`hP-ToK*92>qfk#CtbN90@1t(E7>%F(WJw5`!R_GFnkYP^hItx?+=UAND^9}fABz^X9=b6@(!8Ob${SaC*U`J00| ztoND*BkB!1@>#E#aqOvYPqkic>-E07{vva=r|}j=f5MJ@VOR5sMLyrHYCdiA6}=ow zUP1T!_HNsUSD76V&odIUU)C5t(ZBfK!-qdc%Qv9l+0!a7dK}-iJh9b0>#y>(t?30M zY7h&aeU4c6(YMomTW8qr+acd~)L~3VVAXvYQ$Opwh5wy*fSFhQR`PgOlZayy+jT+Daf!Q4550$q47rO^r-bTcs|0ZVF#BU?B{hmaO?ce6wp5=BTZebQ%E&3F7 zj^+2%`t+6Kd%oH~;>y`ZPTyJmwxfFwwXMx})INy07j5rR^yW_VNyPfyoAz4}hx~2K zg>PZ+z_vE?hyQN$Dt`~QoLIjb-QI@17u|k@y&v6sWWM{Djc-3<{Q$cA)E0jbacm{a z`O1e6qOW2vrkGtb_B69~O(FI|`w$}L`r%TK+{SnkS%*aKIrQY_Pcs`+%skrXOU(6dsoO*CXG`0B#`Vqi9JaHzTe#{7E85i_Q?Z=Nx&=S61u@_e_n<$a4;A2E5_zFlJWOV00*W#nEg zzo%CaG5f0Af#2_$?S*&3v-FM777sDsAFz$>y7{zyL&WTr?|?k>>i=hEbBgP){aT4V zz>Sk zZbXi@e!+P=x*YoyoOhth*@MW@)-O2kM3-YfgL4nMoVyV@+WH0OUUWI0MR4|^%h`*_ z(bi9n-{-p!Ii8oC`JI#m*q&p3%pc z9iEZ+M-eg4NZq}LLe~1yWod3y9Gyf+M^Lq#MH&4{| zDRkGZ?K8{{YZL!8B4%ysQQItf)b=EL)b7n!I*;zUchNrTBQ}Rvx8Gz7@jcYu!n}aUF~&CLHgX;@ zhQ9HBbkOy6SWlPvvxxrsnoC>1;PlYt#Cs^GkI31L$kEm>I0JM!BS_>~M3=J%k)y3& zaF)>J#CvF-3y7R}54H6R&P8-NV@Tw=gf3?u9<`mQKf1Hl@tck9_^?d`mj+kGLHCX=(h-*=Uv$3w0Yf;a)vBkpv z4!ZS4{O_W_gcx66V~FYJcYToAnw%rX_t1@@?Y;dzvK5JY`vdg2xBA98{}5eYN1XGI z(DgUJxwZ8R&X3XMRPXIiu;thfIokRK=cnj$s`vJ1*mC0DYU>xApQFpE-rHYb%ZYod ztzU3{i7sahiT(TvT~6FvZT;kUZ-0%*sovY)V9SYntF50L&-%BB9QC-jFQdzed#kOV Icj!Un|Hf)=G5`Po literal 6229 zcmZ{n>31B}5ycy8MiLOf7_)?ckQbKN#E8TY5|&t4_EBgBX{Xs$0e6u|3~tcMr$y>CQ^G8Ru!YGd)$T4@a9c z&&64uHrvTmoX0Y?gAzyYb^9rV5NAJGH!lK(IQv^k+TCWFpD6K>B0gPP7rA<|juqQC8QL7f0A{fDLJ$?<$SOQx%B%C8=67T&A&fqz|$OEsTu zZ{Upedjmh)-oVecH}D_Z8*4wdH`dng4eacD8;vg4n)lJ4?(~-PyO$Rhl1y;XE7lpU z>ipRIPi3dL4v6F&jUE<0fM%ETFc^Jjoe{=5D7#y@4wyx(CE){Pf0iWewC~cmL##6v zw6wRo+{vXIr_bOz#I%|86|Ww3D~vEw3+$xkRu&)gVY7#S3!4%)nPu?_HKhDxCbPwU z*$>tk%|XtQfsNnoZ`rdd+Us3s`(n~PL5ASll zz}fFg@7}oVdx;hII8Ba$k`q4r>}B1fVAS@W>}HS$?0sR4q?2T6v#PgNV1lET5>N|1 z6BtOk4R8`FV}}E2@dL14+7gMDghJ2f~A#gG*1{tTEQ^ z=}7dE?8UVj2mZu5qqTiYX`Uz9+;acO-fnTG^q^eRa+Fl-e)7Cl>}e_O_w^3?9uxDE zfD^`S=*#EbMXr(@P`!NLjBVvKz=#dDQDQ%O1vVaF^azX}BKz^afb9t|-W9O90OMT& zdq_fUmuUt&Bsn14?+0^eU$V~Tr<2_FCnlqz8w55~=(XbQ*(#lVkdL=$i-f&mQ%9KJ zZ;tcZF7vOwNnt*GobRCYFdsJgoWCudeDsU``CW28+s~>;m2>iG2(#zq`+#$8zps6FK-sZ_1bnm>IEYXXT)0- z){9NO+%MK&)*SZKZd{5jZ_Uw1h@i-$e`bCZQ zasM{1!}P~r_05$$dK&WFzTjVa3kR1)W$nX zAHdiPHuu`Sxl;PLg!8~e7)}O3&_KUq(*~G^_TG>8_wrqMhrZwJVbTEAR9~*LklM9=-8I1K_rI-BS z;+-aLD4g#pVZ7mRUZ^-=#Kb;bVeH#)C%jjLW5av3@&SW~%{%CGBj;O^RmqL2fNz0! z5sW?~SBUqHW_nZJ@A7X%Y;X(t-jz*k-Xrp1^B#eXDL(H9Jw?1!ib>Pv+bp9nSR=9Blj?^H%AO$$60b*Anp06odEYw-v^_^nb;;Lo?%B`LlMr1dRKI z?$~!qUmyD}Vc?%uv41BWjM)EEJo4?4fRpQP%?xtw(L5;uBNsY%i{9*&kc)o$ezKP- z32V-`ufoXpjbb``3$O+lLBlxG=DOVB=@b)6(IDcjT|K;ZQHNV&iAd-=xC{@5nQ< z;rNbV<7dvQbU5K1`MYd5z9ZPH5_6uF4yPvZex8#K$9Du9KR6pTKQDn3-jRREhBF~y zKiK%e;a>bx0w=s9|B?;IcLW gA)PaK{5Pe)CLun)!~nyOxAzXs+#6=@&~1|M0SN<74*&oF diff --git a/Assets/Shaders/Particle_VS.glsl b/Assets/Shaders/Particle_VS.glsl index 2645fe87..d74acdd9 100644 --- a/Assets/Shaders/Particle_VS.glsl +++ b/Assets/Shaders/Particle_VS.glsl @@ -74,24 +74,22 @@ void main() ParticleData particle = outputParticles.data[indices[gl_InstanceIndex]]; vec3 normalized = normalize (particle.velocity.xyz); - float angle = atan (normalized.y, normalized.x); + float angle = 1.1f; + // float angle = atan (normalized.y, normalized.x); vec2 particleScaleData = particle.scaleAndDecay.xz; // x and y - mat4 localModel = mat4 (1.0f); - localModel[0][0] = 1.0f; - localModel[1][1] = 1.0f; - - // localModel[0][0] = particleScaleData.x; - // localModel[1][1] = particleScaleData.y; - - mat4 rotate = mat4(1.0f); + mat3 rotate = mat3 (1.0f); rotate[0][0] = cos(angle); rotate[0][1] = sin(angle); rotate[1][0] = -sin(angle); rotate[1][1] = cos(angle); - // localModel = rotate * localModel; - localModel[3] = vec4 (particle.position.xyz, 1.0f); - // gl_Position = cameraData.vpMat * localModel * vec4(vertexPos, 1.0f); - gl_Position = vec4(vertexPos, 1.0f); + vec3 particlePos = rotate * vertexPos; + + vec3 viewRight = normalize (vec3 (cameraData.viewMat[0][0], cameraData.viewMat[1][0], cameraData.viewMat[2][0])); + vec3 viewUp = normalize(vec3 (cameraData.viewMat[0][1], cameraData.viewMat[1][1], cameraData.viewMat[2][1])); + + particlePos = particle.position.xyz + (viewRight * particlePos.x * particleScaleData.x) + (viewUp * particlePos.y * particleScaleData.y); + + gl_Position = cameraData.vpMat * vec4(particlePos, 1.0f); } \ No newline at end of file diff --git a/Assets/Shaders/Particle_VS.shshaderb b/Assets/Shaders/Particle_VS.shshaderb index c863fca2de80928a25a643004b41c3211faca429..d79ee1d1cd5d1d3e5d7635143926837c84ac367b 100644 GIT binary patch literal 6357 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 }, [comp = component](float val) {comp->SetMinLife(val); }); SHEditorWidgets::DragFloat("Max Life", [comp = component]() {return comp->GetMaxLife(); }, [comp = component](float val) {comp->SetMaxLife(val); }); SHEditorWidgets::DragFloat("Min Size", [comp = component]() {return comp->GetMinSize(); }, [comp = component](float val) {comp->SetMinSize(val); }); - SHEditorWidgets::DragFloat("Man Size", [comp = component]() {return comp->GetMaxSize(); }, [comp = component](float val) {comp->SetMaxSize(val); }); + SHEditorWidgets::DragFloat("Max Size", [comp = component]() {return comp->GetMaxSize(); }, [comp = component](float val) {comp->SetMaxSize(val); }); - SHEditorWidgets::DragVec3("Angular Min", {"x", "y", "z"}, + SHEditorWidgets::DragVec4("Angles and Offsets", {"yaw", "pitch", "yaw off", "pitch off"}, [comp = component]() { - return comp->GetAngularMin(); + return comp->GetAngularRangesAndOffsets(); }, - [comp = component](SHVec3 const& val) + [comp = component](SHVec4 const& val) { - comp->SetAngularMin(val); + comp->SetAngularRangesAndOffsets(val); }); - SHEditorWidgets::DragVec3("Angular Max", { "x", "y", "z" }, + + SHEditorWidgets::DragFloat("Min Speed", [comp = component]() { - return comp->GetAngularMax(); + return comp->GetMinSpeed(); }, - [comp = component](SHVec3 const& val) + [comp = component](float val) { - comp->SetAngularMax(val); + comp->SetMinSpeed(val); }); - SHEditorWidgets::DragVec3("Min Vel", { "x", "y", "z" }, + SHEditorWidgets::DragFloat("Max Speed", [comp = component]() { - return comp->GetMinVelocity(); + return comp->GetMaxSpeed(); }, - [comp = component](SHVec3 const& val) + [comp = component](float val) { - comp->SetMinVelocity(val); - }); - - SHEditorWidgets::DragVec3("Max Vel", { "x", "y", "z" }, - [comp = component]() - { - return comp->GetMaxVelocity(); - }, - [comp = component](SHVec3 const& val) - { - comp->SetMaxVelocity(val); + comp->SetMaxSpeed(val); }); SHEditorWidgets::CheckBox("Is Passive", [comp = component]() {return comp->GetPassive(); }, [comp = component](bool flag) {comp->SetPassive(flag); }); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Particles/SHParticleEmitterComponent.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Particles/SHParticleEmitterComponent.cpp index d2c0e05a..b095f26b 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Particles/SHParticleEmitterComponent.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Particles/SHParticleEmitterComponent.cpp @@ -46,24 +46,20 @@ namespace SHADE cpuEmitterData.lifeAndSizeRange.y = val; } - void SHParticleEmitterComponent::SetAngularMin(SHVec3 const& min) noexcept + void SHParticleEmitterComponent::SetAngularRangesAndOffsets(SHVec4 const& ranges) noexcept { - cpuEmitterData.angularMin = SHVec4 (min); + cpuEmitterData.angularRangesAndOffsets = SHVec4 (ranges); } - void SHParticleEmitterComponent::SetAngularMax(SHVec3 const& max) noexcept + + void SHParticleEmitterComponent::SetMinSpeed(float speed) noexcept { - cpuEmitterData.angularMax = SHVec4(max); + cpuEmitterData.minSpeed = speed; } - void SHParticleEmitterComponent::SetMinVelocity(SHVec3 const& vel) noexcept + void SHParticleEmitterComponent::SetMaxSpeed(float speed) noexcept { - cpuEmitterData.minVel = vel; - } - - void SHParticleEmitterComponent::SetMaxVelocity(SHVec3 const& vel) noexcept - { - cpuEmitterData.maxVel = vel; + cpuEmitterData.maxSpeed = speed; } void SHParticleEmitterComponent::SetMinSize(float size) noexcept @@ -102,19 +98,19 @@ namespace SHADE } - SHVec3 SHParticleEmitterComponent::GetAngularMin(void) const noexcept + SHVec4 const& SHParticleEmitterComponent::GetAngularRangesAndOffsets(void) const noexcept { - return SHVec3 (cpuEmitterData.angularMin.x, cpuEmitterData.angularMin.y, cpuEmitterData.angularMin.z); + return cpuEmitterData.angularRangesAndOffsets; } - SHVec3 SHParticleEmitterComponent::GetMinVelocity(void) const noexcept + float SHParticleEmitterComponent::GetMinSpeed(void) const noexcept { - return SHVec3(cpuEmitterData.minVel.x, cpuEmitterData.minVel.y, cpuEmitterData.minVel.z); + return cpuEmitterData.minSpeed; } - SHVec3 SHParticleEmitterComponent::GetMaxVelocity(void) const noexcept + float SHParticleEmitterComponent::GetMaxSpeed(void) const noexcept { - return SHVec3(cpuEmitterData.maxVel.x, cpuEmitterData.maxVel.y, cpuEmitterData.maxVel.z); + return cpuEmitterData.maxSpeed; } float SHParticleEmitterComponent::GetMinSize(void) const noexcept @@ -127,9 +123,5 @@ namespace SHADE return cpuEmitterData.lifeAndSizeRange.w; } - SHVec3 SHParticleEmitterComponent::GetAngularMax(void) const noexcept - { - return SHVec3(cpuEmitterData.angularMax.x, cpuEmitterData.angularMax.y, cpuEmitterData.angularMax.z); - } } \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Particles/SHParticleEmitterComponent.h b/SHADE_Engine/src/Graphics/MiddleEnd/Particles/SHParticleEmitterComponent.h index 7781c29f..e345c24d 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Particles/SHParticleEmitterComponent.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Particles/SHParticleEmitterComponent.h @@ -16,17 +16,16 @@ namespace SHADE private: struct GPUEmitterStruct { - //! Minimum emitting angular range - SHVec4 angularMin; - - //! Maximum emitting angular range - SHVec4 angularMax; + //! Angular ranges of emission + SHVec4 angularRangesAndOffsets; //! minimum starting velocity - SHVec4 minVel; + float minSpeed; //! Maximum starting velocity - SHVec4 maxVel; + float maxSpeed; + + float padding[2]; //! Spawn lifetime and size range (min and max) SHVec4 lifeAndSizeRange; @@ -111,30 +110,28 @@ namespace SHADE void Emit (void) noexcept; - void SetEmissionCount (uint32_t count) noexcept; - void SetPassive (bool flag) noexcept; - void SetEmissionInterval (float interval) noexcept; - void SetMinLife (float val) noexcept; - void SetMaxLife (float val) noexcept; - void SetAngularMin (SHVec3 const& min) noexcept; - void SetAngularMax (SHVec3 const& max) noexcept; - void SetMinVelocity (SHVec3 const& vel) noexcept; - void SetMaxVelocity (SHVec3 const& vel) noexcept; - void SetMinSize (float size) noexcept; - void SetMaxSize (float size) noexcept; + void SetEmissionCount (uint32_t count) noexcept; + void SetPassive (bool flag) noexcept; + void SetEmissionInterval (float interval) noexcept; + void SetMinLife (float val) noexcept; + void SetMaxLife (float val) noexcept; + void SetAngularRangesAndOffsets (SHVec4 const& ranges) noexcept; + void SetMinSpeed (float speed) noexcept; + void SetMaxSpeed (float speed) noexcept; + void SetMinSize (float size) noexcept; + void SetMaxSize (float size) noexcept; - uint32_t GetEmissionCount (void) const noexcept; - bool GetPassive (void) const noexcept; - float GetEmissionInterval (void) const noexcept; - float GetMinLife (void) const noexcept; - float GetMaxLife (void) const noexcept; - SHVec3 GetAngularMax (void) const noexcept; - SHVec3 GetAngularMin (void) const noexcept; - SHVec3 GetMinVelocity (void) const noexcept; - SHVec3 GetMaxVelocity (void) const noexcept; - float GetMinSize (void) const noexcept; - float GetMaxSize (void) const noexcept; + uint32_t GetEmissionCount (void) const noexcept; + bool GetPassive (void) const noexcept; + float GetEmissionInterval (void) const noexcept; + float GetMinLife (void) const noexcept; + float GetMaxLife (void) const noexcept; + SHVec4 const& GetAngularRangesAndOffsets (void) const noexcept; + float GetMinSpeed (void) const noexcept; + float GetMaxSpeed (void) const noexcept; + float GetMinSize (void) const noexcept; + float GetMaxSize (void) const noexcept; friend class SHParticleSubSystem; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Particles/SHParticleSubSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Particles/SHParticleSubSystem.cpp index 7e1e9455..665f43aa 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Particles/SHParticleSubSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Particles/SHParticleSubSystem.cpp @@ -23,7 +23,7 @@ namespace SHADE void SHParticleSubSystem::InitializeComponent(SHParticleEmitterComponent& comp) noexcept { // TODO: temporary only. - static constexpr uint32_t NUM_PARTICLES = 5; + static constexpr uint32_t NUM_PARTICLES = 2000; comp.maxParticles = NUM_PARTICLES; uint32_t sizeofUint = static_cast(sizeof(uint32_t)); @@ -166,34 +166,46 @@ namespace SHADE //cmdBuffer->DrawArrays(4, 1, 0, 0); } - void SHParticleSubSystem::PreparePrePostUpdateBarriers(std::vector& preUpdateBarriers, std::vector& postUpdateBarriers, std::vector& preDrawBarriers, SHParticleEmitterComponent const& emitter, uint32_t const EMITTER_INDEX, uint32_t const FRAME_INDEX) noexcept + void SHParticleSubSystem::PreparePrePostUpdateBarriers(std::vector& preUpdateBarriers, std::vector& postUpdateBarriers, SHParticleEmitterComponent const& emitter, uint32_t const EMITTER_INDEX, uint32_t const FRAME_INDEX) noexcept { // pre-update particles data barrier. Note that this is for input because we want the input to be available before we use it. - vk::BufferMemoryBarrier particleDataBarrier + vk::BufferMemoryBarrier inputParticleDataBarrierPreUpdate { - .srcAccessMask = vk::AccessFlagBits::eShaderWrite, + .srcAccessMask = vk::AccessFlagBits::eShaderRead | vk::AccessFlagBits::eShaderWrite, .dstAccessMask = vk::AccessFlagBits::eShaderRead, .buffer = emitter.particleData->GetVkBuffer(), .offset = emitter.dynamicOffsets[FRAME_INDEX][DYOFF_INDEX_PARTICLE_INPUT], .size = emitter.chunkSize }; - // pre-update free list data barrier - vk::BufferMemoryBarrier freelistDataBarrier + // pre-update free list data barrier. + vk::BufferMemoryBarrier freelistDataBarrierPreUpdate { - .srcAccessMask = vk::AccessFlagBits::eShaderWrite, - .dstAccessMask = vk::AccessFlagBits::eShaderRead, + .srcAccessMask = vk::AccessFlagBits::eShaderRead | vk::AccessFlagBits::eShaderWrite, + .dstAccessMask = vk::AccessFlagBits::eShaderRead | vk::AccessFlagBits::eShaderWrite, .buffer = emitter.freelistData->GetVkBuffer(), .offset = 0, // Only 1 copy of freelist data, so offset is at 0 .size = static_cast(sizeof (uint32_t)) * (emitter.maxParticles + 1) }; + // pre update indices data barrier. + vk::BufferMemoryBarrier indicesDataBarrierPreUpdate + { + + .srcAccessMask = vk::AccessFlagBits::eShaderWrite | vk::AccessFlagBits::eShaderRead, + .dstAccessMask = vk::AccessFlagBits::eShaderWrite, + .buffer = emitter.indicesData->GetVkBuffer(), + .offset = emitter.dynamicOffsets[FRAME_INDEX][DYOFF_INDEX_INDICES_DATA], + .size = static_cast(sizeof(uint32_t)) * emitter.maxParticles + }; + // ...copy assign barriers on heap - preUpdateBarriers[EMITTER_INDEX * 2] = particleDataBarrier; - preUpdateBarriers[(EMITTER_INDEX * 2) + 1] = freelistDataBarrier; + preUpdateBarriers[EMITTER_INDEX * 3] = inputParticleDataBarrierPreUpdate; + preUpdateBarriers[(EMITTER_INDEX * 3) + 1] = freelistDataBarrierPreUpdate; + preUpdateBarriers[(EMITTER_INDEX * 3) + 2] = indicesDataBarrierPreUpdate; // make new barrier on stack... - vk::BufferMemoryBarrier particleDataBarrierPost + vk::BufferMemoryBarrier outputParticleDataBarrierPostUpdate { .srcAccessMask = vk::AccessFlagBits::eShaderWrite, .dstAccessMask = vk::AccessFlagBits::eShaderRead, @@ -203,7 +215,7 @@ namespace SHADE }; // make new barrier on stack... - vk::BufferMemoryBarrier indicesDataBarrier + vk::BufferMemoryBarrier indicesDataBarrierPostUpdate { .srcAccessMask = vk::AccessFlagBits::eShaderWrite, .dstAccessMask = vk::AccessFlagBits::eShaderRead, @@ -213,9 +225,9 @@ namespace SHADE }; // make new barrier on stack... - vk::BufferMemoryBarrier drawDataBarrier + vk::BufferMemoryBarrier drawDataBarrierPostUpdate { - .srcAccessMask = vk::AccessFlagBits::eShaderWrite | vk::AccessFlagBits::eMemoryWrite, + .srcAccessMask = vk::AccessFlagBits::eShaderWrite, .dstAccessMask = vk::AccessFlagBits::eIndirectCommandRead, .buffer = emitter.drawCallData->GetVkBuffer(), .offset = emitter.dynamicOffsets[FRAME_INDEX][DYOFF_INDEX_DRAW_DATA], @@ -223,9 +235,9 @@ namespace SHADE }; // ...copy assign barriers on heap - postUpdateBarriers[EMITTER_INDEX * 2] = particleDataBarrierPost; - postUpdateBarriers[(EMITTER_INDEX * 2) + 1] = indicesDataBarrier; - preDrawBarriers[EMITTER_INDEX] = drawDataBarrier; + postUpdateBarriers[EMITTER_INDEX * 3] = outputParticleDataBarrierPostUpdate; + postUpdateBarriers[(EMITTER_INDEX * 3) + 1] = indicesDataBarrierPostUpdate; + postUpdateBarriers[(EMITTER_INDEX * 3) + 2] = drawDataBarrierPostUpdate; } void SHParticleSubSystem::Init(Handle device, Handle inDescPool, Handle compatibleRenderpass, Handle subpass, Handle VS, Handle FS, Handle emitCS, Handle defaultUpdateCS) noexcept @@ -322,12 +334,12 @@ namespace SHADE // Every emitter will have its own barrier for its particle data and freelist data. Indices data is not needed since // it's mainly used in update and rendering so a barrier for it is NOT needed here. std::vector preUpdateBarriers{}; - preUpdateBarriers.resize(emitters.size() * 2); + preUpdateBarriers.resize(emitters.size() * 3); // After we invoke the updates for the emitters, we need to make sure all particles and indices data are done updating // before we issue them for rendering. std::vector postUpdateBarriers{}; - postUpdateBarriers.resize(emitters.size() * 2); + postUpdateBarriers.resize(emitters.size() * 3); std::vector preDrawBarriers{}; preDrawBarriers.resize(emitters.size()); @@ -340,8 +352,6 @@ namespace SHADE /* BEGIN EMITTING PARTICES */ /*-----------------------------------------------------------------------*/ - // TODO: Might need to issue a barrier here for input particle data - // bind the pipeline for emitting particles cmdBuffer->BindPipeline(emittingPipelineData.pipeline); @@ -385,7 +395,7 @@ namespace SHADE } // prepare barriers - PreparePrePostUpdateBarriers(preUpdateBarriers, postUpdateBarriers, preDrawBarriers, emitter, i, frameIndex); + PreparePrePostUpdateBarriers(preUpdateBarriers, postUpdateBarriers, emitter, i, frameIndex); // Emitter will emit once and stop emitting next frame (unless specified before reaching here to do so). emitter.toEmit = false; @@ -393,7 +403,7 @@ namespace SHADE } // issue the barrier to wait - cmdBuffer->PipelineBarrier(vk::PipelineStageFlagBits::eComputeShader, vk::PipelineStageFlagBits::eComputeShader, {}, {}, preUpdateBarriers, {}); + cmdBuffer->PipelineBarrier(vk::PipelineStageFlagBits::eComputeShader | vk::PipelineStageFlagBits::eVertexShader | vk::PipelineStageFlagBits::eDrawIndirect, vk::PipelineStageFlagBits::eComputeShader, {}, {}, preUpdateBarriers, {}); @@ -414,39 +424,13 @@ namespace SHADE /* AFTER UPDATING, RENDER PARTICLES */ /*-----------------------------------------------------------------------*/ // issue the barrier to wait for output particles to be done updating and indices data to finish being modified. - cmdBuffer->PipelineBarrier(vk::PipelineStageFlagBits::eComputeShader, vk::PipelineStageFlagBits::eComputeShader, {}, {}, postUpdateBarriers, {}); - cmdBuffer->PipelineBarrier(vk::PipelineStageFlagBits::eComputeShader, vk::PipelineStageFlagBits::eDrawIndirect, {}, {}, preDrawBarriers, {}); + cmdBuffer->PipelineBarrier(vk::PipelineStageFlagBits::eComputeShader, vk::PipelineStageFlagBits::eVertexShader | vk::PipelineStageFlagBits::eDrawIndirect | vk::PipelineStageFlagBits::eVertexShader, {}, {}, postUpdateBarriers, {}); } void SHParticleSubSystem::ResetInstanceCounts(Handle cmdBuffer, uint32_t frameIndex) noexcept { auto& emitters = SHComponentManager::GetDense(); - std::vector preResetBarriers{}; - preResetBarriers.resize(emitters.size()); - - uint32_t i = 0; - for (auto& emitter : emitters) - { - if (emitter.initialized) - { - // pre-update particles data barrier. Note that this is for input because we want the input to be available before we use it. - vk::BufferMemoryBarrier drawDataHostWriteBarrier - { - .srcAccessMask = vk::AccessFlagBits::eIndirectCommandRead | vk::AccessFlagBits::eMemoryRead | vk::AccessFlagBits::eMemoryWrite, - .dstAccessMask = vk::AccessFlagBits::eMemoryWrite | vk::AccessFlagBits::eHostWrite, - .buffer = emitter.drawCallData->GetVkBuffer(), - .offset = emitter.dynamicOffsets[frameIndex][DYOFF_INDEX_DRAW_DATA], - .size = static_cast(sizeof(vk::DrawIndirectCommand)) - }; - - preResetBarriers[i] = drawDataHostWriteBarrier; - } - ++i; - } - - cmdBuffer->PipelineBarrier(vk::PipelineStageFlagBits::eDrawIndirect, vk::PipelineStageFlagBits::eHost, {}, {}, preResetBarriers, {}); - for (auto& emitter : emitters) { diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Particles/SHParticleSubSystem.h b/SHADE_Engine/src/Graphics/MiddleEnd/Particles/SHParticleSubSystem.h index bb8f570d..ec7418cd 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Particles/SHParticleSubSystem.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Particles/SHParticleSubSystem.h @@ -73,7 +73,7 @@ namespace SHADE //! Pipeline data for updating particles PipelineData defaultUpdatePipelineData; - //! Desc pool for particle component desc set allocation + //! Desc pool for particle component desc set allocation Handle descPool; @@ -82,7 +82,7 @@ namespace SHADE void UpdateCompoennt(Handle cmdBuffer, SHParticleEmitterComponent& comp, uint32_t frameIndex) noexcept; void RenderComponent(Handle cmdBuffer, SHParticleEmitterComponent& comp, uint32_t frameIndex) noexcept; - void PreparePrePostUpdateBarriers (std::vector& preUpdateBarriers, std::vector& postUpdateBarriers, std::vector& preDrawBarriers, SHParticleEmitterComponent const& emitter, uint32_t const EMITTER_INDEX, uint32_t const FRAME_INDEX) noexcept; + void PreparePrePostUpdateBarriers (std::vector& preUpdateBarriers, std::vector& postUpdateBarriers, SHParticleEmitterComponent const& emitter, uint32_t const EMITTER_INDEX, uint32_t const FRAME_INDEX) noexcept; public: void Init(Handle device, Handle inDescPool, Handle compatibleRenderpass, Handle subpass, Handle VS, Handle FS, Handle emitCS, Handle defaultUpdateCS) noexcept; diff --git a/SHADE_Engine/src/Serialization/SHYAMLConverters.h b/SHADE_Engine/src/Serialization/SHYAMLConverters.h index 6826efa7..b5f0ffdf 100644 --- a/SHADE_Engine/src/Serialization/SHYAMLConverters.h +++ b/SHADE_Engine/src/Serialization/SHYAMLConverters.h @@ -509,12 +509,11 @@ namespace YAML static constexpr std::string_view EMISSION_INTERVAL_TAG = "Emission Interval"; static constexpr std::string_view MIN_LIFE_TAG = "Min Life"; static constexpr std::string_view MAX_LIFE_TAG = "Max Life"; - static constexpr std::string_view ANGULAR_MIN_TAG = "Angular Min"; - static constexpr std::string_view ANGULAR_MAX_TAG = "Angular Max"; - static constexpr std::string_view MIN_VEL_TAG = "Minimum Velocity"; - static constexpr std::string_view MAX_VEL_TAG = "Maximum Velocity"; + static constexpr std::string_view ANGULAR_RANGES_OFFSET_TAG = "Angular Ranges And Offset"; static constexpr std::string_view MIN_SIZE_TAG = "Minimum Size"; static constexpr std::string_view MAX_SIZE_TAG = "Maximum Size"; + static constexpr std::string_view MIN_SPEED_TAG = "Minimum Speed"; + static constexpr std::string_view MAX_SPEED_TAG = "Maximum Speed"; static YAML::Node encode(SHParticleEmitterComponent const& rhs) { @@ -524,12 +523,11 @@ namespace YAML node[EMISSION_INTERVAL_TAG.data()] = rhs.GetEmissionInterval(); node[MIN_LIFE_TAG.data()] = rhs.GetMinLife(); node[MAX_LIFE_TAG.data()] = rhs.GetMaxLife(); - node[ANGULAR_MIN_TAG.data()] = rhs.GetAngularMin(); - node[ANGULAR_MAX_TAG.data()] = rhs.GetAngularMax(); - node[MIN_VEL_TAG.data()] = rhs.GetMinVelocity(); - node[MAX_VEL_TAG.data()] = rhs.GetMaxVelocity(); + node[MIN_SPEED_TAG.data()] = rhs.GetMinSpeed(); + node[MAX_SPEED_TAG.data()] = rhs.GetMaxSpeed(); node[MIN_SIZE_TAG.data()] = rhs.GetMinSize(); node[MAX_SIZE_TAG.data()] = rhs.GetMaxSize(); + node[ANGULAR_RANGES_OFFSET_TAG.data()] = rhs.GetAngularRangesAndOffsets(); return node; } @@ -550,20 +548,14 @@ namespace YAML if (node[MAX_LIFE_TAG.data()].IsDefined()) rhs.SetMaxLife(node[MAX_LIFE_TAG.data()].as()); - if (node[ANGULAR_MIN_TAG.data()].IsDefined()) - rhs.SetAngularMin(node[ANGULAR_MIN_TAG.data()].as()); + if (node[ANGULAR_RANGES_OFFSET_TAG.data()].IsDefined()) + rhs.SetAngularRangesAndOffsets(node[ANGULAR_RANGES_OFFSET_TAG.data()].as()); - if (node[ANGULAR_MAX_TAG.data()].IsDefined()) - rhs.SetAngularMax(node[ANGULAR_MAX_TAG.data()].as()); + if (node[MIN_SPEED_TAG.data()].IsDefined()) + rhs.SetMinSpeed(node[MIN_SPEED_TAG.data()].as()); - if (node[MIN_VEL_TAG.data()].IsDefined()) - rhs.SetMinVelocity(node[MIN_VEL_TAG.data()].as()); - - if (node[MAX_VEL_TAG.data()].IsDefined()) - rhs.SetMaxVelocity(node[MAX_VEL_TAG.data()].as()); - - if (node[MIN_SIZE_TAG.data()].IsDefined()) - rhs.SetMinSize(node[MIN_SIZE_TAG.data()].as()); + if (node[MAX_SPEED_TAG.data()].IsDefined()) + rhs.SetMaxSpeed (node[MAX_SPEED_TAG.data()].as()); if (node[MAX_SIZE_TAG.data()].IsDefined()) rhs.SetMaxSize(node[MAX_SIZE_TAG.data()].as());