From 46438771ea5dc291586654ae737d7f8250f36901 Mon Sep 17 00:00:00 2001 From: Alexander Gauggel <agauggel@uni-koblenz.de> Date: Thu, 10 Jun 2021 02:06:45 +0200 Subject: [PATCH] [#70] Add voxel visualisation and fix voxelisation bugs --- include/vkcv/Core.hpp | 1 + include/vkcv/PipelineConfig.hpp | 6 +- modules/camera/include/vkcv/camera/Camera.hpp | 2 +- modules/camera/src/vkcv/camera/Camera.cpp | 4 + .../resources/shaders/compile.bat | 6 + .../resources/shaders/voxelVisualisation.frag | 9 ++ .../resources/shaders/voxelVisualisation.geom | 103 ++++++++++++++++++ .../resources/shaders/voxelVisualisation.vert | 30 +++++ .../shaders/voxelVisualisation_frag.spv | Bin 0 -> 484 bytes .../shaders/voxelVisualisation_geom.spv | Bin 0 -> 9608 bytes .../shaders/voxelVisualisation_vert.spv | Bin 0 -> 3072 bytes .../resources/shaders/voxelization.geom | 3 +- .../resources/shaders/voxelization_geom.spv | Bin 2888 -> 3004 bytes projects/cmd_sync_test/src/main.cpp | 91 +++++++++++++++- src/vkcv/Core.cpp | 6 + src/vkcv/ImageManager.cpp | 16 +++ src/vkcv/ImageManager.hpp | 4 + src/vkcv/PipelineConfig.cpp | 6 +- src/vkcv/PipelineManager.cpp | 15 ++- 19 files changed, 289 insertions(+), 13 deletions(-) create mode 100644 projects/cmd_sync_test/resources/shaders/voxelVisualisation.frag create mode 100644 projects/cmd_sync_test/resources/shaders/voxelVisualisation.geom create mode 100644 projects/cmd_sync_test/resources/shaders/voxelVisualisation.vert create mode 100644 projects/cmd_sync_test/resources/shaders/voxelVisualisation_frag.spv create mode 100644 projects/cmd_sync_test/resources/shaders/voxelVisualisation_geom.spv create mode 100644 projects/cmd_sync_test/resources/shaders/voxelVisualisation_vert.spv diff --git a/include/vkcv/Core.hpp b/include/vkcv/Core.hpp index c21ee3d6..061a2bd7 100644 --- a/include/vkcv/Core.hpp +++ b/include/vkcv/Core.hpp @@ -260,5 +260,6 @@ namespace vkcv void prepareSwapchainImageForPresent(const CommandStreamHandle handle); void prepareImageForSampling(const CommandStreamHandle cmdStream, const ImageHandle image); void prepareImageForStorage(const CommandStreamHandle cmdStream, const ImageHandle image); + void recordImageMemoryBarrier(const CommandStreamHandle cmdStream, const ImageHandle image); }; } diff --git a/include/vkcv/PipelineConfig.hpp b/include/vkcv/PipelineConfig.hpp index 2d1d1488..55f659b8 100644 --- a/include/vkcv/PipelineConfig.hpp +++ b/include/vkcv/PipelineConfig.hpp @@ -13,6 +13,8 @@ namespace vkcv { + enum class PrimitiveTopology{PointList, LineList, TriangleList }; + struct PipelineConfig { /** * Constructor for the pipeline. Creates a pipeline using @p vertexCode, @p fragmentCode as well as the @@ -31,7 +33,8 @@ namespace vkcv { const std::vector<VertexAttribute> &vertexAttributes, const std::vector<vk::DescriptorSetLayout> &descriptorLayouts, bool useDynamicViewport, - bool useConservativeRasterization = false); + bool useConservativeRasterization = false, + PrimitiveTopology primitiveTopology = PrimitiveTopology::TriangleList); ShaderProgram m_ShaderProgram; uint32_t m_Height; @@ -41,6 +44,7 @@ namespace vkcv { std::vector<vk::DescriptorSetLayout> m_DescriptorLayouts; bool m_UseDynamicViewport; bool m_UseConservativeRasterization; + PrimitiveTopology m_PrimitiveTopology; }; } \ No newline at end of file diff --git a/modules/camera/include/vkcv/camera/Camera.hpp b/modules/camera/include/vkcv/camera/Camera.hpp index ff8fda81..f21dcc48 100644 --- a/modules/camera/include/vkcv/camera/Camera.hpp +++ b/modules/camera/include/vkcv/camera/Camera.hpp @@ -95,7 +95,7 @@ namespace vkcv { void moveRight(int action); - + void setSpeed(float speed); }; } diff --git a/modules/camera/src/vkcv/camera/Camera.cpp b/modules/camera/src/vkcv/camera/Camera.cpp index af89ed86..f77d55fc 100644 --- a/modules/camera/src/vkcv/camera/Camera.cpp +++ b/modules/camera/src/vkcv/camera/Camera.cpp @@ -176,4 +176,8 @@ namespace vkcv { void Camera::moveRight(int action){ m_right = static_cast<bool>(action); } + + void Camera::setSpeed(float speed) { + m_cameraSpeed = speed; + } } \ No newline at end of file diff --git a/projects/cmd_sync_test/resources/shaders/compile.bat b/projects/cmd_sync_test/resources/shaders/compile.bat index d8f0abf7..26239841 100644 --- a/projects/cmd_sync_test/resources/shaders/compile.bat +++ b/projects/cmd_sync_test/resources/shaders/compile.bat @@ -1,8 +1,14 @@ %VULKAN_SDK%\Bin32\glslc.exe shader.vert -o vert.spv %VULKAN_SDK%\Bin32\glslc.exe shader.frag -o frag.spv + %VULKAN_SDK%\Bin32\glslc.exe shadow.vert -o shadow_vert.spv %VULKAN_SDK%\Bin32\glslc.exe shadow.frag -o shadow_frag.spv + %VULKAN_SDK%\Bin32\glslc.exe voxelization.vert -o voxelization_vert.spv %VULKAN_SDK%\Bin32\glslc.exe voxelization.geom -o voxelization_geom.spv %VULKAN_SDK%\Bin32\glslc.exe voxelization.frag -o voxelization_frag.spv + +%VULKAN_SDK%\Bin32\glslc.exe voxelVisualisation.vert -o voxelVisualisation_vert.spv +%VULKAN_SDK%\Bin32\glslc.exe voxelVisualisation.geom -o voxelVisualisation_geom.spv +%VULKAN_SDK%\Bin32\glslc.exe voxelVisualisation.frag -o voxelVisualisation_frag.spv pause \ No newline at end of file diff --git a/projects/cmd_sync_test/resources/shaders/voxelVisualisation.frag b/projects/cmd_sync_test/resources/shaders/voxelVisualisation.frag new file mode 100644 index 00000000..e1a363c7 --- /dev/null +++ b/projects/cmd_sync_test/resources/shaders/voxelVisualisation.frag @@ -0,0 +1,9 @@ +#version 450 +#extension GL_ARB_separate_shader_objects : enable + +layout(location=0) in vec3 inColor; +layout(location=0) out vec3 outColor; + +void main() { + outColor = inColor; +} \ No newline at end of file diff --git a/projects/cmd_sync_test/resources/shaders/voxelVisualisation.geom b/projects/cmd_sync_test/resources/shaders/voxelVisualisation.geom new file mode 100644 index 00000000..ff0b8b6f --- /dev/null +++ b/projects/cmd_sync_test/resources/shaders/voxelVisualisation.geom @@ -0,0 +1,103 @@ +#version 450 +#extension GL_ARB_separate_shader_objects : enable + +layout(points) in; +layout (triangle_strip, max_vertices = 24) out; + +layout( push_constant ) uniform constants{ + mat4 viewProjection; +}; + +layout(location = 0) in float passCubeHalf[1]; + +layout(location = 0) out vec3 passColor; + +void main() { + float cubeHalf = passCubeHalf[0]; + // right + gl_Position = viewProjection * vec4(gl_in[0].gl_Position.xyz + cubeHalf * vec3(1, 1, 1), 1); + passColor = vec3(1, 0, 0); + EmitVertex(); + gl_Position = viewProjection * vec4(gl_in[0].gl_Position.xyz + cubeHalf * vec3(1, 1, -1), 1); + passColor = vec3(1, 0, 0); + EmitVertex(); + gl_Position = viewProjection * vec4(gl_in[0].gl_Position.xyz + cubeHalf * vec3(1, -1, 1), 1); + passColor = vec3(1, 0, 0); + EmitVertex(); + gl_Position = viewProjection * vec4(gl_in[0].gl_Position.xyz + cubeHalf * vec3(1, -1, -1), 1); + passColor = vec3(1, 0, 0); + EmitVertex(); + EndPrimitive(); + // left + gl_Position = viewProjection * vec4(gl_in[0].gl_Position.xyz + cubeHalf * vec3(-1, 1, 1), 1); + passColor = vec3(1, 0, 0); + EmitVertex(); + gl_Position = viewProjection * vec4(gl_in[0].gl_Position.xyz + cubeHalf * vec3(-1, 1, -1), 1); + passColor = vec3(1, 0, 0); + EmitVertex(); + gl_Position = viewProjection * vec4(gl_in[0].gl_Position.xyz + cubeHalf * vec3(-1, -1, 1), 1); + passColor = vec3(1, 0, 0); + EmitVertex(); + gl_Position = viewProjection * vec4(gl_in[0].gl_Position.xyz + cubeHalf * vec3(-1, -1, -1), 1); + passColor = vec3(1, 0, 0); + EmitVertex(); + EndPrimitive(); + // back + gl_Position = viewProjection * vec4(gl_in[0].gl_Position.xyz + cubeHalf * vec3(1, 1, -1), 1); + passColor = vec3(1, 0, 0); + EmitVertex(); + gl_Position = viewProjection * vec4(gl_in[0].gl_Position.xyz + cubeHalf * vec3(1, -1, -1), 1); + passColor = vec3(1, 0, 0); + EmitVertex(); + gl_Position = viewProjection * vec4(gl_in[0].gl_Position.xyz + cubeHalf * vec3(-1, 1, -1), 1); + passColor = vec3(1, 0, 0); + EmitVertex(); + gl_Position = viewProjection * vec4(gl_in[0].gl_Position.xyz + cubeHalf * vec3(-1, -1, -1), 1); + passColor = vec3(0, 0, 1); + EmitVertex(); + EndPrimitive(); + // front + gl_Position = viewProjection * vec4(gl_in[0].gl_Position.xyz + cubeHalf * vec3(1, 1, 1), 1); + passColor = vec3(0, 0, 1); + EmitVertex(); + gl_Position = viewProjection * vec4(gl_in[0].gl_Position.xyz + cubeHalf * vec3(1, -1, 1), 1); + passColor = vec3(0, 0, 1); + EmitVertex(); + gl_Position = viewProjection * vec4(gl_in[0].gl_Position.xyz + cubeHalf * vec3(-1, 1, 1), 1); + passColor = vec3(0, 0, 1); + EmitVertex(); + gl_Position = viewProjection * vec4(gl_in[0].gl_Position.xyz + cubeHalf * vec3(-1, -1, 1), 1); + passColor = vec3(0, 0, 1); + EmitVertex(); + EndPrimitive(); + // bot + gl_Position = viewProjection * vec4(gl_in[0].gl_Position.xyz + cubeHalf * vec3(1, 1, 1), 1); + passColor = vec3(0, 1, 0); + EmitVertex(); + gl_Position = viewProjection * vec4(gl_in[0].gl_Position.xyz + cubeHalf * vec3(1, 1, -1), 1); + passColor = vec3(0, 1, 0); + EmitVertex(); + gl_Position = viewProjection * vec4(gl_in[0].gl_Position.xyz + cubeHalf * vec3(-1, 1, 1), 1); + passColor = vec3(0, 1, 0); + EmitVertex(); + gl_Position = viewProjection * vec4(gl_in[0].gl_Position.xyz + cubeHalf * vec3(-1, 1, -1), 1); + passColor = vec3(0, 1, 0); + passColor = vec3(0, 1, 0); + EmitVertex(); + EndPrimitive(); + // top + gl_Position = viewProjection * vec4(gl_in[0].gl_Position.xyz + cubeHalf * vec3(1, -1, 1), 1); + passColor = vec3(0, 1, 0); + EmitVertex(); + gl_Position = viewProjection * vec4(gl_in[0].gl_Position.xyz + cubeHalf * vec3(1, -1, -1), 1); + passColor = vec3(0, 1, 0); + EmitVertex(); + gl_Position = viewProjection * vec4(gl_in[0].gl_Position.xyz + cubeHalf * vec3(-1, -1, 1), 1); + passColor = vec3(0, 1, 0); + EmitVertex(); + gl_Position = viewProjection * vec4(gl_in[0].gl_Position.xyz + cubeHalf * vec3(-1, -1, -1), 1); + passColor = vec3(0, 1, 0); + passColor = vec3(0, 1, 0); + EmitVertex(); + EndPrimitive(); +} \ No newline at end of file diff --git a/projects/cmd_sync_test/resources/shaders/voxelVisualisation.vert b/projects/cmd_sync_test/resources/shaders/voxelVisualisation.vert new file mode 100644 index 00000000..270b9ac5 --- /dev/null +++ b/projects/cmd_sync_test/resources/shaders/voxelVisualisation.vert @@ -0,0 +1,30 @@ +#version 450 +#extension GL_ARB_separate_shader_objects : enable + +layout(location = 0) out float passCubeHalf; + +layout( push_constant ) uniform constants{ + mat4 viewProjection; +}; + +layout(set=0, binding=0, r8) uniform image3D voxelImage; +layout(set=0, binding=1) uniform voxelizationInfo{ + float extent; +} voxelInfo; + + +void main() { + passCubeHalf = voxelInfo.extent / float(imageSize(voxelImage).x) * 0.5f; + int voxelResolution = imageSize(voxelImage).x; + int slicePixelCount = voxelResolution * voxelResolution; + int z = gl_VertexIndex / slicePixelCount; + int index2D = gl_VertexIndex % slicePixelCount; + int y = index2D / voxelResolution; + int x = index2D % voxelResolution; + vec3 position = (vec3(x, y, z) / voxelResolution - 0.5) * voxelInfo.extent + passCubeHalf; + gl_Position = vec4(position, 1.0); + + if(imageLoad(voxelImage, ivec3(x,y,z)).x == 0){ + gl_Position.x /= 0; // clip + } +} \ No newline at end of file diff --git a/projects/cmd_sync_test/resources/shaders/voxelVisualisation_frag.spv b/projects/cmd_sync_test/resources/shaders/voxelVisualisation_frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..0d182806527c32ddab5e234ecf03929ae26277e6 GIT binary patch literal 484 zcmZQ(Qf6mhU}WH8;AP-tfB-=TCI&_Z1_o{hHZbk(6YQf`T#}+^Vrl?V!N<T1qQG+e z4D1Xn3=CkLo0ypglHdgEWnd6sU<Qk`GcYhPGcYqSF)%P3Vg#w>WN`P1cMNihFHS8; zEJ`d%jW5nfOi3+@&rixqO)e=0so?^targIk_i>F+E+~jEE~(5(jnB!<ON~#-EJ{r- z$t+6+spCLWmzkHGQ<{RTfR%v->;{<ISQ%IuK<>*gEpg7z$u9!A7o>)pfq@}24<h8w zzyeky2a;r9U;yz!@-V(I0~6RUieO(cfZ1XU%nWP{3=9ek3=HB7EDRt&gZQA3Qea?V z-~fjK16bS|$_KdvCeOtHiUou`h!3(86c1($tYAAp;S6#TNY4)jCI(gp1_oQGT|Ce* Uw_{)iyB);;%fQHB!NAA>0NYD9ZvX%Q literal 0 HcmV?d00001 diff --git a/projects/cmd_sync_test/resources/shaders/voxelVisualisation_geom.spv b/projects/cmd_sync_test/resources/shaders/voxelVisualisation_geom.spv new file mode 100644 index 0000000000000000000000000000000000000000..6a804b752393f0d84c0287580c50c71bb9413492 GIT binary patch literal 9608 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 literal 0 HcmV?d00001 diff --git a/projects/cmd_sync_test/resources/shaders/voxelVisualisation_vert.spv b/projects/cmd_sync_test/resources/shaders/voxelVisualisation_vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..52a320bb31926efffb96e7384f76836ca1690dec GIT binary patch literal 3072 zcmZQ(Qf6mhU}WH8;AJRefB-=TCI&_Z1_lsq2&Ih}7#O%2*udiMKEXbE#U&|vCZ+}; z9efPTAPOwU&%gm@voJ6)<R)h3fjA%$O$G*r5C#SYW(H;kCI$wELyQazEDW3s?mqF3 zK~C|-sRfBei6yD=#TkhysYUVmNm;4MCB+~$Tp%^>{{HShuJOqQ1@Xltl{u;LIhlE> z@hO=_smUdoWvL)_97yUi^OAE)Q;-#~GO#cpyNQ*74eZi_#NuM-(xg<6#GEvcTUi;{ z88{gj7|QZ1Qgbq^5=%1k^E~s?@<DQJ46I-|5IeP^BsH&ufq|8Qm4O?k9;y%|CJYzL zO-xS(sbgc1hlvHH7U$=bf{bPWxkH(OfuT4jGdVRNvm!OeIlnZogn^ZTnL(X_fuV{4 zq8Ai?={fOXsYNBJ6`px1sTCk`76x4g28K)!*T@B|2NYkGU_HzXrVI=W6<{_igEa#K zLqUFVCfHK27#l+n0|P^PPJBRW5yV)Kzt|Wc;vhCi4yJ{TfgP+KlrF&HnRz9_nN_JE zbuc+lyr$>GJLhB;xMUWWB<3ZjGQi|ODFh@}nv(;U1Njk@CO~F@!VHvHlJoOGIzdqn z)(a8?$(LoOmIoB&gHlCiejdp0%nSt}2?hoRcLo-4T*^WD9!T*73R{q{I|DN~?m%t? zsRzZG5=a87AH-K=0ObUTd7$`1mIv`c@*piB{h;^&>Cs|fU;x<%3QLe2NDM^7#6aN% z5(CjNF_0TTVxTaAiGkQ4F;E%>xfNs{NSy}*3j-_+SfO^o_%OeL%z%lpGcYg+fc?Y_ z)(0{}n1KnL=M=%Yj{(dUV_;@rV_;xV0Am&gkUo$bKw{Pm5I!j1g2d#YVF!{^U|?b3 zVt|+d$|oSTAU??LAiG2vSQvP~W<tVJ8_MSe1qxW4g@F&MA7q{+11EzZ0|VGCApKBf zU<$<Nhw2dmi-5``1_qFwAU-HgK*Hh-EDWLy3}Aaf?ghC)9IOu{%fJ9~1BfpH;ez=f zyJaAJdyt<%X$KSr5Vx~1Xh72fh!3(4#0SMWC>}xfSwh_mvJa%+ih%(fh9Gf}ygyVP z6rV8r1E6NgFt9KLLghhXa?m^n(*u$NVUW4O;4+f|ocBQP0P#V224pYDT#!G)!2W0e z`y(2v9%L3wJ_Rh#z#ziF!~n{$5)3R1xeN>pAT=QOf#MgGen4U%J3)mVC~iSwAUi>P zP+kLxnK7_}(+@}=$XJj&elRdGfYK&NEhrp8<s2w1VSG?JMdpLbHDo@h3`6FF$}nU; zs2qdwLE#K4%Rqcb23Bxd0;Lg9`U9mgTLu<zS_0((kT{4BN?#%j3=E+3k^xOCVho`0 zU|<MjU<IceNd^W6kQm5M`A{>Y7#J8p;vL{pnt?$YnzumWtxz#p28cK)E!i<JgUcb1 z7|dQ!{zA4FREB`WVD^H_7?2pqUXXrJ*nz}A`ax+=g@FNFZ@~DfP<{*4-D(UB3?MZi zagcscScAl1>OtibDBZ&N+6)W~AT{k!{W=T`3?MZiagcsc+<?Sj>h%~H7?AbrL-lt< z^@AD!AT=OykbY2Hg2Z6@LG1>R7>sWWbwA9069xtbkQ$IUNIxj<L1HlVW(*AAIu6D+ zhw6vfZ^6L808#@I2k8f;6_6NAy$u5cxE_SXsVxHo14s-eZ^yvE0J0M%Z_mKM01|`A zJ1{VS>tUF@BLf2iNGyPXjRBO`ofsGxKxTsUf#hKNoT2W7>2qOVU;v51^tm!HFo48h z7?j39=D9I2Fo4Vi$-~sTGcYiK(iaRjGq8f~_F!OO0I3Jb!}5YBxShtpfSeb+7#J8p z;(btk-r#zKfdM2AaxbV1@nK*9r(Kwxz6=ZuATbzjgzEKUU|<002g!rN8<ZD8Vjy!s z?hj=EmCulT1u{3Bfq?-e21?(cG!GJsfQo_2QkYmIR18$+2QaXM%cdv>1_qFRkb00j zsGI}&6I8~<K--fbe}dcr;)B$K+yTn(vC#Yu;)C*095fxk`0>zqhw&4j@eJ}ms4hul zU|<000jUGYB{8sq-IT<@zyLBEBoA|YG6MqxNF3zHEex#SG8WXB1c`&n-tP>|3>hFv z1_p*-3@i*FxpW2wuo$T91hE~#tsMr2OeBAS>MM}@Kw*{zYUeR9Fo4nth@Z{CzyJ~h hnGe&OgQgc0E+8?G+Mf(eaQi@R`OCn_V8Ou1007(?_%8qe literal 0 HcmV?d00001 diff --git a/projects/cmd_sync_test/resources/shaders/voxelization.geom b/projects/cmd_sync_test/resources/shaders/voxelization.geom index 1546a75d..23084853 100644 --- a/projects/cmd_sync_test/resources/shaders/voxelization.geom +++ b/projects/cmd_sync_test/resources/shaders/voxelization.geom @@ -24,7 +24,8 @@ void main() { else{ gl_Position = gl_in[i].gl_Position.xzyw; } - passPos = passPosIn[i].xzy; + gl_Position.z = gl_Position.z * 0.5 + 0.5; // xyz are kept in NDC range [-1, 1] so swizzling works, but vulkan needs final z in range [0, 1] + passPos = passPosIn[i]; EmitVertex(); } EndPrimitive(); diff --git a/projects/cmd_sync_test/resources/shaders/voxelization_geom.spv b/projects/cmd_sync_test/resources/shaders/voxelization_geom.spv index abf747e5ff0d15043e493e01d08972e04df6f993..df9871889f968450232a4b8355c9493e50de76ee 100644 GIT binary patch delta 316 zcmX>hwnv<onMs+Qfq{{Mi-DIRe<E)%W9G(0aVEyh$(2mk88bHrGRrgRvN13)Xfv=d zfanwkFtAr(U}4B$U|?WoU|?WpU|_I@@-sKrvU0Q5J2J2_Br-5CBrz~BI5RLX2rw`( z=rAxa*g}m-hRU@vu!4<EWnf?ciGhr7go>pxFff3`L1HlT($UPbV_;?giGkFD%;slc zV8~)%Fk(<*U|?`$U}X?wU|`5*U|`^bNPryxa&Hb)9ArQy0|P_O<fmNns<{jdV4V#N ctPCKd@)#HxKw=^c3=ANZAXD=uYjVp20P6N21poj5 delta 199 zcmdlZenO0wnMs+Qfq{{Mi-DIRb0TjrW75V%aVEy3$(2mk8Iv{#GRrgZvNJF+STnFN zBr-5CByFC{%FP;U%fQ0G&%nTt%)r2)#K6Gd$iT`V$iTpm!oa}52NegY0clNziu*Hg zFo5`J3=9k)F%V{8U|?Wk06Bnx!H$8MA&G&3A#HLbx4ddP)Z_*RR<KPO3=9k)F%brc NN|3D?ljm~F0{}PE7Nr0H diff --git a/projects/cmd_sync_test/src/main.cpp b/projects/cmd_sync_test/src/main.cpp index 3fb53692..894e4a8a 100644 --- a/projects/cmd_sync_test/src/main.cpp +++ b/projects/cmd_sync_test/src/main.cpp @@ -21,6 +21,7 @@ int main(int argc, const char** argv) { vkcv::CameraManager cameraManager(window, windowWidth, windowHeight); cameraManager.getCamera().setPosition(glm::vec3(0.f, 0.f, 3.f)); cameraManager.getCamera().setNearFar(0.1, 30); + cameraManager.getCamera().setSpeed(25.f); window.initEvents(); @@ -83,10 +84,11 @@ int main(int argc, const char** argv) { core.getSwapchainImageFormat() ); + const vk::Format depthBufferFormat = vk::Format::eD32Sfloat; const vkcv::AttachmentDescription depth_attachment( - vkcv::AttachmentOperation::STORE, - vkcv::AttachmentOperation::CLEAR, - vk::Format::eD32Sfloat + vkcv::AttachmentOperation::STORE, + vkcv::AttachmentOperation::CLEAR, + depthBufferFormat ); vkcv::PassConfig trianglePassDefinition({ present_color_attachment, depth_attachment }); @@ -237,6 +239,64 @@ int main(int argc, const char** argv) { voxelizationDescriptorWrites.uniformBufferWrites = { vkcv::UniformBufferDescriptorWrite(1, voxelizationInfoBuffer.getHandle()) }; core.writeDescriptorSet(voxelizationDescriptorSet, voxelizationDescriptorWrites); + const size_t voxelCount = voxelResolution * voxelResolution * voxelResolution; + + vkcv::ShaderProgram voxelVisualisationShader; + voxelVisualisationShader.addShader(vkcv::ShaderStage::VERTEX, "resources/shaders/voxelVisualisation_vert.spv"); + voxelVisualisationShader.addShader(vkcv::ShaderStage::GEOMETRY, "resources/shaders/voxelVisualisation_geom.spv"); + voxelVisualisationShader.addShader(vkcv::ShaderStage::FRAGMENT, "resources/shaders/voxelVisualisation_frag.spv"); + voxelVisualisationShader.reflectShader(vkcv::ShaderStage::VERTEX); + voxelVisualisationShader.reflectShader(vkcv::ShaderStage::GEOMETRY); + voxelVisualisationShader.reflectShader(vkcv::ShaderStage::FRAGMENT); + + const std::vector<vkcv::DescriptorBinding> voxelVisualisationDescriptorBindings = { + vkcv::DescriptorBinding(vkcv::DescriptorType::IMAGE_STORAGE, 1, vkcv::ShaderStage::VERTEX), + vkcv::DescriptorBinding(vkcv::DescriptorType::UNIFORM_BUFFER, 1, vkcv::ShaderStage::VERTEX) }; + vkcv::DescriptorSetHandle voxelVisualisationDescriptorSet = core.createDescriptorSet(voxelVisualisationDescriptorBindings); + + const vkcv::AttachmentDescription voxelVisualisationColorAttachments( + vkcv::AttachmentOperation::STORE, + vkcv::AttachmentOperation::LOAD, + core.getSwapchainImageFormat() + ); + + const vkcv::AttachmentDescription voxelVisualisationDepthAttachments( + vkcv::AttachmentOperation::STORE, + vkcv::AttachmentOperation::LOAD, + depthBufferFormat + ); + + vkcv::PassConfig voxelVisualisationPassDefinition({ voxelVisualisationColorAttachments, voxelVisualisationDepthAttachments }); + vkcv::PassHandle voxelVisualisationPass = core.createPass(voxelVisualisationPassDefinition); + + const vkcv::PipelineConfig voxelVisualisationPipeConfig( + voxelVisualisationShader, + 0, + 0, + voxelVisualisationPass, + {}, + { core.getDescriptorSet(voxelVisualisationDescriptorSet).layout }, + true, + false, + vkcv::PrimitiveTopology::PointList); // points are extended to cubes in the geometry shader + const vkcv::PipelineHandle voxelVisualisationPipe = core.createGraphicsPipeline(voxelVisualisationPipeConfig); + + vkcv::Buffer<uint16_t> voxelVisualisationIndexBuffer = core.createBuffer<uint16_t>(vkcv::BufferType::INDEX, voxelCount); + std::vector<uint16_t> voxelIndexData; + for (int i = 0; i < voxelCount; i++) { + voxelIndexData.push_back(i); + } + + vkcv::DescriptorWrites voxelVisualisationDescriptorWrite; + voxelVisualisationDescriptorWrite.storageImageWrites = { vkcv::StorageImageDescriptorWrite(0, voxelImage.getHandle()) }; + voxelVisualisationDescriptorWrite.uniformBufferWrites = { vkcv::UniformBufferDescriptorWrite(1, voxelizationInfoBuffer.getHandle()) }; + core.writeDescriptorSet(voxelVisualisationDescriptorSet, voxelVisualisationDescriptorWrite); + + voxelVisualisationIndexBuffer.fill(voxelIndexData); + const vkcv::DrawcallInfo voxelVisualisationDrawcall( + vkcv::Mesh({}, voxelVisualisationIndexBuffer.getVulkanHandle(), voxelCount), + { vkcv::DescriptorSetUsage(0, core.getDescriptorSet(voxelVisualisationDescriptorSet).vulkanHandle) }); + const std::vector<glm::vec3> instancePositions = { glm::vec3(0.f, -2.f, 0.f), glm::vec3(3.f, 0.f, 0.f), @@ -264,6 +324,13 @@ int main(int argc, const char** argv) { std::vector<glm::mat4> mvpLight; std::vector<std::array<glm::mat4, 2>> voxelizationMatrices; + bool renderVoxelVis = false; + window.e_key.add([&renderVoxelVis](int key ,int scancode, int action, int mods) { + if (key == GLFW_KEY_V && action == GLFW_PRESS) { + renderVoxelVis = !renderVoxelVis; + } + }); + auto start = std::chrono::system_clock::now(); const auto appStartTime = start; while (window.isWindowOpen()) { @@ -275,7 +342,7 @@ int main(int argc, const char** argv) { } if ((swapchainWidth != windowWidth) || ((swapchainHeight != windowHeight))) { - depthBuffer = core.createImage(vk::Format::eD32Sfloat, swapchainWidth, swapchainHeight).getHandle(); + depthBuffer = core.createImage(depthBufferFormat, swapchainWidth, swapchainHeight).getHandle(); windowWidth = swapchainWidth; windowHeight = swapchainHeight; @@ -311,7 +378,7 @@ int main(int argc, const char** argv) { const glm::mat4 viewProjectionCamera = cameraManager.getCamera().getProjection() * cameraManager.getCamera().getView(); const float voxelizationHalfExtent = 0.5f * voxelizationExtent; - const glm::mat4 voxelizationProjection = vulkanCorrectionMatrix * glm::ortho( + const glm::mat4 voxelizationProjection = glm::ortho( -voxelizationHalfExtent, voxelizationHalfExtent, -voxelizationHalfExtent, @@ -362,6 +429,20 @@ int main(int argc, const char** argv) { pushConstantData, drawcalls, renderTargets); + + if (renderVoxelVis) { + const vkcv::PushConstantData voxelVisualisationPushConstantData((void*)&viewProjectionCamera, sizeof(glm::mat4)); + + core.recordImageMemoryBarrier(cmdStream, voxelImage.getHandle()); + core.recordDrawcallsToCmdStream( + cmdStream, + voxelVisualisationPass, + voxelVisualisationPipe, + voxelVisualisationPushConstantData, + { voxelVisualisationDrawcall }, + renderTargets); + } + core.prepareSwapchainImageForPresent(cmdStream); core.submitCommandStream(cmdStream); diff --git a/src/vkcv/Core.cpp b/src/vkcv/Core.cpp index b7fc5aa9..0d3bf032 100644 --- a/src/vkcv/Core.cpp +++ b/src/vkcv/Core.cpp @@ -470,4 +470,10 @@ namespace vkcv m_ImageManager->recordImageLayoutTransition(image, vk::ImageLayout::eGeneral, cmdBuffer); }, nullptr); } + + void Core::recordImageMemoryBarrier(const CommandStreamHandle cmdStream, const ImageHandle image) { + recordCommandsToStream(cmdStream, [image, this](const vk::CommandBuffer cmdBuffer) { + m_ImageManager->recordImageMemoryBarrier(image, cmdBuffer); + }, nullptr); + } } diff --git a/src/vkcv/ImageManager.cpp b/src/vkcv/ImageManager.cpp index 80849375..cb0ebc73 100644 --- a/src/vkcv/ImageManager.cpp +++ b/src/vkcv/ImageManager.cpp @@ -295,6 +295,22 @@ namespace vkcv { recordImageBarrier(cmdBuffer, transitionBarrier); image.m_layout = newLayout; } + + void ImageManager::recordImageMemoryBarrier( + const ImageHandle& handle, + vk::CommandBuffer cmdBuffer) { + + const uint64_t id = handle.getId(); + + if (id >= m_images.size()) { + std::cerr << "Error: ImageManager::recordImageMemoryBarrier invalid handle" << std::endl; + return; + } + + auto& image = m_images[id]; + const auto transitionBarrier = createImageLayoutTransitionBarrier(image, image.m_layout); + recordImageBarrier(cmdBuffer, transitionBarrier); + } void ImageManager::fillImage(const ImageHandle& handle, void* data, size_t size) { diff --git a/src/vkcv/ImageManager.hpp b/src/vkcv/ImageManager.hpp index 316ad231..6b3bea33 100644 --- a/src/vkcv/ImageManager.hpp +++ b/src/vkcv/ImageManager.hpp @@ -86,6 +86,10 @@ namespace vkcv { vk::ImageLayout newLayout, vk::CommandBuffer cmdBuffer); + void recordImageMemoryBarrier( + const ImageHandle& handle, + vk::CommandBuffer cmdBuffer); + void fillImage(const ImageHandle& handle, void* data, size_t size); [[nodiscard]] diff --git a/src/vkcv/PipelineConfig.cpp b/src/vkcv/PipelineConfig.cpp index 306e4685..46911736 100644 --- a/src/vkcv/PipelineConfig.cpp +++ b/src/vkcv/PipelineConfig.cpp @@ -16,7 +16,8 @@ namespace vkcv { const std::vector<VertexAttribute> &vertexAttributes, const std::vector<vk::DescriptorSetLayout> &descriptorLayouts, bool useDynamicViewport, - bool useConservativeRasterization) + bool useConservativeRasterization, + PrimitiveTopology primitiveTopology) : m_ShaderProgram(shaderProgram), m_Height(height), @@ -25,6 +26,7 @@ namespace vkcv { m_VertexAttributes(vertexAttributes), m_DescriptorLayouts(descriptorLayouts), m_UseDynamicViewport(useDynamicViewport), - m_UseConservativeRasterization(useConservativeRasterization) + m_UseConservativeRasterization(useConservativeRasterization), + m_PrimitiveTopology(primitiveTopology) {} } diff --git a/src/vkcv/PipelineManager.cpp b/src/vkcv/PipelineManager.cpp index 5c7e830e..1971222a 100644 --- a/src/vkcv/PipelineManager.cpp +++ b/src/vkcv/PipelineManager.cpp @@ -32,6 +32,15 @@ namespace vkcv } } + vk::PrimitiveTopology primitiveTopologyToVulkanPrimitiveTopology(const PrimitiveTopology topology) { + switch (topology) { + case(PrimitiveTopology::PointList): return vk::PrimitiveTopology::ePointList; + case(PrimitiveTopology::LineList): return vk::PrimitiveTopology::eLineList; + case(PrimitiveTopology::TriangleList): return vk::PrimitiveTopology::eTriangleList; + default: std::cout << "Error: Unknown primitive topology type" << std::endl; return vk::PrimitiveTopology::eTriangleList; + } + } + PipelineHandle PipelineManager::createPipeline(const PipelineConfig &config, PassManager& passManager) { const vk::RenderPass &pass = passManager.getVkPass(config.m_PassHandle); @@ -114,9 +123,9 @@ namespace vkcv // input assembly state vk::PipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateCreateInfo( - {}, - vk::PrimitiveTopology::eTriangleList, - false + {}, + primitiveTopologyToVulkanPrimitiveTopology(config.m_PrimitiveTopology), + false ); // viewport state -- GitLab