add RenderPass

This commit is contained in:
2025-11-29 20:03:32 +08:00
parent b2ea361518
commit 3f1515bb63
17 changed files with 362 additions and 82 deletions

View File

@ -113,8 +113,32 @@ namespace Prism
void EditorLayer::OnAttach()
{
// RenderPass
FramebufferSpecification geoFramebufferSpec;
geoFramebufferSpec.Width = 1280;
geoFramebufferSpec.Height = 720;
geoFramebufferSpec.Format = FramebufferFormat::RGBA16F;
geoFramebufferSpec.ClearColor = { 0.1f, 0.1f, 0.1f, 1.0f };
RenderPassSpecification geoRenderPassSpec;
geoRenderPassSpec.TargetFramebuffer = FrameBuffer::Create(geoFramebufferSpec);
m_GeoPass = RenderPass::Create(geoRenderPassSpec);
FramebufferSpecification compFramebufferSpec;
compFramebufferSpec.Width = 1280;
compFramebufferSpec.Height = 720;
compFramebufferSpec.Format = FramebufferFormat::RGBA8;
compFramebufferSpec.ClearColor = { 0.1f, 0.1f, 0.1f, 1.0f };
RenderPassSpecification compRenderPassSpec;
compRenderPassSpec.TargetFramebuffer = FrameBuffer::Create(compFramebufferSpec);
m_CompositePass = RenderPass::Create(compRenderPassSpec);
/*
m_Framebuffer.reset(FrameBuffer::Create(1280, 720, FramebufferFormat::RGBA16F));
m_FinalPresentBuffer.reset(FrameBuffer::Create(1280, 720, FramebufferFormat::RGBA8));
*/
m_QuadShader = Shader::Create("assets/shaders/quad.glsl");
m_HDRShader = Shader::Create("assets/shaders/hdr.glsl");
@ -151,7 +175,7 @@ namespace Prism
mi->Set("u_Roughness", roughness);
mi->Set("u_ModelMatrix", glm::translate(glm::mat4(1.0f), glm::vec3(x, 0.0f, 0.0f)));
x += 1.1f;
roughness += 0.15f;
roughness += 0.125f;
m_MetalSphereMaterialInstances.push_back(mi);
}
@ -165,26 +189,17 @@ namespace Prism
mi->Set("u_Roughness", roughness);
mi->Set("u_ModelMatrix", translate(glm::mat4(1.0f), glm::vec3(x, 1.2f, 0.0f)));
x += 1.1f;
roughness += 0.15f;
roughness += 0.125f;
m_DielectricSphereMaterialInstances.push_back(mi);
}
// Create Quad
x = -1;
float y = -1;
float width = 2, height = 2;
struct QuadVertex
{
glm::vec3 Position;
glm::vec2 TexCoord;
};
// Create Quad
static float QuadVertex[] = {
-1.0f, -1.0f, 0.0f, 0.0f, 0.0f,
1.0f, -1.0f, 0.0f, 1.0f, 0.0f,
1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
-1.0f, 1.0f, 0.0f, 0.0f, 1.0f
};
static uint32_t QuadIndices[] = {
0, 1, 2, 2, 3, 0
};
@ -225,7 +240,8 @@ namespace Prism
m_Camera.Update(deltaTime);
auto viewProjection = m_Camera.GetProjectionMatrix() * m_Camera.GetViewMatrix();
m_Framebuffer->Bind();
// m_Framebuffer->Bind();
Renderer::BeginRenderPass(m_GeoPass);
Renderer::Clear(m_ClearColor[0], m_ClearColor[1], m_ClearColor[2], m_ClearColor[3]);
m_QuadShader->Bind();
@ -252,7 +268,6 @@ namespace Prism
m_MeshMaterial->Set("u_MetalnessTexToggle", m_MetalnessInput.UseTexture ? 1.0f : 0.0f);
m_MeshMaterial->Set("u_RoughnessTexToggle", m_RoughnessInput.UseTexture ? 1.0f : 0.0f);
m_MeshMaterial->Set("u_EnvMapRotation", m_EnvMapRotation);
m_MeshMaterial->Set("u_EnvRadianceTex", m_EnvironmentCubeMap);
m_MeshMaterial->Set("u_EnvIrradianceTex", m_EnvironmentIrradiance);
m_MeshMaterial->Set("u_BRDFLUTTexture", m_BRDFLUT);
@ -317,19 +332,23 @@ namespace Prism
m_GridMaterial->Set("u_MVP", viewProjection * glm::scale(glm::mat4(1.0f), glm::vec3(16.0f)));
m_PlaneMesh->Render(deltaTime, m_GridMaterial);
m_Framebuffer->Unbind();
// m_Framebuffer->Unbind();
Renderer::EndRenderPass();
m_FinalPresentBuffer->Bind();
Renderer::BeginRenderPass(m_CompositePass);
// m_FinalPresentBuffer->Bind();
m_HDRShader->Bind();
m_HDRShader->SetFloat("u_Exposure", m_Exposure);
m_Framebuffer->BindTexture();
// m_Framebuffer->BindTexture();
m_GeoPass->GetSpecification().TargetFramebuffer->BindTexture();
/*
m_VertexBuffer->Bind();
m_IndexBuffer->Bind();
*/
m_FullscreenQuadVertexArray->Bind();
Renderer::DrawIndexed(m_FullscreenQuadVertexArray->GetIndexBuffer()->GetCount(), false);
m_FinalPresentBuffer->Unbind();
// m_FinalPresentBuffer->Unbind();
Renderer::EndRenderPass();
}
}
@ -681,10 +700,15 @@ namespace Prism
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0));
ImGui::Begin("Viewport");
auto viewportSize = ImGui::GetContentRegionAvail();
m_Framebuffer->Resize((uint32_t)viewportSize.x, (uint32_t)viewportSize.y);
m_FinalPresentBuffer->Resize((uint32_t)viewportSize.x, (uint32_t)viewportSize.y);
m_GeoPass->GetSpecification().TargetFramebuffer->Resize((uint32_t)viewportSize.x, (uint32_t)viewportSize.y);
m_CompositePass->GetSpecification().TargetFramebuffer->Resize((uint32_t)viewportSize.x, (uint32_t)viewportSize.y);
// m_Framebuffer->Resize((uint32_t)viewportSize.x, (uint32_t)viewportSize.y);
// m_FinalPresentBuffer->Resize((uint32_t)viewportSize.x, (uint32_t)viewportSize.y);
m_Camera.SetProjectionMatrix(glm::perspectiveFov(glm::radians(45.0f), viewportSize.x, viewportSize.y, 0.1f, 10000.0f));
ImGui::Image((ImTextureRef)m_FinalPresentBuffer->GetColorAttachmentRendererID(), viewportSize, {0, 1}, {1, 0});
// ImGui::Image((ImTextureRef)m_FinalPresentBuffer->GetColorAttachmentRendererID(), viewportSize, {0, 1}, {1, 0});
ImGui::Image((ImTextureRef)m_CompositePass->GetSpecification().TargetFramebuffer->GetColorAttachmentRendererID(), viewportSize, { 0, 1 }, { 1, 0 });
// ImGuizmo
if (m_GizmoType != -1)

View File

@ -27,7 +27,8 @@ private:
private:
float m_ClearColor[4];
Ref<FrameBuffer> m_Framebuffer, m_FinalPresentBuffer;
// Ref<FrameBuffer> m_Framebuffer, m_FinalPresentBuffer;
Ref<RenderPass> m_GeoPass, m_CompositePass;
/*
Ref<VertexBuffer> m_VertexBuffer;

View File

@ -18,6 +18,7 @@
#include "Prism/Renderer/Buffer.h"
#include "Prism/Renderer/Renderer.h"
#include "Prism/Renderer/RenderPass.h"
#include "Prism/Renderer/Shader.h"
#include "Prism/Renderer/Texture.h"
#include "Prism/Renderer/FrameBuffer.h"

View File

@ -181,7 +181,7 @@ namespace Prism
bool Application::OnWindowResize(const WindowResizeEvent& e)
{
int width = e.GetWidth(), height = e.GetHeight();
uint32_t width = e.GetWidth(), height = e.GetHeight();
if (width == 0 || height == 0)
{
m_Minimized = true;
@ -192,7 +192,10 @@ namespace Prism
PM_RENDER_2(width, height, { glViewport(0, 0, width, height); });
auto& fbs = FrameBufferPool::GetGlobal()->GetAll();
for (auto& fb : fbs)
fb->Resize(width, height);
{
if (const auto fbp = fb.lock())
fbp->Resize(width, height);
}
return false;
}

View File

@ -10,14 +10,13 @@
namespace Prism
{
OpenGLFrameBuffer::OpenGLFrameBuffer(const uint32_t width, const uint32_t height, const FramebufferFormat format)
: m_Format(format)
OpenGLFrameBuffer::OpenGLFrameBuffer(const FramebufferSpecification& spec)
: m_Specification(spec)
{
OpenGLFrameBuffer::Resize(width, height);
m_Width = width;
m_Height = height;
OpenGLFrameBuffer::Resize(spec.Width, spec.Height);
}
OpenGLFrameBuffer::~OpenGLFrameBuffer()
{
PM_RENDER_S({
@ -29,7 +28,7 @@ namespace Prism
{
PM_RENDER_S({
glBindFramebuffer(GL_FRAMEBUFFER, self->m_RendererID);
glViewport(0, 0, self->m_Width, self->m_Height);
glViewport(0, 0, self->m_Specification.Width, self->m_Specification.Height);
});
}
@ -40,13 +39,13 @@ namespace Prism
});
}
void OpenGLFrameBuffer::Resize(uint32_t width, uint32_t height)
void OpenGLFrameBuffer::Resize(const uint32_t width, const uint32_t height)
{
if (m_Width == width && m_Height == height)
if (m_RendererID && m_Specification.Width == width && m_Specification.Height == height)
return;
m_Width = width;
m_Height = height;
m_Specification.Width = width;
m_Specification.Height = height;
PM_RENDER_S({
if (self->m_RendererID)
{
@ -62,13 +61,13 @@ namespace Prism
glBindTexture(GL_TEXTURE_2D, self->m_ColorAttachment);
// TODO: Create Hazel texture object based on format here
if (self->m_Format == FramebufferFormat::RGBA16F)
if (self->m_Specification.Format == FramebufferFormat::RGBA16F)
{
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, self->m_Width, self->m_Height, 0, GL_RGBA, GL_FLOAT, nullptr);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, self->m_Specification.Width, self->m_Specification.Height, 0, GL_RGBA, GL_FLOAT, nullptr);
}
else if (self->m_Format == FramebufferFormat::RGBA8)
else if (self->m_Specification.Format == FramebufferFormat::RGBA8)
{
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, self->m_Width, self->m_Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, self->m_Specification.Width, self->m_Specification.Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
@ -77,7 +76,7 @@ namespace Prism
glGenTextures(1, &self->m_DepthAttachment);
glBindTexture(GL_TEXTURE_2D, self->m_DepthAttachment);
glTexImage2D(
GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, self->m_Width, self->m_Height, 0,
GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, self->m_Specification.Width, self->m_Specification.Height, 0,
GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL
);

View File

@ -12,7 +12,7 @@ namespace Prism
class OpenGLFrameBuffer : public FrameBuffer
{
public:
OpenGLFrameBuffer(uint32_t width, uint32_t height, FramebufferFormat format);
OpenGLFrameBuffer(const FramebufferSpecification& spec);
virtual ~OpenGLFrameBuffer();
void Bind() const override;
@ -26,15 +26,13 @@ namespace Prism
RendererID GetColorAttachmentRendererID() const override { return m_ColorAttachment; }
RendererID GetDepthAttachmentRendererID() const override { return m_DepthAttachment; }
virtual uint32_t GetWidth() const { return m_Width; }
virtual uint32_t GetHeight() const { return m_Height; }
virtual FramebufferFormat GetFormat() const { return m_Format; }
virtual const FramebufferSpecification& GetSpecification() const override { return m_Specification; }
private:
RendererID m_RendererID = 0;
uint32_t m_Width = 0, m_Height = 0;
FramebufferFormat m_Format;
FramebufferSpecification m_Specification;
RendererID m_ColorAttachment, m_DepthAttachment;
RendererID m_RendererID = 0;
RendererID m_ColorAttachment = 0, m_DepthAttachment = 0;
};
}

View File

@ -0,0 +1,17 @@
//
// Created by sfd on 25-11-29.
//
#include "OpenGLRenderPass.h"
namespace Prism
{
OpenGLRenderPass::OpenGLRenderPass(const RenderPassSpecification& spec)
: m_spec(spec)
{
}
OpenGLRenderPass::~OpenGLRenderPass()
{
}
}

View File

@ -0,0 +1,26 @@
//
// Created by sfd on 25-11-29.
//
#ifndef OPENGLRENDERPASS_H
#define OPENGLRENDERPASS_H
#include "Prism/Renderer/RenderPass.h"
namespace Prism
{
class OpenGLRenderPass : public RenderPass
{
public:
OpenGLRenderPass(const RenderPassSpecification& spec);
virtual ~OpenGLRenderPass();
virtual const RenderPassSpecification& GetSpecification() const override { return m_spec; }
private:
RenderPassSpecification m_spec;
};
}
#endif //OPENGLRENDERPASS_H

View File

@ -8,13 +8,13 @@
namespace Prism
{
FrameBuffer* FrameBuffer::Create(uint32_t width, uint32_t height, FramebufferFormat format)
Ref<FrameBuffer> FrameBuffer::Create(const FramebufferSpecification& spec)
{
FrameBuffer* result = nullptr;
Ref<FrameBuffer> result = nullptr;
switch (RendererAPI::Current())
{
case RendererAPIType::None: return nullptr;
case RendererAPIType::OpenGL: result = new OpenGLFrameBuffer(width, height, format);
case RendererAPIType::OpenGL: result = CreateRef<OpenGLFrameBuffer>(spec);
}
FrameBufferPool::GetGlobal()->Add(result);
return result;
@ -39,7 +39,12 @@ namespace Prism
return std::weak_ptr<FrameBuffer>();
}
void FrameBufferPool::Add(FrameBuffer* framebuffer)
FrameBufferPool* FrameBufferPool::GetGlobal()
{
return s_Instance;
}
void FrameBufferPool::Add(std::weak_ptr<FrameBuffer> framebuffer)
{
m_Pool.push_back(framebuffer);
}

View File

@ -5,6 +5,7 @@
#ifndef FRAMEBUFFER_H
#define FRAMEBUFFER_H
#include "RendererAPI.h"
#include "glm/glm.hpp"
namespace Prism
@ -16,12 +17,25 @@ namespace Prism
RGBA16F = 2
};
struct FramebufferSpecification
{
uint32_t Width = 1280;
uint32_t Height = 720;
glm::vec4 ClearColor;
FramebufferFormat Format;
// SwapChainTarget = screen buffer (i.e. no framebuffer)
bool SwapChainTarget = false;
};
class PRISM_API FrameBuffer
{
public:
static FrameBuffer* Create(uint32_t width, uint32_t height, FramebufferFormat format);
virtual ~FrameBuffer() {}
static Ref<FrameBuffer> Create(const FramebufferSpecification& spec);
virtual const FramebufferSpecification& GetSpecification() const = 0;
virtual void Bind() const = 0;
virtual void Unbind() const = 0;
@ -41,13 +55,14 @@ namespace Prism
~FrameBufferPool();
std::weak_ptr<FrameBuffer> AllocateBuffer();
void Add(FrameBuffer* framebuffer);
void Add(std::weak_ptr<FrameBuffer> framebuffer);
const std::vector<FrameBuffer*>& GetAll() const { return m_Pool; }
const std::vector<std::weak_ptr<FrameBuffer>>& GetAll() const { return m_Pool; }
static FrameBufferPool* GetGlobal();
inline static FrameBufferPool* GetGlobal() { return s_Instance; }
private:
std::vector<FrameBuffer*> m_Pool;
std::vector<std::weak_ptr<FrameBuffer>> m_Pool;
static FrameBufferPool* s_Instance;
};

View File

@ -317,8 +317,8 @@ namespace Prism
}
}
if (!materialOverride)
self->m_MeshShader->SetMat4FromRenderThread("u_ModelMatrix", transform * submesh.Transform);
// if (!materialOverride)
// self->m_MeshShader->SetMat4FromRenderThread("u_ModelMatrix", transform * submesh.Transform);
glDrawElementsBaseVertex(GL_TRIANGLES, submesh.IndexCount, GL_UNSIGNED_INT, (void*)(sizeof(uint32_t) * submesh.BaseIndex), submesh.BaseVertex);
}

View File

@ -0,0 +1,22 @@
//
// Created by sfd on 25-11-29.
//
#include "RenderPass.h"
#include "Prism/Platform/OpenGL/OpenGLRenderPass.h"
namespace Prism
{
Ref<RenderPass> RenderPass::Create(const RenderPassSpecification& spec)
{
switch (RendererAPI::Current())
{
case RendererAPIType::None: PM_CORE_ASSERT(false, "RendererAPI::None is currently not supported!"); return nullptr;
case RendererAPIType::OpenGL: return std::make_shared<OpenGLRenderPass>(spec);
}
PM_CORE_ASSERT(false, "Unknown RendererAPI!");
return nullptr;
}
}

View File

@ -0,0 +1,29 @@
//
// Created by sfd on 25-11-29.
//
#ifndef RENDERPASS_H
#define RENDERPASS_H
#include "FrameBuffer.h"
namespace Prism
{
struct RenderPassSpecification
{
Ref<FrameBuffer> TargetFramebuffer;
};
class PRISM_API RenderPass
{
public:
virtual ~RenderPass() {}
virtual const RenderPassSpecification& GetSpecification() const = 0;
static Ref<RenderPass> Create(const RenderPassSpecification& spec);
};
}
#endif //RENDERPASS_H

View File

@ -52,4 +52,38 @@ namespace Prism
{
s_Instance->m_CommandQueue.Execute();
}
void Renderer::BeginRenderPass(const Ref<RenderPass>& renderPass)
{
s_Instance->IBeginRenderPass(renderPass);
}
void Renderer::EndRenderPass()
{
s_Instance->IEndRenderPass();
}
void Renderer::SubmitMesh(const Ref<Mesh>& mesh)
{
s_Instance->SubmitMeshI(mesh);
}
void Renderer::IBeginRenderPass(const Ref<RenderPass>& renderPass)
{
// TODO: Convert all of this into a render command buffer
m_ActiveRenderPass = renderPass;
renderPass->GetSpecification().TargetFramebuffer->Bind();
}
void Renderer::IEndRenderPass()
{
PM_CORE_ASSERT(m_ActiveRenderPass, "No active render pass! Have you called Renderer::EndRenderPass twice?");
m_ActiveRenderPass->GetSpecification().TargetFramebuffer->Unbind();
m_ActiveRenderPass = nullptr;
}
void Renderer::SubmitMeshI(const Ref<Mesh>& mesh)
{
}
}

View File

@ -4,7 +4,9 @@
#ifndef RENDERER_H
#define RENDERER_H
#include "Mesh.h"
#include "RenderCommandQueue.h"
#include "RenderPass.h"
#include "Shader.h"
#include "Prism/Core/Application.h"
@ -36,10 +38,25 @@ namespace Prism
void WaitAndRender();
inline static Renderer& Get() { return *s_Instance; }
public:
static void BeginRenderPass(const Ref<RenderPass>& renderPass);
static void EndRenderPass();
static void SubmitMesh(const Ref<Mesh>& mesh);
private:
void IBeginRenderPass(const Ref<RenderPass>& renderPass);
void IEndRenderPass();
void SubmitMeshI(const Ref<Mesh>& mesh);
private:
static Renderer* s_Instance;
private:
Ref<RenderPass> m_ActiveRenderPass;
Scope<ShaderLibrary> m_ShaderLibrary;
RenderCommandQueue m_CommandQueue;
};

View File

@ -148,8 +148,26 @@ TestLayer::TestLayer()
void TestLayer::OnAttach()
{
m_FrameBuffer.reset(Prism::FrameBuffer::Create(1280, 720, Prism::FramebufferFormat::RGBA16F));
m_FinalPresentBuffer.reset(Prism::FrameBuffer::Create(1280, 720, Prism::FramebufferFormat::RGBA8));
Prism::FramebufferSpecification geoFramebufferspec;
geoFramebufferspec.Width = 1280;
geoFramebufferspec.Height = 720;
geoFramebufferspec.Format = Prism::FramebufferFormat::RGBA16F;
geoFramebufferspec.ClearColor = {0.1f, 0.1f, 0.1f, 1.0f};
Prism::RenderPassSpecification geoRenderPass;
geoRenderPass.TargetFramebuffer = Prism::FrameBuffer::Create(geoFramebufferspec);
m_GeoPass = Prism::RenderPass::Create(geoRenderPass);
Prism::FramebufferSpecification finalFramebufferspec;
finalFramebufferspec.Width = 1280;
finalFramebufferspec.Height = 720;
finalFramebufferspec.Format = Prism::FramebufferFormat::RGBA8;
finalFramebufferspec.ClearColor = {0.1f, 0.1f, 0.1f, 1.0f};
Prism::RenderPassSpecification finalRenderPass;
finalRenderPass.TargetFramebuffer = Prism::FrameBuffer::Create(finalFramebufferspec);
m_FinalPass = Prism::RenderPass::Create(finalRenderPass);
static float QuadVertex[] = {
-1.0f, -1.0f, 0.0f, 0.0f, 0.0f,
@ -174,13 +192,18 @@ void TestLayer::OnAttach()
m_VertexArray->SetIndexBuffer(ib);
m_SkyBoxTextureCube.reset(Prism::TextureCube::Create("assets/textures/environments/Arches_E_PineTree_Radiance.tga"));
m_EnvironmentIrradiance.reset(Prism::TextureCube::Create("assets/textures/environments/Arches_E_PineTree_Irradiance.tga"));
m_SkyboxShader = Prism::Shader::Create("assets/shaders/quad.glsl");
m_Shader = Prism::Shader::Create("assets/shaders/demo.glsl");
m_SkyBoxShader = Prism::Shader::Create("assets/shaders/quad.glsl");
m_HDRShader = Prism::Shader::Create("assets/shaders/hdr.glsl");
// m_Mesh = std::make_unique<Prism::Mesh>("assets/meshes/cerberus.fbx");
// m_MeshMaterial = Prism::CreateRef<Prism::MaterialInstance>(m_Mesh->GetMaterial());
m_Mesh = std::make_unique<Prism::Mesh>("assets/models/m1911/m1911.fbx");
m_MeshMaterial = Prism::CreateRef<Prism::MaterialInstance>(m_Mesh->GetMaterial());
m_BRDFLUT.reset(Prism::Texture2D::Create("assets/textures/BRDF_LUT.tga"));
m_Light.Direction = {-0.5f, -0.5f, 1.0f};
m_Light.Radiance = {1.0f, 1.0f, 1.0f};
}
void TestLayer::OnDetach()
@ -193,26 +216,47 @@ void TestLayer::OnUpdate(Prism::TimeStep deltaTime)
m_Camera.Update(deltaTime);
auto viewProjection = m_Camera.GetProjectionMatrix() * m_Camera.GetViewMatrix();
m_FrameBuffer->Bind();
Prism::Renderer::BeginRenderPass(m_GeoPass);
Prism::Renderer::Clear(m_clearColor[0], m_clearColor[1], m_clearColor[2], m_clearColor[3]);
// SkyBox
m_SkyboxShader->Bind();
m_SkyboxShader->SetMat4("u_InverseVP", inverse(viewProjection));
m_SkyBoxShader->Bind();
m_SkyBoxShader->SetMat4("u_InverseVP", inverse(viewProjection));
m_SkyBoxTextureCube->Bind(0);
m_VertexArray->Bind();
Prism::Renderer::DrawIndexed(m_VertexArray->GetIndexBuffer()->GetCount(), false);
m_FrameBuffer->Unbind();
m_MeshMaterial->Set("u_AlbedoColor", m_AlbedoInput.Color);
m_MeshMaterial->Set("u_Metalness", m_MetalnessInput.Value);
m_MeshMaterial->Set("u_Roughness", m_RoughnessInput.Value);
m_MeshMaterial->Set("u_ViewProjectionMatrix", viewProjection);
m_MeshMaterial->Set("u_ModelMatrix", glm::scale(glm::mat4(1.0f), glm::vec3(m_MeshScale)));
m_MeshMaterial->Set("lights", m_Light);
m_MeshMaterial->Set("u_CameraPosition", m_Camera.GetPosition());
m_MeshMaterial->Set("u_RadiancePrefilter", m_RadiancePrefilter ? 1.0f : 0.0f);
m_MeshMaterial->Set("u_AlbedoTexToggle", m_AlbedoInput.UseTexture ? 1.0f : 0.0f);
m_MeshMaterial->Set("u_NormalTexToggle", m_NormalInput.UseTexture ? 1.0f : 0.0f);
m_MeshMaterial->Set("u_MetalnessTexToggle", m_MetalnessInput.UseTexture ? 1.0f : 0.0f);
m_MeshMaterial->Set("u_RoughnessTexToggle", m_RoughnessInput.UseTexture ? 1.0f : 0.0f);
m_MeshMaterial->Set("u_EnvMapRotation", m_EnvMapRotation);
m_MeshMaterial->Set("u_EnvRadianceTex", m_SkyBoxTextureCube);
m_MeshMaterial->Set("u_EnvIrradianceTex", m_EnvironmentIrradiance);
m_MeshMaterial->Set("u_BRDFLUTTexture", m_BRDFLUT);
m_Mesh->Render(deltaTime, glm::mat4(1.0f), m_MeshMaterial);
Prism::Renderer::EndRenderPass();
// HDR
m_FinalPresentBuffer->Bind();
Prism::Renderer::BeginRenderPass(m_FinalPass);
m_HDRShader->Bind();
m_HDRShader->SetFloat("u_Exposure", m_Exposure);
m_FrameBuffer->BindTexture();
m_GeoPass->GetSpecification().TargetFramebuffer->BindTexture();
m_VertexArray->Bind();
Prism::Renderer::DrawIndexed(m_VertexArray->GetIndexBuffer()->GetCount(), false);
m_FinalPresentBuffer->Unbind();
Prism::Renderer::EndRenderPass();
}
void TestLayer::OnImGuiRender()
@ -225,16 +269,18 @@ void TestLayer::OnImGuiRender()
ImGui::DragFloat("Exposure", &m_Exposure, 0.01f, 0.0f);
const auto& position = m_Camera.GetPosition();
ImGui::Text("Camera: (%.2f, %.2f, %.2f)", position.x, position.y, position.z);
ImGui::End();
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
ImGui::Begin("Viewport");
auto viewportSize = ImGui::GetContentRegionAvail();
m_FrameBuffer->Resize((uint32_t)viewportSize.x, (uint32_t)viewportSize.y);
m_FinalPresentBuffer->Resize((uint32_t)viewportSize.x, (uint32_t)viewportSize.y);
m_GeoPass->GetSpecification().TargetFramebuffer->Resize((uint32_t)viewportSize.x, (uint32_t)viewportSize.y);
m_FinalPass->GetSpecification().TargetFramebuffer->Resize((uint32_t)viewportSize.x, (uint32_t)viewportSize.y);
m_Camera.SetProjectionMatrix(glm::perspectiveFov(glm::radians(45.0f), viewportSize.x, viewportSize.y, 0.1f, 10000.0f));
ImGui::Image((ImTextureRef)m_FinalPresentBuffer->GetColorAttachmentRendererID(), viewportSize, {0, 1}, {1, 0});
ImGui::Image((ImTextureRef)m_FinalPass->GetSpecification().TargetFramebuffer->GetColorAttachmentRendererID(), viewportSize, {0, 1}, {1, 0});
ImGui::End();
ImGui::PopStyleVar();
}

View File

@ -10,6 +10,7 @@
#include "Prism/Renderer/Camera.h"
#include "Prism/Renderer/FrameBuffer.h"
#include "Prism/Renderer/Mesh.h"
#include "Prism/Renderer/RenderPass.h"
#include "Prism/Renderer/Shader.h"
#include "Prism/Renderer/Texture.h"
@ -28,20 +29,62 @@ private:
glm::vec4 m_clearColor = glm::vec4(0.1f, 0.1f, 0.1f, 1.0f);
glm::vec4 m_TriangleColor = glm::vec4(1.0f);
Prism::Ref<Prism::FrameBuffer> m_FrameBuffer, m_FinalPresentBuffer;
Prism::Ref<Prism::RenderPass> m_GeoPass, m_FinalPass;
Prism::Ref<Prism::TextureCube> m_SkyBoxTextureCube;
Prism::Ref<Prism::VertexArray> m_VertexArray;
Prism::Ref<Prism::Shader> m_SkyboxShader;
Prism::Ref<Prism::Shader> m_Shader;
Prism::Ref<Prism::Shader> m_HDRShader;
Prism::Ref<Prism::TextureCube> m_SkyBoxTextureCube, m_EnvironmentIrradiance;
Prism::Ref<Prism::Shader> m_HDRShader, m_SkyBoxShader;
Prism::Ref<Prism::Mesh> m_Mesh;
Prism::Ref<Prism::MaterialInstance> m_MeshMaterial;
Prism::Ref<Prism::Texture2D> m_BRDFLUT;
Prism::Camera m_Camera;
float m_Exposure = 1.0f;
struct AlbedoInput
{
glm::vec3 Color = { 0.972f, 0.96f, 0.915f };
Prism::Ref<Prism::Texture2D> TextureMap;
bool SRGB = true;
bool UseTexture = false;
};
AlbedoInput m_AlbedoInput;
struct NormalInput
{
Prism::Ref<Prism::Texture2D> TextureMap;
bool UseTexture = false;
};
NormalInput m_NormalInput;
struct MetalnessInput
{
float Value = 1.0f;
Prism::Ref<Prism::Texture2D> TextureMap;
bool UseTexture = false;
};
MetalnessInput m_MetalnessInput;
struct RoughnessInput
{
float Value = 0.5f;
Prism::Ref<Prism::Texture2D> TextureMap;
bool UseTexture = false;
};
RoughnessInput m_RoughnessInput;
struct Light
{
glm::vec3 Direction;
glm::vec3 Radiance;
};
Light m_Light;
float m_LightMultiplier = 0.3f;
float m_MeshScale = 1.0f;
bool m_RadiancePrefilter = false;
float m_EnvMapRotation = 0.0f;
};