From cdfcc722a620ebc777fccec0a0874e9d408c412d Mon Sep 17 00:00:00 2001 From: Alexander Gauggel <agauggel@uni-koblenz.de> Date: Sun, 13 Jun 2021 23:52:48 +0200 Subject: [PATCH] [#70] Add compute shader that resets voxel image every frame --- .../resources/shaders/compile.bat | 2 + .../resources/shaders/voxelReset.comp | 13 +++ .../resources/shaders/voxelReset_comp.spv | Bin 0 -> 912 bytes projects/cmd_sync_test/src/main.cpp | 98 +++++++++++------- 4 files changed, 78 insertions(+), 35 deletions(-) create mode 100644 projects/cmd_sync_test/resources/shaders/voxelReset.comp create mode 100644 projects/cmd_sync_test/resources/shaders/voxelReset_comp.spv diff --git a/projects/cmd_sync_test/resources/shaders/compile.bat b/projects/cmd_sync_test/resources/shaders/compile.bat index 26239841..b43ba299 100644 --- a/projects/cmd_sync_test/resources/shaders/compile.bat +++ b/projects/cmd_sync_test/resources/shaders/compile.bat @@ -11,4 +11,6 @@ %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 + +%VULKAN_SDK%\Bin32\glslc.exe voxelReset.comp -o voxelReset_comp.spv pause \ No newline at end of file diff --git a/projects/cmd_sync_test/resources/shaders/voxelReset.comp b/projects/cmd_sync_test/resources/shaders/voxelReset.comp new file mode 100644 index 00000000..ca67b74c --- /dev/null +++ b/projects/cmd_sync_test/resources/shaders/voxelReset.comp @@ -0,0 +1,13 @@ +#version 440 + +layout(set=0, binding=0, r8) uniform image3D voxelImage; + +layout(local_size_x = 4, local_size_y = 4, local_size_z = 4) in; + +void main(){ + + if(any(greaterThanEqual(gl_GlobalInvocationID, imageSize(voxelImage)))){ + return; + } + imageStore(voxelImage, ivec3(gl_GlobalInvocationID), vec4(0.f)); +} \ No newline at end of file diff --git a/projects/cmd_sync_test/resources/shaders/voxelReset_comp.spv b/projects/cmd_sync_test/resources/shaders/voxelReset_comp.spv new file mode 100644 index 0000000000000000000000000000000000000000..6917b65c17f738d9f3378bd219467f2132e3f62d GIT binary patch literal 912 zcmYk4-D=cO6orp7omyM_Xa6kzW!lS@Vnsy|@02hw&<h_RjG0gaX{NN}&_bWYhw$1r zvj~FUmt-KjtnRbc*=L`%Po~>Bd>F!mupCyyVW?v>bWlPtpEmgoc_l1XdOZ9(Jh`5Z zPu{+J?TNL}HC21-)bv;{fQwOHsy_l7=xUq5JV%$a9r$l9T);&<OyaY%c=#nrFE5kp z>1~lEMP6pfIKRr$X+F!WTWZziWm^0gw+nhywD0dxuZQy@iHpg%Q86fIlXNuAC*|NX zdXK*~@@#UG6@!b>Id{Z#@XQK$4&>Gx0AtSkHLbXN*6)KYrgE-6^Z7cicj&Q5j)1WT z=kY7enh3r`<|!)uW5e~Kwo51bM_?a!kI8a-w?n=T?6=x%SZhDIa~S&BAV<Ld`tkdy z>1UhH+l{_c@mja;CEUAx=Og~Reg%wU+`AtEwKlBv4f?>d$1vaEpwZODd%lTtSYznt z9>w3*CsfZY1K&pOe9r7_-{H>jq|xr0`mIL$MHlDU1@=(?NliU#t^eUhzoYS&y*=_% mpr#Mk|9CamYI6_ISnFZ#(cg|9^`NI0KrMw^E02J^K7ju(u0rns literal 0 HcmV?d00001 diff --git a/projects/cmd_sync_test/src/main.cpp b/projects/cmd_sync_test/src/main.cpp index a8a51b3b..ddc6420f 100644 --- a/projects/cmd_sync_test/src/main.cpp +++ b/projects/cmd_sync_test/src/main.cpp @@ -189,12 +189,6 @@ int main(int argc, const char** argv) { const uint32_t voxelResolution = 32; vkcv::Image voxelImage = core.createImage(vk::Format::eR8Unorm, voxelResolution, voxelResolution, voxelResolution, true); - - { - char voxelData [voxelResolution * voxelResolution * voxelResolution]; - memset(voxelData, 0, sizeof(voxelData)); - voxelImage.fill(voxelData); - } const vk::Format voxelizationDummyFormat = vk::Format::eR8Unorm; vkcv::Image voxelizationDummyRenderTarget = core.createImage(voxelizationDummyFormat, voxelResolution, voxelResolution, 1, false, true); @@ -294,29 +288,9 @@ int main(int argc, const char** argv) { 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), - glm::vec3(-3.f, 0.f, 0.f), - glm::vec3(0.f, 2.f, 0.f), - glm::vec3(0.f, -5.f, 0.f) - }; - const vkcv::DescriptorSetUsage descriptorUsage(0, core.getDescriptorSet(descriptorSet).vulkanHandle); const vkcv::DescriptorSetUsage voxelizationDescriptorUsage(0, core.getDescriptorSet(voxelizationDescriptorSet).vulkanHandle); - std::vector<glm::mat4> modelMatrices; - std::vector<vkcv::DrawcallInfo> drawcalls; - std::vector<vkcv::DrawcallInfo> shadowDrawcalls; - std::vector<vkcv::DrawcallInfo> voxelizationDrawcalls; - for (const auto& position : instancePositions) { - modelMatrices.push_back(glm::translate(glm::mat4(1.f), position)); - drawcalls.push_back(vkcv::DrawcallInfo(loadedMesh, { descriptorUsage })); - shadowDrawcalls.push_back(vkcv::DrawcallInfo(loadedMesh, {})); - voxelizationDrawcalls.push_back(vkcv::DrawcallInfo(loadedMesh, { voxelizationDescriptorUsage })); - } - modelMatrices.back() *= glm::scale(glm::mat4(1.f), glm::vec3(10.f, 1.f, 10.f)); - std::vector<std::array<glm::mat4, 2>> mainPassMatrices; std::vector<glm::mat4> mvpLight; std::vector<std::array<glm::mat4, 2>> voxelizationMatrices; @@ -328,29 +302,43 @@ int main(int argc, const char** argv) { } }); + vkcv::ShaderProgram resetVoxelShader; + resetVoxelShader.addShader(vkcv::ShaderStage::COMPUTE, "resources/shaders/voxelReset_comp.spv"); + resetVoxelShader.reflectShader(vkcv::ShaderStage::COMPUTE); + + vkcv::DescriptorSetHandle resetVoxelDescriptorSet = core.createDescriptorSet(resetVoxelShader.getReflectedDescriptors()[0]); + vkcv::PipelineHandle resetVoxelPipeline = core.createComputePipeline( + resetVoxelShader, + { core.getDescriptorSet(resetVoxelDescriptorSet).layout }); + + vkcv::DescriptorWrites resetVoxelWrites; + resetVoxelWrites.storageImageWrites = { vkcv::StorageImageDescriptorWrite(0, voxelImage.getHandle()) }; + core.writeDescriptorSet(resetVoxelDescriptorSet, resetVoxelWrites); + auto start = std::chrono::system_clock::now(); const auto appStartTime = start; while (window.isWindowOpen()) { vkcv::Window::pollEvents(); - + uint32_t swapchainWidth, swapchainHeight; if (!core.beginFrame(swapchainWidth, swapchainHeight)) { continue; } - + if ((swapchainWidth != windowWidth) || ((swapchainHeight != windowHeight))) { depthBuffer = core.createImage(depthBufferFormat, swapchainWidth, swapchainHeight).getHandle(); - + windowWidth = swapchainWidth; windowHeight = swapchainHeight; } - + auto end = std::chrono::system_clock::now(); auto deltatime = std::chrono::duration_cast<std::chrono::microseconds>(end - start); start = end; cameraManager.getCamera().updateView(deltatime.count() * 0.000001); - const float sunTheta = std::chrono::duration_cast<std::chrono::milliseconds>(end - appStartTime).count() * 0.001f; + const float timeSinceStart = std::chrono::duration_cast<std::chrono::milliseconds>(end - appStartTime).count(); + const float sunTheta = timeSinceStart * 0.001f; lightInfo.direction = glm::normalize(glm::vec3(std::cos(sunTheta), 1, std::sin(sunTheta))); const float shadowProjectionSize = 5.f; @@ -377,18 +365,39 @@ int main(int argc, const char** argv) { const float voxelizationHalfExtent = 0.5f * voxelizationExtent; const glm::mat4 voxelizationProjection = glm::ortho( -voxelizationHalfExtent, - voxelizationHalfExtent, + voxelizationHalfExtent, -voxelizationHalfExtent, - voxelizationHalfExtent, + voxelizationHalfExtent, -voxelizationHalfExtent, - voxelizationHalfExtent); + voxelizationHalfExtent); + + // compute positions and transform matrices + std::vector<glm::vec3> instancePositions = { + glm::vec3(0.f, -2.f, 0.f), + glm::vec3(3.f, 2 * glm::sin(timeSinceStart * 0.0025), 0.f), + glm::vec3(-3.f, 0.f, 0.f), + glm::vec3(0.f, 2.f, 0.f), + glm::vec3(0.f, -5.f, 0.f) + }; + + std::vector<glm::mat4> modelMatrices; + std::vector<vkcv::DrawcallInfo> drawcalls; + std::vector<vkcv::DrawcallInfo> shadowDrawcalls; + std::vector<vkcv::DrawcallInfo> voxelizationDrawcalls; + for (const auto& position : instancePositions) { + modelMatrices.push_back(glm::translate(glm::mat4(1.f), position)); + drawcalls.push_back(vkcv::DrawcallInfo(loadedMesh, { descriptorUsage })); + shadowDrawcalls.push_back(vkcv::DrawcallInfo(loadedMesh, {})); + voxelizationDrawcalls.push_back(vkcv::DrawcallInfo(loadedMesh, { voxelizationDescriptorUsage })); + } + modelMatrices.back() *= glm::scale(glm::mat4(1.f), glm::vec3(10.f, 1.f, 10.f)); mainPassMatrices.clear(); mvpLight.clear(); voxelizationMatrices.clear(); for (const auto& m : modelMatrices) { mainPassMatrices.push_back({ viewProjectionCamera * m, m }); - mvpLight.push_back(lightInfo.lightMatrix* m); + mvpLight.push_back(lightInfo.lightMatrix * m); voxelizationMatrices.push_back({ voxelizationProjection * m, m }); } @@ -400,6 +409,7 @@ int main(int argc, const char** argv) { auto cmdStream = core.createCommandStream(vkcv::QueueType::Graphics); + // shadow map core.recordDrawcallsToCmdStream( cmdStream, shadowPass, @@ -408,7 +418,23 @@ int main(int argc, const char** argv) { shadowDrawcalls, { shadowMap.getHandle() }); + // reset voxels + const uint32_t resetVoxelGroupSize[3] = { 4, 4, 4 }; + uint32_t resetVoxelDispatchCount[3]; + for(int i = 0; i < 3; i++) { + resetVoxelDispatchCount[i] = glm::ceil(voxelResolution / float(resetVoxelGroupSize[i])); + } + core.prepareImageForStorage(cmdStream, voxelImage.getHandle()); + core.recordComputeDispatchToCmdStream( + cmdStream, + resetVoxelPipeline, + resetVoxelDispatchCount, + { vkcv::DescriptorSetUsage(0, core.getDescriptorSet(resetVoxelDescriptorSet).vulkanHandle) }, + vkcv::PushConstantData(nullptr, 0)); + core.recordImageMemoryBarrier(cmdStream, voxelImage.getHandle()); + + // voxelization core.recordDrawcallsToCmdStream( cmdStream, voxelizationPass, @@ -419,6 +445,7 @@ int main(int argc, const char** argv) { core.prepareImageForSampling(cmdStream, shadowMap.getHandle()); + // main pass core.recordDrawcallsToCmdStream( cmdStream, trianglePass, @@ -440,6 +467,7 @@ int main(int argc, const char** argv) { renderTargets); } + // present and end core.prepareSwapchainImageForPresent(cmdStream); core.submitCommandStream(cmdStream); -- GitLab