From 424334dfac6e9b1c51fb4ded7f02d3366f8fec38 Mon Sep 17 00:00:00 2001 From: Alexander Gauggel <agauggel@uni-koblenz.de> Date: Thu, 17 Jun 2021 17:02:00 +0200 Subject: [PATCH] [#70] Albedo color now voxelized --- .../resources/shaders/perMeshResources.inc | 2 + .../resources/shaders/shader.frag | 13 +- .../resources/shaders/voxelBufferToImage.comp | 4 +- .../resources/shaders/voxelization.frag | 10 +- .../resources/shaders/voxelization.geom | 3 + .../resources/shaders/voxelization.vert | 2 + projects/voxelization/src/Voxelization.cpp | 25 ++- projects/voxelization/src/Voxelization.hpp | 9 +- projects/voxelization/src/main.cpp | 156 +++++++++--------- 9 files changed, 123 insertions(+), 101 deletions(-) create mode 100644 projects/voxelization/resources/shaders/perMeshResources.inc diff --git a/projects/voxelization/resources/shaders/perMeshResources.inc b/projects/voxelization/resources/shaders/perMeshResources.inc new file mode 100644 index 00000000..95e4fb7c --- /dev/null +++ b/projects/voxelization/resources/shaders/perMeshResources.inc @@ -0,0 +1,2 @@ +layout(set=1, binding=0) uniform texture2D albedoTexture; +layout(set=1, binding=1) uniform sampler textureSampler; \ No newline at end of file diff --git a/projects/voxelization/resources/shaders/shader.frag b/projects/voxelization/resources/shaders/shader.frag index 95f1b331..edafc8c0 100644 --- a/projects/voxelization/resources/shaders/shader.frag +++ b/projects/voxelization/resources/shaders/shader.frag @@ -1,5 +1,8 @@ #version 450 #extension GL_ARB_separate_shader_objects : enable +#extension GL_GOOGLE_include_directive : enable + +#include "perMeshResources.inc" layout(location = 0) in vec3 passNormal; layout(location = 1) in vec2 passUV; @@ -7,14 +10,12 @@ layout(location = 2) in vec3 passPos; layout(location = 0) out vec3 outColor; -layout(set=0, binding=0) uniform texture2D meshTexture; -layout(set=0, binding=1) uniform sampler textureSampler; -layout(set=0, binding=2) uniform sunBuffer { +layout(set=0, binding=0) uniform sunBuffer { vec3 L; float padding; mat4 lightMatrix; }; -layout(set=0, binding=3) uniform texture2D shadowMap; -layout(set=0, binding=4) uniform sampler shadowMapSampler; +layout(set=0, binding=1) uniform texture2D shadowMap; +layout(set=0, binding=2) uniform sampler shadowMapSampler; float shadowTest(vec3 worldPos){ vec4 lightPos = lightMatrix * vec4(worldPos, 1); @@ -39,6 +40,6 @@ void main() { vec3 sun = sunColor * clamp(dot(N, L), 0, 1); sun *= shadowTest(passPos); vec3 ambient = vec3(0.1); - vec3 albedo = texture(sampler2D(meshTexture, textureSampler), passUV).rgb; + vec3 albedo = texture(sampler2D(albedoTexture, textureSampler), passUV).rgb; outColor = albedo * (sun + ambient); } \ No newline at end of file diff --git a/projects/voxelization/resources/shaders/voxelBufferToImage.comp b/projects/voxelization/resources/shaders/voxelBufferToImage.comp index 20c56e31..5e829888 100644 --- a/projects/voxelization/resources/shaders/voxelBufferToImage.comp +++ b/projects/voxelization/resources/shaders/voxelBufferToImage.comp @@ -3,7 +3,7 @@ #include "voxel.inc" layout(set=0, binding=0, std430) buffer voxelBuffer{ - uint isFilled[]; + uint packedVoxelData[]; }; layout(set=0, binding=1, rgba16f) uniform image3D voxelImage; @@ -19,6 +19,6 @@ void main(){ ivec3 UV = ivec3(gl_GlobalInvocationID); uint flatIndex = flattenVoxelUVToIndex(UV, voxelImageSize); - vec4 color = unpackVoxelInfo(isFilled[flatIndex]); + vec4 color = unpackVoxelInfo(packedVoxelData[flatIndex]); imageStore(voxelImage, UV, vec4(color)); } \ No newline at end of file diff --git a/projects/voxelization/resources/shaders/voxelization.frag b/projects/voxelization/resources/shaders/voxelization.frag index 69e2052c..7ea161ce 100644 --- a/projects/voxelization/resources/shaders/voxelization.frag +++ b/projects/voxelization/resources/shaders/voxelization.frag @@ -3,11 +3,13 @@ #extension GL_GOOGLE_include_directive : enable #include "voxel.inc" +#include "perMeshResources.inc" -layout(location = 0) in vec3 passPos; +layout(location = 0) in vec3 passPos; +layout(location = 1) out vec2 passUV; layout(set=0, binding=0, std430) buffer voxelizationBuffer{ - uint isFilled[]; + uint packedVoxelData[]; }; layout(set=0, binding=1) uniform voxelizationInfo{ @@ -33,6 +35,6 @@ void main() { } uint flatIndex = flattenVoxelUVToIndex(UV, voxelImageSize); - vec3 color = vec3(1, 1, 0); - isFilled[flatIndex] = packVoxelInfo(color); + vec3 color = texture(sampler2D(albedoTexture, textureSampler), passUV).rgb; + atomicMax(packedVoxelData[flatIndex], packVoxelInfo(color)); } \ No newline at end of file diff --git a/projects/voxelization/resources/shaders/voxelization.geom b/projects/voxelization/resources/shaders/voxelization.geom index 23084853..19e31e2d 100644 --- a/projects/voxelization/resources/shaders/voxelization.geom +++ b/projects/voxelization/resources/shaders/voxelization.geom @@ -5,8 +5,10 @@ layout(triangles) in; layout (triangle_strip, max_vertices = 3) out; layout(location = 0) in vec3 passPosIn[3]; +layout(location = 1) in vec2 passUVIn[3]; layout(location = 0) out vec3 passPos; +layout(location = 1) out vec2 passUV; void main() { // compute geometric normal, no normalization necessary @@ -26,6 +28,7 @@ void main() { } 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]; + passUV = passUVIn[i]; EmitVertex(); } EndPrimitive(); diff --git a/projects/voxelization/resources/shaders/voxelization.vert b/projects/voxelization/resources/shaders/voxelization.vert index 6914e951..7a43c08b 100644 --- a/projects/voxelization/resources/shaders/voxelization.vert +++ b/projects/voxelization/resources/shaders/voxelization.vert @@ -6,6 +6,7 @@ layout(location = 1) in vec3 inNormal; layout(location = 2) in vec2 inUV; layout(location = 0) out vec3 passPos; +layout(location = 1) out vec2 passUV; layout( push_constant ) uniform constants{ mat4 mvp; @@ -15,4 +16,5 @@ layout( push_constant ) uniform constants{ void main() { gl_Position = mvp * vec4(inPosition, 1.0); passPos = (model * vec4(inPosition, 1)).xyz; + passUV = inUV; } \ No newline at end of file diff --git a/projects/voxelization/src/Voxelization.cpp b/projects/voxelization/src/Voxelization.cpp index a5658a38..e9748aa3 100644 --- a/projects/voxelization/src/Voxelization.cpp +++ b/projects/voxelization/src/Voxelization.cpp @@ -83,13 +83,18 @@ Voxelization::Voxelization(vkcv::Core* corePtr, const Dependencies& dependencies { voxelizationShader.getReflectedDescriptors()[0] }; m_voxelizationDescriptorSet = m_corePtr->createDescriptorSet(voxelizationDescriptorBindings); + vkcv::DescriptorSetHandle dummyPerMeshDescriptorSet = + m_corePtr->createDescriptorSet({ voxelizationShader.getReflectedDescriptors()[1] }); + const vkcv::PipelineConfig voxelizationPipeConfig{ voxelizationShader, voxelResolution, voxelResolution, m_voxelizationPass, dependencies.vertexLayout, - { m_corePtr->getDescriptorSet(m_voxelizationDescriptorSet).layout }, + { + m_corePtr->getDescriptorSet(m_voxelizationDescriptorSet).layout, + m_corePtr->getDescriptorSet(dummyPerMeshDescriptorSet).layout}, false, true }; m_voxelizationPipe = m_corePtr->createGraphicsPipeline(voxelizationPipeConfig); @@ -175,10 +180,11 @@ Voxelization::Voxelization(vkcv::Core* corePtr, const Dependencies& dependencies } void Voxelization::voxelizeMeshes( - vkcv::CommandStreamHandle cmdStream, - const glm::vec3& cameraPosition, - const std::vector<vkcv::Mesh>& meshes, - const std::vector<glm::mat4>& modelMatrices) { + vkcv::CommandStreamHandle cmdStream, + const glm::vec3& cameraPosition, + const std::vector<vkcv::Mesh>& meshes, + const std::vector<glm::mat4>& modelMatrices, + const std::vector<vkcv::DescriptorSetHandle>& perMeshDescriptorSets) { VoxelizationInfo voxelizationInfo; voxelizationInfo.extent = m_voxelExtent; @@ -226,10 +232,13 @@ void Voxelization::voxelizeMeshes( // voxelization std::vector<vkcv::DrawcallInfo> drawcalls; - for (const auto& mesh : meshes) { + for (int i = 0; i < meshes.size(); i++) { drawcalls.push_back(vkcv::DrawcallInfo( - mesh, - { vkcv::DescriptorSetUsage(0, m_corePtr->getDescriptorSet(m_voxelizationDescriptorSet).vulkanHandle) })); + meshes[i], + { + vkcv::DescriptorSetUsage(0, m_corePtr->getDescriptorSet(m_voxelizationDescriptorSet).vulkanHandle), + vkcv::DescriptorSetUsage(1, m_corePtr->getDescriptorSet(perMeshDescriptorSets[i]).vulkanHandle) + })); } m_corePtr->recordDrawcallsToCmdStream( diff --git a/projects/voxelization/src/Voxelization.hpp b/projects/voxelization/src/Voxelization.hpp index db1f1d85..f0f88493 100644 --- a/projects/voxelization/src/Voxelization.hpp +++ b/projects/voxelization/src/Voxelization.hpp @@ -12,10 +12,11 @@ public: 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); + vkcv::CommandStreamHandle cmdStream, + const glm::vec3& cameraPosition, + const std::vector<vkcv::Mesh>& meshes, + const std::vector<glm::mat4>& modelMatrices, + const std::vector<vkcv::DescriptorSetHandle>& perMeshDescriptorSets); void renderVoxelVisualisation( vkcv::CommandStreamHandle cmdStream, diff --git a/projects/voxelization/src/main.cpp b/projects/voxelization/src/main.cpp index 0a419ddd..b2d13030 100644 --- a/projects/voxelization/src/main.cpp +++ b/projects/voxelization/src/main.cpp @@ -135,15 +135,76 @@ int main(int argc, const char** argv) { const std::vector<vkcv::VertexAttachment> vertexAttachments = forwardProgram.getVertexAttachments(); - std::vector<vkcv::VertexBinding> vertexBindings; - for (size_t i = 0; i < vertexAttachments.size(); i++) { + std::vector<vkcv::VertexBinding> vertexBindings; + for (size_t i = 0; i < vertexAttachments.size(); i++) { vertexBindings.push_back(vkcv::VertexBinding(i, { vertexAttachments[i] })); - } - - const vkcv::VertexLayout vertexLayout (vertexBindings); + } + const vkcv::VertexLayout vertexLayout (vertexBindings); - std::vector<vkcv::DescriptorBinding> descriptorBindings = { forwardProgram.getReflectedDescriptors()[0] }; - vkcv::DescriptorSetHandle descriptorSet = core.createDescriptorSet(descriptorBindings); + // shadow map + vkcv::SamplerHandle shadowSampler = core.createSampler( + vkcv::SamplerFilterType::NEAREST, + vkcv::SamplerFilterType::NEAREST, + vkcv::SamplerMipmapMode::NEAREST, + vkcv::SamplerAddressMode::CLAMP_TO_EDGE + ); + const vk::Format shadowMapFormat = vk::Format::eD16Unorm; + const uint32_t shadowMapResolution = 1024; + const vkcv::Image shadowMap = core.createImage(shadowMapFormat, shadowMapResolution, shadowMapResolution, 1); + + // light info buffer + struct LightInfo { + glm::vec3 direction; + float padding; + glm::mat4 lightMatrix; + }; + LightInfo lightInfo; + vkcv::Buffer lightBuffer = core.createBuffer<LightInfo>(vkcv::BufferType::UNIFORM, sizeof(glm::vec3)); + + vkcv::DescriptorSetHandle forwardShadingDescriptorSet = + core.createDescriptorSet({ forwardProgram.getReflectedDescriptors()[0] }); + + vkcv::DescriptorWrites forwardDescriptorWrites; + forwardDescriptorWrites.uniformBufferWrites = { vkcv::UniformBufferDescriptorWrite(0, lightBuffer.getHandle()) }; + forwardDescriptorWrites.sampledImageWrites = { vkcv::SampledImageDescriptorWrite(1, shadowMap.getHandle()) }; + forwardDescriptorWrites.samplerWrites = { vkcv::SamplerDescriptorWrite(2, shadowSampler) }; + core.writeDescriptorSet(forwardShadingDescriptorSet, forwardDescriptorWrites); + + vkcv::SamplerHandle colorSampler = core.createSampler( + vkcv::SamplerFilterType::LINEAR, + vkcv::SamplerFilterType::LINEAR, + vkcv::SamplerMipmapMode::LINEAR, + vkcv::SamplerAddressMode::REPEAT + ); + + // prepare per mesh descriptor sets + std::vector<vkcv::DescriptorSetHandle> perMeshDescriptorSets; + std::vector<vkcv::Image> sceneImages; + for (const auto& vertexGroup : scene.vertexGroups) { + perMeshDescriptorSets.push_back(core.createDescriptorSet(forwardProgram.getReflectedDescriptors()[1])); + + const auto& material = scene.materials[vertexGroup.materialIndex]; + + int baseColorIndex = material.baseColor; + if (baseColorIndex < 0) { + vkcv_log(vkcv::LogLevel::WARNING, "Material lacks base color"); + baseColorIndex = 0; + } + + vkcv::asset::Texture& sceneTexture = scene.textures[baseColorIndex]; + + sceneImages.push_back(core.createImage(vk::Format::eR8G8B8A8Srgb, sceneTexture.w, sceneTexture.h)); + sceneImages.back().fill(sceneTexture.data.data()); + + vkcv::DescriptorWrites setWrites; + setWrites.sampledImageWrites = { + vkcv::SampledImageDescriptorWrite(0, sceneImages.back().getHandle()) + }; + setWrites.samplerWrites = { + vkcv::SamplerDescriptorWrite(1, colorSampler), + }; + core.writeDescriptorSet(perMeshDescriptorSets.back(), setWrites); + } const vkcv::PipelineConfig forwardPipelineConfig { forwardProgram, @@ -151,7 +212,8 @@ int main(int argc, const char** argv) { windowHeight, forwardPass, vertexLayout, - { core.getDescriptorSet(descriptorSet).layout }, + { core.getDescriptorSet(forwardShadingDescriptorSet).layout, + core.getDescriptorSet(perMeshDescriptorSets[0]).layout }, true }; @@ -161,20 +223,6 @@ int main(int argc, const char** argv) { std::cout << "Error. Could not create graphics pipeline. Exiting." << std::endl; return EXIT_FAILURE; } - - vkcv::SamplerHandle colorSampler = core.createSampler( - vkcv::SamplerFilterType::LINEAR, - vkcv::SamplerFilterType::LINEAR, - vkcv::SamplerMipmapMode::LINEAR, - vkcv::SamplerAddressMode::REPEAT - ); - - vkcv::SamplerHandle shadowSampler = core.createSampler( - vkcv::SamplerFilterType::NEAREST, - vkcv::SamplerFilterType::NEAREST, - vkcv::SamplerMipmapMode::NEAREST, - vkcv::SamplerAddressMode::CLAMP_TO_EDGE - ); vkcv::ImageHandle depthBuffer = core.createImage(depthBufferFormat, windowWidth, windowHeight).getHandle(); vkcv::ImageHandle colorBuffer = core.createImage(colorBufferFormat, windowWidth, windowHeight, 1, true, true).getHandle(); @@ -191,38 +239,22 @@ int main(int argc, const char** argv) { shadowShader.addShader(shaderStage, path); }); - const vk::Format shadowMapFormat = vk::Format::eD16Unorm; const std::vector<vkcv::AttachmentDescription> shadowAttachments = { vkcv::AttachmentDescription(vkcv::AttachmentOperation::STORE, vkcv::AttachmentOperation::CLEAR, shadowMapFormat) }; const vkcv::PassConfig shadowPassConfig(shadowAttachments); const vkcv::PassHandle shadowPass = core.createPass(shadowPassConfig); - - const uint32_t shadowMapResolution = 1024; - const vkcv::Image shadowMap = core.createImage(shadowMapFormat, shadowMapResolution, shadowMapResolution, 1); - const vkcv::PipelineConfig shadowPipeConfig { - shadowShader, - shadowMapResolution, - shadowMapResolution, + const vkcv::PipelineConfig shadowPipeConfig{ + shadowShader, + shadowMapResolution, + shadowMapResolution, shadowPass, vertexLayout, {}, false }; - const vkcv::PipelineHandle shadowPipe = core.createGraphicsPipeline(shadowPipeConfig); - struct LightInfo { - glm::vec3 direction; - float padding; - glm::mat4 lightMatrix; - }; - LightInfo lightInfo; - vkcv::Buffer lightBuffer = core.createBuffer<LightInfo>(vkcv::BufferType::UNIFORM, sizeof(glm::vec3)); - - - const vkcv::DescriptorSetUsage descriptorUsage(0, core.getDescriptorSet(descriptorSet).vulkanHandle); - std::vector<std::array<glm::mat4, 2>> mainPassMatrices; std::vector<glm::mat4> mvpLight; @@ -243,38 +275,6 @@ int main(int argc, const char** argv) { vkcv::PipelineHandle gammaCorrectionPipeline = core.createComputePipeline(gammaCorrectionProgram, { core.getDescriptorSet(gammaCorrectionDescriptorSet).layout }); - // prepare descriptor sets for drawcalls - std::vector<vkcv::Image> sceneImages; - std::vector<vkcv::DescriptorSetHandle> descriptorSets; - for (const auto& vertexGroup : scene.vertexGroups) { - descriptorSets.push_back(core.createDescriptorSet(descriptorBindings)); - - const auto& material = scene.materials[vertexGroup.materialIndex]; - - int baseColorIndex = material.baseColor; - if (baseColorIndex < 0) { - vkcv_log(vkcv::LogLevel::WARNING, "Material lacks base color"); - baseColorIndex = 0; - } - - vkcv::asset::Texture& sceneTexture = scene.textures[baseColorIndex]; - - sceneImages.push_back(core.createImage(vk::Format::eR8G8B8A8Srgb, sceneTexture.w, sceneTexture.h)); - sceneImages.back().fill(sceneTexture.data.data()); - - vkcv::DescriptorWrites setWrites; - setWrites.sampledImageWrites = { - vkcv::SampledImageDescriptorWrite(0, sceneImages.back().getHandle()), - vkcv::SampledImageDescriptorWrite(3, shadowMap.getHandle()) - }; - setWrites.samplerWrites = { - vkcv::SamplerDescriptorWrite(1, colorSampler), - vkcv::SamplerDescriptorWrite(4, shadowSampler), - }; - setWrites.uniformBufferWrites = { vkcv::UniformBufferDescriptorWrite(2, lightBuffer.getHandle()) }; - core.writeDescriptorSet(descriptorSets.back(), setWrites); - } - // model matrices per mesh std::vector<glm::mat4> modelMatrices; modelMatrices.resize(scene.vertexGroups.size(), glm::mat4(1.f)); @@ -298,9 +298,10 @@ int main(int argc, const char** argv) { 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); - drawcalls.push_back(vkcv::DrawcallInfo(meshes[i], { descriptorUsage })); + drawcalls.push_back(vkcv::DrawcallInfo(meshes[i], { + vkcv::DescriptorSetUsage(0, core.getDescriptorSet(forwardShadingDescriptorSet).vulkanHandle), + vkcv::DescriptorSetUsage(1, core.getDescriptorSet(perMeshDescriptorSets[i]).vulkanHandle) })); shadowDrawcalls.push_back(vkcv::DrawcallInfo(meshes[i], {})); } @@ -395,7 +396,8 @@ int main(int argc, const char** argv) { cmdStream, cameraManager.getActiveCamera().getPosition(), meshes, - modelMatrices); + modelMatrices, + perMeshDescriptorSets); // main pass core.recordDrawcallsToCmdStream( -- GitLab