Fixed shading pass with new architecture

This commit is contained in:
antopilo
2025-01-12 22:54:41 -05:00
parent 37fd764248
commit 0ed6e06924
10 changed files with 270 additions and 46 deletions

View File

@@ -10,6 +10,8 @@
#include "src/Rendering/Textures/Material.h"
#include "src/Rendering/Vulkan/SceneRenderPipeline.h"
#include <Tracy.hpp>
@@ -84,15 +86,55 @@ SceneRenderPipeline::SceneRenderPipeline()
}
});
//auto& shadingPass = GBufferPipeline.AddPass("Shading");
//shadingPass.SetShaders(shaderMgr.GetShader("shading_vert"), shaderMgr.GetShader("shading_frag"));
//shadingPass.SetPushConstant<ShadingConstant>(shadingConstant);
//shadingPass.AddAttachment("Output", ImageFormat::RGBA8);
//shadingPass.SetDepthTest(false);
//shadingPass.AddInput("Albedo");
//shadingPass.AddInput("Normal");
//shadingPass.AddInput("Depth");
//shadingPass.AddInput("Material");
auto& shadingPass = GBufferPipeline.AddPass("Shading");
shadingPass.SetShaders(shaderMgr.GetShader("shading_vert"), shaderMgr.GetShader("shading_frag"));
shadingPass.SetPushConstant<ShadingConstant>(shadingConstant);
shadingPass.AddAttachment("Output", ShadingOutput->GetFormat());
shadingPass.SetDepthTest(false);
shadingPass.AddInput("Albedo");
shadingPass.AddInput("Normal");
shadingPass.AddInput("Depth");
shadingPass.AddInput("Material");
shadingPass.SetPreRender([&](PassRenderContext& ctx) {
auto& layout = ctx.renderPass->PipelineLayout;
auto& res = GPUResources::Get();
Cmd& cmd = ctx.commandBuffer;
// Bindless
cmd.BindDescriptorSet(layout, res.ModelDescriptor, 0);
cmd.BindDescriptorSet(layout, res.SamplerDescriptor, 2);
cmd.BindDescriptorSet(layout, res.MaterialDescriptor, 3);
cmd.BindDescriptorSet(layout, res.TexturesDescriptor, 4);
cmd.BindDescriptorSet(layout, res.LightsDescriptor, 5);
cmd.BindDescriptorSet(layout, res.CamerasDescriptor, 6);
// Inputs
shadingConstant.AlbedoTextureID = res.GetBindlessTextureID(GBufferAlbedo->GetID());
shadingConstant.DepthTextureID = res.GetBindlessTextureID(GBufferDepth->GetID());
shadingConstant.NormalTextureID = res.GetBindlessTextureID(GBufferNormal->GetID());
shadingConstant.MaterialTextureID = res.GetBindlessTextureID(GBufferMaterial->GetID());
// Camera
shadingConstant.CameraID = ctx.cameraID;
// Light
shadingConstant.LightCount = res.LightCount;
for (int i = 0; i < CSM_AMOUNT; i++)
{
shadingConstant.CascadeSplits[i] = LightComponent::mCascadeSplitDepth[i];
}
});
shadingPass.SetRender([&](PassRenderContext& ctx) {
auto& cmd = ctx.commandBuffer;
cmd.PushConstants(ctx.renderPass->PipelineLayout, sizeof(ShadingConstant), &shadingConstant);
// Draw full screen quad
auto& quadMesh = VkSceneRenderer::QuadMesh;
cmd.BindDescriptorSet(ctx.renderPass->PipelineLayout, quadMesh->GetDescriptorSet(), 1);
cmd.BindIndexBuffer(quadMesh->GetIndexBuffer()->GetBuffer());
cmd.DrawIndexed(6);
});
GBufferPipeline.Build();
}

View File

@@ -70,7 +70,7 @@ namespace Nuake
void SetCamera(UUID camera);
void Render(PassRenderContext& ctx);
Ref<VulkanImage> GetOutput() { return GBufferAlbedo; }
Ref<VulkanImage> GetOutput() { return ShadingOutput; }
private:
Ref<VulkanImage> ResizeImage(Ref<VulkanImage> image, const Vector2& size);

View File

@@ -57,7 +57,7 @@ namespace Nuake
Vector3 Direction;
float OuterConeAngle;
float InnerConeAngle;
bool CastShadow;
int CastShadow;
int ShadowMapTextureId[4];
int TransformId[4];
float pad[2];

View File

@@ -105,7 +105,7 @@ void VkRenderer::Initialize()
rect_vertices[3].position = { -1.0f, 1.0f, 0 };
rect_vertices[0].normal = { 0, 0, 1 };
rect_vertices[1].normal = { 0.5, 0.5,0.5 };
rect_vertices[1].normal = { 0.5, 0.5, 0.5 };
rect_vertices[2].normal = { 1.0, 0.0, 1.0f };
rect_vertices[3].normal = { 0, 1,0 };
@@ -120,11 +120,8 @@ void VkRenderer::Initialize()
rect_indices[4] = 1;
rect_indices[5] = 3;
GPUResources& resources = GPUResources::Get();
rectangle = resources.CreateMesh(rect_vertices, rect_indices);
Rect = resources.CreateMesh(rect_vertices, rect_indices);
CameraData camData{};
camData.View = Matrix4(1.0f);

View File

@@ -190,12 +190,12 @@ namespace Nuake
VkCommandPool ImguiCommandPool;
// Buffers
Ref<VkMesh> rectangle;
Ref<AllocatedBuffer> CameraBuffer;
Ref<VkSceneRenderer> SceneRenderer;
public:
Ref<VkMesh> Rect;
VkQueue GPUQueue;
Ref<VulkanImage> DrawImage;

View File

@@ -22,6 +22,8 @@
using namespace Nuake;
Ref<VkMesh> VkSceneRenderer::QuadMesh;
void VkSceneRenderer::Init()
{
LoadShaders();
@@ -148,35 +150,32 @@ void VkSceneRenderer::BeginScene(RenderContext inContext)
// Upload mesh material to GPU resources
for (auto& m : mesh.ModelResource->GetMeshes())
{
Ref<Material> material = m->GetMaterial();
if (!material)
{
continue;
}
// TODO: Avoid duplicated materials
MaterialBufferStruct materialBuffer
if (Ref<Material> material = m->GetMaterial(); material)
{
.HasAlbedo = material->HasAlbedo(),
.AlbedoColor = material->data.m_AlbedoColor,
.HasNormal = material->HasNormal(),
.HasMetalness = material->HasMetalness(),
.HasRoughness = material->HasRoughness(),
.HasAO = material->HasAO(),
.MetalnessValue = material->data.u_MetalnessValue,
.RoughnessValue = material->data.u_RoughnessValue,
.AoValue = material->data.u_AOValue,
.AlbedoTextureId = material->HasAlbedo() ? gpu.GetBindlessTextureID(material->AlbedoImage) : 0,
.NormalTextureId = material->HasNormal() ? gpu.GetBindlessTextureID(material->NormalImage) : 0,
.MetalnessTextureId = material->HasMetalness() ? gpu.GetBindlessTextureID(material->MetalnessImage) : 0,
.RoughnessTextureId = material->HasRoughness() ? gpu.GetBindlessTextureID(material->RoughnessImage) : 0,
.AoTextureId = material->HasAO() ? gpu.GetBindlessTextureID(material->AOImage) : 0,
};
MaterialBufferStruct materialBuffer
{
.HasAlbedo = material->HasAlbedo(),
.AlbedoColor = material->data.m_AlbedoColor,
.HasNormal = material->HasNormal(),
.HasMetalness = material->HasMetalness(),
.HasRoughness = material->HasRoughness(),
.HasAO = material->HasAO(),
.MetalnessValue = material->data.u_MetalnessValue,
.RoughnessValue = material->data.u_RoughnessValue,
.AoValue = material->data.u_AOValue,
.AlbedoTextureId = material->HasAlbedo() ? gpu.GetBindlessTextureID(material->AlbedoImage) : 0,
.NormalTextureId = material->HasNormal() ? gpu.GetBindlessTextureID(material->NormalImage) : 0,
.MetalnessTextureId = material->HasMetalness() ? gpu.GetBindlessTextureID(material->MetalnessImage) : 0,
.RoughnessTextureId = material->HasRoughness() ? gpu.GetBindlessTextureID(material->RoughnessImage) : 0,
.AoTextureId = material->HasAO() ? gpu.GetBindlessTextureID(material->AOImage) : 0,
};
// Save bindless mapping index
allMaterials[currentMaterialIndex] = std::move(materialBuffer);
gpu.MeshMaterialMapping[m->GetVkMesh()->GetID()] = currentMaterialIndex;
currentMaterialIndex++;
// Save bindless mapping index
allMaterials[currentMaterialIndex] = std::move(materialBuffer);
gpu.MeshMaterialMapping[m->GetVkMesh()->GetID()] = currentMaterialIndex;
currentMaterialIndex++;
}
}
currentIndex++;

View File

@@ -20,8 +20,8 @@ namespace Nuake
class VkSceneRenderer
{
private:
Ref<VkMesh> QuadMesh;
public:
static Ref<VkMesh> QuadMesh;
public:
RenderContext Context;

View File

@@ -0,0 +1,153 @@
#include "Text.h"
#include "../Renderer.h"
#include "src/Rendering/Renderer.h"
#include "src/UI/Font/FontManager.h"
#include <sstream>
namespace NuakeUI
{
std::shared_ptr<Text> Text::New(const std::string& id, const std::string& text)
{
return std::make_shared<Text>(id, text);
}
Text::Text(const std::string& id, const std::string& text)
{
Type = "text";
ID = id;
mNode = YGNodeNew();
mFont = Renderer::Get().mDefaultFont;
ComputedStyle.FontSize = 36.0f;
SetText(text);
float height = ((mFont->LineHeight) / 32.f) * (ComputedStyle.FontSize * 2.0) * Lines.size();
YGNodeStyleSetHeight(mNode, height);
YGNodeStyleSetMinHeight(mNode, height);
YGNodeStyleSetMinWidth(mNode, CalculateWidth());
YGNodeStyleSetWidthPercent(mNode, 100.f);
}
void Text::SetText(const std::string& text)
{
Lines.clear();
// Split into lines
auto ss = std::stringstream{ text };
for (std::string line; std::getline(ss, line, '\n');)
Lines.push_back(line);
if (std::size(Lines) > 0)
Calculate();
}
std::string Text::GetText() const
{
std::string result = "";
for (const auto& line : Lines)
{
result += line + "\n";
}
return result;
}
void Text::Draw(int z)
{
const float width = YGNodeLayoutGetWidth(mNode);
const float height = YGNodeLayoutGetHeight(mNode);
ComputedSize = { width, height };
float x = YGNodeLayoutGetLeft(mNode);
float y = YGNodeLayoutGetTop(mNode);
// Centers the text in the line height.
y += (ComputedStyle.FontFamily->LineHeight / 64.0f) * (ComputedStyle.FontSize * 2.0) / 2.0f;
x += YGNodeLayoutGetPadding(mNode, YGEdgeLeft);
y += YGNodeLayoutGetPadding(mNode, YGEdgeTop);
auto parent = Parent;
bool hasParent = parent != nullptr;
if (hasParent)
{
x += parent->ComputedPosition.x;
y += parent->ComputedPosition.y - parent->GetScroll();
}
Vector3 position = Vector3(x, y, z);
ComputedPosition = position;
if (ComputedStyle.TextAlign == TextAlignType::Center)
{ // We center the text horizontally.
position.x += (width / 2.0f) - CalculateWidth() / 2.0f;
}
else if (ComputedStyle.TextAlign == TextAlignType::Right)
{ // Aligns the line of the left
position.x += width - CalculateWidth();
}
// Scissor the parent bounding box.
bool hideOverflow = hasParent && Parent->ComputedStyle.Overflow == OverflowType::Hidden;
if (hideOverflow)
{
//glEnable(GL_SCISSOR_TEST);
int clipX = (int)Parent->ComputedPosition.x;
int clipY = (1080 - (int)Parent->ComputedPosition.y - (int)Parent->ComputedSize.y);
int clipWidth = (int)Parent->ComputedSize.x;
int clipHeight = (int)Parent->ComputedSize.y;
//glScissor(clipX, clipY, clipWidth, clipHeight);
}
const float lineYOffset = (ComputedStyle.FontFamily->LineHeight / 32.0f) * (ComputedStyle.FontSize * 2.0);
// Draw each line and offset the Y of the position by the line height.
for (int i = 0; i < Lines.size(); i++)
{
// Draw the first line
Renderer::Get().DrawString(Lines[i], ComputedStyle, ComputedStyle.FontFamily, position);
// Update the Y position to the next line.
position.y += lineYOffset;
}
// Disable scissoring.
if (hideOverflow) {}
//glDisable(GL_SCISSOR_TEST);
}
float Text::CalculateWidth()
{
// If theres no text, then assume it's 0;
if (Lines.size() == 0) return 0.f;
const float fontSize = ComputedStyle.FontSize * 2.0 / 64.f;
// Find the largest line.
float maxWidth = 0.f;
for (auto& l : Lines)
{
float textWidth = 0.f;
// Iterate over each character and add up the advance.
for (char const& c : l)
{
Char letter = mFont->GetChar((int)c);
textWidth += (letter.Advance);
}
if (textWidth > maxWidth)
maxWidth = textWidth;
}
// Scale the width by the font size.
return maxWidth * fontSize;
}
void Text::Calculate()
{
const float halfLineHeight = ComputedStyle.FontFamily->LineHeight / 32.f;
const float linesHeight = Lines.size() * ComputedStyle.FontSize * 2.0;
YGNodeStyleSetHeight(mNode, halfLineHeight * linesHeight);
YGNodeStyleSetWidth(mNode, CalculateWidth());
}
}

View File

@@ -0,0 +1,33 @@
#pragma once
#include "Node.h"
#include "src/UI/Font/Font.h"
#include <memory>
#include <string>
namespace NuakeUI
{
class Header1;
typedef std::shared_ptr<Header1> TextPtr;
class Header1 : public Node
{
public:
std::vector<std::string> Lines;
std::shared_ptr<Font> mFont;
static std::shared_ptr<Header1> New(const std::string& id, const std::string& text);
Header1(const std::string& id, const std::string& text);
~Header1() = default;
void SetText(const std::string& text);
std::string GetText() const;
void Calculate() override;
void Draw(int z) override;
void SetFont(const std::string& fontPath);
float CalculateWidth();
};
}

View File

@@ -255,7 +255,7 @@ PSOutput main(PSInput input)
if(light.castShadow == true)
{
shadow *= ShadowCalculation(light, worldPos, N);
//shadow *= ShadowCalculation(light, worldPos, N);
//output.oColor0 = float4(albedo * 0.1 + float3(shadow, shadow, shadow), 1);
//return output;
}