Skip to content

Commit

Permalink
Feature: Tone Mapping using DXTK's post process effect.
Browse files Browse the repository at this point in the history
  • Loading branch information
InsaneZeroGame committed Jul 24, 2024
1 parent b7e6953 commit d538707
Show file tree
Hide file tree
Showing 11 changed files with 116 additions and 15 deletions.
1 change: 1 addition & 0 deletions renderer/device_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ namespace Renderer
inline ID3D12Device4* g_Device = nullptr;
inline class DescHeap* g_DescHeap[D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES];
inline DXGI_FORMAT g_DisplayFormat = DXGI_FORMAT_R10G10B10A2_UNORM;
inline DXGI_FORMAT g_ColorBufferFormat = DXGI_FORMAT_R16G16B16A16_FLOAT;
//IMGUI Needs 3 desc to work.
constexpr int IMGUI_DESC_HEAP_ONLY = 3;

Expand Down
3 changes: 3 additions & 0 deletions renderer/gpu_resource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -443,8 +443,11 @@ namespace Renderer
{
auto [cpuHandleRTV,gpuHanleRTV] = g_DescHeap[D3D12_DESCRIPTOR_HEAP_TYPE_RTV]->Allocate();
m_RTVHandle = cpuHandleRTV;
m_RTVGPUHandle = gpuHanleRTV;

auto [cpuHandle, gpuHanle] = g_DescHeap[D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV]->Allocate();
m_SRVHandle = cpuHandle;
m_SRVGPUHandle = gpuHanle;
}

ID3D12Resource* Resource = m_pResource;
Expand Down
4 changes: 4 additions & 0 deletions renderer/gpu_resource.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,8 @@ namespace Renderer
// Get pre-created CPU-visible descriptor handles
const D3D12_CPU_DESCRIPTOR_HANDLE& GetSRV(void) const { return m_SRVHandle; }
const D3D12_CPU_DESCRIPTOR_HANDLE& GetRTV(void) const { return m_RTVHandle; }
const D3D12_GPU_DESCRIPTOR_HANDLE& GetSRVGPU(void) const { return m_SRVGPUHandle; }
const D3D12_GPU_DESCRIPTOR_HANDLE& GetRTVGPU(void) const { return m_RTVGPUHandle; }
const D3D12_CPU_DESCRIPTOR_HANDLE& GetUAV(void) const { return m_UAVHandle[0]; }

void SetClearColor(Color ClearColor) { m_ClearColor = ClearColor; }
Expand Down Expand Up @@ -171,6 +173,8 @@ namespace Renderer
D3D12_CPU_DESCRIPTOR_HANDLE m_SRVHandle;
D3D12_CPU_DESCRIPTOR_HANDLE m_RTVHandle;
D3D12_CPU_DESCRIPTOR_HANDLE m_UAVHandle[12];
D3D12_GPU_DESCRIPTOR_HANDLE m_SRVGPUHandle;
D3D12_GPU_DESCRIPTOR_HANDLE m_RTVGPUHandle;
uint32_t m_NumMipMaps; // number of texture sublevels
uint32_t m_SampleCount;
//uint32_t m_SampleCount;
Expand Down
5 changes: 5 additions & 0 deletions renderer/gui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ void Renderer::Gui::EndGui(ID3D12GraphicsCommandList* InCmd) {

void Renderer::Gui::Render() {
ImGui::TextColored({ 0.0f, 1.0f, 0.0f, 1.0f }, "Hello Re3D");
if (mRenderer.lock())
{
//ImGui::Checkbox("Tone Mapping", &mRenderer.lock()->mUseToneMapping);
ImGui::SliderFloat("Tone Mapping Exposure", &mRenderer.lock()->mExposure, 0.0f, 1.0f);
}
if (mCurrentScene)
{
SceneUpdate();
Expand Down
1 change: 1 addition & 0 deletions renderer/pch.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@
#include <Keyboard.h>
#include <Mouse.h>
#include "renderer_context.h"
#include "PostProcess.h"


#pragma comment(lib,"dxgi.lib")
Expand Down
79 changes: 70 additions & 9 deletions renderer/renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
#include "components.h"
#include "gui.h"
#include "renderer_context.h"
#include "PostProcess.h"
#include "GraphicsMemory.h"

Renderer::BaseRenderer::BaseRenderer():
mDeviceManager(std::make_unique<DeviceManager>()),
Expand All @@ -24,13 +26,15 @@ Renderer::BaseRenderer::BaseRenderer():
mComputeCmd = mCmdManager->AllocateCmdList(D3D12_COMMAND_LIST_TYPE_COMPUTE);
mBatchUploader = std::make_unique<ResourceUploadBatch>(g_Device);
mContext = std::make_unique<RendererContext>(mCmdManager);
//Allocate 3 desc for IMGUI.Todo:move this gui,make it transparent to renderer.
g_DescHeap[D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV]->Allocate(3);
CreateTextures();
CreateBuffers();
CreateRootSignature();
CreatePipelineState();
CreateRenderTask();
CreateSkybox();
InitPostProcess();
}

Renderer::BaseRenderer::~BaseRenderer()
Expand Down Expand Up @@ -265,10 +269,37 @@ void Renderer::BaseRenderer::CreateRenderTask()
}
});
}
TransitState(mGraphicsCmd, g_DisplayPlane[lCurrentBackbufferIndex].GetResource(), D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_RESOLVE_DEST);
TransitState(mGraphicsCmd, mContext->GetColorBuffer()->GetResource(), D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_RESOLVE_SOURCE);
mGraphicsCmd->ResolveSubresource(g_DisplayPlane[lCurrentBackbufferIndex].GetResource(), 0, mContext->GetColorBuffer()->GetResource(), 0, DXGI_FORMAT_R10G10B10A2_UNORM);
TransitState(mGraphicsCmd, g_DisplayPlane[lCurrentBackbufferIndex].GetResource(), D3D12_RESOURCE_STATE_RESOLVE_DEST, D3D12_RESOURCE_STATE_RENDER_TARGET);

if (mUseToneMapping)
{
//Resolve MSAA RT to normal RT
TransitState(mGraphicsCmd, mContext->GetColorBuffer()->GetResource(), D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_RESOLVE_SOURCE);
TransitState(mGraphicsCmd, mContext->GetColorAttachment0()->GetResource(), D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_RESOLVE_DEST);
mGraphicsCmd->ResolveSubresource(mContext->GetColorAttachment0()->GetResource(), 0, mContext->GetColorBuffer()->GetResource(), 0, DXGI_FORMAT_R16G16B16A16_FLOAT);
TransitState(mGraphicsCmd, mContext->GetColorAttachment0()->GetResource(), D3D12_RESOURCE_STATE_RESOLVE_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);

//Tone Mapping
ppToneMap->SetHDRSourceTexture(mContext->GetColorAttachment0()->GetSRVGPU());
mGraphicsCmd->OMSetRenderTargets(1, &g_DisplayPlane[lCurrentBackbufferIndex].GetRTV(), true, nullptr);
ppToneMap->SetExposure(mExposure);
ppToneMap->Process(mGraphicsCmd);

}
else
{
//Resolve MSAA RT to swap chain back buffer
TransitState(mGraphicsCmd, g_DisplayPlane[lCurrentBackbufferIndex].GetResource(), D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_RESOLVE_DEST);
TransitState(mGraphicsCmd, mContext->GetColorBuffer()->GetResource(), D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_RESOLVE_SOURCE);
mGraphicsCmd->ResolveSubresource(g_DisplayPlane[lCurrentBackbufferIndex].GetResource(), 0, mContext->GetColorBuffer()->GetResource(), 0, DXGI_FORMAT_R16G16B16A16_FLOAT);
TransitState(mGraphicsCmd, g_DisplayPlane[lCurrentBackbufferIndex].GetResource(), D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_RESOLVE_DEST);
TransitState(mGraphicsCmd, g_DisplayPlane[lCurrentBackbufferIndex].GetResource(), D3D12_RESOURCE_STATE_RESOLVE_DEST, D3D12_RESOURCE_STATE_RENDER_TARGET);
}

};

auto PostProcess = [=](){



};

Expand All @@ -295,11 +326,12 @@ void Renderer::BaseRenderer::CreateRenderTask()
mGraphicsFenceValue++;
mDeviceManager->EndFrame();
};
auto [depthOnlyPass, skyboxpass, colorPass, postRender, computePass, guiPass ] =
mRenderFlow->emplace(DepthOnlyPass, SkyboxPass, ColorPass, PostRender, ComputePass, GuiPass);
auto [depthOnlyPass, skyboxpass, colorPass, postRender, computePass, ppPass, guiPass ] =
mRenderFlow->emplace(DepthOnlyPass, SkyboxPass, ColorPass, PostRender, ComputePass, PostProcess,GuiPass);
skyboxpass.succeed(depthOnlyPass, computePass);
colorPass.succeed(skyboxpass);
guiPass.succeed(colorPass);
ppPass.succeed(colorPass);
guiPass.succeed(ppPass);
postRender.succeed(guiPass);
}

Expand Down Expand Up @@ -503,6 +535,34 @@ void Renderer::BaseRenderer::CreateSkybox()
mBatchUploader->End(mCmdManager->GetQueue(D3D12_COMMAND_LIST_TYPE_COPY));
}

void Renderer::BaseRenderer::InitPostProcess()
{
using namespace DirectX::DX12;

mGPUMemory = std::make_unique<GraphicsMemory>(g_Device);

DirectX::RenderTargetState bloomState(DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_UNKNOWN);

ppBloomExtract = std::make_unique<BasicPostProcess>(g_Device, bloomState,
BasicPostProcess::BloomExtract);

ppBloomBlur = std::make_unique<BasicPostProcess>(g_Device, bloomState,
BasicPostProcess::BloomBlur);

ppBloomCombine = std::make_unique<DualPostProcess>(g_Device, bloomState,
DualPostProcess::BloomCombine);

RenderTargetState toneMapRTState(g_DisplayFormat,
DXGI_FORMAT_UNKNOWN);
ppToneMap = std::make_unique<ToneMapPostProcess>(g_Device, toneMapRTState,
ToneMapPostProcess::ACESFilmic,
ToneMapPostProcess::SRGB);

//RenderTargetState imageBlit(g_DisplayFormat,
// DXGI_FORMAT_D32_FLOAT);
//mImageBlit = std::make_unique<BasicPostProcess>(g_Device, imageBlit, BasicPostProcess::Copy);
}

void Renderer::BaseRenderer::FirstFrame()
{
TransitState(mGraphicsCmd, mContext->GetShadowMap()->GetResource(), D3D12_RESOURCE_STATE_COMMON, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
Expand All @@ -512,6 +572,7 @@ void Renderer::BaseRenderer::FirstFrame()
TransitState(mGraphicsCmd, mLightBuffer->GetResource(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_ALL_SHADER_RESOURCE);
TransitState(mGraphicsCmd, mContext->GetDepthBuffer()->GetResource(), D3D12_RESOURCE_STATE_COMMON, D3D12_RESOURCE_STATE_DEPTH_WRITE);
TransitState(mGraphicsCmd, mContext->GetColorBuffer()->GetResource(), D3D12_RESOURCE_STATE_COMMON, D3D12_RESOURCE_STATE_RESOLVE_SOURCE);
TransitState(mGraphicsCmd, mContext->GetColorAttachment0()->GetResource(), D3D12_RESOURCE_STATE_COMMON, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);

for (size_t cubeFace = 0; cubeFace < 6; cubeFace++)
{
Expand Down Expand Up @@ -562,7 +623,7 @@ void Renderer::BaseRenderer::CreatePipelineState()
lDesc.InputLayout.pInputElementDescs = elements.data();
lDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
lDesc.NumRenderTargets = 1;
lDesc.RTVFormats[0] = DXGI_FORMAT_R10G10B10A2_UNORM;
lDesc.RTVFormats[0] = g_ColorBufferFormat;
lDesc.DSVFormat = DXGI_FORMAT_D32_FLOAT;
lDesc.SampleDesc.Count = 1;
lDesc.Flags = D3D12_PIPELINE_STATE_FLAG_NONE;
Expand All @@ -575,7 +636,7 @@ void Renderer::BaseRenderer::CreatePipelineState()
lDesc.RasterizerState.MultisampleEnable = true;
lDesc.SampleDesc.Count = 8;
lDesc.SampleDesc.Quality = 0;
lDesc.RTVFormats[0] = DXGI_FORMAT_R10G10B10A2_UNORM;
lDesc.RTVFormats[0] = g_ColorBufferFormat;
g_Device->CreateGraphicsPipelineState(&lDesc, IID_PPV_ARGS(&mColorPassPipelineState8XMSAA));
mColorPassPipelineState8XMSAA->SetName(L"mColorPassPipelineState8XMSAA");

Expand Down
19 changes: 18 additions & 1 deletion renderer/renderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@ namespace tf
namespace DirectX
{
class ResourceUploadBatch;
namespace DX12
{
class BasicPostProcess;
class DualPostProcess;
class ToneMapPostProcess;
class GraphicsMemory;
}
}

namespace Renderer
Expand All @@ -27,6 +34,7 @@ namespace Renderer
class UploadBuffer;
class StructuredBuffer;
class VertexBuffer;
class ColorBuffer;
}

struct FrameData
Expand Down Expand Up @@ -65,13 +73,17 @@ namespace Renderer
std::shared_ptr<Resource::Texture> LoadMaterial(std::string_view InTextureName, std::string_view InMatName = {},const std::wstring& InDebugName = L"");
std::shared_ptr<Resource::Texture> LoadMaterial(std::string_view InTextureName, AssetLoader::TextureData* textureData, const std::wstring& InDebugName = L"");


bool mUseToneMapping = true;
float mExposure = 0.0f;
protected:
void CreateGui();
void CreateRenderTask();
void CreateBuffers();
void CreateTextures();
void DepthOnlyPass(const ECS::StaticMeshComponent& InAsset);
void CreateSkybox();
void InitPostProcess();
virtual void FirstFrame();
virtual void PreRender();
virtual void PostRender();
Expand Down Expand Up @@ -129,7 +141,12 @@ namespace Renderer

std::shared_ptr<Resource::StructuredBuffer> mDummyBuffer;
int mFrameIndexCpu = 0;

std::unique_ptr<DirectX::DX12::BasicPostProcess> ppBloomExtract;
std::unique_ptr<DirectX::DX12::BasicPostProcess> ppBloomBlur;
std::unique_ptr<DirectX::DX12::DualPostProcess> ppBloomCombine;
std::unique_ptr<DirectX::DX12::ToneMapPostProcess> ppToneMap;
std::unique_ptr<DirectX::DX12::BasicPostProcess> mImageBlit;
std::unique_ptr<DirectX::DX12::GraphicsMemory> mGPUMemory;
};


Expand Down
10 changes: 9 additions & 1 deletion renderer/renderer_context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ void Renderer::RendererContext::CreateWindowDependentResource(int InWindowWidth,
mDepthBuffer->Create(L"DepthBuffer", mWindowWidth, mWindowHeight, DXGI_FORMAT_D32_FLOAT);
CreateShadowMap(mWindowWidth, mWindowHeight);
CreateColorBuffer(mWindowWidth, mWindowHeight);

mColorAttachment0 = std::make_unique<Resource::ColorBuffer>();
mColorAttachment0->Create(L"ColorAttachment0", mWindowWidth, mWindowHeight, 1, g_ColorBufferFormat);
}

void Renderer::RendererContext::UpdateDataToVertexBuffer(std::span<Vertex> InData)
Expand All @@ -51,6 +54,11 @@ std::shared_ptr<Renderer::Resource::ColorBuffer> Renderer::RendererContext::GetC
return mColorBuffer;
}

std::shared_ptr<Renderer::Resource::ColorBuffer> Renderer::RendererContext::GetColorAttachment0()
{
return mColorAttachment0;
}

std::shared_ptr<Renderer::Resource::DepthBuffer> Renderer::RendererContext::GetDepthBuffer()
{
return mDepthBuffer;
Expand Down Expand Up @@ -91,7 +99,7 @@ void Renderer::RendererContext::CreateColorBuffer(int InShadowMapWidth, int InSh
{
mColorBuffer = std::make_shared<Resource::ColorBuffer>();
mColorBuffer->SetMsaaMode(MSAA_8X);
mColorBuffer->Create(L"ColorBufferMSAA", mWindowWidth, mWindowHeight, 1, DXGI_FORMAT_R10G10B10A2_UNORM);
mColorBuffer->Create(L"ColorBufferMSAA", mWindowWidth, mWindowHeight, 1, DXGI_FORMAT_R16G16B16A16_FLOAT);
}

void Renderer::RendererContext::UploadDataToResource(
Expand Down
3 changes: 3 additions & 0 deletions renderer/renderer_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ namespace Renderer
void UpdateDataToVertexBuffer(std::span<Vertex> InData);
void UpdateDataToIndexBuffer(std::span<int> InData);
std::shared_ptr<Resource::ColorBuffer> GetColorBuffer();
std::shared_ptr<Resource::ColorBuffer> GetColorAttachment0();

private:
template<typename T>
void UploadDataToResource(ID3D12Resource* InDestResource, std::span<T> InData, std::shared_ptr<VertexBufferRenderer<T>> InCpuResource);
Expand Down Expand Up @@ -73,5 +75,6 @@ namespace Renderer
{
MSAA_8X = 8,
};
std::shared_ptr<Resource::ColorBuffer> mColorAttachment0;
};
}
4 changes: 1 addition & 3 deletions renderer/shaders/ForwardPS.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -175,17 +175,15 @@ float4 main(PSInput input) : SV_TARGET
}
}
pointLight += directionalLight;
float gamma = 2.2f;
//float4 ambient = float4(0.15, 0.15, 0.15, 1.0f);
float4 color = float4(pointLight, 1.0f);
float4 colorAfterCorrection = pow(color, 1.0 / gamma);
float2 shadowCoord = input.shadowCoord.xy /input.shadowCoord.w;
//shadwo map
shadowCoord = shadowCoord * float2(0.5, -0.5) + 0.5;
float shadow = shadowMap.SampleCmpLevelZero(shadowSampler, shadowCoord, input.shadowCoord.z/input.shadowCoord.w);
//shadow = 1.0f;
//return diffuseColor;
return colorAfterCorrection * (0.15 + 0.85 * shadow);
return color * (0.15 + 0.85 * shadow);
//if (input.position.x / screen_size < 0.5)
//{
// return diffuse;
Expand Down
2 changes: 1 addition & 1 deletion renderer/skybox.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ void Renderer::Skybox::CreatePipelineState()
lDesc.InputLayout.pInputElementDescs = elements.data();
lDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
lDesc.NumRenderTargets = 1;
lDesc.RTVFormats[0] = DXGI_FORMAT_R10G10B10A2_UNORM;
lDesc.RTVFormats[0] = g_ColorBufferFormat;
//lDesc.DSVFormat = DXGI_FORMAT_D32_FLOAT;
lDesc.SampleDesc.Count = 8;
lDesc.SampleDesc.Quality = 0;
Expand Down

0 comments on commit d538707

Please sign in to comment.