1
Fork 0
mirror of https://github.com/redstrate/Novus.git synced 2025-04-20 11:47:45 +00:00

Implement view position extraction, and provide g_SamplerDepth

This commit is contained in:
Joshua Goins 2024-04-21 13:17:40 -04:00
parent ed9d6e62b8
commit ec47e52f80
2 changed files with 121 additions and 52 deletions

View file

@ -35,6 +35,7 @@ private:
spirv_cross::CompilerGLSL getShaderModuleResources(const physis_Shader &shader); spirv_cross::CompilerGLSL getShaderModuleResources(const physis_Shader &shader);
physis_SHPK directionalLightningShpk; physis_SHPK directionalLightningShpk;
physis_SHPK createViewPositionShpk;
struct RenderModel { struct RenderModel {
physis_SHPK shpk; physis_SHPK shpk;
@ -84,9 +85,9 @@ private:
// Structure definitions from https://github.com/Shaderlayan/Ouroboros // Structure definitions from https://github.com/Shaderlayan/Ouroboros
struct CameraParameter { struct CameraParameter {
glm::mat3x4 m_ViewMatrix; // TODO: does it need alignment? /* m[0] - m[2] */ glm::mat3x4 m_ViewMatrix; // TODO: does it need alignment?
glm::mat3x4 m_InverseViewMatrix; /* m[3] - m[5] */ glm::mat3x4 m_InverseViewMatrix;
glm::mat4 m_InverseViewProjectionMatrix; /* m[6] - m[9] */ glm::mat4 m_InverseViewProjectionMatrix;
glm::mat4 m_InverseProjectionMatrix; glm::mat4 m_InverseProjectionMatrix;
glm::mat4 m_ProjectionMatrix; glm::mat4 m_ProjectionMatrix;
glm::mat4 m_ViewProjectionMatrix; glm::mat4 m_ViewProjectionMatrix;
@ -178,4 +179,5 @@ private:
VulkanImage createImage(int width, int height, VkFormat format, VkImageUsageFlags usage); VulkanImage createImage(int width, int height, VkFormat format, VkImageUsageFlags usage);
VulkanImage normalGBuffer; VulkanImage normalGBuffer;
VulkanImage viewPositionBuffer;
}; };

View file

@ -57,6 +57,7 @@ RenderSystem::RenderSystem(Renderer &renderer, GameData *data)
, m_data(data) , m_data(data)
{ {
normalGBuffer = createImage(640, 480, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT); normalGBuffer = createImage(640, 480, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
viewPositionBuffer = createImage(640, 480, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
size_t vertexSize = planeVertices.size() * sizeof(glm::vec4); size_t vertexSize = planeVertices.size() * sizeof(glm::vec4);
auto [vertexBuffer, vertexMemory] = m_renderer.createBuffer(vertexSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT); auto [vertexBuffer, vertexMemory] = m_renderer.createBuffer(vertexSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
@ -81,6 +82,7 @@ RenderSystem::RenderSystem(Renderer &renderer, GameData *data)
} }
directionalLightningShpk = physis_parse_shpk(physis_gamedata_extract_file(m_data, "shader/sm5/shpk/directionallighting.shpk")); directionalLightningShpk = physis_parse_shpk(physis_gamedata_extract_file(m_data, "shader/sm5/shpk/directionallighting.shpk"));
createViewPositionShpk = physis_parse_shpk(physis_gamedata_extract_file(m_data, "shader/sm5/shpk/createviewposition.shpk"));
// camera data // camera data
{ {
@ -180,10 +182,10 @@ void RenderSystem::render(uint32_t imageIndex, VkCommandBuffer commandBuffer)
int i = 0; int i = 0;
for (const auto pass : passes) { for (const auto pass : passes) {
beginPass(imageIndex, commandBuffer, pass);
// hardcoded to the known pass for now // hardcoded to the known pass for now
if (pass == "PASS_G_OPAQUE" || pass == "PASS_Z_OPAQUE") { if (pass == "PASS_G_OPAQUE" || pass == "PASS_Z_OPAQUE") {
beginPass(imageIndex, commandBuffer, pass);
for (auto &model : m_renderModels) { for (auto &model : m_renderModels) {
std::vector<uint32_t> systemKeys; std::vector<uint32_t> systemKeys;
std::vector<uint32_t> sceneKeys = { std::vector<uint32_t> sceneKeys = {
@ -242,56 +244,107 @@ void RenderSystem::render(uint32_t imageIndex, VkCommandBuffer commandBuffer)
} }
} }
} }
endPass(commandBuffer, pass);
} else if (pass == "PASS_LIGHTING_OPAQUE") { } else if (pass == "PASS_LIGHTING_OPAQUE") {
std::vector<uint32_t> systemKeys = { // first we need to generate the view positions with createviewpositions
physis_shpk_crc("DecodeDepthBuffer_RAWZ"), beginPass(imageIndex, commandBuffer, "PASS_LIGHTING_OPAQUE_VIEWPOSITION");
}; {
std::vector<uint32_t> sceneKeys = { std::vector<uint32_t> systemKeys = {
physis_shpk_crc("GetDirectionalLight_Enable"), physis_shpk_crc("DecodeDepthBuffer_RAWZ"),
physis_shpk_crc("GetFakeSpecular_Disable"), };
physis_shpk_crc("GetUnderWaterLighting_Disable"), std::vector<uint32_t> subviewKeys = {
}; physis_shpk_crc("Default"),
std::vector<uint32_t> subviewKeys = { physis_shpk_crc("SUB_VIEW_MAIN"),
physis_shpk_crc("Default"), };
physis_shpk_crc("SUB_VIEW_MAIN"),
};
const u_int32_t selector = physis_shpk_build_selector_from_all_keys(systemKeys.data(), const u_int32_t selector = physis_shpk_build_selector_from_all_keys(systemKeys.data(),
systemKeys.size(), systemKeys.size(),
sceneKeys.data(), nullptr,
sceneKeys.size(), 0,
nullptr, nullptr,
0, 0,
subviewKeys.data(), subviewKeys.data(),
subviewKeys.size()); subviewKeys.size());
const physis_SHPKNode node = physis_shpk_get_node(&directionalLightningShpk, selector); const physis_SHPKNode node = physis_shpk_get_node(&createViewPositionShpk, selector);
// check if invalid // check if invalid
if (node.pass_count == 0) { if (node.pass_count == 0) {
continue; continue;
}
const int passIndice = node.pass_indices[i];
if (passIndice != INVALID_PASS) {
const Pass currentPass = node.passes[passIndice];
const uint32_t vertexShaderIndice = currentPass.vertex_shader;
const uint32_t pixelShaderIndice = currentPass.pixel_shader;
physis_Shader vertexShader = createViewPositionShpk.vertex_shaders[vertexShaderIndice];
physis_Shader pixelShader = createViewPositionShpk.pixel_shaders[pixelShaderIndice];
bindPipeline(commandBuffer, "PASS_LIGHTING_OPAQUE_VIEWPOSITION", vertexShader, pixelShader);
VkDeviceSize offsets[] = {0};
vkCmdBindVertexBuffers(commandBuffer, 0, 1, &m_planeVertexBuffer, offsets);
vkCmdDraw(commandBuffer, 6, 1, 0, 0);
}
} }
endPass(commandBuffer, pass);
const int passIndice = node.pass_indices[i]; beginPass(imageIndex, commandBuffer, pass);
if (passIndice != INVALID_PASS) { // then run the directionallighting shader
const Pass currentPass = node.passes[passIndice]; {
std::vector<uint32_t> systemKeys = {
physis_shpk_crc("DecodeDepthBuffer_RAWZ"),
};
std::vector<uint32_t> sceneKeys = {
physis_shpk_crc("GetDirectionalLight_Enable"),
physis_shpk_crc("GetFakeSpecular_Disable"),
physis_shpk_crc("GetUnderWaterLighting_Disable"),
};
std::vector<uint32_t> subviewKeys = {
physis_shpk_crc("Default"),
physis_shpk_crc("SUB_VIEW_MAIN"),
};
const uint32_t vertexShaderIndice = currentPass.vertex_shader; const u_int32_t selector = physis_shpk_build_selector_from_all_keys(systemKeys.data(),
const uint32_t pixelShaderIndice = currentPass.pixel_shader; systemKeys.size(),
sceneKeys.data(),
sceneKeys.size(),
nullptr,
0,
subviewKeys.data(),
subviewKeys.size());
const physis_SHPKNode node = physis_shpk_get_node(&directionalLightningShpk, selector);
physis_Shader vertexShader = directionalLightningShpk.vertex_shaders[vertexShaderIndice]; // check if invalid
physis_Shader pixelShader = directionalLightningShpk.pixel_shaders[pixelShaderIndice]; if (node.pass_count == 0) {
continue;
}
bindPipeline(commandBuffer, pass, vertexShader, pixelShader); const int passIndice = node.pass_indices[i];
if (passIndice != INVALID_PASS) {
const Pass currentPass = node.passes[passIndice];
VkDeviceSize offsets[] = {0}; const uint32_t vertexShaderIndice = currentPass.vertex_shader;
vkCmdBindVertexBuffers(commandBuffer, 0, 1, &m_planeVertexBuffer, offsets); const uint32_t pixelShaderIndice = currentPass.pixel_shader;
vkCmdDraw(commandBuffer, 6, 1, 0, 0); physis_Shader vertexShader = directionalLightningShpk.vertex_shaders[vertexShaderIndice];
physis_Shader pixelShader = directionalLightningShpk.pixel_shaders[pixelShaderIndice];
bindPipeline(commandBuffer, pass, vertexShader, pixelShader);
VkDeviceSize offsets[] = {0};
vkCmdBindVertexBuffers(commandBuffer, 0, 1, &m_planeVertexBuffer, offsets);
vkCmdDraw(commandBuffer, 6, 1, 0, 0);
}
} }
endPass(commandBuffer, pass);
} }
endPass(commandBuffer, pass);
i++; i++;
} }
} }
@ -299,14 +352,14 @@ void RenderSystem::render(uint32_t imageIndex, VkCommandBuffer commandBuffer)
void RenderSystem::setSize(uint32_t width, uint32_t height) void RenderSystem::setSize(uint32_t width, uint32_t height)
{ {
m_extent = {width, height}; m_extent = {width, height};
// TODO: this is because of our terrible resource handling. an image referenced in these may be gone due to resizing, for example
for (auto &[hash, cachedPipeline] : m_cachedPipelines) {
cachedPipeline.cachedDescriptors.clear();
}
} }
void RenderSystem::beginPass(uint32_t imageIndex, VkCommandBuffer commandBuffer, const std::string_view passName) void RenderSystem::beginPass(uint32_t imageIndex, VkCommandBuffer commandBuffer, const std::string_view passName)
{ {
if (passName != "PASS_G_OPAQUE" && passName != "PASS_LIGHTING_OPAQUE" && passName != "PASS_Z_OPAQUE") {
return;
}
VkRenderingInfo renderingInfo{VK_STRUCTURE_TYPE_RENDERING_INFO}; VkRenderingInfo renderingInfo{VK_STRUCTURE_TYPE_RENDERING_INFO};
renderingInfo.renderArea.extent = m_extent; renderingInfo.renderArea.extent = m_extent;
@ -388,6 +441,22 @@ void RenderSystem::beginPass(uint32_t imageIndex, VkCommandBuffer commandBuffer,
attachmentInfo.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; attachmentInfo.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
attachmentInfo.storeOp = VK_ATTACHMENT_STORE_OP_STORE; attachmentInfo.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
colorAttachments.push_back(attachmentInfo);
}
} else if (passName == "PASS_LIGHTING_OPAQUE_VIEWPOSITION") {
// TODO: Hack we should not be using a special pass for this, we should just design our API better
{
VkRenderingAttachmentInfo attachmentInfo{VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO};
attachmentInfo.imageView = viewPositionBuffer.imageView;
attachmentInfo.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; // VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
attachmentInfo.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
attachmentInfo.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
attachmentInfo.clearValue.color.float32[0] = 0.24;
attachmentInfo.clearValue.color.float32[1] = 0.24;
attachmentInfo.clearValue.color.float32[2] = 0.24;
attachmentInfo.clearValue.color.float32[3] = 1.0;
colorAttachments.push_back(attachmentInfo); colorAttachments.push_back(attachmentInfo);
} }
} else if (passName == "PASS_Z_OPAQUE") { } else if (passName == "PASS_Z_OPAQUE") {
@ -432,9 +501,6 @@ void RenderSystem::beginPass(uint32_t imageIndex, VkCommandBuffer commandBuffer,
void RenderSystem::endPass(VkCommandBuffer commandBuffer, std::string_view passName) void RenderSystem::endPass(VkCommandBuffer commandBuffer, std::string_view passName)
{ {
if (passName != "PASS_G_OPAQUE" && passName != "PASS_LIGHTING_OPAQUE" && passName != "PASS_Z_OPAQUE") {
return;
}
vkCmdEndRendering(commandBuffer); vkCmdEndRendering(commandBuffer);
} }
@ -464,7 +530,7 @@ void RenderSystem::bindPipeline(VkCommandBuffer commandBuffer, std::string_view
// TODO: temporary // TODO: temporary
if (passName == "PASS_G_OPAQUE" || passName == "PASS_Z_OPAQUE") { if (passName == "PASS_G_OPAQUE" || passName == "PASS_Z_OPAQUE") {
binding.stride = sizeof(Vertex); binding.stride = sizeof(Vertex);
} else if (passName == "PASS_LIGHTING_OPAQUE") { } else if (passName == "PASS_LIGHTING_OPAQUE" || passName == "PASS_LIGHTING_OPAQUE_VIEWPOSITION") {
binding.stride = sizeof(glm::vec4); binding.stride = sizeof(glm::vec4);
} }
@ -879,8 +945,9 @@ VkDescriptorSet RenderSystem::createDescriptorFor(const CachedPipeline &pipeline
if (strcmp(name, "g_SamplerGBuffer") == 0) { if (strcmp(name, "g_SamplerGBuffer") == 0) {
info->imageView = normalGBuffer.imageView; info->imageView = normalGBuffer.imageView;
} else if (strcmp(name, "g_SamplerViewPosition") == 0) { } else if (strcmp(name, "g_SamplerViewPosition") == 0) {
// FIXME: hack because i don't know what samplerviewposition is yet info->imageView = viewPositionBuffer.imageView;
info->imageView = normalGBuffer.imageView; } else if (strcmp(name, "g_SamplerDepth") == 0) {
info->imageView = m_renderer.depthView;
} else { } else {
info->imageView = m_renderer.dummyView; info->imageView = m_renderer.dummyView;
} }