Push previous work

This commit is contained in:
Antoine Pilote
2025-01-10 16:09:45 -05:00
parent 7e5a45de52
commit 996c3e6e16
8 changed files with 212 additions and 137 deletions

View File

@@ -52,8 +52,8 @@ VkPipeline PipelineBuilder::BuildPipeline(VkDevice device)
if (ColorBlendAttachment.size() == 0)
{
Logger::Log("Forgot blend attachment!", "vulkan", CRITICAL);
assert(false && "Error");
Logger::Log("Forgot blend attachment?", "vulkan", CRITICAL);
//assert(false && "Error");
}
// completely clear VertexInputStateCreateInfo, as we have no need for it

View File

@@ -18,6 +18,18 @@
namespace Nuake
{
struct CameraView
{
Matrix4 View;
Matrix4 Projection;
Matrix4 ViewProjection;
Matrix4 InverseView;
Matrix4 InverseProjection;
Vector3 Position;
float Near;
float Far;
};
struct LightResource
{
@@ -31,6 +43,7 @@ namespace Nuake
std::map<UUID, Ref<VkMesh>> Meshes;
std::map<UUID, Ref<VulkanImage>> Images;
std::map<UUID, Ref<VulkanImage>> Light;
std::vector<CameraView> Cameras;
// Bindless buffer layouts
VkDescriptorSetLayout CameraDescriptorLayout;
@@ -41,14 +54,17 @@ namespace Nuake
VkDescriptorSetLayout MaterialDescriptorLayout;
VkDescriptorSetLayout TexturesDescriptorLayout;
VkDescriptorSetLayout LightsDescriptorLayout;
VkDescriptorSetLayout CamerasDescriptorLayout;
VkDescriptorSet CameraDescriptor;
VkDescriptorSet ModelDescriptor;
VkDescriptorSet SamplerDescriptor;
VkDescriptorSet MaterialDescriptor;
VkDescriptorSet LightsDescriptor;
VkDescriptorSet CamerasDescriptor;
std::map<UUID, uint32_t> BindlessTextureMapping;
std::map<UUID, uint32_t> CameraMapping;
public:
VkDescriptorSet TextureDescriptor;
@@ -77,11 +93,16 @@ namespace Nuake
Ref<VulkanImage> GetTexture(const UUID& id);
std::vector<Ref<VulkanImage>> GetAllTextures();
void AddCamera(const UUID& id, const CameraView& camera);
CameraView GetCamera(const UUID& id);
std::vector<CameraView> GetAllCameras();
void ClearCameras();
std::vector<VkDescriptorSetLayout> GetBindlessLayout();
uint32_t GetBindlessTextureID(const UUID& id);
void RecreateBindlessTextures();
void RecreateBindlessCameras();
private:
void CreateBindlessLayout();
};

View File

@@ -130,6 +130,7 @@ namespace Nuake
constexpr uint32_t MAX_MODEL_MATRIX = 3000;
constexpr uint32_t MAX_MATERIAL = 1000;
constexpr uint32_t MAX_TEXTURES = 500;
constexpr uint32_t MAX_CAMERAS = 100;
constexpr uint32_t MAX_LIGHTS = 100;
class VkRenderer
{

View File

@@ -119,6 +119,34 @@ std::vector<Ref<VulkanImage>> GPUResources::GetAllTextures()
return allImages;
}
void GPUResources::AddCamera(const UUID& id, const CameraView& camera)
{
Cameras.push_back(camera);
CameraMapping[id] = Cameras.size() - 1;
}
CameraView GPUResources::GetCamera(const UUID& id)
{
if (CameraMapping.find(id) != CameraMapping.end())
{
return Cameras[CameraMapping[id]];
}
Logger::Log("Camera with ID does not exist", "vulkan", CRITICAL);
return Cameras[0];
}
std::vector<CameraView> GPUResources::GetAllCameras()
{
return Cameras;
}
void GPUResources::ClearCameras()
{
Cameras.clear();
CameraMapping.clear();
}
void GPUResources::CreateBindlessLayout()
{
auto& vk = VkRenderer::Get();
@@ -179,7 +207,18 @@ void GPUResources::CreateBindlessLayout()
LightsDescriptorLayout = builder.Build(device, VK_SHADER_STAGE_ALL_GRAPHICS);
}
TextureDescriptor = VkRenderer::Get().GetDescriptorAllocator().Allocate(VkRenderer::Get().GetDevice(), TexturesDescriptorLayout);
// bindless cameras
{
DescriptorLayoutBuilder builder;
builder.AddBinding(0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, MAX_CAMERAS);
CamerasDescriptorLayout = builder.Build(device, VK_SHADER_STAGE_ALL_GRAPHICS);
}
auto& vk = VkRenderer::Get();
auto device = vk.GetDevice();
auto allocator = vk.GetDescriptorAllocator();
TextureDescriptor = allocator.Allocate(device, TexturesDescriptorLayout);
CamerasDescriptor = allocator.Allocate(device, CamerasDescriptorLayout);
}
void GPUResources::RecreateBindlessTextures()
@@ -210,6 +249,15 @@ void GPUResources::RecreateBindlessTextures()
vkUpdateDescriptorSets(VkRenderer::Get().GetDevice(), 1, &write, 0, nullptr);
}
void GPUResources::RecreateBindlessCameras()
{
if (!CamerasDescriptor)
{
CreateBindlessLayout();
}
}
std::vector<VkDescriptorSetLayout> GPUResources::GetBindlessLayout()
{
std::vector<VkDescriptorSetLayout> layouts = {

View File

@@ -18,6 +18,7 @@
#include "Pipeline/RenderPipeline.h"
#include "src/Rendering/Vulkan/DescriptorLayoutBuilder.h"
#include <src\Scene\Components\CameraComponent.h>
using namespace Nuake;
@@ -82,10 +83,29 @@ void VkSceneRenderer::BeginScene(RenderContext inContext)
throw std::runtime_error("Draw image is not initialized");
}
// Build camera view list
auto view = scene->m_Registry.view<TransformComponent, CameraComponent>();
for (auto e : view)
{
auto [transform, camera] = view.get<TransformComponent, CameraComponent>(e);
CameraView camData{};
camData.View = camera.CameraInstance->GetTransform();
camData.Projection = camera.CameraInstance->GetPerspective();
camData.InverseView = glm::inverse(camData.Projection);
camData.InverseProjection = glm::inverse(camData.Projection);
camData.Position = transform.GetGlobalTransform()[3];
camData.Near = camera.CameraInstance->Near;
camData.Far = camera.CameraInstance->Far;
GPUResources::Get().AddCamera(camera.ID, camData);
}
// Execute light
PassRenderContext passCtx = { };
passCtx.scene = inContext.CurrentScene;
passCtx.commandBuffer = inContext.CommandBuffer;
passCtx.resolution = Context.Size;
ShadowPipeline.Execute(passCtx);
GBufferPipeline.Execute(passCtx);
}
ModelPushConstant modelPushConstant{};
@@ -262,61 +282,118 @@ void VkSceneRenderer::CreateDescriptors()
void VkSceneRenderer::CreatePipelines()
{
//ShadowPipeline = RenderPipeline();
//auto& shadowPass = ShadowPipeline.AddPass("Shadow");
//shadowPass.AddAttachment("Depth", ImageFormat::D32F, ImageUsage::Depth);
//shadowPass.SetShaders(Shaders["shading_vert"], Shaders["shading_frag"]);
//shadowPass.SetPreRender([&](PassRenderContext& ctx) {
// std::vector<VkDescriptorSet> descriptors2 = { CameraBufferDescriptors, ModelBufferDescriptor };
// vkCmdBindDescriptorSets(
// ctx.commandBuffer,
// VK_PIPELINE_BIND_POINT_GRAPHICS,
// ctx.renderPass->PipelineLayout,
// 0, // firstSet
// 2, // descriptorSetCount
// descriptors2.data(), // pointer to the descriptor set(s)
// 0, // dynamicOffsetCount
// nullptr // dynamicOffsets
// );
//
// // Bind material
// vkCmdBindDescriptorSets(
// ctx.commandBuffer,
// VK_PIPELINE_BIND_POINT_GRAPHICS,
// ctx.renderPass->PipelineLayout,
// 4, // firstSet
// 1, // descriptorSetCount
// &MaterialBufferDescriptor, // pointer to the descriptor set(s)
// 0, // dynamicOffsetCount
// nullptr // dynamicOffsets
// );
//
// vkCmdBindDescriptorSets(
// ctx.commandBuffer,
// VK_PIPELINE_BIND_POINT_GRAPHICS,
// ctx.renderPass->PipelineLayout,
// 5, // firstSet
// 1, // descriptorSetCount
// &GPUResources::Get().TextureDescriptor, // pointer to the descriptor set(s)
// 0, // dynamicOffsetCount
// nullptr // dynamicOffsets
// );
//
// vkCmdBindDescriptorSets(
// ctx.commandBuffer,
// VK_PIPELINE_BIND_POINT_GRAPHICS,
// ctx.renderPass->PipelineLayout,
// 6, // firstSet
// 1, // descriptorSetCount
// &LightBufferDescriptor, // pointer to the descriptor set(s)
// 0, // dynamicOffsetCount
// nullptr // dynamicOffsets
// );
//
// vkCmdBindDescriptorSets(ctx.commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx.renderPass->PipelineLayout, 3, 1, //&SamplerDescriptor, 0, nullptr);
//});
//shadowPass.SetRender([&](PassRenderContext& ctx) {});
ShadowPipeline = RenderPipeline();
auto& shadowPass = ShadowPipeline.AddPass("Shadow");
shadowPass.AddAttachment("Depth", ImageFormat::D32F, ImageUsage::Depth);
shadowPass.SetShaders(Shaders["shadow_vert"], Shaders["shadow_frag"]);
shadowPass.SetPushConstant<ModelPushConstant>(modelPushConstant);
shadowPass.SetPreRender([&](PassRenderContext& ctx) {
std::vector<VkDescriptorSet> descriptors2 = { CameraBufferDescriptors, ModelBufferDescriptor };
vkCmdBindDescriptorSets(
ctx.commandBuffer,
VK_PIPELINE_BIND_POINT_GRAPHICS,
ctx.renderPass->PipelineLayout,
0, // firstSet
2, // descriptorSetCount
descriptors2.data(), // pointer to the descriptor set(s)
0, // dynamicOffsetCount
nullptr // dynamicOffsets
);
// Bind material
vkCmdBindDescriptorSets(
ctx.commandBuffer,
VK_PIPELINE_BIND_POINT_GRAPHICS,
ctx.renderPass->PipelineLayout,
4, // firstSet
1, // descriptorSetCount
&MaterialBufferDescriptor, // pointer to the descriptor set(s)
0, // dynamicOffsetCount
nullptr // dynamicOffsets
);
vkCmdBindDescriptorSets(
ctx.commandBuffer,
VK_PIPELINE_BIND_POINT_GRAPHICS,
ctx.renderPass->PipelineLayout,
5, // firstSet
1, // descriptorSetCount
&GPUResources::Get().TextureDescriptor, // pointer to the descriptor set(s)
0, // dynamicOffsetCount
nullptr // dynamicOffsets
);
vkCmdBindDescriptorSets(
ctx.commandBuffer,
VK_PIPELINE_BIND_POINT_GRAPHICS,
ctx.renderPass->PipelineLayout,
6, // firstSet
1, // descriptorSetCount
&LightBufferDescriptor, // pointer to the descriptor set(s)
0, // dynamicOffsetCount
nullptr // dynamicOffsets
);
vkCmdBindDescriptorSets(ctx.commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx.renderPass->PipelineLayout, 3, 1, &SamplerDescriptor, 0, nullptr);
});
shadowPass.SetRender([&](PassRenderContext& ctx) {
auto& cmd = ctx.commandBuffer;
auto& scene = ctx.scene;
auto& vk = VkRenderer::Get();
// Draw the scene
{
ZoneScopedN("Render Models");
auto view = scene->m_Registry.view<TransformComponent, ModelComponent, VisibilityComponent>();
for (auto e : view)
{
auto [transform, mesh, visibility] = view.get<TransformComponent, ModelComponent, VisibilityComponent>(e);
if (!mesh.ModelResource || !visibility.Visible)
{
continue;
}
Entity entity = Entity((entt::entity)e, scene.get());
for (auto& m : mesh.ModelResource->GetMeshes())
{
Ref<VkMesh> vkMesh = m->GetVkMesh();
Matrix4 globalTransform = transform.GetGlobalTransform();
auto descSet = vkMesh->GetDescriptorSet();
vkCmdBindDescriptorSets(
cmd,
VK_PIPELINE_BIND_POINT_GRAPHICS,
ctx.renderPass->PipelineLayout,
2, // firstSet
1, // descriptorSetCount
&descSet, // pointer to the descriptor set(s)
0, // dynamicOffsetCount
nullptr // dynamicOffsets
);
// Bind texture descriptor set
Ref<Material> material = m->GetMaterial();
Ref<VulkanImage> albedo = GPUResources::Get().GetTexture(material->AlbedoImage);
modelPushConstant.Index = ModelMatrixMapping[entity.GetID()];
modelPushConstant.MaterialIndex = MeshMaterialMapping[vkMesh->GetID()];
vkCmdPushConstants(
cmd,
ctx.renderPass->PipelineLayout,
VK_SHADER_STAGE_ALL_GRAPHICS, // Stage matching the pipeline layout
0, // Offset
sizeof(ModelPushConstant), // Size of the push constant
&modelPushConstant // Pointer to the value
);
vkCmdBindIndexBuffer(cmd, vkMesh->GetIndexBuffer()->GetBuffer(), 0, VK_INDEX_TYPE_UINT32);
vkCmdDrawIndexed(cmd, vkMesh->GetIndexBuffer()->GetSize() / sizeof(uint32_t), 1, 0, 0, 0);
}
}
}
});
ShadowPipeline.Build();
GBufferPipeline = RenderPipeline();
auto& gBufferPass = GBufferPipeline.AddPass("GBuffer");
@@ -332,11 +409,11 @@ void VkSceneRenderer::CreatePipelines()
ctx.commandBuffer,
VK_PIPELINE_BIND_POINT_GRAPHICS,
ctx.renderPass->PipelineLayout,
0, // firstSet
2, // descriptorSetCount
descriptors2.data(), // pointer to the descriptor set(s)
0, // dynamicOffsetCount
nullptr // dynamicOffsets
0, // firstSet
2, // descriptorSetCount
descriptors2.data(), // pointer to the descriptor set(s)
0, // dynamicOffsetCount
nullptr // dynamicOffsets
);
// Bind material
@@ -433,7 +510,6 @@ void VkSceneRenderer::CreatePipelines()
}
});
auto& shadingPass = GBufferPipeline.AddPass("Shading");
shadingPass.SetShaders(Shaders["shading_vert"], Shaders["shading_frag"]);

View File

@@ -6,6 +6,7 @@
#include "src/Core/Core.h"
#include "src/Resource/Serializable.h"
#include "src/Rendering/Camera.h"
#include "src/Resource/UUID.h"
namespace Nuake
{
@@ -13,8 +14,8 @@ namespace Nuake
class CameraComponent : public Component
{
NUAKECOMPONENT(CameraComponent, "Camera")
public:
UUID ID;
Ref<Camera> CameraInstance;
TransformComponent* transformComponent;

View File

@@ -54,16 +54,10 @@ StructuredBuffer<Light> lights;
struct PSInput {
float4 Position : SV_Position;
float3 Color : TEXCOORD0;
float2 UV : TEXCOORD1;
float3 Normal : TEXCOORD2;
float3x3 TBN : TEXCOORD3;
};
struct PSOutput {
float4 oColor0 : SV_TARGET;
float4 oNormal : SV_TARGET1;
float4 oMaterial : SV_TARGET2;
};
struct ModelPushConstant
@@ -78,59 +72,5 @@ ModelPushConstant pushConstants;
PSOutput main(PSInput input)
{
PSOutput output;
Material inMaterial = material[pushConstants.materialIndex];
// NORMAL
// TODO use TBN matrix
float3 normal = float3(0.5, 0.5, 1.0);
if(inMaterial.hasNormal == 1)
{
// Sample from texture.
}
normal = mul(input.TBN, normal);
normal = input.Normal / 2.0f + 0.5f;
output.oNormal = float4(normal, 1.0f);
// MATERIAL
// ALBEDO COLOR
float4 albedoColor = float4(inMaterial.albedo.xyz, 1.0f);
if(inMaterial.hasAlbedo == 1)
{
float4 albedoSample = textures[inMaterial.albedoTextureId].Sample(mySampler, input.UV);
// Alpha cutout?
if(albedoSample.a < 0.001f)
{
discard;
}
albedoColor.xyz = albedoSample.xyz;
}
output.oColor0 = albedoColor;
// MATERIAL PROPERTIES
float metalnessValue = inMaterial.metalnessValue;
if(inMaterial.hasMetalness == 1)
{
// TODO: Sample from metal texture
}
float aoValue = inMaterial.aoValue;
if(inMaterial.hasAO == 1)
{
// TODO: Sample from AO texture
}
float roughnessValue = inMaterial.roughnessValue;
if(inMaterial.hasRoughness == 1)
{
// TODO: Sample from roughness texture
}
float3 materialOuput = float3(inMaterial.metalnessValue, inMaterial.aoValue, inMaterial.roughnessValue);
output.oMaterial = float4(materialOuput, 1.0f);
return output;
}

View File

@@ -57,10 +57,6 @@ ModelPushConstant pushConstants;
// Outputs
struct VSOutput {
float4 Position : SV_Position;
float3 Color : TEXCOORD0;
float2 UV : TEXCOORD1;
float3 Normal : TEXCOORD2;
float3x3 TBN : TEXCOORD3;
};
// Main vertex shader
@@ -69,7 +65,6 @@ VSOutput main(uint vertexIndex : SV_VertexID)
VSOutput output;
Camera camData = camera[0];
ModelData modelData = model[pushConstants.modelIndex];
// Load vertex data from the buffer
@@ -77,13 +72,6 @@ VSOutput main(uint vertexIndex : SV_VertexID)
// Output the position of each vertex
output.Position = mul(camData.proj, mul(camData.view, mul(modelData.model, float4(v.position, 1.0f))));
output.Color = normalize(float3(v.position.xyz));
output.UV = float2(v.uv_x, v.uv_y);
output.Normal = normalize(v.normal);
float3 T = normalize(mul((float3x3)modelData.model, normalize(v.tangent.xyz)));
float3 B = normalize(mul((float3x3)modelData.model, normalize(v.bitangent.xyz)));
float3 N = normalize(mul((float3x3)modelData.model, normalize(v.normal)).xyz);
output.TBN = transpose(float3x3(T, B, N));
return output;
}