1
Fork 0
mirror of https://github.com/redstrate/Novus.git synced 2025-04-24 13:07:44 +00:00

Fix specular not showing correctly, and more

The specular for lights now show up correctly. The offscreen buffers
use more accurate formats. And a new Scene struct is added for future
usage.
This commit is contained in:
Joshua Goins 2024-04-27 21:11:53 -04:00
parent 7cd519fac2
commit 729dce011a
13 changed files with 69 additions and 42 deletions

View file

@ -15,6 +15,7 @@ target_sources(renderer
include/drawobject.h
include/gamerenderer.h
include/rendermanager.h
include/scene.h
include/shaderstructs.h
include/simplerenderer.h
include/swapchain.h

View file

@ -17,6 +17,7 @@ class Renderer;
struct DrawObject;
struct Camera;
struct Texture;
struct Scene;
/// Base class for all rendering implementations
class BaseRenderer
@ -28,7 +29,7 @@ public:
virtual void resize() = 0;
/// Render a frame into @p commandBuffer. @p currentFrame is the same value as SwapChain::currentFrame for convenience.
virtual void render(VkCommandBuffer commandBuffer, uint32_t currentFrame, Camera &camera, const std::vector<DrawObject> &models) = 0;
virtual void render(VkCommandBuffer commandBuffer, uint32_t currentFrame, Camera &camera, Scene &scene, const std::vector<DrawObject> &models) = 0;
/// The final composite texture that is drawn into with render()
virtual Texture &getCompositeTexture() = 0;

View file

@ -16,7 +16,7 @@ struct Camera {
float nearPlane = 0.1f;
/// Far plane
float farPlane = 100.0f;
float farPlane = 1000.0f;
glm::mat4 perspective, view;
glm::vec3 position;

View file

@ -3,6 +3,7 @@
#pragma once
#include <array>
#include <string_view>
#include <vector>
@ -35,7 +36,7 @@ public:
Texture createTexture(int width, int height, VkFormat format, VkImageUsageFlags usage);
Texture createDummyTexture();
Texture createDummyTexture(std::array<uint8_t, 4> values = {255, 255, 255, 255});
Buffer createDummyBuffer();
VkCommandBuffer beginSingleTimeCommands();

View file

@ -30,7 +30,7 @@ public:
void resize() override;
void render(VkCommandBuffer commandBuffer, uint32_t currentFrame, Camera &camera, const std::vector<DrawObject> &models) override;
void render(VkCommandBuffer commandBuffer, uint32_t currentFrame, Camera &camera, Scene &scene, const std::vector<DrawObject> &models) override;
Texture &getCompositeTexture() override;
@ -104,5 +104,7 @@ private:
Texture m_ZBuffer; // what is this?
Texture m_dummyTex;
VkSampler m_sampler;
VkSampler m_normalSampler;
Buffer m_dummyBuffer;
Texture m_placeholderTileNormal;
};

View file

@ -15,6 +15,7 @@
#include "camera.h"
#include "device.h"
#include "drawobject.h"
#include "scene.h"
class ImGuiPass;
struct ImGuiContext;
@ -40,6 +41,7 @@ public:
VkRenderPass presentationRenderPass() const;
Camera camera;
Scene scene;
ImGuiContext *ctx = nullptr;

9
renderer/include/scene.h Normal file
View file

@ -0,0 +1,9 @@
// SPDX-FileCopyrightText: 2024 Joshua Goins <josh@redstrate.com>
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
struct Scene {
glm::vec3 sunDirection;
glm::vec3 pointLightPosition;
};

View file

@ -12,8 +12,8 @@ struct CameraParameter {
glm::mat4 m_InverseProjectionMatrix; // used for view position recalc
glm::mat4 m_ProjectionMatrix; // FIXME: ourburos is wrong, this is actually viewProjection
glm::mat4 m_MainViewToProjectionMatrix;
glm::vec3 m_EyePosition;
glm::vec3 m_LookAtVector;
glm::vec4 m_EyePosition;
glm::vec4 m_LookAtVector;
};
struct JointMatrixArray {

View file

@ -30,7 +30,7 @@ public:
void resize() override;
void render(VkCommandBuffer commandBuffer, uint32_t currentFrame, Camera &camera, const std::vector<DrawObject> &models) override;
void render(VkCommandBuffer commandBuffer, uint32_t currentFrame, Camera &camera, Scene &scene, const std::vector<DrawObject> &models) override;
Texture &getCompositeTexture() override;

View file

@ -135,7 +135,7 @@ Texture Device::createTexture(const int width, const int height, const VkFormat
return {format, viewCreateInfo.subresourceRange, image, imageView, imageMemory};
}
Texture Device::createDummyTexture()
Texture Device::createDummyTexture(std::array<uint8_t, 4> values)
{
auto texture = createTexture(1, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT);
@ -164,12 +164,10 @@ Texture Device::createDummyTexture()
vkBindBufferMemory(device, stagingBuffer, stagingBufferMemory, 0);
uint8_t dummydata[4] = {255, 255, 255, 255};
// copy to staging buffer
void *mapped_data;
vkMapMemory(device, stagingBufferMemory, 0, 4 * sizeof(uint8_t), 0, &mapped_data);
memcpy(mapped_data, dummydata, 4 * sizeof(uint8_t));
memcpy(mapped_data, values.data(), 4 * sizeof(uint8_t));
vkUnmapMemory(device, stagingBufferMemory);
// copy staging buffer to image

View file

@ -20,13 +20,13 @@
// TODO: maybe need UV?
// note: SQEX passes the vertice positions as UV coordinates (yes, -1 to 1.) the shaders then transform them back with the g_CommonParameter.m_RenderTarget vec4
const std::vector<glm::vec4> planeVertices = {
{-1.0f, -1.0f, 0.0f, 1.0f},
{1.0f, -1.0f, 0.0f, 1.0f},
{1.0f, 1.0f, 0.0f, 1.0f},
{1.0f, 1.0f, 1.0f, 1.0f},
{-1.0f, 1.0f, 1.0f, 1.0f},
{-1.0f, -1.0f, 1.0f, 1.0f},
{-1.0f, 1.0f, 0.0f, 1.0f},
{-1.0f, -1.0f, 0.0f, 1.0f},
{1.0f, 1.0f, 0.0f, 1.0f},
{-1.0f, -1.0f, 1.0f, 1.0f},
{1.0f, -1.0f, 1.0f, 1.0f},
{1.0f, 1.0f, 1.0f, 1.0f},
};
dxvk::Logger dxvk::Logger::s_instance("dxbc.log");
@ -61,6 +61,9 @@ GameRenderer::GameRenderer(Device &device, GameData *data)
m_dummyTex = m_device.createDummyTexture();
m_dummyBuffer = m_device.createDummyBuffer();
// don't know how to get tile normal yet
m_placeholderTileNormal = m_device.createDummyTexture({128, 128, 255, 255});
size_t vertexSize = planeVertices.size() * sizeof(glm::vec4);
m_planeVertexBuffer = m_device.createBuffer(vertexSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
m_device.copyToBuffer(m_planeVertexBuffer, (void *)planeVertices.data(), vertexSize);
@ -84,7 +87,9 @@ GameRenderer::GameRenderer(Device &device, GameData *data)
const float wetnessMax = 1.0f;
const float maybeWetness = 0.0f;
instanceParameter.g_InstanceParameter.m_Wetness = {maybeWetness, 2.0f, wetnessMin, wetnessMax};
// instanceParameter.g_InstanceParameter.m_Wetness = {maybeWetness, 2.0f, wetnessMin, wetnessMax};
// instanceParameter.g_InstanceParameter.m_CameraLight.m_DiffuseSpecular = glm::vec4(1.0f);
// instanceParameter.g_InstanceParameter.m_CameraLight.m_Rim = glm::vec4(1.0f);
m_device.copyToBuffer(g_InstanceParameter, &instanceParameter, sizeof(InstanceParameter));
}
@ -178,20 +183,29 @@ GameRenderer::GameRenderer(Device &device, GameData *data)
VkSamplerCreateInfo samplerInfo = {};
samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
samplerInfo.magFilter = VK_FILTER_LINEAR;
samplerInfo.minFilter = VK_FILTER_LINEAR;
samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;
samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
samplerInfo.maxLod = 1.0f;
samplerInfo.magFilter = VK_FILTER_NEAREST;
samplerInfo.minFilter = VK_FILTER_NEAREST;
samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
samplerInfo.borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
samplerInfo.maxAnisotropy = 1.0f;
vkCreateSampler(m_device.device, &samplerInfo, nullptr, &m_sampler);
samplerInfo.magFilter = VK_FILTER_LINEAR;
samplerInfo.minFilter = VK_FILTER_LINEAR;
samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT;
samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT;
samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT;
vkCreateSampler(m_device.device, &samplerInfo, nullptr, &m_normalSampler);
createImageResources();
}
void GameRenderer::render(VkCommandBuffer commandBuffer, uint32_t imageIndex, Camera &camera, const std::vector<DrawObject> &models)
void GameRenderer::render(VkCommandBuffer commandBuffer, uint32_t imageIndex, Camera &camera, Scene &scene, const std::vector<DrawObject> &models)
{
// TODO: this shouldn't be here
CameraParameter cameraParameter{};
@ -204,12 +218,12 @@ void GameRenderer::render(VkCommandBuffer commandBuffer, uint32_t imageIndex, Ca
cameraParameter.m_InverseViewProjectionMatrix = glm::transpose(glm::inverse(viewProjectionMatrix));
// known params
cameraParameter.m_InverseProjectionMatrix = glm::transpose(glm::inverse(camera.perspective));
cameraParameter.m_InverseProjectionMatrix = glm::transpose(glm::inverse(viewProjectionMatrix));
cameraParameter.m_ProjectionMatrix = glm::transpose(viewProjectionMatrix);
cameraParameter.m_MainViewToProjectionMatrix = glm::transpose(glm::inverse(camera.perspective));
cameraParameter.m_EyePosition = camera.position; // placeholder
cameraParameter.m_LookAtVector = glm::vec3(0.0f); // placeholder
cameraParameter.m_EyePosition = glm::vec4(camera.position, 0.0f);
cameraParameter.m_LookAtVector = glm::vec4(0.0f); // placeholder
m_device.copyToBuffer(g_CameraParameter, &cameraParameter, sizeof(CameraParameter));
@ -276,12 +290,7 @@ void GameRenderer::render(VkCommandBuffer commandBuffer, uint32_t imageIndex, Ca
bool found = false;
for (int z = 0; z < renderMaterial.mat.num_shader_keys; z++) {
if (renderMaterial.mat.shader_keys[z].category == id) {
// TODO: Temporary workaround for materials that need tile normals
if (id == 0xB616DC5A) {
materialKeys.push_back(0x22A4AABF);
} else {
materialKeys.push_back(renderMaterial.mat.shader_keys[z].value);
}
materialKeys.push_back(renderMaterial.mat.shader_keys[z].value);
found = true;
}
}
@ -897,7 +906,7 @@ GameRenderer::bindPipeline(VkCommandBuffer commandBuffer, std::string_view passN
rasterizer.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
rasterizer.lineWidth = 1.0f;
rasterizer.cullMode = VK_CULL_MODE_NONE; // TODO: implement cull mode
rasterizer.frontFace = VK_FRONT_FACE_CLOCKWISE;
rasterizer.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
VkPipelineMultisampleStateCreateInfo multisampling = {};
multisampling.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
@ -905,7 +914,7 @@ GameRenderer::bindPipeline(VkCommandBuffer commandBuffer, std::string_view passN
VkPipelineColorBlendAttachmentState colorBlendAttachment = {};
colorBlendAttachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
colorBlendAttachment.blendEnable = VK_TRUE;
colorBlendAttachment.blendEnable = VK_FALSE;
colorBlendAttachment.srcColorBlendFactor = VK_BLEND_FACTOR_ONE;
colorBlendAttachment.dstColorBlendFactor = VK_BLEND_FACTOR_ZERO;
colorBlendAttachment.colorBlendOp = VK_BLEND_OP_ADD;
@ -957,7 +966,9 @@ GameRenderer::bindPipeline(VkCommandBuffer commandBuffer, std::string_view passN
VkPipelineDepthStencilStateCreateInfo depthStencil = {};
depthStencil.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
depthStencil.depthTestEnable = VK_TRUE;
if (passName != "PASS_LIGHTING_OPAQUE_VIEWPOSITION") {
depthStencil.depthTestEnable = VK_TRUE;
}
if (passName == "PASS_G_OPAQUE") {
depthStencil.depthWriteEnable = VK_TRUE;
}
@ -1165,6 +1176,8 @@ GameRenderer::createDescriptorFor(const DrawObject *object, const CachedPipeline
} else if (strcmp(name, "g_SamplerSpecular") == 0) {
Q_ASSERT(material);
info->imageView = material->specularTexture->view;
} else if (strcmp(name, "g_SamplerTileNormal") == 0) {
info->imageView = m_placeholderTileNormal.imageView;
} else {
info->imageView = m_dummyTex.imageView;
qInfo() << "Unknown image" << name;
@ -1181,7 +1194,7 @@ GameRenderer::createDescriptorFor(const DrawObject *object, const CachedPipeline
auto info = &imageInfo.emplace_back();
descriptorWrite.pImageInfo = info;
info->sampler = m_sampler;
info->sampler = m_normalSampler;
} break;
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: {
auto info = &bufferInfo.emplace_back();
@ -1270,7 +1283,7 @@ void GameRenderer::createImageResources()
m_viewPositionBuffer = m_device.createTexture(m_device.swapChain->extent.width,
m_device.swapChain->extent.height,
VK_FORMAT_R8G8B8A8_UNORM,
VK_FORMAT_R16G16B16A16_SFLOAT,
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT);
m_device.nameTexture(m_viewPositionBuffer, "View Position");

View file

@ -404,7 +404,7 @@ void RenderManager::render(const std::vector<DrawObject> &models)
updateCamera(camera);
m_renderer->render(commandBuffer, m_device->swapChain->currentFrame, camera, models);
m_renderer->render(commandBuffer, m_device->swapChain->currentFrame, camera, scene, models);
VkRenderPassBeginInfo renderPassInfo = {};
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;

View file

@ -48,7 +48,7 @@ void SimpleRenderer::resize()
vkCreateFramebuffer(m_device.device, &framebufferInfo, nullptr, &m_framebuffer);
}
void SimpleRenderer::render(VkCommandBuffer commandBuffer, uint32_t currentFrame, Camera &camera, const std::vector<DrawObject> &models)
void SimpleRenderer::render(VkCommandBuffer commandBuffer, uint32_t currentFrame, Camera &camera, Scene &scene, const std::vector<DrawObject> &models)
{
VkRenderPassBeginInfo renderPassInfo = {};
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;