From 73c5a0ff4a2e0e69ad37aa553f53eb4a044f539e Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Sat, 4 Mar 2023 23:12:12 +0800 Subject: [PATCH 1/6] Updated shadow shaders --- Assets/Shaders/DeferredComposite_CS.glsl | 2 +- Assets/Shaders/DeferredComposite_CS.shshaderb | Bin 10101 -> 10085 bytes Assets/Shaders/ShadowMap_FS.glsl | 8 +++++++- Assets/Shaders/ShadowMap_FS.shshaderb | Bin 789 -> 1229 bytes 4 files changed, 8 insertions(+), 2 deletions(-) diff --git a/Assets/Shaders/DeferredComposite_CS.glsl b/Assets/Shaders/DeferredComposite_CS.glsl index 12352d4d..2cf33ae1 100644 --- a/Assets/Shaders/DeferredComposite_CS.glsl +++ b/Assets/Shaders/DeferredComposite_CS.glsl @@ -83,7 +83,7 @@ float CalcShadowValue (sampler2D shadowMap, vec4 worldSpaceFragPos, mat4 lightPV return 0.0f; } else - return 0.3f; + return 1.0f; // return step (fragPosLightPOV.z, ); } diff --git a/Assets/Shaders/DeferredComposite_CS.shshaderb b/Assets/Shaders/DeferredComposite_CS.shshaderb index a5197b3bb424b07718a21240adc9134a72f08195..e0b019b110f203343587a12900cb4cdfacd2b8c4 100644 GIT binary patch literal 10085 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 K_e|_>oc{p)UnD;O diff --git a/Assets/Shaders/ShadowMap_FS.glsl b/Assets/Shaders/ShadowMap_FS.glsl index b19a32a6..59904b5e 100644 --- a/Assets/Shaders/ShadowMap_FS.glsl +++ b/Assets/Shaders/ShadowMap_FS.glsl @@ -7,6 +7,12 @@ layout(location = 0) out vec4 shadowMap; void main() { + float depth = gl_FragCoord.z; + + float dx = dFdx(depth); + float dy = dFdy(depth); + + float moment2 = depth * depth + 0.25f * (dx * dx + dy * dy); // shadowMap = vec4 (0.0f, 0.0f, gl_FragCoord.z, 1.0f); - shadowMap = vec4 (gl_FragCoord.z, gl_FragCoord.z * gl_FragCoord.z, 0.0f, 1.0f); + shadowMap = vec4 (gl_FragCoord.z, moment2, 0.0f, 1.0f); } \ No newline at end of file diff --git a/Assets/Shaders/ShadowMap_FS.shshaderb b/Assets/Shaders/ShadowMap_FS.shshaderb index 709a2ecc8a2443df79dbbed62ab544a4ac5cc464..78d304c1c888675793ea571220284d752acb2677 100644 GIT binary patch literal 1229 zcmZ9K-A@xi6vao{@=*k;2>5Lg#SfGag2u#%L4$oM!Ke?uP1f#GR@>cmyH$C^2mdkS zyZ$-8n0S86Oj6zCX3jbH%)K*rr}3j|%C9oEGGWXqQ#Ui_{)uGHm@z5FOq=m?ZM9#w z*9S$ozV%=O%dDxCPCRpF!cdCn2XR7TTCu8V$cL^5LKRgt=DRjk&6H`i?ar%bb`WJj z9u$!s90p;O+w|T0s8bC7^(Yl5UE2$i?l9;^c58DZ3pyWEXOcR*Z{OG?O@>K)kmh~+ zaTxUCgE-2Suaj@>@3-2!wv%OcP#pCl+l!OPhHlTL3Kjv8umjNT7E zsk?+xRvc=rX-?d^+p{n7p!+;c^H5ZJMYELe%LzUQJ_1+Gl5jumM@g|MUMuIt4AReg zL8e?w9%>SEjx*D%3ch(wlX)(elQkt?6dsq>ETdY^o!O%;sos>s+@&dA*UCRcf9yE@ z&=$l`Yi%m{)*PP^rZ4+vwc@2ddDcq`V~)4U-xT7d`1lem)>yiT@c3m%Xt@t(eQFExc8nH#_Rb7$G_>Eoav$h54!hU7N)1?R~+|ycqe$! zz2}-Ry*+O_?)NN<<3a!GdS4f&7CG-*5#~RW^S&FxoRb`PWY%bY*0+TJpY?5N=>9x+ dgxU8}e~CA9Pk{%Wcf#ACHgAaBAHBXuioZ{gZEXMm delta 327 zcmZvWJqp4=6og+k#`u?*_>(B22(j}5f<&+q6u~Pf7Iq32mR24hEH)m-8+Zhd5^yHQ z&V_G(=DjyNukyVZcr{b9Wva*)F{C1nbdz9Vl_6J?-MelHujj*df4r=>C%rU!{e=`V zb?_Y)zN;Jnb^SD=ID`U2DS`qRVlUz3chsl(o8Ht|ui!L*tzEV91KhaAsL&?`q`wuc!H^rv;7r4L)>k1I|(3ARY5{fCpG(k`T<06nUMjm?G)~ Fd;m-c7byS$ From 826df94c96d9576a0a27930c699058097b961916 Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Mon, 6 Mar 2023 00:02:06 +0800 Subject: [PATCH 2/6] Shadows WIP --- Assets/Shaders/Anim_VS.glsl | 9 +- Assets/Shaders/Anim_VS.shshaderb | Bin 6053 -> 6505 bytes Assets/Shaders/DeferredComposite_CS.glsl | 32 +++-- Assets/Shaders/DeferredComposite_CS.shshaderb | Bin 10085 -> 11109 bytes Assets/Shaders/ShadowMapBlur_CS.glsl | 58 +++++++++ Assets/Shaders/ShadowMapBlur_CS.shshaderb | Bin 0 -> 4569 bytes .../Shaders/ShadowMapBlur_CS.shshaderb.shmeta | 3 + Assets/Shaders/ShinyHighlight_FS.glsl | 3 +- Assets/Shaders/ShinyHighlight_FS.shshaderb | Bin 5273 -> 5397 bytes Assets/Shaders/TestCube_FS.glsl | 7 +- Assets/Shaders/TestCube_FS.shshaderb | Bin 2557 -> 2913 bytes Assets/Shaders/TestCube_VS.glsl | 9 +- Assets/Shaders/TestCube_VS.shshaderb | Bin 4133 -> 4585 bytes .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 112 ++++++++++-------- .../MiddleEnd/Interface/SHGraphicsSystem.h | 1 + .../MiddleEnd/Lights/SHLightingSubSystem.cpp | 19 +-- .../MiddleEnd/Lights/SHLightingSubSystem.h | 5 +- .../RenderGraph/SHRenderGraphNode.cpp | 1 + 18 files changed, 183 insertions(+), 76 deletions(-) create mode 100644 Assets/Shaders/ShadowMapBlur_CS.glsl create mode 100644 Assets/Shaders/ShadowMapBlur_CS.shshaderb create mode 100644 Assets/Shaders/ShadowMapBlur_CS.shshaderb.shmeta diff --git a/Assets/Shaders/Anim_VS.glsl b/Assets/Shaders/Anim_VS.glsl index 2213b2fd..5282f062 100644 --- a/Assets/Shaders/Anim_VS.glsl +++ b/Assets/Shaders/Anim_VS.glsl @@ -20,10 +20,11 @@ layout(location = 0) out struct vec2 uv; // location = 1 vec4 normal; // location = 2 vec4 worldPos; // location = 3 + vec3 worldNormal; // location = 4 } Out; // material stuff -layout(location = 4) out struct +layout(location = 5) out struct { int materialIndex; uint eid; @@ -61,11 +62,13 @@ void main() // uvs for texturing in fragment shader Out.uv = aUV; - mat3 transposeInv = mat3 (transpose(inverse(modelViewMat))); + mat3 mvTransInv = mat3 (transpose(inverse(modelViewMat))); + mat3 modelTransInv = mat3 (transpose(inverse(worldTransform))); // normals are also in view space - Out.normal.rgb = transposeInv * aNormal.rgb; + Out.normal.rgb = mvTransInv * aNormal.rgb; Out.normal.rgb = normalize (Out.normal.rgb); + Out.worldNormal = normalize (modelTransInv * aNormal); // Compute bone matrix mat4 boneMatrix = BoneMatrices.data[firstBoneIndex + aBoneIndices[0]] * aBoneWeights[0]; diff --git a/Assets/Shaders/Anim_VS.shshaderb b/Assets/Shaders/Anim_VS.shshaderb index 6318555888e0c1f04b668c241c14b5ab73baa8b8..41ddaec30d51d8329f421590fc375cb48161e8fd 100644 GIT binary patch literal 6505 zcmZ9Pd3ao96^C!uVgrjX5wU$wussq zuqZ_+;J(Fu-}fDH!F}KNy6^a>|M)z<@11+n`}E^Ee82NM%XiLqzB_@A-49K&)z!Ir zNs@FVOOsQQ|Fo%OdD01!Bz;M5whs;O7+yEinpk(?MeB7rHR;Mc^;woYIK$oid#X~c zt1LxMK^}sfhg^VcK(0h4kz0`?$lb^>6Me>&OkBWX7ohK9$6Mn;B)FCQD9o*tWN z9jK*awQ4;bo2WL^@m6&%)$gQ&U$s77o1G{+^x#pftA{gA;tW@BvSblYRa$AYTB&WT zPo(=Zo0+|pBuT3ii@w%Zt4`j~8m=5jn{98;u-}o{*5lZc9`f4zWNmC)eWq2ZkEf9q zTTgZ;)p{$POq*LPtqM$Uat{7ejfu3jtD5e+s?uub=}FE7Y^hA8%}VBqXK%)7pKi=l zTh&H(-@Rnf*Lvrs+X;fR=D9p=a87T!+1RV6H4UJT7tXOJ=eDoWtWE4}R_Zf*8qFzt z>q;IA?=n~5xwP3DZOp)RXPkA+&K>u$hB_H4HM!o*#~QNy2C{;8UKzi=9pIV1AMQ7+ z)pu0c#ewPmEK6qJ+n0a}+vdgE;%WHC^>-c_&%@hMy^$}+n6}N?VB1owPH(NY z-|M2y8EKoX)fR2u_c0T&d^>)-m7SIPWLnSO?NI(b^k?=YQTKc3L)Ied{w`?u8@qxW zzFpVq_6FCz_?~;b`4rm%4AesQa$fBj04M$9XrS_ad7S@9Y+KSM(6N zJ-F;4xMB}-_GJx++3g|DP`8Ju!FOy;&QpKiulj>>-FK_*Z=&b<{#^RIf-|3-dvKm9 zXDz{r<=S`FmF0`te0!dy&*@YwUq(|GpFx!OQ$jpP-M-ab{nY0h)JMK;>&|*HhqjA} zu{ZmXTbt*MeoE*k!<*kc`m6iq<+LwjH&%PZF9&Ns6T5#wJ=>b~Kb>8hy!q7qX5@_5 z_YB0P{|a_(QNMrMJx@K(dpOwq5x){_%nCe9?25INbL@Seg}#biPTjLsvzu4GpN`ID z*RCF--y_jG5$*P%K9F#u$!=gfasj?1}S-QNrI zX}@O?AMfjaID1`*{WqDPxc&D0Z828~(bl$iC%*$5qun~xk0EmE&i4VN1KGfDfIZuT zOP~M3^swu@n*AKaKGmJg=n1<2eGzv3=X3oM{CmNtBK{r>l64vTX~iTH+ zj?YB=-u=eSVeYdKd42r8ABLF2-w|`D>k~Q72AjjXiX8o5`N;7IusQr~Fo(K6+WkHs zg$y9t&EcDQG$J4RW59l=cM+p~9iorCIlVi%@V^i&r|x@vJmR-@HSs0(Cm?dJ;GPJU zb6&w+oO8}@lp89uKM65jf9-y=N6D-062!ChvA<31mm>ZS#2nQ1i&_W4_7=5X1}@gR z1zpY+b!`R96>Ggb=ZdvH8P0h9wHIq0LicQaqSh0o)q6)~gqupRvwh_#qoU+-y@T|WALCfJ!q-_HV@ z$G){i-_HhXiyp?na;~UnH&|YAMLiKyfip%vVy*|vD=uxtzQ@sxDfT^qF0Z&ECi+g{ zb|dE2*S@b~m$z^4W)I?Bs5`S8kV)hyb5*Y*`p6G*pL^M#gIs|4{rg*FUnTY$qQA?t z^plIYDR9KC1V>yQY@GEQr=MKJO@kw@0gkxmf{pV|jMGmpzKte0;_R=CK7+`|y|;2s z-W7M~JFx%Roby}MH)@&#NABVs?1MMPWlj3YMcjUH#1-%00DPQfoPKf zci>~pD-q-5t$9A@qMlcw7i)esx-~nS@OcebK5Bj~*f{y9`E}r^S$ov{da$;r`3+!e zj{GI?8xi@ac>!#keB^l(*xG&jW%f5Ca<1Us0$z|{9m@UQ3f5O!_`MBmY)656J9r`I zBK95V`f7{VcY=-WEO74vFXUXrz8hU%Z4vt(u(4eQ?!DlJoQv4^q3f&7zv0gD{fNC- zlezVYd1{MUeE?jX=LgZ9r{7HYdY(2bRg*e`?i)fV&o3fNw($=v$HJhjEF zz6vhR^K0nN^ZtU**TM2J&u@T@laG0R6CCr@9&`8>SleJe&u@dBXXGz|zk|rfJiiMz zPCoK{4?K^=-FzP`=L+rzU}IfzH$MdHt1bL~1U9xf&mW^3Tb$=l(Dl_8u|EYHTb$?5 z(2Xt5^XKULYKz!kfQ@x_!Tl0!Y;m5yLf2PY%=6b^d$A^S>l5?T=KZc=|2;B*EJxz* z{*d#b{}KH>B>vywPhfrI!{^W7c_e)P0@hDnpY`m2MK&PzQeyubBIgS3?_jyO>k{}M uIp=-F|3mx}Y`p&3HzG<W0?k;`#d6=O*@lBgc?F#CuTJ?|+=M5&1u1)LLEu literal 6053 zcmZ9O`FmVd8OLv$WQr6h1zJ#`&ZKCotp&BzDpDF+48_m{TZ${;lDQ2RCo^F(NoieZ za9^Rg3kbOHJMJRl0x6*)(sf zoQj-|oP%sZo`-Blu0dXnEFwpdCFBJ1Z)A{vE0`Z6=@1#l#;3+6CdS6Enwp-Qo0{(( zX=PKbyq!%o^KLfX%NH~KPO13i?djG+v+6L6N42hD);NVV9JOTSGM-I)SvOBxd)v+I z_QGanPbEpRyt(XaeXV@vmfm=JBG?ddGiVjC{b zByab!nXJ1f?WHiau!CA)wO%5MxXpudR=f0*@bv!aUWw3p}Pl%dkC(&2RZj;4c=e(5NoKrhp54OYz_8P zfA6pQQ%ZfQ)cwx6p7+n8zau#F$vFq-nsU|>oLH`Zmj;V`QJZ(qwe>lhisc(<>f*IT zc|LW-b=2Lrx??@{c?b28@7sooy_iGWWyH8Q_anEt%o+Qsqn`$Ee)H(B?wyy@zM9!s z?Ge8Qto>ZfJ5<^e=q ze|6uBoONByTu035x|c9F5P4_CJkMoz@7m3y?mLq+&o<_Isq23!cmR>tU)^^o=ULU6 zcOXe}>b_$+?c>bGYxjKjF}t>$_6cUsS3c_T-ADWs zxbOR9FPm_l%Y|6{CU}PH!Mnf6ZJkaKFEPH_Roct#2PnehW56yX&Z*C^>ce z=XYTM+0OfRf9}Cy+<#&GKI*%H`69%9s(beSjR;-4zX{YY$L{+*1MzK-l4UjXnTX#8 zzXv;6L0up1o~b{b&q3BA<}lZJh`c_&)u$om@S9)`b$ueogYPM7yi!&%c*Z;egWd!xsLcc z^9vCPFKQhH zySJ$IN^rH--RN?TsA~^cu3GC=C0DKWC2+>;uf1C97`kig6SZCqw$@#U=c=xswO!2o zQsf#$|8eGP5&h$SsOuAZyAEt0PUD7-Fux43X0f&dWxw}>wYk4W!6%8FV}ieS_V9Y- zKq*W`9`_nC2f@aeKVohG%PS6T)tHx~8zUDnuK>#{j)<9L5BtzxiCBxd_4S;5oAT~k zpI0Gr(bLy}{Z@KU+{=xKKJugFonpQT@hs0re3Q}Z6s*6)wQgdTi@2M?5$8LMxM{F) z)^D7CauJt-Bd!UKxIqORN|^#HsN-Ul|;`xo5%!N$r( z><7U5Y74&)f{pbK1ot7Zv2qdnVX(g1!tWzsV+SkTN5RI*MeMy`eYN@b#XjDLxEE_O zw?5HNZPBay!PS0#4BdWukHhByuzd9ML9lW1(a(p#(a#6L(T9(NwT+f{@Dt!AB=Xn6 zpG4%NpPvF7Cm(q}4X*a{Gw5=TIIquwjdjG?d=9Lyw($Er*jRfP+!w&c%0=uK!TM?o zzb}D}wRgdN8EmXv#C`>=ueR{}D%jX+Kfi`+9n_cQXGAIf1M~JO_3C{>Mr?kpBby10FX3 diff --git a/Assets/Shaders/DeferredComposite_CS.glsl b/Assets/Shaders/DeferredComposite_CS.glsl index 2cf33ae1..18f53de4 100644 --- a/Assets/Shaders/DeferredComposite_CS.glsl +++ b/Assets/Shaders/DeferredComposite_CS.glsl @@ -2,6 +2,7 @@ struct DirectionalLightStruct { + vec4 directionWorld; vec3 direction; uint isActive; uint cullingMask; @@ -22,7 +23,7 @@ layout(local_size_x = 16, local_size_y = 16) in; layout(set = 3, binding = 0, rgba32f) uniform image2D positions; layout(set = 3, binding = 1, rgba32f) uniform image2D normals; layout(set = 3, binding = 2, rgba8) uniform image2D albedo; -layout(set = 3, binding = 3, r32ui) uniform uimage2D lightLayerData; +layout(set = 3, binding = 3, rgba32ui) uniform uimage2D lightLayerData; layout(set = 3, binding = 4, r8) uniform image2D ssaoBlurredImage; layout(set = 3, binding = 5, rgba8) uniform image2D positionWorldSpace; layout(set = 3, binding = 6, rgba8) uniform image2D targetImage; @@ -54,7 +55,7 @@ float LinStep (float val, float low, float high) return clamp ((val - low)/(high - low), 0.0f, 1.0f); } -float CalcShadowValue (sampler2D shadowMap, vec4 worldSpaceFragPos, mat4 lightPV) +float CalcShadowValue (sampler2D shadowMap, vec4 worldSpaceFragPos, mat4 lightPV, vec3 worldNormal, vec3 lightDir) { // clip space for fragment from light view space vec4 fragPosLightPOV = lightPV * worldSpaceFragPos; @@ -69,6 +70,13 @@ float CalcShadowValue (sampler2D shadowMap, vec4 worldSpaceFragPos, mat4 lightPV if (converted.x < 0.0f || converted.x > 1.0f || converted.y < 0.0f || converted.y > 1.0f) return 1.0f; + float returnVal = 0.0f; + + float worldNormalDotLight = dot (normalize (worldNormal), normalize(lightDir)); + + if (worldNormalDotLight < 0.0f) + return 0.7f; + if (fragPosLightPOV.z > moments.x && fragPosLightPOV.w > 0.0f) { float p = step (fragPosLightPOV.z, moments.x); @@ -76,15 +84,19 @@ float CalcShadowValue (sampler2D shadowMap, vec4 worldSpaceFragPos, mat4 lightPV float d = fragPosLightPOV.z - moments.x; float pMax = LinStep (variance / (variance + (d * d)), 0.9f, 1.0f); - return min (max (p, pMax), 1.0f); + + returnVal = min (max (p, pMax) + 0.7f, 1.0f); + + return returnVal; + } else if (fragPosLightPOV.z > 1.0f) { return 0.0f; } - else - return 1.0f; - // return step (fragPosLightPOV.z, ); + + return 1.0f; + } void main() @@ -104,8 +116,12 @@ void main() // normal of fragment vec3 normalView = imageLoad(normals, globalThread).rgb; + uvec4 lightLayerAndNormal = imageLoad (lightLayerData, globalThread); + // light layer index - uint lightLayer = imageLoad (lightLayerData, globalThread).r; + uint lightLayer = lightLayerAndNormal.x; + + vec3 worldNormal = vec3 (unpackHalf2x16 (lightLayerAndNormal.y).xy, unpackHalf2x16 (lightLayerAndNormal.z).x); vec3 fragColor = vec3 (0.0f); @@ -138,7 +154,7 @@ void main() if ((DirLightData.dLightData[i].shadowData & uint(1)) == 1) { // calculate shadow map here - fragColor *= CalcShadowValue (shadowMaps[0], positionWorld, DirLightData.dLightData[i].pvMatrix).xxx; + fragColor.rgb *= CalcShadowValue (shadowMaps[0], positionWorld, DirLightData.dLightData[i].pvMatrix, worldNormal, DirLightData.dLightData[i].directionWorld.xyz).xxx; } } } diff --git a/Assets/Shaders/DeferredComposite_CS.shshaderb b/Assets/Shaders/DeferredComposite_CS.shshaderb index e0b019b110f203343587a12900cb4cdfacd2b8c4..57401b13063ae5536870be4281bf45663baf213c 100644 GIT binary patch literal 11109 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 PzIq4stK-?~cj0dVKJ1B) literal 10085 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 0 && uv.y >= 0 && uv.x < imageSize.x && uv.y < imageSize.y) + { + return imageLoad (shadowMap, uv); + } + + return vec4 (0.0f); +} + +shared vec4 sharedPixels[16 + BLUR_WIDTH - 1][16 + BLUR_WIDTH - 1]; + +void main() +{ + ivec2 globalThread = ivec2 (gl_GlobalInvocationID.xy); + ivec2 localThread = ivec2 (gl_LocalInvocationID.xy); + ivec2 inputImageSize = imageSize(shadowMap); + + // Load color into shared memory + ivec2 start = ivec2 (gl_WorkGroupID) * ivec2 (gl_WorkGroupSize) - (BLUR_HALF_WIDTH); + for (int i = localThread.x; i < SHM_WIDTH; i += int (gl_WorkGroupSize.x)) + { + for (int j = localThread.y; j < SHM_WIDTH; j += int (gl_WorkGroupSize.y)) + { + vec4 value = GetShadowMapValue (start + ivec2 (i, j), inputImageSize); + sharedPixels[i][j] = value; + } + } + + // wait for all shared memory to load + barrier(); + + ivec2 shmStart = ivec2 (localThread + (BLUR_HALF_WIDTH)); + + vec4 sum = vec4 (0.0f); + for (int i = -BLUR_HALF_WIDTH; i <= BLUR_HALF_WIDTH; ++i) + { + for (int j = -BLUR_HALF_WIDTH; j <= BLUR_HALF_WIDTH; ++j) + { + vec4 sharedVal = sharedPixels[shmStart.x + i][shmStart.y + j]; + sum += sharedVal; + } + } + + sum /= (BLUR_WIDTH * BLUR_WIDTH); + imageStore(shadowMapBlurred, globalThread, sum); +} \ No newline at end of file diff --git a/Assets/Shaders/ShadowMapBlur_CS.shshaderb b/Assets/Shaders/ShadowMapBlur_CS.shshaderb new file mode 100644 index 0000000000000000000000000000000000000000..d02afaf1c4385f91bf082bc5cae9570086ea2cd9 GIT binary patch literal 4569 zcmZ9O3!9Zy700&>XBa@a3ItLO-c2GvGGd~qy+q6q& zq;y`Il`csCnxxYFGz}&ddQH}A(X&%~!B@L`yH|~l4Xj#s?P{0INo}gaH#c>p3V1p) zSZfT)e+Ai!Y(wUeL!ag6WwBNp|E8h;jWL~Ws@;9no}Oy=*1rCck-pKf2b=Z2W@D({ zH_&L+`^Op+b>lipagCw==J-H4ph85sk4lbjfW^%aMz$mBSFEnryJ3`n!`J5%^ka2_1XX?u^q+U zcQyN}g{y05Vz|FH))*e@+EVx{N!^5uWv+2ntm&4XvV@%NsSAH&Xk>h>>yyUZYd8Gp zSgkdNHqLpI=g#5Qo@#4&e8i&e?=IIDF>T2`-B;l0X#_ptJhIIQ(nzgU8_f3opR(K2 z!`RHBRUg>ic%a@K#Uy_v9Vz(1-rP!2^QheTV1bW;qy97C$@-OaqF84>P6b>^Gt${f zZt}1;H^*Cep;DFodJY#O-oCI`fc><+ce9b@*>NPJbtM2U<>9%*vSsKN&jN~f#cKNgKxrn{{8{lW`4cYb# z{LJb4>kBKTl~lL)^_i0oaV{IM-Gj3;_f2SP%bQ!<^OG}vBieZT3BTv5KWxu4;(NgE z+5EBp9bo6Tvbb3(eFH3~M9iJw@|u2Z=Vp(?XlLraVulZa^)JW&{p^#|-iwygcKr{~ zo~^t+Yx{=e^dHE$oc|DQ(YbTy!ajwKyYPD+XONV(Y_^`~ceb!U z$@ez)Am!~&$)!XWs2Q3#rAh9;=QMLO|kv` z3BNP#Vh- z=51i#h5hxQw>}Pv^E4_t3C4C1ocL!MBcNB5o1p9`R13B(n zU}N>!qvtQT3BTuYH{u=_Aoguv-$vw(_kL)9z`gqp+WV(|m)Jh^y@;Rw8d|?Pa_t10 z<0SRG>jQ{fKk^|twC_R8#AIt2v@K|HC8~y=gZPbGcUR+8OBYA`}0}<81tYfid#?^4W}o&7;r# z__pMt#sgsQls?~?_Igfe7WzSC4&oYp#`sp{qlX`Y%RTMGwkQ4O*pIko6FCo{e}p`Y zxNaX}PC4V8q4RVO>ZoxLY)<#&-FXC&^LO3#`sB)INb87vodwVy-G1>^eI{G{bF86sFTkaGR=OyR*I4@_b z?Hw_nI`aJmT%O-wvE?G4J~`LNz4MO5e%=7PpY6OB_wy!lW{MojdwmPucw=I(a^_lt z{u^>O+rGWOBR6K--2XtV)la;!`sF_2MO}~h{~hDzAbzuvFLNdx=<`eX0T zVUAgVj@c{%%fFuA%o4ENV&pyYE=BwKe)N3?ku$eAa$f|te);|_$Ci)Wp9RaA+gV2* z^*hXV9{O{Lb?n=CYuHC8+Rr|W`8?8z*oQd!SOK<=@*Xe7mXDZAz|N-}b1Alb{GGcD z>^gaS?L=Ek9lc%-wio+1-ahR0O0=K78gm6A=X!DUaTR##%)S68A2C;h?X^7DmDuvp z>leYUlegEXrH)=#f$gOeG2TAxbv4@0UXA$@B4@ASxVP)T*JRs!do5z`JM(?K4s4A4 Q|5&SS4s&U*M|*$&4|n0d!2kdN literal 0 HcmV?d00001 diff --git a/Assets/Shaders/ShadowMapBlur_CS.shshaderb.shmeta b/Assets/Shaders/ShadowMapBlur_CS.shshaderb.shmeta new file mode 100644 index 00000000..cc90d5c9 --- /dev/null +++ b/Assets/Shaders/ShadowMapBlur_CS.shshaderb.shmeta @@ -0,0 +1,3 @@ +Name: ShadowMapBlur_CS +ID: 38004013 +Type: 2 diff --git a/Assets/Shaders/ShinyHighlight_FS.glsl b/Assets/Shaders/ShinyHighlight_FS.glsl index bb41a0fb..be26f866 100644 --- a/Assets/Shaders/ShinyHighlight_FS.glsl +++ b/Assets/Shaders/ShinyHighlight_FS.glsl @@ -57,7 +57,7 @@ layout (std430, set = 2, binding = 0) buffer MaterialProperties // For mater layout(location = 0) out vec4 position; layout(location = 1) out uint outEntityID; -layout(location = 2) out uint lightLayerIndices; +layout(location = 2) out uvec4 lightLayerIndices; layout(location = 3) out vec4 normals; layout(location = 4) out vec4 albedo; layout(location = 5) out vec4 worldSpacePosition; @@ -76,7 +76,6 @@ void main() worldSpacePosition = In.worldPos; outEntityID = In2.eid; - lightLayerIndices = In2.lightLayerIndex; // float vpHeight = float (In2.screenSpacePos.y) - MatProp.data[In2.materialIndex].highlightPosition; // bring the frame of reference to the object's screen space pos diff --git a/Assets/Shaders/ShinyHighlight_FS.shshaderb b/Assets/Shaders/ShinyHighlight_FS.shshaderb index 408bba83d06bbbc37f21629ca6e54476d96e147a..572f3b31d0ed23942fb76dda3dfd28153ef4d70c 100644 GIT binary patch delta 922 zcmZ8gOKTHR82#pzu}w8@+M<>55lpEH1vjM?D+M7fRPeEAbjZL$2;SW&UxNzyO@CSI#^o|5CoPOUq-($|5N#D)9y*6=nY+SPA*kxbD zl2JJ=$8RRyk8~k_1p56i_ne|D>&V;nu%UF|PL*n4E!7CqcwgObw)G$P$BZYQ9737Gs#(SvpM0^MiD@Xdbdv4N~K6rxztKoratt3%gSM9-9?~$eZ{)Nu6vB|MA|KQ}B zg`Ao@q|qd`Q$rffQ5!Q_ZigCARUDzl*($ajAzlG+f`7v06CvaD902yNFoT9l~hSMB1@`s4@ z;^N>kcc%?j8K3;eYlEM~i?+9j2d(S#XJ$Lh*t7vG;a%TB+yoYZY2Y>%@h<#s zo4^v*@-lT`9$*h^D*$_Wr3hfXW4JO}Vsj^;hVjvF8ByQ0K*KGIt{8&Jz^)&yw>da=x9HX2BkEYKgvC MnzObByQNw0FQhwmj{pDw delta 837 zcmYk4OG`pQ7=}lW=bSEf11TtwN+^n`RYW(#2&^EAD7ruw(@~F=9n5MIxM&gWilIgH z2ig>byM95N+O}>{`~E@iYjem?UT5a{zWFYrxBYj0t8z&2D<~2n|i(@o0 z-i?bud!@r}dSC#Ra~BV4(2kUU>{ox|IPfwEdo_gmsO#C{fJ|XQVf~`qQ)60TU5fA7 zi4-}kyu|i7PC%0sV0U ze~tOZp%SB~KzATU_d<;B!MY2P$MEBDh&^Z&V$3cy2Qij|Bq91QkdNmSv<;C*F&zJX zWL~_)9xNyFx>y>3@Lac=!JaIJbe#4O;tR0&BIJ#f$DY0`6y}IW5bu(^x;d9zJvEK^ K66NovA@dhK(P&8k diff --git a/Assets/Shaders/TestCube_FS.glsl b/Assets/Shaders/TestCube_FS.glsl index 90b1922c..678ffb0e 100644 --- a/Assets/Shaders/TestCube_FS.glsl +++ b/Assets/Shaders/TestCube_FS.glsl @@ -17,10 +17,11 @@ layout(location = 0) in struct vec2 uv; // location = 1 vec4 normal; // location = 2 vec4 worldPos; // location = 3 + vec3 worldNormal; // location = 4 } In; // material stuff -layout(location = 4) flat in struct +layout(location = 5) flat in struct { int materialIndex; uint eid; @@ -35,7 +36,7 @@ layout (std430, set = 2, binding = 0) buffer MaterialProperties // For mater layout(location = 0) out vec4 position; layout(location = 1) out uint outEntityID; -layout(location = 2) out uint lightLayerIndices; +layout(location = 2) out uvec4 lightLayerIndices; layout(location = 3) out vec4 normals; layout(location = 4) out vec4 albedo; layout(location = 5) out vec4 worldSpacePosition; @@ -48,5 +49,5 @@ void main() worldSpacePosition = In.worldPos; outEntityID = In2.eid; - lightLayerIndices = In2.lightLayerIndex; + lightLayerIndices = uvec4 (In2.lightLayerIndex, packHalf2x16 (In.worldNormal.xy), packHalf2x16 (vec2 (In.worldNormal.z, 1.0f)), 1); } \ No newline at end of file diff --git a/Assets/Shaders/TestCube_FS.shshaderb b/Assets/Shaders/TestCube_FS.shshaderb index 2974523d7405e05bdcf30d419f0663694bcc271b..5374023a8a56c4d4726e2a1768556e058c308433 100644 GIT binary patch literal 2913 zcmZ9MTXz#x6vt1=#aeDf1Vp5!t=0=#Yb}T(U}|d!1{w&``ZQ~rIkcnGnK+qL`sRz@ zNPY3mPvwhi`TtGMDZ#VW&c6N6-uvvmC$l>zO?fIO7GE)D%FLM4=7+J#oHHk6F(v=w z^)dg`@xR1p%(Ursp9Y&dPlCt}`*}PlvOI{>$UcwLJ#*63%loZPud_TXqUE*gD}+8{ zDrE*@pH;r9ICK!kDUMe~XGBV2-ViN`z7jP>Ezzv*gIB?lDyq_$zZI;io2^dJe7qhE z?I6sf;t8T1E(U|1X_Hb~;s22q?VQ+#O2RmO3+IPE8+XcABpV)ETJ zQ!C#-$cAwdXJs#HdfzF%k5iZ5%ZD~Ey4g^+YH6dFqr(>%dXlQ_Fu_(YF?9WxEKedX z>UcXfl=g??3*@B#ZB;;x%wZgBSnA9qOm=OQ;jfvi(hK{%80EH%i)~J}2Vv38v%yAK zgvvFx$!z*rlI7xcO%NQlyZdc+N9r-2cZA7cKb)}fj$NyuIyJ>;h%1-P<1itiS`$+V zIq`8KiqPRb3*xRe=@s)14jt<8@_~!z3!=~XrbIT5jiSKf>dnR;ubUNOt!zpEH<V0 zk52yc`i0Lc9`zw#l*D@)qD#W_AB0YS8~U9V2aEld)0r7I@H67ziG|MJFFO7?-QxS^ zE;u*@hS;aYsS^yb(dh-Y3)0VuH=KUW>CB76{d3}ACu?JN%Ptj)VD zPOZe4JYK&d<_*<$qjLI;?0Xw zXG26h^aT+%da)?p5OLi9>N zns`&c?BZ)8_Lm*KEhK$8FT#FDH~4PQJ^rF(@a(9^Uy_U+JiCkzp4q)GS`zvA%;^JX zZz>z}`$)7P0)vnF5*zHtBK$q4^Z$a4_{@4m#13QU4s++f20Iw$|CxxIeOz{7&Dpnw z;my}Y+{5l`zajbmwSO)fc4}vrz7YA^@%eWW^GoOd&E>cyojlm-72h>B@-d4$BI;!S zd~feMJ9zdK9sIiZHzMlu?_yUroE?1A=^lSiI(R=j@NE%xFzjAOL=E>v)W9A-5Mkfa zo9W#{XT#26*G_2@iMQo+-UzNK`y=tkA|JOanb>vlp7V8;pV;3!8$0b|K9x)kV&d@$0nf|P-|-1U4&>ci?oWMLZKk8DyIL>&@Ju%@O^S8_m5eAnTXaPfFBC}+>Vf$4gwj?yA-%L+t z*Dq^NppgxyVWKYH)EWxhMw<+VQYag}X)nSZuWWyYy$CHW$#x6%%B-=#tV<;lyIbhV z`Ki#4dFipVq2SxyVtY!P6@k&v{v$bfXF)*UR0aHl@PWQ4{;GhV?lXVQ>G&BF9RD4y zcLn~@?0za-o$2;Zu`)!5-xIix^ZUY@u;X~wY1~O?8v^q}CnvGbqq-N{w^2X(_l~`c vmQ&V~YtDX;I#s?a?Wi*As;&LDfKFG;41T5G;(_oN3gAe~ diff --git a/Assets/Shaders/TestCube_VS.glsl b/Assets/Shaders/TestCube_VS.glsl index 1b45c333..07b89b6b 100644 --- a/Assets/Shaders/TestCube_VS.glsl +++ b/Assets/Shaders/TestCube_VS.glsl @@ -20,11 +20,12 @@ layout(location = 0) out struct vec2 uv; // location = 1 vec4 normal; // location = 2 vec4 worldPos; // location = 3 + vec3 worldNormal; // location = 4 } Out; // material stuff -layout(location = 4) out struct +layout(location = 5) out struct { int materialIndex; uint eid; @@ -57,11 +58,13 @@ void main() // uvs for texturing in fragment shader Out.uv = aUV; - mat3 transposeInv = mat3 (transpose(inverse(modelViewMat))); + mat3 mvTransInv = mat3 (transpose(inverse(modelViewMat))); + mat3 modelTransInv = mat3 (transpose(inverse(worldTransform))); // normals are also in view space - Out.normal.rgb = transposeInv * aNormal.rgb; + Out.normal.rgb = mvTransInv * aNormal.rgb; Out.normal.rgb = normalize (Out.normal.rgb); + Out.worldNormal = normalize (modelTransInv * aNormal); // clip space for rendering gl_Position = cameraData.vpMat * worldTransform * vec4 (aVertexPos, 1.0f); diff --git a/Assets/Shaders/TestCube_VS.shshaderb b/Assets/Shaders/TestCube_VS.shshaderb index 1bb76ec42331e3ece2cf26e15e72fbbb613e2633..e607761c64bec9e2e8ee7eabc6921c6bed9b9f1b 100644 GIT binary patch literal 4585 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 diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index bbbbd1dd..54e5a1ff 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -141,25 +141,28 @@ namespace SHADE //SHAssetManager::CompileAsset("../../Assets/Shaders/Text_VS.glsl", false); //SHAssetManager::CompileAsset("../../Assets/Shaders/Trajectory_VS.glsl", false); //SHAssetManager::CompileAsset("../../Assets/Shaders/Trajectory_FS.glsl", false); + //SHAssetManager::CompileAsset("../../Assets/Shaders/ShadowMapBlur_CS.glsl", false); + //SHAssetManager::CompileAsset("../../Assets/Shaders/Anim_VS.glsl", false); // Load Built In Shaders - static constexpr AssetID VS_DEFAULT = 39210065; defaultVertShader = SHResourceManager::LoadOrGet(VS_DEFAULT); - static constexpr AssetID VS_ANIM = 47911992; animtVertShader = SHResourceManager::LoadOrGet(VS_ANIM); - static constexpr AssetID FS_DEFAULT = 46377769; defaultFragShader = SHResourceManager::LoadOrGet(FS_DEFAULT); - static constexpr AssetID VS_DEBUG = 48002439; debugVertShader = SHResourceManager::LoadOrGet(VS_DEBUG); - static constexpr AssetID FS_DEBUG = 36671027; debugFragShader = SHResourceManager::LoadOrGet(FS_DEBUG); - static constexpr AssetID VS_DEBUG_MESH = 42127043; debugMeshVertShader = SHResourceManager::LoadOrGet(VS_DEBUG_MESH); - static constexpr AssetID CS_COMPOSITE = 45072428; deferredCompositeShader = SHResourceManager::LoadOrGet(CS_COMPOSITE); - static constexpr AssetID SSAO = 38430899; ssaoShader = SHResourceManager::LoadOrGet(SSAO); - static constexpr AssetID SSAO_BLUR = 39760835; ssaoBlurShader = SHResourceManager::LoadOrGet(SSAO_BLUR); - static constexpr AssetID TEXT_VS = 39816727; textVS = SHResourceManager::LoadOrGet(TEXT_VS); - static constexpr AssetID TEXT_FS = 38024754; textFS = SHResourceManager::LoadOrGet(TEXT_FS); - static constexpr AssetID RENDER_SC_VS = 48082949; renderToSwapchainVS = SHResourceManager::LoadOrGet(RENDER_SC_VS); - static constexpr AssetID RENDER_SC_FS = 36869006; renderToSwapchainFS = SHResourceManager::LoadOrGet(RENDER_SC_FS); - static constexpr AssetID SHADOW_MAP_VS = 44646107; shadowMapVS = SHResourceManager::LoadOrGet(SHADOW_MAP_VS); - static constexpr AssetID SHADOW_MAP_FS = 45925790; shadowMapFS = SHResourceManager::LoadOrGet(SHADOW_MAP_FS); - static constexpr AssetID TRAJECTORY_VS = 41042628; trajectoryVS = SHResourceManager::LoadOrGet(TRAJECTORY_VS); - static constexpr AssetID TRAJECTORY_FS = 45635685; trajectoryFS = SHResourceManager::LoadOrGet(TRAJECTORY_FS); + static constexpr AssetID VS_DEFAULT = 39210065; defaultVertShader = SHResourceManager::LoadOrGet(VS_DEFAULT); + static constexpr AssetID VS_ANIM = 47911992; animtVertShader = SHResourceManager::LoadOrGet(VS_ANIM); + static constexpr AssetID FS_DEFAULT = 46377769; defaultFragShader = SHResourceManager::LoadOrGet(FS_DEFAULT); + static constexpr AssetID VS_DEBUG = 48002439; debugVertShader = SHResourceManager::LoadOrGet(VS_DEBUG); + static constexpr AssetID FS_DEBUG = 36671027; debugFragShader = SHResourceManager::LoadOrGet(FS_DEBUG); + static constexpr AssetID VS_DEBUG_MESH = 42127043; debugMeshVertShader = SHResourceManager::LoadOrGet(VS_DEBUG_MESH); + static constexpr AssetID CS_COMPOSITE = 45072428; deferredCompositeShader = SHResourceManager::LoadOrGet(CS_COMPOSITE); + static constexpr AssetID SSAO = 38430899; ssaoShader = SHResourceManager::LoadOrGet(SSAO); + static constexpr AssetID SSAO_BLUR = 39760835; ssaoBlurShader = SHResourceManager::LoadOrGet(SSAO_BLUR); + static constexpr AssetID TEXT_VS = 39816727; textVS = SHResourceManager::LoadOrGet(TEXT_VS); + static constexpr AssetID TEXT_FS = 38024754; textFS = SHResourceManager::LoadOrGet(TEXT_FS); + static constexpr AssetID RENDER_SC_VS = 48082949; renderToSwapchainVS = SHResourceManager::LoadOrGet(RENDER_SC_VS); + static constexpr AssetID RENDER_SC_FS = 36869006; renderToSwapchainFS = SHResourceManager::LoadOrGet(RENDER_SC_FS); + static constexpr AssetID SHADOW_MAP_VS = 44646107; shadowMapVS = SHResourceManager::LoadOrGet(SHADOW_MAP_VS); + static constexpr AssetID SHADOW_MAP_FS = 45925790; shadowMapFS = SHResourceManager::LoadOrGet(SHADOW_MAP_FS); + static constexpr AssetID TRAJECTORY_VS = 41042628; trajectoryVS = SHResourceManager::LoadOrGet(TRAJECTORY_VS); + static constexpr AssetID TRAJECTORY_FS = 45635685; trajectoryFS = SHResourceManager::LoadOrGet(TRAJECTORY_FS); + static constexpr AssetID SHADOW_BLUR_CS = 38004013; shadowMapBlurCS = SHResourceManager::LoadOrGet(SHADOW_BLUR_CS); } @@ -217,7 +220,7 @@ namespace SHADE renderGraph->AddResource("Albedo", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, true, windowDims.first, windowDims.second); renderGraph->AddResource("Depth Buffer", { SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT }, true, windowDims.first, windowDims.second, vk::Format::eD32SfloatS8Uint); renderGraph->AddResource("Entity ID", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::SHARED }, true, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc); - renderGraph->AddResource("Light Layer Indices", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, true, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc); + renderGraph->AddResource("Light Layer Indices And World Normals", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, true, windowDims.first, windowDims.second, vk::Format::eR32G32B32A32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc); renderGraph->AddResource("Scene", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE, SH_RENDER_GRAPH_RESOURCE_FLAGS::SHARED }, true, windowDims.first, windowDims.second); renderGraph->AddResource("SSAO", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, true, windowDims.first, windowDims.second, vk::Format::eR8Unorm); renderGraph->AddResource("SSAO Blur", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, true, windowDims.first, windowDims.second, vk::Format::eR8Unorm); @@ -231,7 +234,7 @@ namespace SHADE { "Position", "Entity ID", - "Light Layer Indices", + "Light Layer Indices And World Normals", "Normals", "Albedo", "Depth Buffer", @@ -248,7 +251,7 @@ namespace SHADE auto gBufferSubpass = gBufferNode->AddSubpass(SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_WRITE_SUBPASS.data(), worldViewport, worldRenderer); gBufferSubpass->AddColorOutput("Position"); gBufferSubpass->AddColorOutput("Entity ID"); - gBufferSubpass->AddColorOutput("Light Layer Indices"); + gBufferSubpass->AddColorOutput("Light Layer Indices And World Normals"); gBufferSubpass->AddColorOutput("Normals"); gBufferSubpass->AddColorOutput("Albedo"); gBufferSubpass->AddColorOutput("Position World Space"); @@ -258,7 +261,7 @@ namespace SHADE auto gBufferVfxSubpass = gBufferNode->AddSubpass(SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_WRITE_VFX_SUBPASS.data(), worldViewport, worldRenderer); gBufferVfxSubpass->AddColorOutput("Position"); gBufferVfxSubpass->AddColorOutput("Entity ID"); - gBufferVfxSubpass->AddColorOutput("Light Layer Indices"); + gBufferVfxSubpass->AddColorOutput("Light Layer Indices And World Normals"); gBufferVfxSubpass->AddColorOutput("Normals"); gBufferVfxSubpass->AddColorOutput("Albedo"); gBufferVfxSubpass->AddColorOutput("Position World Space"); @@ -314,7 +317,7 @@ namespace SHADE auto deferredCompositeNode = renderGraph->AddNode(SHGraphicsConstants::RenderGraphEntityNames::DEFERRED_COMPOSITE_PASS.data(), { "Position", - "Light Layer Indices", + "Light Layer Indices And World Normals", "Normals", "Albedo", "Scene", @@ -327,7 +330,7 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* DEFERRED COMPOSITE SUBPASS INIT */ /*-----------------------------------------------------------------------*/ - auto deferredCompositeCompute = deferredCompositeNode->AddNodeCompute(SHGraphicsConstants::RenderGraphEntityNames::DEFERRED_COMPOSITE_COMPUTE.data(), deferredCompositeShader, {"Position", "Normals", "Albedo", "Light Layer Indices", "SSAO Blur", "Position World Space", "Scene", "Object VFX"}, {}, SHLightingSubSystem::MAX_SHADOWS); + auto deferredCompositeCompute = deferredCompositeNode->AddNodeCompute(SHGraphicsConstants::RenderGraphEntityNames::DEFERRED_COMPOSITE_COMPUTE.data(), deferredCompositeShader, {"Position", "Normals", "Albedo", "Light Layer Indices And World Normals", "SSAO Blur", "Position World Space", "Scene", "Object VFX"}, {}, SHLightingSubSystem::MAX_SHADOWS); deferredCompositeCompute->AddPreComputeFunction([=](Handle cmdBuffer, uint32_t frameIndex) { lightingSubSystem->PrepareShadowMapsForRead(cmdBuffer); @@ -669,21 +672,21 @@ namespace SHADE #endif } - //static bool shadowAdded = false; + static bool shadowAdded = false; - //if (shadowAdded == false && SHInputManager::GetKey(SHInputManager::SH_KEYCODE::B)) - //{ - // shadowAdded = true; - // auto& lightComps = SHComponentManager::GetDense(); - // //if (lightComps.size() > 2) - // //{ - // // lightComps[2].SetEnableShadow(true); - // //} - // for (auto& comp : lightComps) - // { - // comp.SetEnableShadow(true); - // } - //} + if (shadowAdded == false && SHInputManager::GetKey(SHInputManager::SH_KEYCODE::B)) + { + shadowAdded = true; + auto& lightComps = SHComponentManager::GetDense(); + if (lightComps.size() > 2) + { + lightComps[2].SetEnableShadow(true); + } + for (auto& comp : lightComps) + { + comp.SetEnableShadow(true); + } + } renderGraph->Begin(frameIndex); auto cmdBuffer = renderGraph->GetCommandBuffer(frameIndex); @@ -866,6 +869,7 @@ namespace SHADE auto* lightComp = SHComponentManager::GetComponent(EVENT_DATA->lightEntity); std::string depthResourceName = "ShadowMap_Depth " + std::to_string(EVENT_DATA->lightEntity); std::string shadowMapResourceName = "ShadowMap " + std::to_string(EVENT_DATA->lightEntity); + std::string shadowMapBlurredResourceName = "ShadowMap Blurred" + std::to_string(EVENT_DATA->lightEntity); Handle companionSubpass = renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_PASS.data())->GetSubpass(SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_WRITE_SUBPASS); if (EVENT_DATA->generateRenderer) @@ -878,17 +882,31 @@ namespace SHADE lightComp->SetShadowMapIndex (lightingSubSystem->GetNumShadowMaps()); } + // Add the shadow map resource to the graph renderGraph->AddResource(depthResourceName, {SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH}, false, SHLightingSubSystem::SHADOW_MAP_WIDTH, SHLightingSubSystem::SHADOW_MAP_HEIGHT, vk::Format::eD32Sfloat); - renderGraph->AddResource(shadowMapResourceName, { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT }, false, SHLightingSubSystem::SHADOW_MAP_WIDTH, SHLightingSubSystem::SHADOW_MAP_HEIGHT, vk::Format::eR32G32B32A32Sfloat); + renderGraph->AddResource(shadowMapResourceName, { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, false, SHLightingSubSystem::SHADOW_MAP_WIDTH, SHLightingSubSystem::SHADOW_MAP_HEIGHT, vk::Format::eR32G32B32A32Sfloat); + renderGraph->AddResource(shadowMapBlurredResourceName, { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, false, SHLightingSubSystem::SHADOW_MAP_WIDTH, SHLightingSubSystem::SHADOW_MAP_HEIGHT, vk::Format::eR32G32B32A32Sfloat); + + // link resource to node. This means linking the resource and regenerating the node's renderpass and framebuffer. - auto shadowMapNode = renderGraph->AddNodeAfter(SHGraphicsConstants::RenderGraphEntityNames::SHADOW_MAP_PASS.data() + shadowMapResourceName, {depthResourceName.c_str(), shadowMapResourceName.c_str()}, SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_PASS.data()); + auto shadowMapNode = renderGraph->AddNodeAfter(SHGraphicsConstants::RenderGraphEntityNames::SHADOW_MAP_PASS.data() + shadowMapResourceName, {depthResourceName.c_str(), shadowMapResourceName.c_str(), shadowMapBlurredResourceName.c_str()}, SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_PASS.data()); // Add a subpass to render to that shadow map - auto newSubpass = shadowMapNode->RuntimeAddSubpass(shadowMapResourceName + " Subpass", shadowMapViewport, lightComp->GetRenderer()); - newSubpass->AddColorOutput(shadowMapResourceName); - newSubpass->AddDepthOutput(depthResourceName, SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH); + auto shadowMapDrawSubpass = shadowMapNode->RuntimeAddSubpass(shadowMapResourceName + " Subpass", shadowMapViewport, lightComp->GetRenderer()); + shadowMapDrawSubpass->AddColorOutput(shadowMapResourceName); + shadowMapDrawSubpass->AddDepthOutput(depthResourceName, SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH); + + // add dummy subpass to transition the shadow map images for compute shader usage + //auto dummySubpass = shadowMapNode->RuntimeAddSubpass(shadowMapResourceName + "Dummy", {}, {}); + //dummySubpass->AddGeneralColorOutput(shadowMapResourceName); + //dummySubpass->AddGeneralColorOutput(shadowMapBlurredResourceName); + + // add compute pass to blur shadow ma + shadowMapNode->AddNodeCompute(SHGraphicsConstants::RenderGraphEntityNames::SHADOW_MAP_PASS.data() + shadowMapResourceName, shadowMapBlurCS, { shadowMapResourceName.c_str(), shadowMapBlurredResourceName.c_str() }); + //shadowMapNode->AddNodeCompute(SHGraphicsConstants::RenderGraphEntityNames::SHADOW_MAP_PASS.data() + shadowMapResourceName, shadowMapBlurCS, { shadowMapBlurredResourceName.c_str(), shadowMapResourceName.c_str() }); + //shadowMapNode->AddNodeCompute(SHGraphicsConstants::RenderGraphEntityNames::SHADOW_MAP_PASS.data() + shadowMapResourceName, shadowMapBlurCS, { shadowMapResourceName.c_str(), shadowMapBlurredResourceName.c_str() }); // regenerate the node shadowMapNode->RuntimeStandaloneRegenerate(); @@ -905,16 +923,16 @@ namespace SHADE tempLibrary.Init(device); tempLibrary.CreateGraphicsPipelines ( - { shadowMapVS, shadowMapFS }, shadowMapNode->GetRenderpass(), newSubpass, + { shadowMapVS, shadowMapFS }, shadowMapNode->GetRenderpass(), shadowMapDrawSubpass, SHGraphicsPredefinedData::SystemType::BATCHING, SHGraphicsPredefinedData::GetShadowMapViState(), rasterState ); - shadowMapPipeline = tempLibrary.GetGraphicsPipeline({ shadowMapVS, shadowMapFS, newSubpass }); + shadowMapPipeline = tempLibrary.GetGraphicsPipeline({ shadowMapVS, shadowMapFS, shadowMapDrawSubpass }); } - newSubpass->SetCompanionSubpass(companionSubpass, shadowMapPipeline); // set companion subpass and pipeline + shadowMapDrawSubpass->SetCompanionSubpass(companionSubpass, shadowMapPipeline); // set companion subpass and pipeline - // add the shadow map to the lighting system - uint32_t const NEW_SHADOW_MAP_INDEX = lightingSubSystem->AddShadowMap(renderGraph->GetRenderGraphResource(shadowMapResourceName), EVENT_DATA->lightEntity); + // add the shadow map and the blurred version to the lighting system + uint32_t const NEW_SHADOW_MAP_INDEX = lightingSubSystem->AddShadowMap(renderGraph->GetRenderGraphResource(shadowMapBlurredResourceName), EVENT_DATA->lightEntity); auto nodeCompute = renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::DEFERRED_COMPOSITE_PASS.data())->GetNodeCompute(SHGraphicsConstants::RenderGraphEntityNames::DEFERRED_COMPOSITE_COMPUTE.data()); nodeCompute->ModifyWriteDescImageComputeResource(SHGraphicsConstants::DescriptorSetBindings::SHADOW_MAP_IMAGE_SAMPLER_DATA, lightingSubSystem->GetViewSamplerLayout(NEW_SHADOW_MAP_INDEX), NEW_SHADOW_MAP_INDEX); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h index 0b98f843..33227f8f 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h @@ -481,6 +481,7 @@ namespace SHADE Handle shadowMapFS; Handle trajectoryVS; Handle trajectoryFS; + Handle shadowMapBlurCS; // Fonts Handle testFont; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.cpp index cace495c..cd308487 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.cpp @@ -53,7 +53,8 @@ namespace SHADE SHVec4 transformedDir = SHMatrix::Transpose(viewMat) * SHVec4(lightData.direction[0], lightData.direction[1], lightData.direction[2], 0.0f); lightPtr->cullingMask = lightData.cullingMask; - lightPtr->direction = SHVec3 (transformedDir.x, transformedDir.y, transformedDir.z); + lightPtr->directionWorld = SHVec4 (lightData.direction.x, lightData.direction.y, lightData.direction.z, 1.0f); + lightPtr->direction = SHVec3(transformedDir.x, transformedDir.y, transformedDir.z); //lightPtr->direction = lightData.direction; lightPtr->diffuseColor = lightData.color; lightPtr->active = lightComp->isActive; @@ -601,14 +602,14 @@ namespace SHADE } - uint32_t SHLightingSubSystem::AddShadowMap(Handle newShadowMap, EntityID lightEntity) noexcept + uint32_t SHLightingSubSystem::AddShadowMap(Handle newShadowMapBlurred, EntityID lightEntity) noexcept { // Add to container of shadow maps shadowMapIndexing.emplace(lightEntity, static_cast (shadowMaps.size())); - shadowMaps.emplace_back(newShadowMap); + shadowMaps.emplace_back(newShadowMapBlurred); // Just use the image view stored in the resource - Handle const NEW_IMAGE_VIEW = newShadowMap->GetImageView(); + Handle const NEW_IMAGE_VIEW = newShadowMapBlurred->GetImageView(); // Prepare to write to descriptor shadowMapImageSamplers.emplace_back(NEW_IMAGE_VIEW, shadowMapSampler, vk::ImageLayout::eShaderReadOnlyOptimal); @@ -634,13 +635,13 @@ namespace SHADE // add to barriers shadowMapMemoryBarriers.push_back (vk::ImageMemoryBarrier { - .srcAccessMask = vk::AccessFlagBits::eColorAttachmentWrite | vk::AccessFlagBits::eColorAttachmentRead, + .srcAccessMask = vk::AccessFlagBits::eShaderWrite, .dstAccessMask = vk::AccessFlagBits::eShaderRead, - .oldLayout = vk::ImageLayout::eColorAttachmentOptimal, - .newLayout = vk::ImageLayout::eShaderReadOnlyOptimal, + .oldLayout = vk::ImageLayout::eGeneral, + .newLayout = vk::ImageLayout::eGeneral, .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, - .image = newShadowMap->GetImage()->GetVkImage(), + .image = newShadowMapBlurred->GetImage()->GetVkImage(), .subresourceRange = vk::ImageSubresourceRange { .aspectMask = vk::ImageAspectFlagBits::eColor, @@ -658,7 +659,7 @@ namespace SHADE void SHLightingSubSystem::PrepareShadowMapsForRead(Handle cmdBuffer) noexcept { // Issue barrier to transition shadow maps for reading in compute shader - cmdBuffer->PipelineBarrier(vk::PipelineStageFlagBits::eColorAttachmentOutput, vk::PipelineStageFlagBits::eComputeShader, {}, {}, {}, shadowMapMemoryBarriers); + cmdBuffer->PipelineBarrier(vk::PipelineStageFlagBits::eComputeShader, vk::PipelineStageFlagBits::eComputeShader, {}, {}, {}, shadowMapMemoryBarriers); } //void SHLightingSubSystem::HandleResize(Handle compute) noexcept diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.h b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.h index 69b00f2c..3613f762 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.h @@ -28,6 +28,9 @@ namespace SHADE // Represents how the data will be interpreted in GPU. we want to copy to a container of these before passing to GPU. struct SHDirectionalLightData { + //! Direction of the light + SHVec4 directionWorld; + //! Direction of the light SHVec3 direction; @@ -213,7 +216,7 @@ namespace SHADE void Run (SHMatrix const& viewMat, uint32_t frameIndex) noexcept; void Exit (void) noexcept; void BindDescSet (Handle cmdBuffer, uint32_t setIndex, uint32_t frameIndex) noexcept; - uint32_t AddShadowMap (Handle newShadowMap, EntityID lightEntity) noexcept; + uint32_t AddShadowMap (Handle newShadowMapBlurred, EntityID lightEntity) noexcept; void PrepareShadowMapsForRead (Handle cmdBuffer) noexcept; //void HandleResize (Handle compute) noexcept; //void RemoveShadowMap (uint32_t index) noexcept; diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp index 34bfe8cd..36d2e20a 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp @@ -798,6 +798,7 @@ namespace SHADE /***************************************************************************/ void SHRenderGraphNode::RuntimeStandaloneRegenerate(void) noexcept { + AddDummySubpassIfNeeded(); StandaloneConfigureAttDesc(false); ConfigureSubpasses(); CreateRenderpass(); From b6b2c75fc3b228bce3958e77e999fcbce72cb152 Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Tue, 7 Mar 2023 17:39:51 +0800 Subject: [PATCH 3/6] Implemented Shadows (f0kin finally) --- Assets/Shaders/ShinyHighlight_FS.glsl | 8 ++++-- Assets/Shaders/ShinyHighlight_FS.shshaderb | Bin 5397 -> 5733 bytes Assets/Shaders/ShinyHighlight_VS.glsl | 9 ++++--- Assets/Shaders/ShinyHighlight_VS.shshaderb | Bin 5705 -> 6141 bytes .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 16 ++++++------ .../src/Graphics/RenderGraph/SHSubpass.cpp | 23 ++++++++++-------- .../src/Graphics/RenderGraph/SHSubpass.h | 7 +++--- 7 files changed, 38 insertions(+), 25 deletions(-) diff --git a/Assets/Shaders/ShinyHighlight_FS.glsl b/Assets/Shaders/ShinyHighlight_FS.glsl index be26f866..18f979fe 100644 --- a/Assets/Shaders/ShinyHighlight_FS.glsl +++ b/Assets/Shaders/ShinyHighlight_FS.glsl @@ -32,10 +32,11 @@ layout(location = 0) in struct vec2 uv; // location = 1 vec4 normal; // location = 2 vec4 worldPos; // location = 3 + vec3 worldNormal; // location = 4 } In; // material stuff -layout(location = 4) flat in struct +layout(location = 5) flat in struct { int materialIndex; uint eid; @@ -72,10 +73,11 @@ void main() { position = In.vertPos; normals = In.normal; - albedo = texture(textures[nonuniformEXT(MatProp.data[In2.materialIndex].textureIndex)], In.uv); + albedo = vec4 (texture(textures[nonuniformEXT(MatProp.data[In2.materialIndex].textureIndex)], In.uv).xyz, 1.0f); worldSpacePosition = In.worldPos; outEntityID = In2.eid; + lightLayerIndices = uvec4 (In2.lightLayerIndex, 0, 0, 1); // float vpHeight = float (In2.screenSpacePos.y) - MatProp.data[In2.materialIndex].highlightPosition; // bring the frame of reference to the object's screen space pos @@ -100,4 +102,6 @@ void main() } else objectVFX = vec4(0.0f, 0.0f, 0.0f, 1.0f); + + objectVFX.a = 1.0f; } \ No newline at end of file diff --git a/Assets/Shaders/ShinyHighlight_FS.shshaderb b/Assets/Shaders/ShinyHighlight_FS.shshaderb index 572f3b31d0ed23942fb76dda3dfd28153ef4d70c..a3a6230df5e550a976d687e26fd3bab001c76575 100644 GIT binary patch literal 5733 zcmZ9O`*&2;6~`}RCV>zhR>WG{Gy#jYSgI6XMT0@YByE&vD4?|+FEcmEmC4-k&YcAM z0Fhd$wzieNpJLw?r4O`-wRZWFe?k9~u0GakSHGWg&rU9LV6Xk%-@VU1`|NYhoosk? zQ{YC=$}N3Cup;OW)&_seso<($rI^6!*EZ(*b+6x)?hjT4(^ChlV}}n^>ruOw#;q(# zt8ud)9gCZ@!J44g&96*OPi}8#_3b-vyM@&2f*!X5x!3DoNgA0C<0g(_$yUkD5+;mD z4oDuBR3&F67bP2%hj}Vos7KWX!8=M?3RVY|$?E7sd#dfI6{cYpRoio6JxZ&|k;kK2 z*1j@EE|pttgw5GbI2%=W?zp8D){ZLAD)O+sX4335v5`;;)RH{Tpk}6H*1Yfy%=hZm-Gh@pyL5`3Gdz+u4$TZEkyi+4Z}XwBsyJT>s1J z#<2b+0!g37#Z>mLM1FqM_aMFuO+Nd*8!+7@V_y_U{tjU>A zr~>xL+2^_1&gLG3jU!P#!Cww;lbuD!vQ8Sgyl}URyFbjP(xkOF%tEcz=Qz<8JHg$= z?$wzP&mQK~sD^~iSre!eKYPmN;@Z(>)Mg>h=1ys?6Qyz3U@^5NrV4t6k5Q)p4fgU0 zX{xM z%^j|G-jVCOh4>BAKi*f;$;O&loE@Lo>*9HDSF9J;T*KMdjC}1{*vRi;Ihd2Z&>D|u zrJ&}Q16_q6jT#{@fr84~$q8|q*W{f{7v?`JzL6|O>0~?~D+BYN7uRX2#Yb^9by)Q}9x0~cdq0((Lr5%;2sg<&an};+EM*LJRiC9gy%dL;%Kpzq}idkp3y_j6CdYk zKI5$aRNwuVg?%jJ++(RZ&%NJrd%1 zXVgL-v#Eta?1=O_hf5B#kFxiTNnhNU$5je=dm~RvO5y5>+Z#e6ZoxSB_&u~@`_kjK|s0Z8nbG4#~8`d21 zf;S0K>yVR@ZeIRd3pcD&;+(+77xlHu|3UBPjE7_oNs}9Xm$z9Tj(BP#A8TW?4{ZE{ zTIB|5<`RcSh#~ifq*q9YAvg9`&s`(?M&TiEZ}av|vKh?(ur%|FwQ=`Z+u}beOl?*> zZvp>x`bEA~np(+G9A;my$Q^PJ_W|LLOJlS4PH6@lxv_ayj6wf~sGs}@^LZP*twCYl z05-YqlBPyDa$)l>;ON6H=^+VYP}%O5CO14{{k%t*+VPVId&G0Bv)kjmuccs*Y}PP) zpD=?xTK^`5$;tdrdc4{D+1Gwa5Init`g=fDvHzd;HuDdAoY$S({C*LS{}E}{!p~j$ ztjBg2KPQ{moG%5~RnJi`^NvUuX4izR{z$k_!hUUkv%-H@0PDxX#Ii4J{n_IBgKhav zdk!1^j3fx&-Lp}VF9^{G?j_$5a#`FeA#n%}RtWaDGbU!_+{;8-8~ZO`4VyNZt|FI z0*^3ONVpFVYEG~8l!O?DaSsZ^5o_E-o@4HmPJ{KP9VR9S@N=i>AKzen*6)MD)XulU z`h7?ko_M|~*u?XV_>AM1_sYG0bcyeAzwy`>|Cli6W9LbHD0xgmt$a`F61XE?YSOG- zmBt62k)D-|sxy2m9(R0RH}TX?&yFtndfZ#VrWWqXyrlcCG(A76S`y)w#O?|{J5zE$ z;r%E5TB+xnvbj5L2^_UxXA<~-x)92174e>Ug1F#Ku7 zP}k=r@Nz>Nly9sUlN8Rj`{fDtZyeBf91P*QXIVX?Ub5$X*kRKoG^Pb z`)k6)*g9VqCI+7Q&q~8t{5OP)^S>#Z`PRR02@?a){O6_N=pT3W+mf@A;ywM2=WUJe z%4Xfmn)8D6_awx?|5G`CAkFxX?hU^0OW^pu0NYwW6z*Q@N8;dZtse_h<0Ze=PlSnq z|F`m4Ui3foE~w|H64otCh-XdedQqA|UBvuM@@ENkf$7IN>6au{cc&qW3 z!t~tE=vTtTzz^uwbFY3aSs^J&@Y~$q2(v%4e=A(f^*hF-$T_`PJEggne=9`VF6m;DoC_548?Za}{S%>Sc=eQcB9V}0`5-v8un z;w&GW<$Fz-eD>{sT^Oz?%)2NKA7}icG-t$FneS4Uj~LGEvh78bwp=SrE_^ocy~5OP_I1L=wcjV382B^3FV_o`3*RZvy84-+|3h5!Hn literal 5397 zcmZ9O`F9*g5y!{Tu4K#d5n?BVfFs$E1RP9aoC^~>axAX|imgP(4&fNayCZ4h(ad^w zRPHY*SFRJg1GRT~8FC}}NN7c{2B@y8B?owywpQ5lDwg{T!5VSeJt zxLJ0tjgd>`hG~?|ccb|@+_U?xcGNtnJZs6r_Od+dX31P$EQY7LQJTypaUuUO{>G6b zjp>Q7*=~oO@=O|sX_CcZD=D;6vJ|tH%j4scteJLO)quJps{5~NM;o=5#i)J9+}(St z{|CgblW!?XyGrfwuym(rPUp)#yuODgllcYb9}#YK$`${H9`^pa>vucvBxRDj{@2yZ z9g1NLDudZeaZ%3X9dR|saem#U)foDpsYOu=H|SzG>E*mgTTIj-H)lJgmDmes+?&&J znDdU(6LBlYUk~;Om+|ScTf}~TJ-A2QBT+e15nJ}Z!3;-kJeX|2RkkE?Y$IujSYXv;%S_1fY%o7FvyU1wR3cQTdjcD3_fT;DCk zZhQQEsx_23ENrS@b@yJRY+9)!|GoJQPg7Okt=Q{pk25o$b(K5z8}XGj4|M0|^kwPYF?@{G zJ2n*jPI!K`#+7(-@lCwu&LmCuXd3G0n0(tL3@~r7ig|}%>cr1G1oK@2^A5L57>3D7 zFDBJH-VkF)PpxqH;mBig^a*aQgk1MZ4@&q>5o2%5ay3*H+<=65-Wj!!$1t@ph}|c> z(b+X;ukK?Ym=OQRExou##hzTTYwov(Iduv7c`so00_Hb}Z|o+I`8~qV9;l!5W?22k z_4mT=jP=6e*e9Iz!|s9QV~=pQf9?eRU{D`;wI4NiFQ||B8}u)FOgUHw`$k#RKI){V zo7DSFg&Wf;aZcFASM^O=?^f^Uj7Nn>rO6Gy*JJ8|Bc58x$J*Ouu`gob(Fl1yD7{94 zpFCjhE!U1Sp1!`sl)2z-s8Vnzq0(XLY?HO4#T%7 z@@_eZ`+)4-(qPv9xHJQf++f}iW1D|3)K7kd`Md+((KgxKcQCo`m!?KIa)EgRaP;95 z(xVav{oN}~PWC~6`F&w6;t>4geNcLh1V4Gf`#gt#zqgqSJ|NASh7ZYRuxIP%lx%Vm z|0!>8m$v>MmR;@t5s!&~%-g*hdziOJJpQB7#)Ne_E4~TTflxofec-+0V;{ejrY1P@gL(6CVEV{!0qfnXy9UqOWWfDP z4Bs|l=^?*=^bw4Hq7R3C_*5T0+lSBhVSdZ2`7ie2OMUoqAHLFuuX;SLUC{dvOZYC_ zE_qOUpuZoH!0*$J$2_+9j|vmd+qd{#vf+v68v!PMzw|>A-i77AP4>9tA*YAjyLebO zZ;}{%)!2i=_-9ocb0;Kl?-|+T;LX{-AC(PH{9$P@@w~OqIDU0a?&7f(e!%@Mf|<)5;_Z#==JL+I z;P~EJyg}CEPJeO5H{k9WnDyxMmn8jtjyylE8+1Z;Q(}F_XZ;{|%ln`5YsH?+gz5X7 z1ddw3^AhTQQR{;jB*ehyK1bqtoAabFb1wKfCuPHNmuyZd8~z!^3`#Fb$OBKWLeE)G zGGREwxoqCx(|&$iHXL!x#|LM9D;$6Ao$H8$x4xCKt#A0K*VgOG#&2hLS~lmvJ>mOj zac5-XvweM8Hs3Ay=X|YSkxf2)#(hmTJl{_0=lcO?d7qNao(!LpO^mJcv}|I|Ntl0D z8qVUMkzJkttT6Mff6vJ#2A=unrQzrwcl8Cy1xfXue%|3mMBdR~&S zZe2n=Yf{(ur5V&k%*&ErNvI2(e(-&MMPfDnPyzL1{&SCsvwU!t?-#PkH>0z< zRr;3_xT-MkE$`!uIXBLTvohb?va3E~{;SIFm+(7Jt?ZMrR&t+m4oR=8*uxcjeZ?NB z*c)WC_9kiD!)DpU7`|RMc@4iuHo2`QH^?Ri-eR`MCb!|OvdL+4Zj?<7ynQ=vl1(mr qHt)T%son6+va4&qPna0^7kpoCkxedq_FZ_tZ1#okf7&mYUj83_h%5sD diff --git a/Assets/Shaders/ShinyHighlight_VS.glsl b/Assets/Shaders/ShinyHighlight_VS.glsl index c0268737..483af1f0 100644 --- a/Assets/Shaders/ShinyHighlight_VS.glsl +++ b/Assets/Shaders/ShinyHighlight_VS.glsl @@ -17,6 +17,7 @@ layout(location = 0) out struct vec2 uv; // location = 1 vec4 normal; // location = 2 vec4 worldPos; // location = 3 + vec3 worldNormal; // location = 4 } Out; @@ -36,7 +37,7 @@ struct GenericData }; // material stuff -layout(location = 4) out struct +layout(location = 5) out struct { int materialIndex; uint eid; @@ -76,11 +77,13 @@ void main() // uvs for texturing in fragment shader Out.uv = aUV; - mat3 transposeInv = mat3 (transpose(inverse(modelViewMat))); + mat3 mvTransInv = mat3 (transpose(inverse(modelViewMat))); + mat3 modelTransInv = mat3 (transpose(inverse(worldTransform))); // normals are also in view space - Out.normal.rgb = transposeInv * aNormal.rgb; + Out.normal.rgb = mvTransInv * aNormal.rgb; Out.normal.rgb = normalize (Out.normal.rgb); + Out.worldNormal = normalize (modelTransInv * aNormal); // Get center of object in world position vec4 worldPos = vec4(worldTransform[3][0], worldTransform[3][1], worldTransform[3][2], 1.0f); diff --git a/Assets/Shaders/ShinyHighlight_VS.shshaderb b/Assets/Shaders/ShinyHighlight_VS.shshaderb index 9818708504495b5706c860c5448aa90b2077dc57..95eac304277d9591e76c296a0c74bea47b4eb2ad 100644 GIT binary patch literal 6141 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 JKf19K{2w*kCO!ZF literal 5705 zcmZ9O`*&Pb6~}LrW>QKEluD@zHEje_OKTOVRisTHn6?HIY-oL;;W~4ZUYyK~Gn2H% z2L(mI7f?m;U7sk{_X}TjE&nQiaVGd0X?z(%gF4rZ)g{MB(CpQ-ITK->3^Onj6 za6NE|-QZ5J51arGgUjGG@OSV}a0LwWZ;1KdBwb52Q`7TPGc!}u_s!Qko%vq>d^4MG z=B;eLk$1CtKVQl8TUYVRTlMC0qv|k%N42gI)>zLPj#@IhDlet|tedCJ;)SUo&4k)1OYyXWfB!gxjk$a&gB>mS=xL|j?VrvY{WJK6&3)N#ZO1Y%(%??K2wz$A z@bbb!W^MLSo1@`{V0edKVqSc`##Mj!{;Ia-{A|`8G{_ihmUn22>tS8;?xo#Vec)tY&f4XSSD)0AUA@BD3WsHw>s(f49u=&Q-{pMT?c9r@TX6@_1F;?~+IK~GP z+}hQ*F#;Dp_Cuc=uHyJmmfRrD-c;k%jr0CRF1f4Y>{~TX-MHsL#K}e66g{IcasQW&veevz6JGA?Ls``mik9@up?XG7%-gk#JI)aNn+5g~-(Jy*#tb393 zTc}^$>B#5)q#}+*8)fl)Lo9n0>zl})O zG2R%VeGI?YllFT`-ToT43*DHFz@h(j%xi$W{_4ILIqjR6jny9Un~}9!*Bh8!-#zJn z6SFpX^QrsZ8gx7(Sus|WOZ8@g*~w{G=`lGDDkl#NlpgV`F?^;h?OMO}N5t;?LQ>u;Rv$~z15 z_y@o+&~6@e-=&=PyP3`D`D$19oyyq{*Vqq|#zL|-nex=2i&uW9=w3eI2b+`QRIaE_j_XwVLq{qRbFJ)W^LbOwoWZe!1kLr>~*g7w`CAnO!sP^xsOG zy#DHbkMuYHKT6rPwX6Gm(yqRh`AVtpqo?lA+z#vd4~)M<`ucuu1Fo;``Oj8#&(pt2 zwBL)}@5BwjZ^$9CY+}9rFsjAHNB=0CV{5F^9T7 zk>f4M=CJpXV+>h7a%@L7hu;%(sE+~dJDJ}OCV+Nxj5F^7@}ciR_MKlOM*BN}KJwep})k)b)#64Qi zh3?w=M6Jh=t#uOES9SfY&2PX5zzLxLH1qvH|F|FO`o!KIMD`pua6>(}4+3l60kqAP z=Y0}coBPu?2jmk($Ti2DR`#Q6>*u8wS+^&6+3T*PI_5!XPDxCLb6?1^#u$;BO6M2!_MinHYZ<4XT*S32an&Al z%DCu(esae3nEPNim;}~oAJ#E118w2Af*gL<6@F)twT0igil23a-+5$h@tz+;b`9gT z?Fa6w%dE{a+R6NBFab6LbB!~92FR;>W}gMdc_-CB2lSDToO0&8!2ATz|8WrYJz4UR z^Yf)o+=DNm%Lzx^1K*PO;3;5^z%%9h_#&LK+GG8vkzK!fFP=fy*I~{2$VJSv$i`If z#Fx;GiFcuoT*Q1C*%;3u-o#gsjTr*2qmNwd`>V*t%ia3HGM#d7%9{ z@Knitz2q-4dnaCI{uX!%Yy^H2Tx*p1+dx~VymQ|vxrqBNdc;j4N8I<2wME?bk>zH~ z8h(ImF8QeI60)^vi~jr&*}YcJ;Ya9~fW!XiBNs70MmDB;4nIM^1mYa@k&B-G6nW6o z!T0}X=yJkgoaf;huQ2}{YygwM8q|%^?wj}(m;lu`@#~Uz&2i-4fZZVe&iE~|KJxl_ zXMYFwfw&vLFFB@F?hhqrjp6sllC$P`&woNTUVrVr=Xj5QMs|ID+`|FpzktiYJK-MH L_4_Z~*bn{(aS`y8 diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index 54e5a1ff..999337ae 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -128,7 +128,7 @@ namespace SHADE SHFreetypeInstance::Init(); - //SHAssetManager::CompileAsset("../../Assets/Shaders/DeferredComposite_CS.glsl", false); + SHAssetManager::CompileAsset("../../Assets/Shaders/DeferredComposite_CS.glsl", false); //SHAssetManager::CompileAsset("../../Assets/Shaders/ShadowMap_FS.glsl", false); //SHAssetManager::CompileAsset("../../Assets/Shaders/ShadowMap_FS.glsl", false); //SHAssetManager::CompileAsset("../../Assets/Shaders/SSAO_CS.glsl", false); @@ -865,12 +865,13 @@ namespace SHADE // we need to wait for the device to finish using the graph first device->WaitIdle(); - auto const& EVENT_DATA = reinterpret_cast*>(eventPtr.get())->data; - auto* lightComp = SHComponentManager::GetComponent(EVENT_DATA->lightEntity); - std::string depthResourceName = "ShadowMap_Depth " + std::to_string(EVENT_DATA->lightEntity); - std::string shadowMapResourceName = "ShadowMap " + std::to_string(EVENT_DATA->lightEntity); + auto const& EVENT_DATA = reinterpret_cast*>(eventPtr.get())->data; + auto* lightComp = SHComponentManager::GetComponent(EVENT_DATA->lightEntity); + std::string depthResourceName = "ShadowMap_Depth " + std::to_string(EVENT_DATA->lightEntity); + std::string shadowMapResourceName = "ShadowMap " + std::to_string(EVENT_DATA->lightEntity); std::string shadowMapBlurredResourceName = "ShadowMap Blurred" + std::to_string(EVENT_DATA->lightEntity); - Handle companionSubpass = renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_PASS.data())->GetSubpass(SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_WRITE_SUBPASS); + Handle gBufferWriteSubpass = renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_PASS.data())->GetSubpass(SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_WRITE_SUBPASS); + Handle gBufferWriteVfxSubpass = renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_PASS.data())->GetSubpass(SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_WRITE_VFX_SUBPASS); if (EVENT_DATA->generateRenderer) { @@ -929,7 +930,8 @@ namespace SHADE ); shadowMapPipeline = tempLibrary.GetGraphicsPipeline({ shadowMapVS, shadowMapFS, shadowMapDrawSubpass }); } - shadowMapDrawSubpass->SetCompanionSubpass(companionSubpass, shadowMapPipeline); // set companion subpass and pipeline + shadowMapDrawSubpass->AddCompanionSubpass(gBufferWriteSubpass, shadowMapPipeline); // set companion subpass and pipeline + shadowMapDrawSubpass->AddCompanionSubpass(gBufferWriteVfxSubpass, shadowMapPipeline); // set companion subpass and pipeline // add the shadow map and the blurred version to the lighting system uint32_t const NEW_SHADOW_MAP_INDEX = lightingSubSystem->AddShadowMap(renderGraph->GetRenderGraphResource(shadowMapBlurredResourceName), EVENT_DATA->lightEntity); diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp index 14a5d864..db78c5aa 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp @@ -77,7 +77,7 @@ namespace SHADE , name { rhs.name } , viewport {rhs.viewport} , renderer {rhs.renderer} - , companionSubpass {rhs.companionSubpass} + , companionSubpasses {std::move (rhs.companionSubpasses)} , dummyPipelineLayout{rhs.dummyPipelineLayout} { @@ -115,7 +115,7 @@ namespace SHADE name = std::move(rhs.name); renderer = rhs.renderer; viewport = rhs.viewport; - companionSubpass = rhs.companionSubpass; + companionSubpasses = rhs.companionSubpasses; dummyPipelineLayout = rhs.dummyPipelineLayout; @@ -237,17 +237,19 @@ namespace SHADE BindInputDescriptorSets (commandBuffer, descMappings.at(SHPredefinedDescriptorTypes::RENDER_GRAPH_RESOURCE), frameIndex); - // If companion subpass is not a valid handle, render super batch normally - if (!companionSubpass.companion) + if (companionSubpasses.empty()) { // Draw all the batches superBatch->Draw(commandBuffer, frameIndex); } else { - // if not bind pipeline for companion and and execute draw command - commandBuffer->BindPipeline(companionSubpass.pipeline); - companionSubpass.companion->superBatch->Draw(commandBuffer, frameIndex, false); + for (auto& companion : companionSubpasses) + { + // if not bind pipeline for companion and and execute draw command + commandBuffer->BindPipeline(companion.pipeline); + companion.subpass->superBatch->Draw(commandBuffer, frameIndex, false); + } } } @@ -493,10 +495,11 @@ namespace SHADE subpassIndex = index; } - void SHSubpass::SetCompanionSubpass(Handle companion, Handle pipeline) noexcept + void SHSubpass::AddCompanionSubpass(Handle companion, Handle pipeline) noexcept { - companionSubpass.companion = companion; - companionSubpass.pipeline = pipeline; + companionSubpasses.push_back(CompanionSubpass{companion, pipeline}); + //companionSubpass.companion = companion; + //companionSubpass.pipeline = pipeline; } /***************************************************************************/ diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h index 1300ee2b..640ccb2d 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h @@ -33,7 +33,7 @@ namespace SHADE struct CompanionSubpass { // subpass whose data will be borrowed to draw - Handle companion; + Handle subpass; // Pipeline that will be used for all the draw calls from all batches of the companion subpass Handle pipeline; @@ -114,7 +114,8 @@ namespace SHADE //! Optional component to a companion subpass. If the subpass handle of this object //! is valid, the subpass will be drawn using this companion's data. - CompanionSubpass companionSubpass; + //CompanionSubpass companionSubpass; + std::vector companionSubpasses; private: /*-----------------------------------------------------------------------*/ @@ -165,7 +166,7 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* PUBLIC SETTERS AND GETTERS */ /*-----------------------------------------------------------------------*/ - void SetCompanionSubpass (Handle companion, Handle pipeline) noexcept; + void AddCompanionSubpass (Handle companion, Handle pipeline) noexcept; Handle GetParentNode(void) const noexcept; SHSubPassIndex GetIndex() const noexcept; From ff4c294313cf3bb9f1b09338af92283b93560f7a Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Tue, 7 Mar 2023 18:43:59 +0800 Subject: [PATCH 4/6] Added dynamic flags for render graph nodes and light comp shadow flags --- .../Inspector/SHEditorComponentView.hpp | 1 + .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 16 ---------------- .../MiddleEnd/Lights/SHLightComponent.cpp | 6 ++++++ .../MiddleEnd/Lights/SHLightComponent.h | 1 + .../MiddleEnd/Lights/SHLightingSubSystem.cpp | 2 +- .../src/Graphics/RenderGraph/SHRenderGraph.cpp | 6 +++++- .../Graphics/RenderGraph/SHRenderGraphNode.cpp | 18 +++++++++++++++++- .../Graphics/RenderGraph/SHRenderGraphNode.h | 13 ++++++++++++- 8 files changed, 43 insertions(+), 20 deletions(-) diff --git a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp index 8adb45b5..9ebd47bc 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp @@ -470,6 +470,7 @@ namespace SHADE SHEditorWidgets::DragVec3("Direction", { "X", "Y", "Z" }, [component]() {return component->GetDirection(); }, [component](SHVec3 const& vec) {component->SetDirection(vec); }); SHEditorWidgets::ColorPicker("Color", [component]() {return component->GetColor(); }, [component](SHVec4 const& rgba) {component->SetColor(rgba); }); SHEditorWidgets::DragFloat("Strength", [component]() {return component->GetStrength(); }, [component](float const& value) {component->SetStrength(value); }); + SHEditorWidgets::CheckBox("Casting Shadows", [comp = component]() {return comp->GetEnableShadow(); }, [comp = component](bool b) {comp->SetEnableShadow(b);}); } else { diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index 999337ae..69b4503c 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -672,22 +672,6 @@ namespace SHADE #endif } - static bool shadowAdded = false; - - if (shadowAdded == false && SHInputManager::GetKey(SHInputManager::SH_KEYCODE::B)) - { - shadowAdded = true; - auto& lightComps = SHComponentManager::GetDense(); - if (lightComps.size() > 2) - { - lightComps[2].SetEnableShadow(true); - } - for (auto& comp : lightComps) - { - comp.SetEnableShadow(true); - } - } - renderGraph->Begin(frameIndex); auto cmdBuffer = renderGraph->GetCommandBuffer(frameIndex); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightComponent.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightComponent.cpp index 6943ec09..61552614 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightComponent.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightComponent.cpp @@ -190,6 +190,11 @@ namespace SHADE return renderer; } + bool SHLightComponent::GetEnableShadow(void) const noexcept + { + return lightData.castShadows; + } + } RTTR_REGISTRATION @@ -212,5 +217,6 @@ RTTR_REGISTRATION .property("Color", &SHLightComponent::GetColor, &SHLightComponent::SetColor) .property("Layer", &SHLightComponent::GetCullingMask, &SHLightComponent::SetCullingMask) .property("Strength", &SHLightComponent::GetStrength, &SHLightComponent::SetStrength) + .property("Casting Shadows", &SHLightComponent::GetEnableShadow, &SHLightComponent::SetEnableShadow) ; } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightComponent.h b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightComponent.h index 4974f3f5..a90d23b0 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightComponent.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightComponent.h @@ -69,6 +69,7 @@ namespace SHADE //uint32_t GetIndexInBuffer (void) const noexcept; float GetStrength (void) const noexcept; Handle GetRenderer (void) const noexcept; + bool GetEnableShadow (void) const noexcept; RTTR_ENABLE() }; } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.cpp index cd308487..f89582fc 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.cpp @@ -526,7 +526,7 @@ namespace SHADE if (auto renderer = light.GetRenderer()) { //SHMatrix orthoMatrix = SHMatrix::OrthographicRH() - renderer->UpdateDataManual(frameIndex, GetViewMatrix(&light), SHMatrix::OrthographicLH(12.0f, 12.0f, 1.0f, 80.0f)); + renderer->UpdateDataManual(frameIndex, GetViewMatrix(&light), SHMatrix::OrthographicLH(15.0f, 15.0f, 1.0f, 80.0f)); } auto enumValue = SHUtilities::ConvertEnum(light.GetLightData().type); diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp index e4e6889c..04d4af0b 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp @@ -479,7 +479,7 @@ namespace SHADE // get target node auto targetNode = nodes.begin() + nodeIndexing.at(nodeToAddAfter); - auto node = nodes.insert(targetNode, renderGraphStorage->resourceHub->Create(nodeName, renderGraphStorage, std::move(descInitParams), std::vector>())); + auto node = nodes.insert(targetNode, renderGraphStorage->resourceHub->Create(nodeName, renderGraphStorage, std::move(descInitParams), std::vector>(), true)); ReindexNodes (); return *node; @@ -583,6 +583,10 @@ namespace SHADE for (auto& node : nodes) { + // if node is dynamic check for active flag + if ((node->isDynamic) ? !node->dynamicIsActive : false) + continue; + if (node->renderpass) { // bind static global data diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp index 36d2e20a..2f316c79 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp @@ -292,7 +292,7 @@ namespace SHADE */ /***************************************************************************/ - SHRenderGraphNode::SHRenderGraphNode(std::string nodeName, Handle renderGraphStorage, std::vector attDescInitParams, std::vector> predecessors) noexcept + SHRenderGraphNode::SHRenderGraphNode(std::string nodeName, Handle renderGraphStorage, std::vector attDescInitParams, std::vector> predecessors, bool inIsDynamic) noexcept : graphStorage{ renderGraphStorage} , renderpass{} , framebuffers{} @@ -305,6 +305,8 @@ namespace SHADE , configured{ false } , nodeComputes{} , name { std::move(nodeName) } + , dynamicIsActive {true} // default set to true + , isDynamic{inIsDynamic} { // pipeline library initialization pipelineLibrary.Init(graphStorage->logicalDevice); @@ -368,6 +370,8 @@ namespace SHADE , nodeComputes{ std::move(rhs.nodeComputes) } , name { std::move(rhs.name) } , ISelfHandle{std::move(rhs)} + , dynamicIsActive {rhs.dynamicIsActive} + , isDynamic {rhs.isDynamic} { rhs.renderpass = {}; @@ -393,6 +397,8 @@ namespace SHADE spDeps = std::move(rhs.spDeps); nodeComputes = std::move(rhs.nodeComputes); name = std::move(rhs.name); + dynamicIsActive = rhs.dynamicIsActive; + isDynamic = rhs.isDynamic; rhs.renderpass = {}; @@ -805,6 +811,11 @@ namespace SHADE CreateFramebuffer(); } + void SHRenderGraphNode::SetDynamicActive(bool active) noexcept + { + dynamicIsActive = active; + } + /***************************************************************************/ /*! @@ -850,4 +861,9 @@ namespace SHADE return {}; } + bool SHRenderGraphNode::GetDynamicActive(void) const noexcept + { + return dynamicIsActive; + } + } \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h index b070b8fa..2877fdee 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h @@ -80,6 +80,13 @@ namespace SHADE //! Whether or not the node has been configured already or not bool configured; + //! Whether or not the rendergraph should be executed. Should ONLY be used for dynamic + //! nodes that are independent from other nodes. + bool dynamicIsActive; + + //! True if the function is dynamic + bool isDynamic; + //! Manages batching for this RenderPass SHBatcher batcher; @@ -101,7 +108,7 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* CTORS AND DTORS */ /*-----------------------------------------------------------------------*/ - SHRenderGraphNode(std::string nodeName, Handle renderGraphStorage, std::vector attDescInitParams, std::vector> predecessors) noexcept; + SHRenderGraphNode(std::string nodeName, Handle renderGraphStorage, std::vector attDescInitParams, std::vector> predecessors, bool inIsDynamic = false) noexcept; SHRenderGraphNode(SHRenderGraphNode&& rhs) noexcept; SHRenderGraphNode& operator= (SHRenderGraphNode&& rhs) noexcept; @@ -123,11 +130,15 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* SETTERS AND GETTERS */ /*-----------------------------------------------------------------------*/ + void SetDynamicActive(bool active) noexcept; + Handle GetRenderpass(void) const noexcept; Handle GetSubpass(std::string_view subpassName) const noexcept; Handle GetResource (uint32_t resourceIndex) const noexcept; std::vector> const& GetResources (void) const noexcept; Handle GetNodeCompute (std::string nodeComputeName) const noexcept; + bool GetDynamicActive (void) const noexcept; + friend class SHRenderGraph; }; From 64e60a511438f07bcc4ee6c1115be64ef6b0a6cc Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Wed, 8 Mar 2023 09:38:07 +0800 Subject: [PATCH 5/6] Added editor functionality for lights to enable shadows --- SHADE_Engine/src/Events/SHEventDefines.h | 1 + .../src/Graphics/Events/SHGraphicsEvents.h | 13 +- .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 169 +++++++++++------- .../MiddleEnd/Interface/SHGraphicsSystem.h | 1 + .../MiddleEnd/Lights/SHLightComponent.cpp | 19 +- .../MiddleEnd/Lights/SHLightComponent.h | 2 + .../MiddleEnd/Lights/SHLightingSubSystem.cpp | 110 +++++++----- .../MiddleEnd/Lights/SHLightingSubSystem.h | 22 +-- .../Graphics/RenderGraph/SHRenderGraph.cpp | 22 ++- .../src/Graphics/RenderGraph/SHRenderGraph.h | 1 + .../RenderGraph/SHRenderGraphNode.cpp | 16 ++ .../Graphics/RenderGraph/SHRenderGraphNode.h | 11 +- .../src/Graphics/RenderGraph/SHSubpass.cpp | 35 +++- .../src/Graphics/RenderGraph/SHSubpass.h | 1 + 14 files changed, 290 insertions(+), 133 deletions(-) diff --git a/SHADE_Engine/src/Events/SHEventDefines.h b/SHADE_Engine/src/Events/SHEventDefines.h index a7447be0..e03dfd82 100644 --- a/SHADE_Engine/src/Events/SHEventDefines.h +++ b/SHADE_Engine/src/Events/SHEventDefines.h @@ -30,4 +30,5 @@ constexpr SHEventIdentifier SH_BUTTON_RELEASE_EVENT { 21 }; constexpr SHEventIdentifier SH_BUTTON_HOVER_ENTER_EVENT { 22 }; constexpr SHEventIdentifier SH_BUTTON_HOVER_EXIT_EVENT { 23 }; constexpr SHEventIdentifier SH_ASSET_COMPILE_EVENT { 24 }; +constexpr SHEventIdentifier SH_LIGHT_DELETE_EVENT { 25 }; diff --git a/SHADE_Engine/src/Graphics/Events/SHGraphicsEvents.h b/SHADE_Engine/src/Graphics/Events/SHGraphicsEvents.h index 51cd7aa2..e8f00c8a 100644 --- a/SHADE_Engine/src/Graphics/Events/SHGraphicsEvents.h +++ b/SHADE_Engine/src/Graphics/Events/SHGraphicsEvents.h @@ -6,13 +6,16 @@ namespace SHADE { - struct SHLightEnableShadowEvent + struct SHLightShadowEvent { //! We need to get the light component and initialize the relevant variables. EntityID lightEntity; //! Generate a renderer for the light component - bool generateRenderer; + bool firstEnable; + + //! True when light is set enable shadow + bool enableShadow; }; struct SHWindowResizeEvent @@ -23,4 +26,10 @@ namespace SHADE // New height when window resizes uint32_t resizeHeight; }; + + struct SHDeleteLightEvent + { + //! Entity of the light we are deleting + EntityID lightEntity; + }; } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index 69b4503c..22f0423d 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -537,12 +537,21 @@ namespace SHADE ReceiverPtr lightEnableShadowReceivePtr = std::dynamic_pointer_cast(lightEnableShadowReceiver); SHEventManager::SubscribeTo(SH_GRAPHICS_LIGHT_ENABLE_SHADOW_EVENT, lightEnableShadowReceivePtr); + std::shared_ptr> lightDeleteEvent + { + std::make_shared>(this, &SHGraphicsSystem::ReceiveLightDeleteEvent) + }; + ReceiverPtr lightDeleteReceivePtr = std::dynamic_pointer_cast(lightDeleteEvent); + SHEventManager::SubscribeTo(SH_ASSET_COMPILE_EVENT, lightDeleteReceivePtr); + + std::shared_ptr> compileAssetReceiever { std::make_shared>(this, &SHGraphicsSystem::ReceiveCompileAssetEvent) }; ReceiverPtr compileAssetReceivePtr = std::dynamic_pointer_cast(compileAssetReceiever); SHEventManager::SubscribeTo(SH_ASSET_COMPILE_EVENT, compileAssetReceivePtr); + } void SHGraphicsSystem::InitGenericDataAndTexturesDescSet(void) noexcept @@ -846,10 +855,7 @@ namespace SHADE SHEventHandle SHGraphicsSystem::ReceiveLightEnableShadowEvent(SHEventPtr eventPtr) noexcept { - // we need to wait for the device to finish using the graph first - device->WaitIdle(); - - auto const& EVENT_DATA = reinterpret_cast*>(eventPtr.get())->data; + auto const& EVENT_DATA = reinterpret_cast*>(eventPtr.get())->data; auto* lightComp = SHComponentManager::GetComponent(EVENT_DATA->lightEntity); std::string depthResourceName = "ShadowMap_Depth " + std::to_string(EVENT_DATA->lightEntity); std::string shadowMapResourceName = "ShadowMap " + std::to_string(EVENT_DATA->lightEntity); @@ -857,71 +863,112 @@ namespace SHADE Handle gBufferWriteSubpass = renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_PASS.data())->GetSubpass(SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_WRITE_SUBPASS); Handle gBufferWriteVfxSubpass = renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_PASS.data())->GetSubpass(SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_WRITE_VFX_SUBPASS); - if (EVENT_DATA->generateRenderer) + if (EVENT_DATA->enableShadow) { - // Create new renderer for the light component and give it to the light component - Handle newRenderer = resourceManager.Create(device, swapchain->GetNumImages(), descPool, SHRenderer::PROJECTION_TYPE::ORTHOGRAPHIC); - lightComp->SetRenderer (newRenderer); + // When the light first enables shadow rendering, we need to prepare the relevant objects to render shadows; namely renderpasses and subpasses, pipelines and descriptor sets + if (EVENT_DATA->firstEnable) + { + // we need to wait for the device to finish using the graph first + device->WaitIdle(); - // assign shadow map index to light component - lightComp->SetShadowMapIndex (lightingSubSystem->GetNumShadowMaps()); + // Create new renderer for the light component and give it to the light component + Handle newRenderer = resourceManager.Create(device, swapchain->GetNumImages(), descPool, SHRenderer::PROJECTION_TYPE::ORTHOGRAPHIC); + lightComp->SetRenderer(newRenderer); + + // assign shadow map index to light component + lightComp->SetShadowMapIndex(lightingSubSystem->GetNumShadowMaps()); + + + // Add the shadow map resource to the graph + renderGraph->AddResource(depthResourceName, { SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH }, false, SHLightingSubSystem::SHADOW_MAP_WIDTH, SHLightingSubSystem::SHADOW_MAP_HEIGHT, vk::Format::eD32Sfloat); + renderGraph->AddResource(shadowMapResourceName, { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, false, SHLightingSubSystem::SHADOW_MAP_WIDTH, SHLightingSubSystem::SHADOW_MAP_HEIGHT, vk::Format::eR32G32B32A32Sfloat); + renderGraph->AddResource(shadowMapBlurredResourceName, { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, false, SHLightingSubSystem::SHADOW_MAP_WIDTH, SHLightingSubSystem::SHADOW_MAP_HEIGHT, vk::Format::eR32G32B32A32Sfloat); + + + + // link resource to node. This means linking the resource and regenerating the node's renderpass and framebuffer. + auto shadowMapNode = renderGraph->AddNodeAfter(SHGraphicsConstants::RenderGraphEntityNames::SHADOW_MAP_PASS.data() + shadowMapResourceName, { depthResourceName.c_str(), shadowMapResourceName.c_str(), shadowMapBlurredResourceName.c_str() }, SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_PASS.data()); + + // Add a subpass to render to that shadow map + auto shadowMapDrawSubpass = shadowMapNode->RuntimeAddSubpass(shadowMapResourceName + " Subpass", shadowMapViewport, lightComp->GetRenderer()); + shadowMapDrawSubpass->AddColorOutput(shadowMapResourceName); + shadowMapDrawSubpass->AddDepthOutput(depthResourceName, SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH); + + // add compute pass to blur shadow ma + shadowMapNode->AddNodeCompute(SHGraphicsConstants::RenderGraphEntityNames::SHADOW_MAP_PASS.data() + shadowMapResourceName, shadowMapBlurCS, { shadowMapResourceName.c_str(), shadowMapBlurredResourceName.c_str() }); + + // regenerate the node + shadowMapNode->RuntimeStandaloneRegenerate(); + + // Create pipeline from new renderpass and subpass if it's not created yet + if (!shadowMapPipeline) + { + SHPipelineLibrary tempLibrary{}; + Handle rgNode = renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::SHADOW_MAP_PASS.data()); + + SHRasterizationState rasterState{}; + rasterState.cull_mode = vk::CullModeFlagBits::eBack; + + tempLibrary.Init(device); + tempLibrary.CreateGraphicsPipelines + ( + { shadowMapVS, shadowMapFS }, shadowMapNode->GetRenderpass(), shadowMapDrawSubpass, + SHGraphicsPredefinedData::SystemType::BATCHING, + SHGraphicsPredefinedData::GetShadowMapViState(), rasterState + ); + shadowMapPipeline = tempLibrary.GetGraphicsPipeline({ shadowMapVS, shadowMapFS, shadowMapDrawSubpass }); + } + shadowMapDrawSubpass->AddCompanionSubpass(gBufferWriteSubpass, shadowMapPipeline); // set companion subpass and pipeline + shadowMapDrawSubpass->AddCompanionSubpass(gBufferWriteVfxSubpass, shadowMapPipeline); // set companion subpass and pipeline + + // add the shadow map and the blurred version to the lighting system + uint32_t const NEW_SHADOW_MAP_INDEX = lightingSubSystem->AddShadowMap(renderGraph->GetRenderGraphResource(shadowMapBlurredResourceName), EVENT_DATA->lightEntity); + + // Get deferred composite node compute and modify descriptor set + auto nodeCompute = renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::DEFERRED_COMPOSITE_PASS.data())->GetNodeCompute(SHGraphicsConstants::RenderGraphEntityNames::DEFERRED_COMPOSITE_COMPUTE.data()); + nodeCompute->ModifyWriteDescImageComputeResource(SHGraphicsConstants::DescriptorSetBindings::SHADOW_MAP_IMAGE_SAMPLER_DATA, lightingSubSystem->GetViewSamplerLayout(NEW_SHADOW_MAP_INDEX), NEW_SHADOW_MAP_INDEX); + } + else + { + // get the shadow map node + renderGraph->GetNode (SHGraphicsConstants::RenderGraphEntityNames::SHADOW_MAP_PASS.data() + shadowMapResourceName)->SetDynamicActive(true); + } + } + else + { + // get the shadow map node + renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::SHADOW_MAP_PASS.data() + shadowMapResourceName)->SetDynamicActive(false); } + return eventPtr->handle; + } - // Add the shadow map resource to the graph - renderGraph->AddResource(depthResourceName, {SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH}, false, SHLightingSubSystem::SHADOW_MAP_WIDTH, SHLightingSubSystem::SHADOW_MAP_HEIGHT, vk::Format::eD32Sfloat); - renderGraph->AddResource(shadowMapResourceName, { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, false, SHLightingSubSystem::SHADOW_MAP_WIDTH, SHLightingSubSystem::SHADOW_MAP_HEIGHT, vk::Format::eR32G32B32A32Sfloat); - renderGraph->AddResource(shadowMapBlurredResourceName, { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, false, SHLightingSubSystem::SHADOW_MAP_WIDTH, SHLightingSubSystem::SHADOW_MAP_HEIGHT, vk::Format::eR32G32B32A32Sfloat); + SHEventHandle SHGraphicsSystem::ReceiveLightDeleteEvent(SHEventPtr eventPtr) noexcept + { + // we need to wait for the device to finish using the graph first + device->WaitIdle(); - - - // link resource to node. This means linking the resource and regenerating the node's renderpass and framebuffer. - auto shadowMapNode = renderGraph->AddNodeAfter(SHGraphicsConstants::RenderGraphEntityNames::SHADOW_MAP_PASS.data() + shadowMapResourceName, {depthResourceName.c_str(), shadowMapResourceName.c_str(), shadowMapBlurredResourceName.c_str()}, SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_PASS.data()); - - // Add a subpass to render to that shadow map - auto shadowMapDrawSubpass = shadowMapNode->RuntimeAddSubpass(shadowMapResourceName + " Subpass", shadowMapViewport, lightComp->GetRenderer()); - shadowMapDrawSubpass->AddColorOutput(shadowMapResourceName); - shadowMapDrawSubpass->AddDepthOutput(depthResourceName, SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH); - - // add dummy subpass to transition the shadow map images for compute shader usage - //auto dummySubpass = shadowMapNode->RuntimeAddSubpass(shadowMapResourceName + "Dummy", {}, {}); - //dummySubpass->AddGeneralColorOutput(shadowMapResourceName); - //dummySubpass->AddGeneralColorOutput(shadowMapBlurredResourceName); - - // add compute pass to blur shadow ma - shadowMapNode->AddNodeCompute(SHGraphicsConstants::RenderGraphEntityNames::SHADOW_MAP_PASS.data() + shadowMapResourceName, shadowMapBlurCS, { shadowMapResourceName.c_str(), shadowMapBlurredResourceName.c_str() }); - //shadowMapNode->AddNodeCompute(SHGraphicsConstants::RenderGraphEntityNames::SHADOW_MAP_PASS.data() + shadowMapResourceName, shadowMapBlurCS, { shadowMapBlurredResourceName.c_str(), shadowMapResourceName.c_str() }); - //shadowMapNode->AddNodeCompute(SHGraphicsConstants::RenderGraphEntityNames::SHADOW_MAP_PASS.data() + shadowMapResourceName, shadowMapBlurCS, { shadowMapResourceName.c_str(), shadowMapBlurredResourceName.c_str() }); - - // regenerate the node - shadowMapNode->RuntimeStandaloneRegenerate(); - - // Create pipeline from new renderpass and subpass if it's not created yet - if (!shadowMapPipeline) - { - SHPipelineLibrary tempLibrary{}; - Handle rgNode = renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::SHADOW_MAP_PASS.data()); - - SHRasterizationState rasterState{}; - rasterState.cull_mode = vk::CullModeFlagBits::eBack; - - tempLibrary.Init(device); - tempLibrary.CreateGraphicsPipelines - ( - { shadowMapVS, shadowMapFS }, shadowMapNode->GetRenderpass(), shadowMapDrawSubpass, - SHGraphicsPredefinedData::SystemType::BATCHING, - SHGraphicsPredefinedData::GetShadowMapViState(), rasterState - ); - shadowMapPipeline = tempLibrary.GetGraphicsPipeline({ shadowMapVS, shadowMapFS, shadowMapDrawSubpass }); - } - shadowMapDrawSubpass->AddCompanionSubpass(gBufferWriteSubpass, shadowMapPipeline); // set companion subpass and pipeline - shadowMapDrawSubpass->AddCompanionSubpass(gBufferWriteVfxSubpass, shadowMapPipeline); // set companion subpass and pipeline + auto const& EVENT_DATA = reinterpret_cast*>(eventPtr.get())->data; + auto* lightComp = SHComponentManager::GetComponent(EVENT_DATA->lightEntity); - // add the shadow map and the blurred version to the lighting system - uint32_t const NEW_SHADOW_MAP_INDEX = lightingSubSystem->AddShadowMap(renderGraph->GetRenderGraphResource(shadowMapBlurredResourceName), EVENT_DATA->lightEntity); + if (lightComp && lightComp->GetShadowMapIndex()) + { + std::string depthResourceName = "ShadowMap_Depth " + std::to_string(EVENT_DATA->lightEntity); + std::string shadowMapResourceName = "ShadowMap " + std::to_string(EVENT_DATA->lightEntity); + std::string shadowMapBlurredResourceName = "ShadowMap Blurred" + std::to_string(EVENT_DATA->lightEntity); + + // Remove render graph node + renderGraph->RemoveNode(SHGraphicsConstants::RenderGraphEntityNames::SHADOW_MAP_PASS.data() + shadowMapResourceName); + + // Remove render graph resource + renderGraph->RemoveResource(depthResourceName); + renderGraph->RemoveResource(shadowMapResourceName); + renderGraph->RemoveResource(shadowMapBlurredResourceName); + + // Register light component shadow map index into light system as recyclable + lightingSubSystem->RemoveShadowMap (EVENT_DATA->lightEntity); + } - auto nodeCompute = renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::DEFERRED_COMPOSITE_PASS.data())->GetNodeCompute(SHGraphicsConstants::RenderGraphEntityNames::DEFERRED_COMPOSITE_COMPUTE.data()); - nodeCompute->ModifyWriteDescImageComputeResource(SHGraphicsConstants::DescriptorSetBindings::SHADOW_MAP_IMAGE_SAMPLER_DATA, lightingSubSystem->GetViewSamplerLayout(NEW_SHADOW_MAP_INDEX), NEW_SHADOW_MAP_INDEX); return eventPtr->handle; } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h index 33227f8f..68752a6e 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h @@ -182,6 +182,7 @@ namespace SHADE /* Light functions */ /*-----------------------------------------------------------------------*/ SHEventHandle ReceiveLightEnableShadowEvent (SHEventPtr eventPtr) noexcept; + SHEventHandle ReceiveLightDeleteEvent (SHEventPtr eventPtr) noexcept; /*-----------------------------------------------------------------------*/ /* Asset Events */ diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightComponent.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightComponent.cpp index 61552614..5e95c6ad 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightComponent.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightComponent.cpp @@ -113,15 +113,21 @@ namespace SHADE lightData.castShadows = flag; // If the flag is true - if (flag && lightData.shadowMapIndex == SHLightData::INVALID_SHADOW_MAP_INDEX) + if (flag) { // Create new event and broadcast it - SHLightEnableShadowEvent newEvent; + SHLightShadowEvent newEvent; newEvent.lightEntity = GetEID(); - newEvent.generateRenderer = static_cast(!renderer); - SHEventManager::BroadcastEvent(newEvent, SH_GRAPHICS_LIGHT_ENABLE_SHADOW_EVENT); + // If shadow map index is invalid, that means light is enabling shadow for the first time. + newEvent.firstEnable = (lightData.shadowMapIndex == SHLightData::INVALID_SHADOW_MAP_INDEX); + + // pass the flag to the event + newEvent.enableShadow = flag; + + SHEventManager::BroadcastEvent(newEvent, SH_GRAPHICS_LIGHT_ENABLE_SHADOW_EVENT); } + } void SHLightComponent::SetRenderer(Handle newRenderer) noexcept @@ -195,6 +201,11 @@ namespace SHADE return lightData.castShadows; } + uint32_t SHLightComponent::GetShadowMapIndex(void) const noexcept + { + return lightData.shadowMapIndex; + } + } RTTR_REGISTRATION diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightComponent.h b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightComponent.h index a90d23b0..a24b5ede 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightComponent.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightComponent.h @@ -70,6 +70,8 @@ namespace SHADE float GetStrength (void) const noexcept; Handle GetRenderer (void) const noexcept; bool GetEnableShadow (void) const noexcept; + uint32_t GetShadowMapIndex (void) const noexcept; + RTTR_ENABLE() }; } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.cpp index f89582fc..27685d69 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.cpp @@ -599,39 +599,15 @@ namespace SHADE { //Bind descriptor set(We bind at an offset because the buffer holds NUM_FRAME_BUFFERS sets of data). cmdBuffer->BindDescriptorSet(lightingDataDescSet, SH_PIPELINE_TYPE::COMPUTE, setIndex, { dynamicOffsets[frameIndex] }); - } uint32_t SHLightingSubSystem::AddShadowMap(Handle newShadowMapBlurred, EntityID lightEntity) noexcept { - // Add to container of shadow maps - shadowMapIndexing.emplace(lightEntity, static_cast (shadowMaps.size())); - shadowMaps.emplace_back(newShadowMapBlurred); + uint32_t usedIndex = 0; // Just use the image view stored in the resource Handle const NEW_IMAGE_VIEW = newShadowMapBlurred->GetImageView(); - // Prepare to write to descriptor - shadowMapImageSamplers.emplace_back(NEW_IMAGE_VIEW, shadowMapSampler, vk::ImageLayout::eShaderReadOnlyOptimal); - - // Update descriptor set - //static constexpr uint32_t SHADOW_MAP_DESC_SET_INDEX = 0; - //uint32_t const SHADOW_MAP_DESC_ARRAY_INDEX = static_cast(shadowMapImageSamplers.size()) - 1u; - //shadowMapDescriptorSet->ModifyWriteDescImage - //( - // SHADOW_MAP_DESC_SET_INDEX, - // SHGraphicsConstants::DescriptorSetBindings::SHADOW_MAP_IMAGE_SAMPLER_DATA, - // shadowMapImageSamplers[SHADOW_MAP_DESC_ARRAY_INDEX], - // SHADOW_MAP_DESC_ARRAY_INDEX - //); - - //// TODO: Definitely can be optimized by writing a function that modifies a specific descriptor in the array - //shadowMapDescriptorSet->UpdateDescriptorSetImages - //( - // SHADOW_MAP_DESC_SET_INDEX, - // SHGraphicsConstants::DescriptorSetBindings::SHADOW_MAP_IMAGE_SAMPLER_DATA - //); - // add to barriers shadowMapMemoryBarriers.push_back (vk::ImageMemoryBarrier { @@ -652,8 +628,68 @@ namespace SHADE } }); + if (recyclableIndices.empty()) + { + shadowMaps.emplace_back(newShadowMapBlurred); + + // Prepare to write to descriptor + shadowMapImageSamplers.emplace_back(NEW_IMAGE_VIEW, shadowMapSampler, vk::ImageLayout::eShaderReadOnlyOptimal); + + // Add to container of shadow maps + shadowMapIndexing.emplace(lightEntity, static_cast (shadowMaps.size())); + + usedIndex = static_cast(shadowMapImageSamplers.size()) - 1u; + } + else + { + uint32_t usedIndex = recyclableIndices.top(); + recyclableIndices.pop(); + + // Recycle the slot in the vector of shadow maps + shadowMaps[usedIndex] = newShadowMapBlurred; + + // register indexing for shadow maps + shadowMapIndexing.emplace(lightEntity, usedIndex); + + // Recycle the slot in the vector of image view, samplers and layout + shadowMapImageSamplers[usedIndex] = std::make_tuple(NEW_IMAGE_VIEW, shadowMapSampler, vk::ImageLayout::eShaderReadOnlyOptimal); + } + + // return new index of shadow map - return static_cast(shadowMapImageSamplers.size()) - 1u; + return usedIndex; + } + + void SHLightingSubSystem::RemoveShadowMap(EntityID lightEntity) noexcept + { + auto* lightComp = SHComponentManager::GetComponent(lightEntity); + + if (lightComp && shadowMapIndexing.contains(lightEntity)) + { + uint32_t shadowMapIndex = shadowMapIndexing[lightEntity]; + + // Recycle the shadow map index used by the component + RecycleShadowMapIndex(lightComp); + + // Not removed from container, can recycle + shadowMaps[shadowMapIndex] = {}; + + // Not removed from container, can recycle + shadowMapImageSamplers[shadowMapIndex] = {}; + + // Remove from barriers + shadowMapMemoryBarriers.erase(shadowMapMemoryBarriers.begin() + shadowMapIndex); + + // remove from map for indexing + shadowMapIndexing.erase(lightEntity); + } + } + + void SHLightingSubSystem::RecycleShadowMapIndex(SHLightComponent* lightComp) noexcept + { + // if index is recyclable, recycle it + if (lightComp && lightComp->GetShadowMapIndex() != SHLightData::INVALID_SHADOW_MAP_INDEX) + recyclableIndices.push (lightComp->GetShadowMapIndex()); } void SHLightingSubSystem::PrepareShadowMapsForRead(Handle cmdBuffer) noexcept @@ -662,28 +698,6 @@ namespace SHADE cmdBuffer->PipelineBarrier(vk::PipelineStageFlagBits::eComputeShader, vk::PipelineStageFlagBits::eComputeShader, {}, {}, {}, shadowMapMemoryBarriers); } - //void SHLightingSubSystem::HandleResize(Handle compute) noexcept - //{ - // uint32_t const NUM_SHADOW_MAPS = static_cast(shadowMaps.size()); - // for (uint32_t i = 0; i < NUM_SHADOW_MAPS; ++i) - // { - // // Just use the image view stored in the resource - // Handle const NEW_IMAGE_VIEW = shadowMaps[i]->GetImageView(); - - // // set new image view - // std::get>(shadowMapImageSamplers[i]) = NEW_IMAGE_VIEW; - - // // Set image for barrier - // shadowMapMemoryBarriers[i].image = shadowMaps[i]->GetImage()->GetVkImage(); - // } - - // if (NUM_SHADOW_MAPS > 0) - // { - // // modify descriptors in render graph node compute - // compute->ModifyWriteDescImageComputeResource (SHGraphicsConstants::DescriptorSetBindings::SHADOW_MAP_IMAGE_SAMPLER_DATA, shadowMapImageSamplers); - // } - //} - Handle SHLightingSubSystem::GetLightDataDescriptorSet(void) const noexcept { return lightingDataDescSet; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.h b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.h index 3613f762..652b8226 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.h @@ -9,6 +9,7 @@ #include "Graphics/MiddleEnd/Interface/SHGraphicsConstants.h" #include "Graphics/RenderGraph/SHRenderGraphResource.h" #include "ECS_Base/SHECSMacros.h" +#include namespace SHADE @@ -183,10 +184,6 @@ namespace SHADE //! Shadow maps for every light that casts a shadow Order here doesn't matter. We just want to store it std::vector> shadowMaps; - //! Descriptor sets required to be given to the compute shader for shadow calculation. This will be a descriptor array. - //! It will also be preallocated. - //Handle shadowMapDescriptorSet; - //! Combined image samplers for the texture descriptors std::vector, Handle, vk::ImageLayout>> shadowMapImageSamplers; @@ -194,6 +191,9 @@ namespace SHADE //! to VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) std::vector shadowMapMemoryBarriers; + //! recycled indices after deleting lights with shadows + std::stack recyclableIndices; + //! Resource hub from Graphics System SHResourceHub* resourceHub; @@ -212,12 +212,14 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* PUBLIC MEMBER FUNCTIONS */ /*-----------------------------------------------------------------------*/ - void Init (Handle device, Handle descPool, SHResourceHub* rh, Handle inShadowMapSampler) noexcept; - void Run (SHMatrix const& viewMat, uint32_t frameIndex) noexcept; - void Exit (void) noexcept; - void BindDescSet (Handle cmdBuffer, uint32_t setIndex, uint32_t frameIndex) noexcept; - uint32_t AddShadowMap (Handle newShadowMapBlurred, EntityID lightEntity) noexcept; - void PrepareShadowMapsForRead (Handle cmdBuffer) noexcept; + void Init (Handle device, Handle descPool, SHResourceHub* rh, Handle inShadowMapSampler) noexcept; + void Run (SHMatrix const& viewMat, uint32_t frameIndex) noexcept; + void Exit (void) noexcept; + void BindDescSet (Handle cmdBuffer, uint32_t setIndex, uint32_t frameIndex) noexcept; + uint32_t AddShadowMap (Handle newShadowMapBlurred, EntityID lightEntity) noexcept; + void RemoveShadowMap (EntityID lightEntity) noexcept; + void RecycleShadowMapIndex (SHLightComponent* lightComp) noexcept; + void PrepareShadowMapsForRead (Handle cmdBuffer) noexcept; //void HandleResize (Handle compute) noexcept; //void RemoveShadowMap (uint32_t index) noexcept; diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp index 04d4af0b..34206e5b 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp @@ -81,7 +81,8 @@ namespace SHADE renderGraphStorage->logicalDevice->WaitIdle(); - uint64_t handleID = renderGraphStorage->graphResources->at (resourceName).GetId().Raw; + auto resourceHdl = renderGraphStorage->graphResources->at(resourceName); + uint64_t handleID = resourceHdl.GetId().Raw; // Record nodes that will be affected std::vector affectedNodes{}; @@ -89,7 +90,7 @@ namespace SHADE // Detach resource from all nodes if applicable for (uint32_t i = 0; i < nodes.size(); ++i) { - if (nodes[i]->DetachResource(resourceName, handleID)) + if (nodes[i] && nodes[i]->DetachResource(resourceName, handleID)) affectedNodes.emplace_back(i); } @@ -109,6 +110,8 @@ namespace SHADE renderGraphStorage->graphResources->at(resourceName).Free(); renderGraphStorage->graphResources->erase (resourceName); + + resourceHdl.Free (); /* * IMPORTANT NOTES * @@ -121,6 +124,21 @@ namespace SHADE */ } + void SHRenderGraph::RemoveNode(std::string nodeName) noexcept + { + if (nodeIndexing.contains(nodeName)) + { + // wait for device to stop + renderGraphStorage->logicalDevice->WaitIdle(); + + // Get handle to node since it exists + auto nodeHdl = nodes[nodeIndexing[nodeName]]; + + nodeHdl.Free(); + nodeIndexing.erase(nodeName); + } + } + void SHRenderGraph::LinkNonOwningResource(Handle resourceOrigin, std::string resourceName) noexcept { // resource to link diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h index 0ae30015..42d829b0 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h @@ -112,6 +112,7 @@ namespace SHADE ); void RemoveResource (std::string resourceName) noexcept; + void RemoveNode (std::string nodeName) noexcept; void LinkNonOwningResource ( diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp index 2f316c79..53363a63 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp @@ -405,6 +405,22 @@ namespace SHADE return *this; } + SHRenderGraphNode::~SHRenderGraphNode(void) noexcept + { + if (renderpass) + renderpass.Free(); + + for (auto& framebuffer : framebuffers) + framebuffer.Free(); + + for (auto& subpass : subpasses) + subpass.Free(); + + // Too tired to test, its nearing end of milestone 3.... + //for (auto& nc : nodeComputes) + // nc.Free(); + } + /***************************************************************************/ /*! diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h index 2877fdee..971a84ae 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h @@ -111,6 +111,7 @@ namespace SHADE SHRenderGraphNode(std::string nodeName, Handle renderGraphStorage, std::vector attDescInitParams, std::vector> predecessors, bool inIsDynamic = false) noexcept; SHRenderGraphNode(SHRenderGraphNode&& rhs) noexcept; SHRenderGraphNode& operator= (SHRenderGraphNode&& rhs) noexcept; + ~SHRenderGraphNode (void) noexcept; /*-----------------------------------------------------------------------*/ /* PUBLIC MEMBER FUNCTIONS */ @@ -132,12 +133,12 @@ namespace SHADE /*-----------------------------------------------------------------------*/ void SetDynamicActive(bool active) noexcept; - Handle GetRenderpass(void) const noexcept; - Handle GetSubpass(std::string_view subpassName) const noexcept; - Handle GetResource (uint32_t resourceIndex) const noexcept; + Handle GetRenderpass(void) const noexcept; + Handle GetSubpass(std::string_view subpassName) const noexcept; + Handle GetResource (uint32_t resourceIndex) const noexcept; std::vector> const& GetResources (void) const noexcept; - Handle GetNodeCompute (std::string nodeComputeName) const noexcept; - bool GetDynamicActive (void) const noexcept; + Handle GetNodeCompute (std::string nodeComputeName) const noexcept; + bool GetDynamicActive (void) const noexcept; friend class SHRenderGraph; }; diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp index db78c5aa..ca13155d 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp @@ -80,6 +80,14 @@ namespace SHADE , companionSubpasses {std::move (rhs.companionSubpasses)} , dummyPipelineLayout{rhs.dummyPipelineLayout} { + superBatch = std::move(rhs.superBatch); + rhs.superBatch = {}; + + inputDescriptorLayout = std::move(rhs.inputDescriptorLayout); + rhs.inputDescriptorLayout = {}; + + dummyPipelineLayout = std::move(rhs.dummyPipelineLayout); + rhs.dummyPipelineLayout = {}; } @@ -101,7 +109,6 @@ namespace SHADE subpassIndex = std::move(rhs.subpassIndex); parentNode = std::move(rhs.parentNode); - superBatch = std::move(rhs.superBatch); colorReferences = std::move(rhs.colorReferences); depthReferences = std::move(rhs.depthReferences); inputReferences = std::move(rhs.inputReferences); @@ -118,10 +125,36 @@ namespace SHADE companionSubpasses = rhs.companionSubpasses; dummyPipelineLayout = rhs.dummyPipelineLayout; + superBatch = std::move(rhs.superBatch); + rhs.superBatch = {}; + + inputDescriptorLayout = std::move(rhs.inputDescriptorLayout); + rhs.inputDescriptorLayout = {}; + + dummyPipelineLayout = std::move(rhs.dummyPipelineLayout); + rhs.dummyPipelineLayout = {}; return *this; } + SHSubpass::~SHSubpass(void) noexcept + { + graphStorage->logicalDevice->WaitIdle(); + + for (auto& set : inputImageDescriptorSets) + set.Free(); + + if (inputDescriptorLayout) + inputDescriptorLayout.Free(); + + if (dummyPipelineLayout) + dummyPipelineLayout.Free(); + + // not working + //if (superBatch) + // superBatch.Free(); + } + /***************************************************************************/ /*! diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h index 640ccb2d..7f843773 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h @@ -130,6 +130,7 @@ namespace SHADE SHSubpass(const std::string& name, Handle inViewport, Handle inRenderer, Handle renderGraphStorage, Handle const& parent, uint32_t index, std::unordered_map const* mapping) noexcept; SHSubpass(SHSubpass&& rhs) noexcept; SHSubpass& operator=(SHSubpass&& rhs) noexcept; + ~SHSubpass(void) noexcept; /*-----------------------------------------------------------------------*/ /* PUBLIC MEMBER FUNCTIONS */ From 2bba48b09f9d489d2ffd0f37ae34db98162ff1aa Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Wed, 8 Mar 2023 10:02:51 +0800 Subject: [PATCH 6/6] Accounted for deletion of lights - Not entirely urgent, but removal of resources from render graph fails. Need a valid check of handles. --- SHADE_Engine/src/Events/SHEventDefines.h | 2 +- .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 12 ++++++------ .../Graphics/MiddleEnd/Lights/SHLightComponent.cpp | 8 ++++++++ 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/SHADE_Engine/src/Events/SHEventDefines.h b/SHADE_Engine/src/Events/SHEventDefines.h index e03dfd82..cdef68b9 100644 --- a/SHADE_Engine/src/Events/SHEventDefines.h +++ b/SHADE_Engine/src/Events/SHEventDefines.h @@ -30,5 +30,5 @@ constexpr SHEventIdentifier SH_BUTTON_RELEASE_EVENT { 21 }; constexpr SHEventIdentifier SH_BUTTON_HOVER_ENTER_EVENT { 22 }; constexpr SHEventIdentifier SH_BUTTON_HOVER_EXIT_EVENT { 23 }; constexpr SHEventIdentifier SH_ASSET_COMPILE_EVENT { 24 }; -constexpr SHEventIdentifier SH_LIGHT_DELETE_EVENT { 25 }; +constexpr SHEventIdentifier SH_GRAPHICS_LIGHT_DELETE_EVENT { 25 }; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index 22f0423d..d41e93d1 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -542,7 +542,7 @@ namespace SHADE std::make_shared>(this, &SHGraphicsSystem::ReceiveLightDeleteEvent) }; ReceiverPtr lightDeleteReceivePtr = std::dynamic_pointer_cast(lightDeleteEvent); - SHEventManager::SubscribeTo(SH_ASSET_COMPILE_EVENT, lightDeleteReceivePtr); + SHEventManager::SubscribeTo(SH_GRAPHICS_LIGHT_DELETE_EVENT, lightDeleteReceivePtr); std::shared_ptr> compileAssetReceiever @@ -951,19 +951,19 @@ namespace SHADE auto const& EVENT_DATA = reinterpret_cast*>(eventPtr.get())->data; auto* lightComp = SHComponentManager::GetComponent(EVENT_DATA->lightEntity); - if (lightComp && lightComp->GetShadowMapIndex()) + if (lightComp && lightComp->GetShadowMapIndex() != SHLightData::INVALID_SHADOW_MAP_INDEX) { std::string depthResourceName = "ShadowMap_Depth " + std::to_string(EVENT_DATA->lightEntity); std::string shadowMapResourceName = "ShadowMap " + std::to_string(EVENT_DATA->lightEntity); std::string shadowMapBlurredResourceName = "ShadowMap Blurred" + std::to_string(EVENT_DATA->lightEntity); // Remove render graph node - renderGraph->RemoveNode(SHGraphicsConstants::RenderGraphEntityNames::SHADOW_MAP_PASS.data() + shadowMapResourceName); + //renderGraph->RemoveNode(SHGraphicsConstants::RenderGraphEntityNames::SHADOW_MAP_PASS.data() + shadowMapResourceName); // Remove render graph resource - renderGraph->RemoveResource(depthResourceName); - renderGraph->RemoveResource(shadowMapResourceName); - renderGraph->RemoveResource(shadowMapBlurredResourceName); + //renderGraph->RemoveResource(depthResourceName); + //renderGraph->RemoveResource(shadowMapResourceName); + //renderGraph->RemoveResource(shadowMapBlurredResourceName); // Register light component shadow map index into light system as recyclable lightingSubSystem->RemoveShadowMap (EVENT_DATA->lightEntity); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightComponent.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightComponent.cpp index 5e95c6ad..f8578647 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightComponent.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightComponent.cpp @@ -21,6 +21,14 @@ namespace SHADE void SHLightComponent::OnDestroy(void) { + if (lightData.shadowMapIndex != SHLightData::INVALID_SHADOW_MAP_INDEX) + { + // Create new event and broadcast it + SHDeleteLightEvent newEvent; + newEvent.lightEntity = GetEID(); + + SHEventManager::BroadcastEvent(newEvent, SH_GRAPHICS_LIGHT_DELETE_EVENT); + } }