Skip to content
Snippets Groups Projects
Commit 7077401d authored by Alexander Gauggel's avatar Alexander Gauggel
Browse files

[#70] Put voxelization in separate class to improve readability

parent ccb204b1
No related branches found
No related tags found
1 merge request!57Resolve "Basic voxelization"
...@@ -11,6 +11,10 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) ...@@ -11,6 +11,10 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
# adding source files to the project # adding source files to the project
add_executable(voxelization src/main.cpp) add_executable(voxelization src/main.cpp)
target_sources(voxelization PRIVATE
src/Voxelization.hpp
src/Voxelization.cpp)
# this should fix the execution path to load local files from the project (for MSVC) # this should fix the execution path to load local files from the project (for MSVC)
if(MSVC) if(MSVC)
set_target_properties(voxelization PROPERTIES RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) set_target_properties(voxelization PROPERTIES RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
......
#include "Voxelization.hpp"
#include <vkcv/shader/GLSLCompiler.hpp>
#include <glm/gtc/matrix_transform.hpp>
vkcv::ShaderProgram loadVoxelizationShader() {
vkcv::shader::GLSLCompiler compiler;
vkcv::ShaderProgram shader;
compiler.compile(vkcv::ShaderStage::VERTEX, "resources/shaders/voxelization.vert",
[&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) {
shader.addShader(shaderStage, path);
});
compiler.compile(vkcv::ShaderStage::GEOMETRY, "resources/shaders/voxelization.geom",
[&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) {
shader.addShader(shaderStage, path);
});
compiler.compile(vkcv::ShaderStage::FRAGMENT, "resources/shaders/voxelization.frag",
[&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) {
shader.addShader(shaderStage, path);
});
return shader;
}
vkcv::ShaderProgram loadVoxelVisualisationShader() {
vkcv::shader::GLSLCompiler compiler;
vkcv::ShaderProgram shader;
compiler.compile(vkcv::ShaderStage::VERTEX, "resources/shaders/voxelVisualisation.vert",
[&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) {
shader.addShader(shaderStage, path);
});
compiler.compile(vkcv::ShaderStage::GEOMETRY, "resources/shaders/voxelVisualisation.geom",
[&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) {
shader.addShader(shaderStage, path);
});
compiler.compile(vkcv::ShaderStage::FRAGMENT, "resources/shaders/voxelVisualisation.frag",
[&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) {
shader.addShader(shaderStage, path);
});
return shader;
}
vkcv::ShaderProgram loadVoxelResetShader() {
vkcv::shader::GLSLCompiler compiler;
vkcv::ShaderProgram shader;
compiler.compile(vkcv::ShaderStage::COMPUTE, "resources/shaders/voxelReset.comp",
[&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) {
shader.addShader(shaderStage, path);
});
return shader;
}
const uint32_t voxelResolution = 32;
const size_t voxelCount = voxelResolution * voxelResolution * voxelResolution;
const vk::Format voxelizationDummyFormat = vk::Format::eR8Unorm;
Voxelization::Voxelization(vkcv::Core* corePtr, const Dependencies& dependencies)
:
m_corePtr(corePtr),
m_voxelImage(m_corePtr->createImage(vk::Format::eR8Unorm, voxelResolution, voxelResolution, voxelResolution, true)),
m_dummyRenderTarget(m_corePtr->createImage(voxelizationDummyFormat, voxelResolution, voxelResolution, 1, false, true)),
m_voxelInfoBuffer(m_corePtr->createBuffer<VoxelizationInfo>(vkcv::BufferType::UNIFORM, 1)),
m_visualisationIndexBuffer(m_corePtr->createBuffer<uint16_t>(vkcv::BufferType::INDEX, voxelCount)) {
assert(corePtr);
const vkcv::ShaderProgram voxelizationShader = loadVoxelizationShader();
vkcv::PassConfig voxelizationPassConfig({
vkcv::AttachmentDescription(vkcv::AttachmentOperation::DONT_CARE, vkcv::AttachmentOperation::DONT_CARE, voxelizationDummyFormat) });
m_voxelizationPass = m_corePtr->createPass(voxelizationPassConfig);
std::vector<vkcv::DescriptorBinding> voxelizationDescriptorBindings = { voxelizationShader.getReflectedDescriptors()[0] };
m_voxelizationDescriptorSet = m_corePtr->createDescriptorSet(voxelizationDescriptorBindings);
const vkcv::PipelineConfig voxelizationPipeConfig{
voxelizationShader,
voxelResolution,
voxelResolution,
m_voxelizationPass,
dependencies.vertexLayout,
{ m_corePtr->getDescriptorSet(m_voxelizationDescriptorSet).layout },
false,
true };
m_voxelizationPipe = m_corePtr->createGraphicsPipeline(voxelizationPipeConfig);
vkcv::DescriptorWrites voxelizationDescriptorWrites;
voxelizationDescriptorWrites.storageImageWrites = { vkcv::StorageImageDescriptorWrite(0, m_voxelImage.getHandle()) };
voxelizationDescriptorWrites.uniformBufferWrites = { vkcv::UniformBufferDescriptorWrite(1, m_voxelInfoBuffer.getHandle()) };
m_corePtr->writeDescriptorSet(m_voxelizationDescriptorSet, voxelizationDescriptorWrites);
vkcv::ShaderProgram voxelVisualisationShader = loadVoxelVisualisationShader();
const std::vector<vkcv::DescriptorBinding> voxelVisualisationDescriptorBindings = { voxelVisualisationShader.getReflectedDescriptors()[0] };
m_visualisationDescriptorSet = m_corePtr->createDescriptorSet(voxelVisualisationDescriptorBindings);
const vkcv::AttachmentDescription voxelVisualisationColorAttachments(
vkcv::AttachmentOperation::STORE,
vkcv::AttachmentOperation::LOAD,
dependencies.colorBufferFormat
);
const vkcv::AttachmentDescription voxelVisualisationDepthAttachments(
vkcv::AttachmentOperation::STORE,
vkcv::AttachmentOperation::LOAD,
dependencies.depthBufferFormat
);
vkcv::PassConfig voxelVisualisationPassDefinition({ voxelVisualisationColorAttachments, voxelVisualisationDepthAttachments });
m_visualisationPass = m_corePtr->createPass(voxelVisualisationPassDefinition);
const vkcv::PipelineConfig voxelVisualisationPipeConfig{
voxelVisualisationShader,
0,
0,
m_visualisationPass,
{},
{ m_corePtr->getDescriptorSet(m_visualisationDescriptorSet).layout },
true,
false,
vkcv::PrimitiveTopology::PointList }; // points are extended to cubes in the geometry shader
m_visualisationPipe = m_corePtr->createGraphicsPipeline(voxelVisualisationPipeConfig);
std::vector<uint16_t> voxelIndexData;
for (int i = 0; i < voxelCount; i++) {
voxelIndexData.push_back(i);
}
m_visualisationIndexBuffer.fill(voxelIndexData);
vkcv::DescriptorWrites voxelVisualisationDescriptorWrite;
voxelVisualisationDescriptorWrite.storageImageWrites = { vkcv::StorageImageDescriptorWrite(0, m_voxelImage.getHandle()) };
voxelVisualisationDescriptorWrite.uniformBufferWrites = { vkcv::UniformBufferDescriptorWrite(1, m_voxelInfoBuffer.getHandle()) };
m_corePtr->writeDescriptorSet(m_visualisationDescriptorSet, voxelVisualisationDescriptorWrite);
const vkcv::DescriptorSetUsage voxelizationDescriptorUsage(0, m_corePtr->getDescriptorSet(m_visualisationDescriptorSet).vulkanHandle);
vkcv::ShaderProgram resetVoxelShader = loadVoxelResetShader();
m_voxelResetDescriptorSet = m_corePtr->createDescriptorSet(resetVoxelShader.getReflectedDescriptors()[0]);
m_voxelResetPipe = m_corePtr->createComputePipeline(
resetVoxelShader,
{ m_corePtr->getDescriptorSet(m_voxelResetDescriptorSet).layout });
vkcv::DescriptorWrites resetVoxelWrites;
resetVoxelWrites.storageImageWrites = { vkcv::StorageImageDescriptorWrite(0, m_voxelImage.getHandle()) };
m_corePtr->writeDescriptorSet(m_voxelResetDescriptorSet, resetVoxelWrites);
}
void Voxelization::voxelizeMeshes(
vkcv::CommandStreamHandle cmdStream,
const glm::vec3& cameraPosition,
const std::vector<vkcv::Mesh>& meshes,
const std::vector<glm::mat4>& modelMatrices) {
const float voxelizationExtent = 20.f;
VoxelizationInfo voxelizationInfo;
voxelizationInfo.extent = voxelizationExtent;
// move voxel offset with camera in voxel sized steps
const float voxelSize = voxelizationExtent / voxelResolution;
voxelizationInfo.offset = glm::floor(cameraPosition / voxelSize) * voxelSize;
m_voxelInfoBuffer.fill({ voxelizationInfo });
const float voxelizationHalfExtent = 0.5f * voxelizationExtent;
const glm::mat4 voxelizationProjection = glm::ortho(
-voxelizationHalfExtent,
voxelizationHalfExtent,
-voxelizationHalfExtent,
voxelizationHalfExtent,
-voxelizationHalfExtent,
voxelizationHalfExtent);
const glm::mat4 voxelizationView = glm::translate(glm::mat4(1.f), -voxelizationInfo.offset);
const glm::mat4 voxelizationViewProjection = voxelizationProjection * voxelizationView;
std::vector<std::array<glm::mat4, 2>> voxelizationMatrices;
for (const auto& m : modelMatrices) {
voxelizationMatrices.push_back({ voxelizationViewProjection * m, m });
}
const vkcv::PushConstantData voxelizationPushConstantData((void*)voxelizationMatrices.data(), 2 * sizeof(glm::mat4));
// 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]));
}
m_corePtr->prepareImageForStorage(cmdStream, m_voxelImage.getHandle());
m_corePtr->recordComputeDispatchToCmdStream(
cmdStream,
m_voxelResetPipe,
resetVoxelDispatchCount,
{ vkcv::DescriptorSetUsage(0, m_corePtr->getDescriptorSet(m_voxelResetDescriptorSet).vulkanHandle) },
vkcv::PushConstantData(nullptr, 0));
m_corePtr->recordImageMemoryBarrier(cmdStream, m_voxelImage.getHandle());
std::vector<vkcv::DrawcallInfo> drawcalls;
for (const auto& mesh : meshes) {
drawcalls.push_back(vkcv::DrawcallInfo(
mesh,
{ vkcv::DescriptorSetUsage(0, m_corePtr->getDescriptorSet(m_voxelizationDescriptorSet).vulkanHandle) }));
}
// voxelization
m_corePtr->recordDrawcallsToCmdStream(
cmdStream,
m_voxelizationPass,
m_voxelizationPipe,
voxelizationPushConstantData,
drawcalls,
{ m_dummyRenderTarget.getHandle() });
m_corePtr->recordImageMemoryBarrier(cmdStream, m_voxelImage.getHandle());
}
void Voxelization::renderVoxelVisualisation(
vkcv::CommandStreamHandle cmdStream,
const glm::mat4& viewProjectin,
const std::vector<vkcv::ImageHandle>& renderTargets) {
const vkcv::PushConstantData voxelVisualisationPushConstantData((void*)&viewProjectin, sizeof(glm::mat4));
const auto drawcall = vkcv::DrawcallInfo(
vkcv::Mesh({}, m_visualisationIndexBuffer.getVulkanHandle(), voxelCount),
{ vkcv::DescriptorSetUsage(0, m_corePtr->getDescriptorSet(m_visualisationDescriptorSet).vulkanHandle) });
m_corePtr->recordDrawcallsToCmdStream(
cmdStream,
m_visualisationPass,
m_visualisationPipe,
voxelVisualisationPushConstantData,
{ drawcall },
renderTargets);
}
\ No newline at end of file
#pragma once
#include <vkcv/Core.hpp>
#include <glm/glm.hpp>
class Voxelization{
public:
struct Dependencies {
vkcv::VertexLayout vertexLayout;
vk::Format colorBufferFormat;
vk::Format depthBufferFormat;
};
Voxelization(vkcv::Core* corePtr, const Dependencies& dependencies);
void voxelizeMeshes(
vkcv::CommandStreamHandle cmdStream,
const glm::vec3& cameraPosition,
const std::vector<vkcv::Mesh>& meshes,
const std::vector<glm::mat4>& modelMatrices);
void renderVoxelVisualisation(
vkcv::CommandStreamHandle cmdStream,
const glm::mat4& viewProjectin,
const std::vector<vkcv::ImageHandle>& renderTargets);
private:
vkcv::Core* m_corePtr;
vkcv::Image m_voxelImage;
vkcv::Image m_dummyRenderTarget;
vkcv::PassHandle m_voxelizationPass;
vkcv::PipelineHandle m_voxelizationPipe;
vkcv::DescriptorSetHandle m_voxelizationDescriptorSet;
vkcv::PipelineHandle m_voxelResetPipe;
vkcv::DescriptorSetHandle m_voxelResetDescriptorSet;
vkcv::PassHandle m_visualisationPass;
vkcv::PipelineHandle m_visualisationPipe;
vkcv::Buffer<uint16_t> m_visualisationIndexBuffer;
vkcv::DescriptorSetHandle m_visualisationDescriptorSet;
struct VoxelizationInfo {
glm::vec3 offset;
float extent;
};
vkcv::Buffer<VoxelizationInfo> m_voxelInfoBuffer;
};
\ No newline at end of file
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include <vkcv/asset/asset_loader.hpp> #include <vkcv/asset/asset_loader.hpp>
#include <vkcv/shader/GLSLCompiler.hpp> #include <vkcv/shader/GLSLCompiler.hpp>
#include <vkcv/Logger.hpp> #include <vkcv/Logger.hpp>
#include "Voxelization.hpp"
int main(int argc, const char** argv) { int main(int argc, const char** argv) {
const char* applicationName = "Voxelization"; const char* applicationName = "Voxelization";
...@@ -145,10 +146,10 @@ int main(int argc, const char** argv) { ...@@ -145,10 +146,10 @@ int main(int argc, const char** argv) {
vkcv::DescriptorSetHandle descriptorSet = core.createDescriptorSet(descriptorBindings); vkcv::DescriptorSetHandle descriptorSet = core.createDescriptorSet(descriptorBindings);
const vkcv::PipelineConfig forwardPipelineConfig { const vkcv::PipelineConfig forwardPipelineConfig {
forwardProgram, forwardProgram,
windowWidth, windowWidth,
windowHeight, windowHeight,
forwardPass, forwardPass,
vertexLayout, vertexLayout,
{ core.getDescriptorSet(descriptorSet).layout }, { core.getDescriptorSet(descriptorSet).layout },
true true
...@@ -219,123 +220,11 @@ int main(int argc, const char** argv) { ...@@ -219,123 +220,11 @@ int main(int argc, const char** argv) {
LightInfo lightInfo; LightInfo lightInfo;
vkcv::Buffer lightBuffer = core.createBuffer<LightInfo>(vkcv::BufferType::UNIFORM, sizeof(glm::vec3)); vkcv::Buffer lightBuffer = core.createBuffer<LightInfo>(vkcv::BufferType::UNIFORM, sizeof(glm::vec3));
const uint32_t voxelResolution = 32;
vkcv::Image voxelImage = core.createImage(vk::Format::eR8Unorm, voxelResolution, voxelResolution, voxelResolution, true);
const vk::Format voxelizationDummyFormat = vk::Format::eR8Unorm;
vkcv::Image voxelizationDummyRenderTarget = core.createImage(voxelizationDummyFormat, voxelResolution, voxelResolution, 1, false, true);
vkcv::ShaderProgram voxelizationShader;
compiler.compile(vkcv::ShaderStage::VERTEX, "resources/shaders/voxelization.vert",
[&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) {
voxelizationShader.addShader(shaderStage, path);
});
compiler.compile(vkcv::ShaderStage::GEOMETRY, "resources/shaders/voxelization.geom",
[&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) {
voxelizationShader.addShader(shaderStage, path);
});
compiler.compile(vkcv::ShaderStage::FRAGMENT, "resources/shaders/voxelization.frag",
[&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) {
voxelizationShader.addShader(shaderStage, path);
});
vkcv::PassConfig voxelizationPassConfig({
vkcv::AttachmentDescription(vkcv::AttachmentOperation::DONT_CARE, vkcv::AttachmentOperation::DONT_CARE, voxelizationDummyFormat)});
vkcv::PassHandle voxelizationPass = core.createPass(voxelizationPassConfig);
std::vector<vkcv::DescriptorBinding> voxelizationDescriptorBindings = { voxelizationShader.getReflectedDescriptors()[0] };
vkcv::DescriptorSetHandle voxelizationDescriptorSet = core.createDescriptorSet(voxelizationDescriptorBindings);
const vkcv::PipelineConfig voxelizationPipeConfig{
voxelizationShader,
voxelResolution,
voxelResolution,
voxelizationPass,
vertexLayout,
{ core.getDescriptorSet(voxelizationDescriptorSet).layout },
false,
true };
const vkcv::PipelineHandle voxelizationPipe = core.createGraphicsPipeline(voxelizationPipeConfig);
struct VoxelizationInfo {
glm::vec3 offset;
float extent;
};
vkcv::Buffer voxelizationInfoBuffer = core.createBuffer<VoxelizationInfo>(vkcv::BufferType::UNIFORM, sizeof(VoxelizationInfo));
vkcv::DescriptorWrites voxelizationDescriptorWrites;
voxelizationDescriptorWrites.storageImageWrites = { vkcv::StorageImageDescriptorWrite(0, voxelImage.getHandle()) };
voxelizationDescriptorWrites.uniformBufferWrites = { vkcv::UniformBufferDescriptorWrite(1, voxelizationInfoBuffer.getHandle()) };
core.writeDescriptorSet(voxelizationDescriptorSet, voxelizationDescriptorWrites);
const size_t voxelCount = voxelResolution * voxelResolution * voxelResolution;
vkcv::ShaderProgram voxelVisualisationShader;
compiler.compile(vkcv::ShaderStage::VERTEX, "resources/shaders/voxelVisualisation.vert",
[&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) {
voxelVisualisationShader.addShader(shaderStage, path);
});
compiler.compile(vkcv::ShaderStage::GEOMETRY, "resources/shaders/voxelVisualisation.geom",
[&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) {
voxelVisualisationShader.addShader(shaderStage, path);
});
compiler.compile(vkcv::ShaderStage::FRAGMENT, "resources/shaders/voxelVisualisation.frag",
[&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) {
voxelVisualisationShader.addShader(shaderStage, path);
});
const std::vector<vkcv::DescriptorBinding> voxelVisualisationDescriptorBindings = { voxelVisualisationShader.getReflectedDescriptors()[0] };
vkcv::DescriptorSetHandle voxelVisualisationDescriptorSet = core.createDescriptorSet(voxelVisualisationDescriptorBindings);
const vkcv::AttachmentDescription voxelVisualisationColorAttachments(
vkcv::AttachmentOperation::STORE,
vkcv::AttachmentOperation::LOAD,
colorBufferFormat
);
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 vkcv::DescriptorSetUsage descriptorUsage(0, core.getDescriptorSet(descriptorSet).vulkanHandle); const vkcv::DescriptorSetUsage descriptorUsage(0, core.getDescriptorSet(descriptorSet).vulkanHandle);
const vkcv::DescriptorSetUsage voxelizationDescriptorUsage(0, core.getDescriptorSet(voxelizationDescriptorSet).vulkanHandle);
std::vector<std::array<glm::mat4, 2>> mainPassMatrices; std::vector<std::array<glm::mat4, 2>> mainPassMatrices;
std::vector<glm::mat4> mvpLight; std::vector<glm::mat4> mvpLight;
std::vector<std::array<glm::mat4, 2>> voxelizationMatrices;
bool renderVoxelVis = false; bool renderVoxelVis = false;
window.e_key.add([&renderVoxelVis](int key ,int scancode, int action, int mods) { window.e_key.add([&renderVoxelVis](int key ,int scancode, int action, int mods) {
...@@ -344,21 +233,6 @@ int main(int argc, const char** argv) { ...@@ -344,21 +233,6 @@ int main(int argc, const char** argv) {
} }
}); });
vkcv::ShaderProgram resetVoxelShader;
compiler.compile(vkcv::ShaderStage::COMPUTE, "resources/shaders/voxelReset.comp",
[&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) {
resetVoxelShader.addShader(shaderStage, path);
});
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);
// gamma correction compute shader // gamma correction compute shader
vkcv::ShaderProgram gammaCorrectionProgram; vkcv::ShaderProgram gammaCorrectionProgram;
compiler.compile(vkcv::ShaderStage::COMPUTE, "resources/shaders/gammaCorrection.comp", compiler.compile(vkcv::ShaderStage::COMPUTE, "resources/shaders/gammaCorrection.comp",
...@@ -412,19 +286,30 @@ int main(int argc, const char** argv) { ...@@ -412,19 +286,30 @@ int main(int argc, const char** argv) {
} }
// prepare drawcalls // prepare drawcalls
std::vector<vkcv::DrawcallInfo> drawcalls; std::vector<vkcv::Mesh> meshes;
std::vector<vkcv::DrawcallInfo> shadowDrawcalls;
std::vector<vkcv::DrawcallInfo> voxelizationDrawcalls;
for (int i = 0; i < scene.vertexGroups.size(); i++) { for (int i = 0; i < scene.vertexGroups.size(); i++) {
vkcv::Mesh mesh(vertexBufferBindings[i], indexBuffers[i].getVulkanHandle(), scene.vertexGroups[i].numIndices); vkcv::Mesh mesh(
vertexBufferBindings[i],
indexBuffers[i].getVulkanHandle(),
scene.vertexGroups[i].numIndices);
meshes.push_back(mesh);
}
std::vector<vkcv::DrawcallInfo> drawcalls;
std::vector<vkcv::DrawcallInfo> shadowDrawcalls;
for (int i = 0; i < meshes.size(); i++) {
vkcv::DescriptorSetUsage descriptorUsage(0, core.getDescriptorSet(descriptorSets[i]).vulkanHandle); vkcv::DescriptorSetUsage descriptorUsage(0, core.getDescriptorSet(descriptorSets[i]).vulkanHandle);
drawcalls.push_back(vkcv::DrawcallInfo(mesh, { descriptorUsage })); drawcalls.push_back(vkcv::DrawcallInfo(meshes[i], { descriptorUsage }));
shadowDrawcalls.push_back(vkcv::DrawcallInfo(mesh, {})); shadowDrawcalls.push_back(vkcv::DrawcallInfo(meshes[i], {}));
voxelizationDrawcalls.push_back(vkcv::DrawcallInfo(mesh, { voxelizationDescriptorUsage }));
} }
Voxelization::Dependencies voxelDependencies;
voxelDependencies.colorBufferFormat = colorBufferFormat;
voxelDependencies.depthBufferFormat = depthBufferFormat;
voxelDependencies.vertexLayout = vertexLayout;
Voxelization voxelization(&core, voxelDependencies);
auto start = std::chrono::system_clock::now(); auto start = std::chrono::system_clock::now();
const auto appStartTime = start; const auto appStartTime = start;
while (window.isWindowOpen()) { while (window.isWindowOpen()) {
...@@ -482,43 +367,18 @@ int main(int argc, const char** argv) { ...@@ -482,43 +367,18 @@ int main(int argc, const char** argv) {
const glm::mat4 viewProjectionCamera = cameraManager.getActiveCamera().getMVP(); const glm::mat4 viewProjectionCamera = cameraManager.getActiveCamera().getMVP();
const float voxelizationExtent = 20.f;
VoxelizationInfo voxelizationInfo;
voxelizationInfo.extent = voxelizationExtent;
// move voxel offset with camera in voxel sized steps
const glm::vec3 cameraPos = cameraManager.getActiveCamera().getPosition();
const float voxelSize = voxelizationExtent / voxelResolution;
voxelizationInfo.offset = glm::floor(cameraPos / voxelSize) * voxelSize;
voxelizationInfoBuffer.fill({ voxelizationInfo });
const float voxelizationHalfExtent = 0.5f * voxelizationExtent;
const glm::mat4 voxelizationProjection = glm::ortho(
-voxelizationHalfExtent,
voxelizationHalfExtent,
-voxelizationHalfExtent,
voxelizationHalfExtent,
-voxelizationHalfExtent,
voxelizationHalfExtent);
const glm::mat4 voxelizationView = glm::translate(glm::mat4(1.f), -voxelizationInfo.offset);
const glm::mat4 voxelizationViewProjection = voxelizationProjection * voxelizationView;
mainPassMatrices.clear(); mainPassMatrices.clear();
mvpLight.clear(); mvpLight.clear();
voxelizationMatrices.clear();
for (const auto& m : modelMatrices) { for (const auto& m : modelMatrices) {
mainPassMatrices.push_back({ viewProjectionCamera * m, m }); mainPassMatrices.push_back({ viewProjectionCamera * m, m });
mvpLight.push_back(lightInfo.lightMatrix * m); mvpLight.push_back(lightInfo.lightMatrix * m);
voxelizationMatrices.push_back({ voxelizationViewProjection * m, m });
} }
vkcv::PushConstantData pushConstantData((void*)mainPassMatrices.data(), 2 * sizeof(glm::mat4)); vkcv::PushConstantData pushConstantData((void*)mainPassMatrices.data(), 2 * sizeof(glm::mat4));
const std::vector<vkcv::ImageHandle> renderTargets = { colorBuffer, depthBuffer }; const std::vector<vkcv::ImageHandle> renderTargets = { colorBuffer, depthBuffer };
const vkcv::PushConstantData shadowPushConstantData((void*)mvpLight.data(), sizeof(glm::mat4)); const vkcv::PushConstantData shadowPushConstantData((void*)mvpLight.data(), sizeof(glm::mat4));
const vkcv::PushConstantData voxelizationPushConstantData((void*)voxelizationMatrices.data(), 2 * sizeof(glm::mat4));
auto cmdStream = core.createCommandStream(vkcv::QueueType::Graphics); auto cmdStream = core.createCommandStream(vkcv::QueueType::Graphics);
...@@ -530,34 +390,14 @@ int main(int argc, const char** argv) { ...@@ -530,34 +390,14 @@ int main(int argc, const char** argv) {
shadowPushConstantData, shadowPushConstantData,
shadowDrawcalls, shadowDrawcalls,
{ shadowMap.getHandle() }); { 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,
voxelizationPipe,
voxelizationPushConstantData,
voxelizationDrawcalls,
{ voxelizationDummyRenderTarget.getHandle() });
core.prepareImageForSampling(cmdStream, shadowMap.getHandle()); core.prepareImageForSampling(cmdStream, shadowMap.getHandle());
voxelization.voxelizeMeshes(
cmdStream,
cameraManager.getActiveCamera().getPosition(),
meshes,
modelMatrices);
// main pass // main pass
core.recordDrawcallsToCmdStream( core.recordDrawcallsToCmdStream(
cmdStream, cmdStream,
...@@ -568,16 +408,7 @@ int main(int argc, const char** argv) { ...@@ -568,16 +408,7 @@ int main(int argc, const char** argv) {
renderTargets); renderTargets);
if (renderVoxelVis) { if (renderVoxelVis) {
const vkcv::PushConstantData voxelVisualisationPushConstantData((void*)&viewProjectionCamera, sizeof(glm::mat4)); voxelization.renderVoxelVisualisation(cmdStream, viewProjectionCamera, renderTargets);
core.recordImageMemoryBarrier(cmdStream, voxelImage.getHandle());
core.recordDrawcallsToCmdStream(
cmdStream,
voxelVisualisationPass,
voxelVisualisationPipe,
voxelVisualisationPushConstantData,
{ voxelVisualisationDrawcall },
renderTargets);
} }
const uint32_t gammaCorrectionLocalGroupSize = 8; const uint32_t gammaCorrectionLocalGroupSize = 8;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment