1
Fork 0
mirror of https://github.com/redstrate/Novus.git synced 2025-06-07 21:57:46 +00:00

More stuff that's needed for directional lighting

It's not working yet as we're missing view positions and the normal
clear color is wrong, but it's getting there. It can display a nice
blobby plane with the light color right now.
This commit is contained in:
Joshua Goins 2024-04-21 13:04:25 -04:00
parent 7f1c167251
commit ed9d6e62b8
2 changed files with 139 additions and 22 deletions

View file

@ -84,7 +84,7 @@ 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; glm::mat3x4 m_ViewMatrix; // TODO: does it need alignment?
glm::mat3x4 m_InverseViewMatrix; glm::mat3x4 m_InverseViewMatrix;
glm::mat4 m_InverseViewProjectionMatrix; glm::mat4 m_InverseViewProjectionMatrix;
glm::mat4 m_InverseProjectionMatrix; glm::mat4 m_InverseProjectionMatrix;
@ -132,12 +132,40 @@ private:
UniformBuffer g_ModelParameter; UniformBuffer g_ModelParameter;
struct MaterialParameter { struct MaterialParameter {
glm::vec3 g_DiffuseColor; glm::vec3 g_DiffuseColor; // TODO: align to vec4
float g_AlphaThreshold; float g_AlphaThreshold;
}; };
UniformBuffer g_MaterialParameter; UniformBuffer g_MaterialParameter;
struct CommonParameter {
glm::vec4 m_RenderTarget;
glm::vec4 m_Viewport;
glm::vec4 m_Misc;
glm::vec4 m_Misc2;
};
UniformBuffer g_CommonParameter;
struct LightParam {
glm::vec4 m_Position;
glm::vec4 m_Direction;
glm::vec4 m_DiffuseColor;
glm::vec4 m_SpecularColor;
glm::vec4 m_Attenuation;
/*glm::vec4 m_ClipMin;
glm::vec3 m_ClipMax;
glm::vec3 m_FadeScale;
glm::vec4 m_ShadowTexMask;
glm::vec4 m_PlaneRayDirection;
glm::mat3x4 m_PlaneInversMatrix;
glm::mat3x4 m_WorldViewInversMatrix;
glm::mat4 m_LightMapMatrix;
glm::mat4 m_WorldViewProjectionMatrix;*/
};
UniformBuffer g_LightParam;
VkBuffer m_planeVertexBuffer; VkBuffer m_planeVertexBuffer;
VkDeviceMemory m_planeVertexMemory; VkDeviceMemory m_planeVertexMemory;

View file

@ -18,13 +18,13 @@
// TODO: maybe need UV? // TODO: maybe need UV?
const std::vector<glm::vec4> planeVertices = { const std::vector<glm::vec4> planeVertices = {
{-0.5f, -0.5f, 0.0f, 0.0f}, {-1.0f, -1.0f, 0.0f, 1.0f},
{0.5f, -0.5f, 0.0f, 0.0f}, {1.0f, -1.0f, 0.0f, 1.0f},
{0.5f, 0.5f, 0.0f, 0.0f}, {1.0f, 1.0f, 0.0f, 1.0f},
{-0.5f, 0.5f, 0.0f, 0.0f}, {-1.0f, 1.0f, 0.0f, 1.0f},
{-0.5f, -0.5f, 0.0f, 0.0f}, {-1.0f, -1.0f, 0.0f, 1.0f},
{0.5f, 0.5f, 0.0f, 0.0f}, {1.0f, 1.0f, 0.0f, 1.0f},
}; };
dxvk::Logger dxvk::Logger::s_instance("dxbc.log"); dxvk::Logger dxvk::Logger::s_instance("dxbc.log");
@ -32,8 +32,9 @@ dxvk::Logger dxvk::Logger::s_instance("dxbc.log");
const std::array<std::string, 14> passes = { const std::array<std::string, 14> passes = {
// Shadows? // Shadows?
"PASS_0", "PASS_0",
// Z "prepass"
"PASS_Z_OPAQUE", "PASS_Z_OPAQUE",
// Z "Prepass", normals + depth (or is this maybe G_OPAQUE? // computes and stores normals (TODO: denote how these normals are special)
"PASS_G_OPAQUE", "PASS_G_OPAQUE",
// g run for each light // g run for each light
// takes view pos, then unknown texture and normal // takes view pos, then unknown texture and normal
@ -121,6 +122,32 @@ RenderSystem::RenderSystem(Renderer &renderer, GameData *data)
materialParameter.g_DiffuseColor = glm::vec3(1.0f); materialParameter.g_DiffuseColor = glm::vec3(1.0f);
copyDataToUniform(g_MaterialParameter, &materialParameter, sizeof(MaterialParameter)); copyDataToUniform(g_MaterialParameter, &materialParameter, sizeof(MaterialParameter));
} }
// light data
{
g_LightParam = createUniformBuffer(sizeof(LightParam));
LightParam lightParam{};
lightParam.m_Position = glm::vec4(5);
lightParam.m_Direction = glm::normalize(glm::vec4(0) - lightParam.m_Position);
lightParam.m_DiffuseColor = glm::vec4(1);
lightParam.m_SpecularColor = glm::vec4(1);
lightParam.m_Attenuation = glm::vec4(5.0f);
/*lightParam.m_ClipMin = glm::vec4(0.0f);
lightParam.m_ClipMax = glm::vec4(5.0f);*/
copyDataToUniform(g_LightParam, &lightParam, sizeof(LightParam));
}
// common data
{
g_CommonParameter = createUniformBuffer(sizeof(CommonParameter));
CommonParameter commonParam{};
commonParam.m_RenderTarget = {640.0f, 480.0f, 0.0f, 0.0f}; // used to convert screen-space coordinates back into 0.0-1.0
copyDataToUniform(g_CommonParameter, &commonParam, sizeof(CommonParameter));
}
} }
void RenderSystem::testInit(::RenderModel *m) void RenderSystem::testInit(::RenderModel *m)
@ -156,7 +183,7 @@ void RenderSystem::render(uint32_t imageIndex, VkCommandBuffer commandBuffer)
beginPass(imageIndex, commandBuffer, pass); beginPass(imageIndex, commandBuffer, pass);
// hardcoded to the known pass for now // hardcoded to the known pass for now
if (pass == "PASS_G_OPAQUE") { if (pass == "PASS_G_OPAQUE" || pass == "PASS_Z_OPAQUE") {
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 = {
@ -276,7 +303,7 @@ void RenderSystem::setSize(uint32_t width, uint32_t height)
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") { if (passName != "PASS_G_OPAQUE" && passName != "PASS_LIGHTING_OPAQUE" && passName != "PASS_Z_OPAQUE") {
return; return;
} }
@ -363,8 +390,33 @@ void RenderSystem::beginPass(uint32_t imageIndex, VkCommandBuffer commandBuffer,
colorAttachments.push_back(attachmentInfo); colorAttachments.push_back(attachmentInfo);
} }
} else { } else if (passName == "PASS_Z_OPAQUE") {
// qWarning() << "Unimplemented pass" << passName; // normals, it seems like
{
VkRenderingAttachmentInfo attachmentInfo{VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO};
attachmentInfo.imageView = m_renderer.swapchainViews[imageIndex];
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);
}
// unknown
{
VkRenderingAttachmentInfo attachmentInfo{VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO};
attachmentInfo.imageView = VK_NULL_HANDLE;
attachmentInfo.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
attachmentInfo.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
attachmentInfo.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
colorAttachments.push_back(attachmentInfo);
}
} }
renderingInfo.layerCount = 1; renderingInfo.layerCount = 1;
@ -380,7 +432,7 @@ 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") { if (passName != "PASS_G_OPAQUE" && passName != "PASS_LIGHTING_OPAQUE" && passName != "PASS_Z_OPAQUE") {
return; return;
} }
vkCmdEndRendering(commandBuffer); vkCmdEndRendering(commandBuffer);
@ -410,7 +462,7 @@ void RenderSystem::bindPipeline(VkCommandBuffer commandBuffer, std::string_view
VkVertexInputBindingDescription binding = {}; VkVertexInputBindingDescription binding = {};
// TODO: temporary // TODO: temporary
if (passName == "PASS_G_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") {
binding.stride = sizeof(glm::vec4); binding.stride = sizeof(glm::vec4);
@ -589,7 +641,7 @@ void RenderSystem::bindPipeline(VkCommandBuffer commandBuffer, std::string_view
VkPipelineRasterizationStateCreateInfo rasterizer = {}; VkPipelineRasterizationStateCreateInfo rasterizer = {};
rasterizer.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; rasterizer.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
rasterizer.lineWidth = 1.0f; rasterizer.lineWidth = 1.0f;
rasterizer.cullMode = VK_CULL_MODE_BACK_BIT; rasterizer.cullMode = VK_CULL_MODE_NONE; // TODO: implement cull mode
rasterizer.frontFace = VK_FRONT_FACE_CLOCKWISE; rasterizer.frontFace = VK_FRONT_FACE_CLOCKWISE;
VkPipelineMultisampleStateCreateInfo multisampling = {}; VkPipelineMultisampleStateCreateInfo multisampling = {};
@ -798,8 +850,17 @@ VkDescriptorSet RenderSystem::createDescriptorFor(const CachedPipeline &pipeline
int j = 0; int j = 0;
int z = 0; int z = 0;
int p = 0;
VkShaderStageFlags currentStageFlags;
for (auto binding : pipeline.requestedSets[i].bindings) { for (auto binding : pipeline.requestedSets[i].bindings) {
if (binding.used) { if (binding.used) {
// a giant hack
if (currentStageFlags != binding.stageFlags) {
z = 0;
p = 0;
currentStageFlags = binding.stageFlags;
}
VkWriteDescriptorSet &descriptorWrite = writes.emplace_back(); VkWriteDescriptorSet &descriptorWrite = writes.emplace_back();
descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
descriptorWrite.descriptorType = binding.type; descriptorWrite.descriptorType = binding.type;
@ -812,7 +873,23 @@ VkDescriptorSet RenderSystem::createDescriptorFor(const CachedPipeline &pipeline
auto info = &imageInfo.emplace_back(); auto info = &imageInfo.emplace_back();
descriptorWrite.pImageInfo = info; descriptorWrite.pImageInfo = info;
info->imageView = m_renderer.dummyView; if (binding.stageFlags == VK_SHADER_STAGE_FRAGMENT_BIT && p < 4) {
auto name = pipeline.pixelShader.resource_parameters[p].name;
qInfo() << "Requesting image" << name << "at" << j;
if (strcmp(name, "g_SamplerGBuffer") == 0) {
info->imageView = normalGBuffer.imageView;
} else if (strcmp(name, "g_SamplerViewPosition") == 0) {
// FIXME: hack because i don't know what samplerviewposition is yet
info->imageView = normalGBuffer.imageView;
} else {
info->imageView = m_renderer.dummyView;
}
p++;
} else {
info->imageView = m_renderer.dummyView;
}
info->imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; info->imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
} break; } break;
case VK_DESCRIPTOR_TYPE_SAMPLER: { case VK_DESCRIPTOR_TYPE_SAMPLER: {
@ -830,8 +907,7 @@ VkDescriptorSet RenderSystem::createDescriptorFor(const CachedPipeline &pipeline
info->range = buffer.size; info->range = buffer.size;
}; };
if (binding.stageFlags == VK_SHADER_STAGE_VERTEX_BIT && z < 4) { auto bindBuffer = [this, &useUniformBuffer, &info, j](const char *name) {
auto name = pipeline.vertexShader.scalar_parameters[z].name;
qInfo() << "Requesting" << name << "at" << j; qInfo() << "Requesting" << name << "at" << j;
if (strcmp(name, "g_CameraParameter") == 0) { if (strcmp(name, "g_CameraParameter") == 0) {
@ -842,16 +918,29 @@ VkDescriptorSet RenderSystem::createDescriptorFor(const CachedPipeline &pipeline
useUniformBuffer(g_InstanceParameter); useUniformBuffer(g_InstanceParameter);
} else if (strcmp(name, "g_ModelParameter") == 0) { } else if (strcmp(name, "g_ModelParameter") == 0) {
useUniformBuffer(g_ModelParameter); useUniformBuffer(g_ModelParameter);
} else if (strcmp(name, "g_MaterialParameter") == 0) {
useUniformBuffer(g_MaterialParameter);
} else if (strcmp(name, "g_LightParam") == 0) {
useUniformBuffer(g_LightParam);
} else if (strcmp(name, "g_CommonParameter") == 0) {
useUniformBuffer(g_CommonParameter);
} else { } else {
qInfo() << "Unknown resource:" << name; qInfo() << "Unknown resource:" << name;
info->buffer = m_renderer.dummyBuffer; info->buffer = m_renderer.dummyBuffer;
info->range = 655360; info->range = 655360;
} }
};
if (binding.stageFlags == VK_SHADER_STAGE_VERTEX_BIT) {
auto name = pipeline.vertexShader.scalar_parameters[z].name;
bindBuffer(name);
z++;
} else if (binding.stageFlags == VK_SHADER_STAGE_FRAGMENT_BIT) {
auto name = pipeline.pixelShader.scalar_parameters[z].name;
bindBuffer(name);
z++; z++;
} else if (binding.stageFlags == VK_SHADER_STAGE_FRAGMENT_BIT && j == 0) {
// TODO: temporary hack
useUniformBuffer(g_MaterialParameter);
} else { } else {
// placeholder buffer so it at least doesn't crash // placeholder buffer so it at least doesn't crash
info->buffer = m_renderer.dummyBuffer; info->buffer = m_renderer.dummyBuffer;