Voxel pass
This commit is contained in:
parent
74e156179f
commit
15f5b090b5
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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;
|
||||||
|
};
|
||||||
}
|
}
|
|
@ -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
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
Loading…
Reference in New Issue