1
0
Fork 0

Voxel pass

This commit is contained in:
May B. 2020-10-14 21:14:43 +02:00
parent 74e156179f
commit 15f5b090b5
7 changed files with 179 additions and 124 deletions

View File

@ -3,7 +3,6 @@
#include "PhysicalDeviceInfo.hpp" #include "PhysicalDeviceInfo.hpp"
#include "Pipeline.hpp" #include "Pipeline.hpp"
#include "Renderer.hpp" #include "Renderer.hpp"
#include "buffer/VertexData.hpp"
using namespace render::vk; using namespace render::vk;
@ -23,15 +22,6 @@ CommandCenter::CommandCenter(VkDevice device, const PhysicalDeviceInfo &info, co
} }
} }
modelBuffer = ShortIndexedVertexBuffer::Create(buffer::vk::vertices, buffer::vk::indices);
if (!modelBuffer) {
FATAL("Cannot create vertex buffer");
}
sampleTexture = Texture::LoadFromFile(TEXTURES_DIR + opt.textures + "/terrain/Mapl.dds", {true, true, Texture::Wrap::MIRRORED_REPEAT, opt.anisotropy});
if (!sampleTexture) {
FATAL("Failed to create texture sampler!");
}
indicCubeBuffer = Indicator::Create(Indicator::CUBE.first, Indicator::CUBE.second); indicCubeBuffer = Indicator::Create(Indicator::CUBE.first, Indicator::CUBE.second);
if (!indicCubeBuffer) { if (!indicCubeBuffer) {
FATAL("Failed to create vertex buffer!"); FATAL("Failed to create vertex buffer!");
@ -50,6 +40,8 @@ CommandCenter::CommandCenter(VkDevice device, const PhysicalDeviceInfo &info, co
colorSamples = info.samples; colorSamples = info.samples;
LOG_D("Samples: " << colorSamples); LOG_D("Samples: " << colorSamples);
depthFormat = info.findDepthFormat(); depthFormat = info.findDepthFormat();
loadAtlases(opt.textures);
} }
CommandCenter::~CommandCenter() { CommandCenter::~CommandCenter() {
if(!freed) if(!freed)
@ -57,6 +49,30 @@ CommandCenter::~CommandCenter() {
vkDestroyCommandPool(device, graphicsPool, ALLOC); vkDestroyCommandPool(device, graphicsPool, ALLOC);
} }
#include "../../../core/world/materials.hpp"
void CommandCenter::loadAtlases(const std::string& textures) {
voxelTextureAtlas.reset();
voxelNormalAtlas.reset();
voxelHOSAtlas.reset();
std::vector<std::string> paths;
auto makePaths = [&](const std::string &suffix) {
paths.clear();
paths.reserve(world::materials::textures.size());
for (auto& texture: world::materials::textures) {
paths.push_back(TEXTURES_DIR + textures + "/terrain/" + texture + suffix + ".dds");
}
return paths;
};
voxelTextureAtlas = TextureArray::LoadFromFiles(makePaths(""), {}); //TODO: anisotropy/mipmap options
voxelNormalAtlas = TextureArray::LoadFromFiles(makePaths(".nrm"), {});
voxelHOSAtlas = TextureArray::LoadFromFiles(makePaths(".hos"), {});
if(!(voxelTextureAtlas && voxelNormalAtlas && voxelHOSAtlas)) {
FATAL("Failed to load texture pack!");
}
}
#include <glm/gtc/matrix_transform.hpp> #include <glm/gtc/matrix_transform.hpp>
void CommandCenter::allocate(const std::vector<VkImageView>& views, const Pipeline& pipe, VkExtent2D extent) { void CommandCenter::allocate(const std::vector<VkImageView>& views, const Pipeline& pipe, VkExtent2D extent) {
assert(freed); assert(freed);
@ -97,7 +113,7 @@ void CommandCenter::allocate(const std::vector<VkImageView>& views, const Pipeli
{ // Uniform buffers { // Uniform buffers
std::vector<Buffer::requirement> requirements; std::vector<Buffer::requirement> requirements;
requirements.resize(framebuffers.size(), Buffer::requirement(sizeof(UniformBufferObject), Buffer::Usage::UNIFORM)); requirements.resize(framebuffers.size(), Buffer::requirement(sizeof(VoxelUBO), Buffer::Usage::UNIFORM));
uniformBuffers.allocate(requirements, true); uniformBuffers.allocate(requirements, true);
if (!uniformBuffers) { if (!uniformBuffers) {
FATAL("Failed to allocate UBO"); FATAL("Failed to allocate UBO");
@ -108,7 +124,7 @@ void CommandCenter::allocate(const std::vector<VkImageView>& views, const Pipeli
poolSizes[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; poolSizes[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
poolSizes[0].descriptorCount = framebuffers.size(); poolSizes[0].descriptorCount = framebuffers.size();
poolSizes[1].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; poolSizes[1].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
poolSizes[1].descriptorCount = framebuffers.size(); poolSizes[1].descriptorCount = framebuffers.size() * 3;
VkDescriptorPoolCreateInfo poolInfo{}; VkDescriptorPoolCreateInfo poolInfo{};
poolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; poolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
@ -121,12 +137,13 @@ void CommandCenter::allocate(const std::vector<VkImageView>& views, const Pipeli
FATAL("Failed to create descriptor pool!"); FATAL("Failed to create descriptor pool!");
} }
poolSizes[1].descriptorCount = framebuffers.size();
if (vkCreateDescriptorPool(device, &poolInfo, nullptr, &skyDescriptorPool) != VK_SUCCESS) { if (vkCreateDescriptorPool(device, &poolInfo, nullptr, &skyDescriptorPool) != VK_SUCCESS) {
FATAL("Failed to create descriptor pool!"); FATAL("Failed to create descriptor pool!");
} }
poolInfo.poolSizeCount = 1; poolInfo.poolSizeCount = 1;
poolInfo.pPoolSizes = &poolSizes[0];
if (vkCreateDescriptorPool(device, &poolInfo, nullptr, &indicDescriptorPool) != VK_SUCCESS) { if (vkCreateDescriptorPool(device, &poolInfo, nullptr, &indicDescriptorPool) != VK_SUCCESS) {
FATAL("Failed to create descriptor pool!"); FATAL("Failed to create descriptor pool!");
@ -155,7 +172,7 @@ void CommandCenter::allocate(const std::vector<VkImageView>& views, const Pipeli
VkDescriptorBufferInfo bufferInfo{}; VkDescriptorBufferInfo bufferInfo{};
bufferInfo.buffer = uniformBuffers.at(i); bufferInfo.buffer = uniformBuffers.at(i);
bufferInfo.offset = 0; bufferInfo.offset = 0;
bufferInfo.range = sizeof(UniformBufferObject); bufferInfo.range = sizeof(VoxelUBO);
std::array<VkWriteDescriptorSet, 2> descriptorWrites{}; std::array<VkWriteDescriptorSet, 2> descriptorWrites{};
descriptorWrites[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; descriptorWrites[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
@ -172,17 +189,33 @@ void CommandCenter::allocate(const std::vector<VkImageView>& views, const Pipeli
descriptorWrites[1].dstArrayElement = 0; descriptorWrites[1].dstArrayElement = 0;
descriptorWrites[1].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; descriptorWrites[1].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
descriptorWrites[1].descriptorCount = 1; descriptorWrites[1].descriptorCount = 1;
descriptorWrites[1].pImageInfo = &sampleTexture->getDescriptor(); descriptorWrites[1].pImageInfo = &voxelTextureAtlas->getDescriptor();
descriptorWrites[2].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
descriptorWrites[2].dstSet = voxelDescriptorSets[i];
descriptorWrites[2].dstBinding = 2;
descriptorWrites[2].dstArrayElement = 0;
descriptorWrites[2].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
descriptorWrites[2].descriptorCount = 1;
descriptorWrites[2].pImageInfo = &voxelNormalAtlas->getDescriptor();
descriptorWrites[3].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
descriptorWrites[3].dstSet = voxelDescriptorSets[i];
descriptorWrites[3].dstBinding = 3;
descriptorWrites[3].dstArrayElement = 0;
descriptorWrites[3].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
descriptorWrites[3].descriptorCount = 1;
descriptorWrites[3].pImageInfo = &voxelHOSAtlas->getDescriptor();
vkUpdateDescriptorSets(device, descriptorWrites.size(), descriptorWrites.data(), 0, nullptr); vkUpdateDescriptorSets(device, descriptorWrites.size(), descriptorWrites.data(), 0, nullptr);
bufferInfo.range = sizeof(ViewProjUBO);
descriptorWrites[0].dstSet = skyDescriptorSets[i]; descriptorWrites[0].dstSet = skyDescriptorSets[i];
descriptorWrites[1].dstSet = skyDescriptorSets[i]; descriptorWrites[1].dstSet = skyDescriptorSets[i];
descriptorWrites[1].pImageInfo = &skyboxTexture->getDescriptor(); descriptorWrites[1].pImageInfo = &skyboxTexture->getDescriptor();
vkUpdateDescriptorSets(device, descriptorWrites.size(), descriptorWrites.data(), 0, nullptr); vkUpdateDescriptorSets(device, 2, descriptorWrites.data(), 0, nullptr);
descriptorWrites[0].dstSet = indicDescriptorSets[i]; descriptorWrites[0].dstSet = indicDescriptorSets[i];
vkUpdateDescriptorSets(device, 1, &descriptorWrites[0], 0, nullptr); vkUpdateDescriptorSets(device, 1, descriptorWrites.data(), 0, nullptr);
} }
} }
{ {
@ -221,10 +254,7 @@ void CommandCenter::free() {
#include <chrono> #include <chrono>
#include <memory.h> #include <memory.h>
void CommandCenter::startRecording(uint32_t idx, VkRenderPass renderPass, VkExtent2D extent, const glm::vec4& clear_color, glm::mat4 view, glm::mat4 proj) { void CommandCenter::startRecording(uint32_t idx, VkRenderPass renderPass, VkExtent2D extent, const VoxelUBO& ubo) {
UniformBufferObject ubo{};
ubo.view = view;
ubo.proj = proj;
uniformBuffers.write(idx, data_view(&ubo, sizeof(ubo))); uniformBuffers.write(idx, data_view(&ubo, sizeof(ubo)));
VkCommandBufferBeginInfo beginInfo{}; VkCommandBufferBeginInfo beginInfo{};
@ -245,7 +275,7 @@ void CommandCenter::startRecording(uint32_t idx, VkRenderPass renderPass, VkExte
renderPassInfo.renderArea.extent = extent; renderPassInfo.renderArea.extent = extent;
std::array<VkClearValue, 2> clearValues{}; std::array<VkClearValue, 2> clearValues{};
clearValues[0].color = {clear_color.x, clear_color.y, clear_color.z, clear_color.a}; clearValues[0].color = {ubo.fog.x, ubo.fog.y, ubo.fog.z, 1};
clearValues[1].depthStencil = {1.0f, 0}; clearValues[1].depthStencil = {1.0f, 0};
renderPassInfo.clearValueCount = clearValues.size(); renderPassInfo.clearValueCount = clearValues.size();
renderPassInfo.pClearValues = clearValues.data(); renderPassInfo.pClearValues = clearValues.data();
@ -256,22 +286,17 @@ void CommandCenter::startRecording(uint32_t idx, VkRenderPass renderPass, VkExte
void CommandCenter::startWorldPass(uint32_t idx, const Subpass &worldPass) { void CommandCenter::startWorldPass(uint32_t idx, const Subpass &worldPass) {
vkCmdBindPipeline(graphicsBuffers[idx], VK_PIPELINE_BIND_POINT_GRAPHICS, worldPass.pipeline); vkCmdBindPipeline(graphicsBuffers[idx], VK_PIPELINE_BIND_POINT_GRAPHICS, worldPass.pipeline);
vkCmdBindDescriptorSets(graphicsBuffers[idx], VK_PIPELINE_BIND_POINT_GRAPHICS, worldPass.layout, 0, 1, &voxelDescriptorSets[idx], 0, nullptr); vkCmdBindDescriptorSets(graphicsBuffers[idx], VK_PIPELINE_BIND_POINT_GRAPHICS, worldPass.layout, 0, 1, &voxelDescriptorSets[idx], 0, nullptr);
static auto startTime = std::chrono::high_resolution_clock::now();
auto currentTime = std::chrono::high_resolution_clock::now();
float time = std::chrono::duration<float, std::chrono::seconds::period>(currentTime - startTime).count();
ModelPush push{};
push.model = glm::translate(glm::mat4(1.0f), glm::vec3(98.0f, -2.f, -2.f));
push.model = glm::rotate(push.model, time * glm::radians(90.0f), glm::vec3(0.0f, 0.0f, 1.0f));
vkCmdPushConstants(graphicsBuffers[idx], worldPass.layout, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(push), &push);
} }
void CommandCenter::recordModel(uint32_t i) { size_t CommandCenter::recordModel(uint32_t i, const Subpass &worldPass, const UniqueCurvaturePush& push, const LodModel *const modelBuffer) {
vkCmdPushConstants(graphicsBuffers[i], worldPass.layout, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(push), &push);
VkBuffer vertexBuffers[] = {modelBuffer->getVertex()}; VkBuffer vertexBuffers[] = {modelBuffer->getVertex()};
VkDeviceSize offsets[] = {0}; VkDeviceSize offsets[] = {0};
vkCmdBindVertexBuffers(graphicsBuffers[i], 0, 1, vertexBuffers, offsets); vkCmdBindVertexBuffers(graphicsBuffers[i], 0, 1, vertexBuffers, offsets);
vkCmdBindIndexBuffer(graphicsBuffers[i], modelBuffer->getIndex(), 0, VK_INDEX_TYPE_UINT16); vkCmdBindIndexBuffer(graphicsBuffers[i], modelBuffer->getIndex(), 0, VK_INDEX_TYPE_UINT16);
vkCmdDrawIndexed(graphicsBuffers[i], static_cast<uint32_t>(buffer::vk::indices.size()), 1, 0, 0, 0); auto size = modelBuffer->getIndexSize();
vkCmdDrawIndexed(graphicsBuffers[i], size, 1, modelBuffer->getIndexStart(), 0, 0);
return size;
} }
void CommandCenter::startEntityPass(uint32_t) { } void CommandCenter::startEntityPass(uint32_t) { }
void CommandCenter::recordIndicator(uint32_t idx, const Subpass& indicPass, glm::mat4 model) { void CommandCenter::recordIndicator(uint32_t idx, const Subpass& indicPass, glm::mat4 model) {
@ -287,7 +312,7 @@ void CommandCenter::recordIndicator(uint32_t idx, const Subpass& indicPass, glm:
vkCmdBindVertexBuffers(graphicsBuffers[idx], 0, 1, vertexBuffers, offsets); vkCmdBindVertexBuffers(graphicsBuffers[idx], 0, 1, vertexBuffers, offsets);
vkCmdDraw(graphicsBuffers[idx], indicCubeBuffer->size, 1, 0, 0); vkCmdDraw(graphicsBuffers[idx], indicCubeBuffer->size, 1, 0, 0);
} }
void CommandCenter::recordPostprocess(uint32_t idx, const Subpass& skyPass, bool skybox, glm::mat4, glm::mat4) { void CommandCenter::recordPostprocess(uint32_t idx, const Subpass& skyPass, bool skybox) {
vkCmdNextSubpass(graphicsBuffers[idx], VK_SUBPASS_CONTENTS_INLINE); vkCmdNextSubpass(graphicsBuffers[idx], VK_SUBPASS_CONTENTS_INLINE);
if (skybox) { if (skybox) {
vkCmdBindPipeline(graphicsBuffers[idx], VK_PIPELINE_BIND_POINT_GRAPHICS, skyPass.pipeline); vkCmdBindPipeline(graphicsBuffers[idx], VK_PIPELINE_BIND_POINT_GRAPHICS, skyPass.pipeline);

View File

@ -17,18 +17,20 @@ public:
CommandCenter(VkDevice, const PhysicalDeviceInfo&, const renderOptions&); CommandCenter(VkDevice, const PhysicalDeviceInfo&, const renderOptions&);
~CommandCenter(); ~CommandCenter();
void startRecording(uint32_t idx, VkRenderPass, VkExtent2D, const glm::vec4& clear, glm::mat4 view, glm::mat4 proj); void startRecording(uint32_t idx, VkRenderPass, VkExtent2D, const VoxelUBO&);
void startWorldPass(uint32_t idx, const Subpass&); void startWorldPass(uint32_t idx, const Subpass&);
void recordModel(uint32_t idx); size_t recordModel(uint32_t idx, const Subpass &worldPass, const UniqueCurvaturePush&, const LodModel *const);
void startEntityPass(uint32_t idx); void startEntityPass(uint32_t idx);
void recordIndicator(uint32_t idx, const Subpass&, glm::mat4 model); void recordIndicator(uint32_t idx, const Subpass&, glm::mat4 model);
void recordPostprocess(uint32_t idx, const Subpass&, bool skybox, glm::mat4 view, glm::mat4 proj); void recordPostprocess(uint32_t idx, const Subpass&, bool skybox);
void submitGraphics(uint32_t, VkSemaphore, VkSemaphore, VkFence); void submitGraphics(uint32_t, VkSemaphore, VkSemaphore, VkFence);
void allocate(const std::vector<VkImageView>&, const Pipeline&, VkExtent2D); void allocate(const std::vector<VkImageView>&, const Pipeline&, VkExtent2D);
void free(); void free();
private: private:
void loadAtlases(const std::string &texturePath);
VkDevice device; VkDevice device;
std::vector<VkFramebuffer> framebuffers; std::vector<VkFramebuffer> framebuffers;
@ -47,8 +49,9 @@ private:
VkDescriptorPool voxelDescriptorPool; VkDescriptorPool voxelDescriptorPool;
std::vector<VkDescriptorSet> voxelDescriptorSets; std::vector<VkDescriptorSet> voxelDescriptorSets;
std::unique_ptr<Texture> sampleTexture; std::unique_ptr<TextureArray> voxelTextureAtlas;
std::unique_ptr<ShortIndexedVertexBuffer> modelBuffer; std::unique_ptr<TextureArray> voxelNormalAtlas;
std::unique_ptr<TextureArray> voxelHOSAtlas;
VkDescriptorPool indicDescriptorPool; VkDescriptorPool indicDescriptorPool;
std::vector<VkDescriptorSet> indicDescriptorSets; std::vector<VkDescriptorSet> indicDescriptorSets;

View File

@ -3,7 +3,6 @@
#include "PhysicalDeviceInfo.hpp" #include "PhysicalDeviceInfo.hpp"
#include "../../../core/data/file.hpp" #include "../../../core/data/file.hpp"
#include "../Renderer.hpp" #include "../Renderer.hpp"
#include "buffer/VertexData.hpp"
#include "api/Models.hpp" #include "api/Models.hpp"
#include <map> #include <map>
@ -129,15 +128,26 @@ Pipeline::Pipeline(VkDevice device, const PhysicalDeviceInfo &info, const render
} }
} }
//MAYBE: use sets (ubo, (samplers, passInfos)) //MAYBE: use sets (ubo, (samplers, passInfos))
//MAYBE: reuse sub UBO
{ // Voxel descriptor { // Voxel descriptor
VkDescriptorSetLayoutBinding samplerLayoutBinding{}; std::array<VkDescriptorSetLayoutBinding, 4> bindings{};
samplerLayoutBinding.binding = 1; bindings[0] = VoxelUBO::getLayoutBinding();
samplerLayoutBinding.descriptorCount = 1; bindings[1].binding = 1;
samplerLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; bindings[1].descriptorCount = 1;
samplerLayoutBinding.pImmutableSamplers = nullptr; bindings[1].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
samplerLayoutBinding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; bindings[1].pImmutableSamplers = nullptr; //TODO: set immuable samplers
bindings[1].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
bindings[2].binding = 2;
bindings[2].descriptorCount = 1;
bindings[2].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
bindings[2].pImmutableSamplers = nullptr;
bindings[2].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
bindings[3].binding = 3;
bindings[3].descriptorCount = 1;
bindings[3].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
bindings[3].pImmutableSamplers = nullptr;
bindings[3].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
std::vector<VkDescriptorSetLayoutBinding> bindings = {UniformBufferObject::getLayoutBinding(), samplerLayoutBinding};
VkDescriptorSetLayoutCreateInfo layoutInfo{}; VkDescriptorSetLayoutCreateInfo layoutInfo{};
layoutInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; layoutInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
layoutInfo.bindingCount = bindings.size(); layoutInfo.bindingCount = bindings.size();
@ -150,7 +160,7 @@ Pipeline::Pipeline(VkDevice device, const PhysicalDeviceInfo &info, const render
{ // Indicator descriptor { // Indicator descriptor
VkDescriptorSetLayoutCreateInfo layoutInfo{}; VkDescriptorSetLayoutCreateInfo layoutInfo{};
layoutInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; layoutInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
auto binding = UniformBufferObject::getLayoutBinding(); auto binding = ViewProjUBO::getLayoutBinding();
layoutInfo.bindingCount = 1; layoutInfo.bindingCount = 1;
layoutInfo.pBindings = &binding; layoutInfo.pBindings = &binding;
@ -166,7 +176,7 @@ Pipeline::Pipeline(VkDevice device, const PhysicalDeviceInfo &info, const render
samplerLayoutBinding.pImmutableSamplers = nullptr; samplerLayoutBinding.pImmutableSamplers = nullptr;
samplerLayoutBinding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; samplerLayoutBinding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
std::vector<VkDescriptorSetLayoutBinding> bindings = {UniformBufferObject::getLayoutBinding(), samplerLayoutBinding}; std::vector<VkDescriptorSetLayoutBinding> bindings = {ViewProjUBO::getLayoutBinding(), samplerLayoutBinding};
VkDescriptorSetLayoutCreateInfo layoutInfo{}; VkDescriptorSetLayoutCreateInfo layoutInfo{};
layoutInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; layoutInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
layoutInfo.bindingCount = bindings.size(); layoutInfo.bindingCount = bindings.size();
@ -342,25 +352,35 @@ Pipeline::Pipeline(VkDevice device, const PhysicalDeviceInfo &info, const render
multisampling.alphaToOneEnable = VK_FALSE; multisampling.alphaToOneEnable = VK_FALSE;
{ // World pipeline { // World pipeline
/*struct Push {
alignas(16) glm::mat4 Model;
alignas(16) glm::vec4 SphereProj;
alignas(4) float Curvature;
};*/
VkPushConstantRange pushRange{}; VkPushConstantRange pushRange{};
pushRange.offset = 0; pushRange.offset = 0;
pushRange.size = sizeof(ModelPush); pushRange.size = sizeof(ModelPush);
pushRange.stageFlags = VK_SHADER_STAGE_VERTEX_BIT; pushRange.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
setLayout(worldPass, {voxelDescriptorSet}, {pushRange}); setLayout(worldPass, {voxelDescriptorSet}, {pushRange});
auto shaderStages = setShaders(worldPass, "Tris");
auto unitSize = 1; //TODO: load from world.voxel_density
std::vector<unsigned char> speData;
std::vector<VkSpecializationMapEntry> speIndex;
auto specialization = makeSpecialization({
{0, data_view(&options.voxel.fog, sizeof(bool))},
{1, data_view(&options.voxel.pbr, sizeof(bool))},
{2, data_view(&options.voxel.triplanar, sizeof(bool))},
{3, data_view(&options.voxel.stochastic, sizeof(bool))},
{4, data_view(&options.voxel.blend, sizeof(bool))},
{5, data_view(&options.voxel.curvature, sizeof(bool))},
{6, data_view(&options.voxel.curv_depth, sizeof(bool))},
{16, data_view(&unitSize, sizeof(int))}}, speData, speIndex);
auto withGeometry = options.voxel.geometry; //MAYBE: && features.geometry
auto shaderStages = setShaders(worldPass, withGeometry ? "Tris.geo" : "Tris", withGeometry, &specialization);
VkPipelineVertexInputStateCreateInfo vertexInputInfo{}; VkPipelineVertexInputStateCreateInfo vertexInputInfo{};
vertexInputInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; vertexInputInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
auto bindingDescription = buffer::vk::VertexData::getBindingDescription(); auto bindingDescription = Model::getBindingDescription();
vertexInputInfo.vertexBindingDescriptionCount = 1; vertexInputInfo.vertexBindingDescriptionCount = 1;
vertexInputInfo.pVertexBindingDescriptions = &bindingDescription; vertexInputInfo.pVertexBindingDescriptions = &bindingDescription;
auto attributeDescriptions = buffer::vk::VertexData::getAttributeDescriptions(); auto attributeDescriptions = Model::getAttributeDescriptions();
vertexInputInfo.vertexAttributeDescriptionCount = attributeDescriptions.size(); vertexInputInfo.vertexAttributeDescriptionCount = attributeDescriptions.size();
vertexInputInfo.pVertexAttributeDescriptions = attributeDescriptions.data(); vertexInputInfo.pVertexAttributeDescriptions = attributeDescriptions.data();

View File

@ -411,8 +411,14 @@ void Renderer::beginFrame() {
if (auto newImage = swapChain->acquireNextImage(imageAvailableSemaphores[currentFrame], inFlightFences[currentFrame])) { if (auto newImage = swapChain->acquireNextImage(imageAvailableSemaphores[currentFrame], inFlightFences[currentFrame])) {
currentImage = newImage.value(); currentImage = newImage.value();
VoxelUBO ubo{};
ubo.proj = ProjectionMatrix;
ubo.view = ViewMatrix;
ubo.fog = options.clear_color;
ubo.fog.a = FogDepth;
ubo.lightInv = LightInvDir;
commandCenter->startRecording(currentImage, pipeline->getRenderPass(), commandCenter->startRecording(currentImage, pipeline->getRenderPass(),
getInfos().swapDetails.capabilities.currentExtent, options.clear_color, ViewMatrix, ProjectionMatrix); getInfos().swapDetails.capabilities.currentExtent, ubo);
allocator->setTracyZone("Submit"); allocator->setTracyZone("Submit");
} else { } else {
recreateSwapChain(); recreateSwapChain();
@ -423,10 +429,15 @@ void Renderer::beginFrame() {
std::function<size_t(render::LodModel *const, glm::mat4, glm::vec4, float)> Renderer::beginWorldPass() { std::function<size_t(render::LodModel *const, glm::mat4, glm::vec4, float)> Renderer::beginWorldPass() {
assert(currentImage < swapChain->getImageViews().size()); assert(currentImage < swapChain->getImageViews().size());
commandCenter->startWorldPass(currentImage, pipeline->getWorldPass()); auto& pass = pipeline->getWorldPass();
commandCenter->recordModel(currentImage); commandCenter->startWorldPass(currentImage, pass);
return [&](render::LodModel *const, glm::mat4, glm::vec4, float) { return [&](render::LodModel *const rBuffer, glm::mat4 model, glm::vec4 sphere, float curv) {
return 0; //WorldPass->setup(this, model); auto buffer = dynamic_cast<render::vk::LodModel *const>(rBuffer);
UniqueCurvaturePush push{};
push.model = model;
push.sphereProj = sphere;
push.curvature = curv;
return commandCenter->recordModel(currentImage, pass, push, buffer);
}; };
} }
@ -447,7 +458,7 @@ size_t Renderer::drawIndicatorCube(glm::mat4 model) {
} }
void Renderer::postProcess() { void Renderer::postProcess() {
commandCenter->recordPostprocess(currentImage, pipeline->getSkyPass(), options.skybox, ViewMatrix, ProjectionMatrix); commandCenter->recordPostprocess(currentImage, pipeline->getSkyPass(), options.skybox);
} }
void Renderer::endFrame() { void Renderer::endFrame() {

View File

@ -223,8 +223,8 @@ std::unique_ptr<TextureCube> TextureCube::LoadFromFiles(const std::string& prefi
std::unique_ptr<TextureArray> TextureArray::LoadFromFiles(const std::vector<std::string>& paths, const sampling& props) { std::unique_ptr<TextureArray> TextureArray::LoadFromFiles(const std::vector<std::string>& paths, const sampling& props) {
std::vector<std::vector<unsigned char>> datas; std::vector<std::vector<unsigned char>> datas;
std::vector<data_view> views; std::vector<data_view> views;
datas.resize(1); datas.resize(paths.size());
views.reserve(6); views.reserve(paths.size());
auto header = [&] { auto header = [&] {
if (auto header = render::Image::Read(paths.at(0), datas.at(0))) { if (auto header = render::Image::Read(paths.at(0), datas.at(0))) {
views.push_back(datas.at(0)); views.push_back(datas.at(0));
@ -232,7 +232,6 @@ std::unique_ptr<TextureArray> TextureArray::LoadFromFiles(const std::vector<std:
} }
FATAL("Cannot read first texture"); FATAL("Cannot read first texture");
}(); }();
datas.reserve(paths.size());
for (size_t i = 1; i < paths.size(); i++) { for (size_t i = 1; i < paths.size(); i++) {
if(!render::Image::Read(paths.at(i), datas.at(i)).has_value()) { if(!render::Image::Read(paths.at(i), datas.at(i)).has_value()) {
FATAL("Cannot read depth texture"); FATAL("Cannot read depth texture");

View File

@ -73,6 +73,30 @@ class Model final: public render::Model, public ShortIndexedVertexBuffer {
public: public:
static std::unique_ptr<Model> Create(const Data &); static std::unique_ptr<Model> Create(const Data &);
static VkVertexInputBindingDescription getBindingDescription() {
VkVertexInputBindingDescription description{};
description.binding = 0;
description.stride = sizeof(PackedVertexData);
description.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
return description;
}
static std::array<VkVertexInputAttributeDescription, 3> getAttributeDescriptions() {
std::array<VkVertexInputAttributeDescription, 3> attributeDescriptions{};
attributeDescriptions[0].binding = 0;
attributeDescriptions[0].location = 0;
attributeDescriptions[0].format = VK_FORMAT_R16G16B16_SFLOAT;
attributeDescriptions[0].offset = offsetof(PackedVertexData, PosMat[0]);
attributeDescriptions[1].binding = 0;
attributeDescriptions[1].location = 1;
attributeDescriptions[1].format = VK_FORMAT_R16_UINT;
attributeDescriptions[1].offset = offsetof(PackedVertexData, PosMat[3]);
attributeDescriptions[2].binding = 0;
attributeDescriptions[2].location = 2;
attributeDescriptions[2].format = VK_FORMAT_R16G16B16_SFLOAT;
attributeDescriptions[2].offset = offsetof(PackedVertexData, Nrm);
return attributeDescriptions;
}
protected: protected:
Model(size_t size, VkBuffer vertex, VkBuffer index, memory::ptr mem): Model(size_t size, VkBuffer vertex, VkBuffer index, memory::ptr mem):
ShortIndexedVertexBuffer(vertex, index, std::move(mem)), indexSize(size) { } ShortIndexedVertexBuffer(vertex, index, std::move(mem)), indexSize(size) { }
@ -85,6 +109,9 @@ public:
static void MakeDefault(); static void MakeDefault();
constexpr uint32_t getIndexStart() const { return getOffset(level); }
constexpr uint32_t getIndexSize() const { return getOffset(level+1) - getOffset(level); }
protected: protected:
LodModel(size_t size, const std::vector<size_t>& off, LodModel(size_t size, const std::vector<size_t>& off,
VkBuffer vertex, VkBuffer index, memory::ptr mem): VkBuffer vertex, VkBuffer index, memory::ptr mem):
@ -95,7 +122,7 @@ protected:
} }
}; };
struct UniformBufferObject { struct ViewProjUBO {
alignas(16) glm::mat4 view; alignas(16) glm::mat4 view;
alignas(16) glm::mat4 proj; alignas(16) glm::mat4 proj;
@ -109,9 +136,35 @@ struct UniformBufferObject {
return uboLayoutBinding; return uboLayoutBinding;
} }
}; };
struct VoxelUBO {
alignas(16) glm::mat4 view;
alignas(16) glm::mat4 proj;
alignas(16) glm::vec3 lightInv;
//NOTE: one "free" space
alignas(16) glm::vec4 fog;
static VkDescriptorSetLayoutBinding getLayoutBinding() {
VkDescriptorSetLayoutBinding uboLayoutBinding{};
uboLayoutBinding.binding = 0;
uboLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
uboLayoutBinding.descriptorCount = 1;
uboLayoutBinding.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT;
uboLayoutBinding.pImmutableSamplers = nullptr;
return uboLayoutBinding;
}
};
struct ModelPush { struct ModelPush {
alignas(16) glm::mat4 model; alignas(16) glm::mat4 model;
}; };
struct CurvaturePush {
alignas(16) glm::vec4 sphereProj;
alignas(4) float curvature;
};
struct UniqueCurvaturePush {
alignas(16) glm::mat4 model;
alignas(16) glm::vec4 sphereProj;
alignas(4) float curvature;
};
} }

View File

@ -1,56 +0,0 @@
#pragma once
#include <glm/glm.hpp>
#include <vector>
#include <array>
#include <volk.h>
namespace buffer::vk {
struct VertexData {
glm::vec3 pos;
glm::vec3 color;
glm::vec2 uv;
static VkVertexInputBindingDescription getBindingDescription() {
VkVertexInputBindingDescription description{};
description.binding = 0;
description.stride = sizeof(VertexData);
description.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
return description;
}
static std::array<VkVertexInputAttributeDescription, 3> getAttributeDescriptions() {
std::array<VkVertexInputAttributeDescription, 3> attributeDescriptions{};
attributeDescriptions[0].binding = 0;
attributeDescriptions[0].location = 0;
attributeDescriptions[0].format = VK_FORMAT_R32G32B32_SFLOAT;
attributeDescriptions[0].offset = offsetof(VertexData, pos);
attributeDescriptions[1].binding = 0;
attributeDescriptions[1].location = 1;
attributeDescriptions[1].format = VK_FORMAT_R32G32B32_SFLOAT;
attributeDescriptions[1].offset = offsetof(VertexData, color);
attributeDescriptions[2].binding = 0;
attributeDescriptions[2].location = 2;
attributeDescriptions[2].format = VK_FORMAT_R32G32_SFLOAT;
attributeDescriptions[2].offset = offsetof(VertexData, uv);
return attributeDescriptions;
}
};
const std::vector<VertexData> vertices = {
{{-0.5f, -0.5f, 0.0f}, {1.0f, 0.0f, 0.0f}, {0.0f, 0.0f}},
{{0.5f, -0.5f, 0.0f}, {0.0f, 1.0f, 0.0f}, {1.0f, 0.0f}},
{{0.5f, 0.5f, 0.0f}, {0.0f, 0.0f, 1.0f}, {1.0f, 1.0f}},
{{-0.5f, 0.5f, 0.0f}, {1.0f, 1.0f, 1.0f}, {0.0f, 1.0f}},
{{-0.5f, -0.5f, -0.5f}, {1.0f, 0.0f, 0.0f}, {0.0f, 0.0f}},
{{0.5f, -0.5f, -0.5f}, {0.0f, 1.0f, 0.0f}, {1.0f, 0.0f}},
{{0.5f, 0.5f, -0.5f}, {0.0f, 0.0f, 1.0f}, {1.0f, 1.0f}},
{{-0.5f, 0.5f, -0.5f}, {1.0f, 1.0f, 1.0f}, {0.0f, 1.0f}}};
const std::vector<uint16_t> indices = {
0, 1, 2, 2, 3, 0,
4, 5, 6, 6, 7, 4
};
}