diff --git a/Editor/Editor/EditorLayer.cpp b/Editor/Editor/EditorLayer.cpp index 995ba78..e98b730 100644 --- a/Editor/Editor/EditorLayer.cpp +++ b/Editor/Editor/EditorLayer.cpp @@ -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) diff --git a/Editor/Editor/EditorLayer.h b/Editor/Editor/EditorLayer.h index 1ac23cb..d906c10 100644 --- a/Editor/Editor/EditorLayer.h +++ b/Editor/Editor/EditorLayer.h @@ -27,7 +27,8 @@ private: private: float m_ClearColor[4]; - Ref m_Framebuffer, m_FinalPresentBuffer; + // Ref m_Framebuffer, m_FinalPresentBuffer; + Ref m_GeoPass, m_CompositePass; /* Ref m_VertexBuffer; diff --git a/Prism/src/Prism.h b/Prism/src/Prism.h index 298f21f..8c966ea 100644 --- a/Prism/src/Prism.h +++ b/Prism/src/Prism.h @@ -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" diff --git a/Prism/src/Prism/Core/Application.cpp b/Prism/src/Prism/Core/Application.cpp index 861a9ac..b9eb4a2 100644 --- a/Prism/src/Prism/Core/Application.cpp +++ b/Prism/src/Prism/Core/Application.cpp @@ -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; } diff --git a/Prism/src/Prism/Platform/OpenGL/OpenGLFrameBuffer.cpp b/Prism/src/Prism/Platform/OpenGL/OpenGLFrameBuffer.cpp index ac84674..3e70722 100644 --- a/Prism/src/Prism/Platform/OpenGL/OpenGLFrameBuffer.cpp +++ b/Prism/src/Prism/Platform/OpenGL/OpenGLFrameBuffer.cpp @@ -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 ); diff --git a/Prism/src/Prism/Platform/OpenGL/OpenGLFrameBuffer.h b/Prism/src/Prism/Platform/OpenGL/OpenGLFrameBuffer.h index dbe4b42..59826a5 100644 --- a/Prism/src/Prism/Platform/OpenGL/OpenGLFrameBuffer.h +++ b/Prism/src/Prism/Platform/OpenGL/OpenGLFrameBuffer.h @@ -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; }; } diff --git a/Prism/src/Prism/Platform/OpenGL/OpenGLRenderPass.cpp b/Prism/src/Prism/Platform/OpenGL/OpenGLRenderPass.cpp new file mode 100644 index 0000000..ea5826d --- /dev/null +++ b/Prism/src/Prism/Platform/OpenGL/OpenGLRenderPass.cpp @@ -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() + { + } +} diff --git a/Prism/src/Prism/Platform/OpenGL/OpenGLRenderPass.h b/Prism/src/Prism/Platform/OpenGL/OpenGLRenderPass.h new file mode 100644 index 0000000..d5661c0 --- /dev/null +++ b/Prism/src/Prism/Platform/OpenGL/OpenGLRenderPass.h @@ -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 diff --git a/Prism/src/Prism/Renderer/FrameBuffer.cpp b/Prism/src/Prism/Renderer/FrameBuffer.cpp index 1ba318d..eb60510 100644 --- a/Prism/src/Prism/Renderer/FrameBuffer.cpp +++ b/Prism/src/Prism/Renderer/FrameBuffer.cpp @@ -8,13 +8,13 @@ namespace Prism { - FrameBuffer* FrameBuffer::Create(uint32_t width, uint32_t height, FramebufferFormat format) + Ref FrameBuffer::Create(const FramebufferSpecification& spec) { - FrameBuffer* result = nullptr; + Ref result = nullptr; switch (RendererAPI::Current()) { case RendererAPIType::None: return nullptr; - case RendererAPIType::OpenGL: result = new OpenGLFrameBuffer(width, height, format); + case RendererAPIType::OpenGL: result = CreateRef(spec); } FrameBufferPool::GetGlobal()->Add(result); return result; @@ -39,7 +39,12 @@ namespace Prism return std::weak_ptr(); } - void FrameBufferPool::Add(FrameBuffer* framebuffer) + FrameBufferPool* FrameBufferPool::GetGlobal() + { + return s_Instance; + } + + void FrameBufferPool::Add(std::weak_ptr framebuffer) { m_Pool.push_back(framebuffer); } diff --git a/Prism/src/Prism/Renderer/FrameBuffer.h b/Prism/src/Prism/Renderer/FrameBuffer.h index d2d3efd..8bf5eda 100644 --- a/Prism/src/Prism/Renderer/FrameBuffer.h +++ b/Prism/src/Prism/Renderer/FrameBuffer.h @@ -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 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 AllocateBuffer(); - void Add(FrameBuffer* framebuffer); + void Add(std::weak_ptr framebuffer); - const std::vector& GetAll() const { return m_Pool; } + const std::vector>& GetAll() const { return m_Pool; } + + static FrameBufferPool* GetGlobal(); - inline static FrameBufferPool* GetGlobal() { return s_Instance; } private: - std::vector m_Pool; + std::vector> m_Pool; static FrameBufferPool* s_Instance; }; diff --git a/Prism/src/Prism/Renderer/Mesh.cpp b/Prism/src/Prism/Renderer/Mesh.cpp index ffb03ad..ba9ddc0 100644 --- a/Prism/src/Prism/Renderer/Mesh.cpp +++ b/Prism/src/Prism/Renderer/Mesh.cpp @@ -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); } diff --git a/Prism/src/Prism/Renderer/RenderPass.cpp b/Prism/src/Prism/Renderer/RenderPass.cpp new file mode 100644 index 0000000..f9b2bfd --- /dev/null +++ b/Prism/src/Prism/Renderer/RenderPass.cpp @@ -0,0 +1,22 @@ +// +// Created by sfd on 25-11-29. +// + +#include "RenderPass.h" + +#include "Prism/Platform/OpenGL/OpenGLRenderPass.h" + +namespace Prism +{ + Ref 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(spec); + } + + PM_CORE_ASSERT(false, "Unknown RendererAPI!"); + return nullptr; + } +} diff --git a/Prism/src/Prism/Renderer/RenderPass.h b/Prism/src/Prism/Renderer/RenderPass.h new file mode 100644 index 0000000..b63c4df --- /dev/null +++ b/Prism/src/Prism/Renderer/RenderPass.h @@ -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 TargetFramebuffer; + }; + + class PRISM_API RenderPass + { + public: + virtual ~RenderPass() {} + + virtual const RenderPassSpecification& GetSpecification() const = 0; + + static Ref Create(const RenderPassSpecification& spec); + }; +} + + +#endif //RENDERPASS_H diff --git a/Prism/src/Prism/Renderer/Renderer.cpp b/Prism/src/Prism/Renderer/Renderer.cpp index bcd7c44..c82b211 100644 --- a/Prism/src/Prism/Renderer/Renderer.cpp +++ b/Prism/src/Prism/Renderer/Renderer.cpp @@ -52,4 +52,38 @@ namespace Prism { s_Instance->m_CommandQueue.Execute(); } + + void Renderer::BeginRenderPass(const Ref& renderPass) + { + s_Instance->IBeginRenderPass(renderPass); + } + + void Renderer::EndRenderPass() + { + s_Instance->IEndRenderPass(); + } + + void Renderer::SubmitMesh(const Ref& mesh) + { + s_Instance->SubmitMeshI(mesh); + } + + void Renderer::IBeginRenderPass(const Ref& 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) + { + } } diff --git a/Prism/src/Prism/Renderer/Renderer.h b/Prism/src/Prism/Renderer/Renderer.h index a781a88..8ba42c1 100644 --- a/Prism/src/Prism/Renderer/Renderer.h +++ b/Prism/src/Prism/Renderer/Renderer.h @@ -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); + static void EndRenderPass(); + + static void SubmitMesh(const Ref& mesh); + + private: + void IBeginRenderPass(const Ref& renderPass); + void IEndRenderPass(); + + void SubmitMeshI(const Ref& mesh); + + private: static Renderer* s_Instance; + private: + Ref m_ActiveRenderPass; Scope m_ShaderLibrary; - RenderCommandQueue m_CommandQueue; }; diff --git a/Sandbox/Sandbox/Layer/TestLayer.cpp b/Sandbox/Sandbox/Layer/TestLayer.cpp index 9d88bf0..260b65f 100644 --- a/Sandbox/Sandbox/Layer/TestLayer.cpp +++ b/Sandbox/Sandbox/Layer/TestLayer.cpp @@ -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("assets/meshes/cerberus.fbx"); - // m_MeshMaterial = Prism::CreateRef(m_Mesh->GetMaterial()); + m_Mesh = std::make_unique("assets/models/m1911/m1911.fbx"); + m_MeshMaterial = Prism::CreateRef(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(); } diff --git a/Sandbox/Sandbox/Layer/TestLayer.h b/Sandbox/Sandbox/Layer/TestLayer.h index 460cb40..63c16b8 100644 --- a/Sandbox/Sandbox/Layer/TestLayer.h +++ b/Sandbox/Sandbox/Layer/TestLayer.h @@ -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 m_FrameBuffer, m_FinalPresentBuffer; + Prism::Ref m_GeoPass, m_FinalPass; - - Prism::Ref m_SkyBoxTextureCube; Prism::Ref m_VertexArray; - Prism::Ref m_SkyboxShader; - Prism::Ref m_Shader; - Prism::Ref m_HDRShader; + Prism::Ref m_SkyBoxTextureCube, m_EnvironmentIrradiance; + Prism::Ref m_HDRShader, m_SkyBoxShader; Prism::Ref m_Mesh; Prism::Ref m_MeshMaterial; + Prism::Ref m_BRDFLUT; Prism::Camera m_Camera; float m_Exposure = 1.0f; + + struct AlbedoInput + { + glm::vec3 Color = { 0.972f, 0.96f, 0.915f }; + Prism::Ref TextureMap; + bool SRGB = true; + bool UseTexture = false; + }; + AlbedoInput m_AlbedoInput; + + struct NormalInput + { + Prism::Ref TextureMap; + bool UseTexture = false; + }; + NormalInput m_NormalInput; + + struct MetalnessInput + { + float Value = 1.0f; + Prism::Ref TextureMap; + bool UseTexture = false; + }; + MetalnessInput m_MetalnessInput; + + struct RoughnessInput + { + float Value = 0.5f; + Prism::Ref 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; };