diff --git a/Content/Shaders/GBuffer.flax b/Content/Shaders/GBuffer.flax index a2ecc2b80..0d2d9b4a0 100644 --- a/Content/Shaders/GBuffer.flax +++ b/Content/Shaders/GBuffer.flax @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:70414c6d184befbec5edbea3d8b377114bb03328df4a972216ae357244b7f8f4 -size 2764 +oid sha256:bfbd11dc6e19b6fc8837d7f5275524baa333f24184395358b945c9cbf95b2dda +size 3134 diff --git a/Source/Engine/Renderer/GBufferPass.cpp b/Source/Engine/Renderer/GBufferPass.cpp index 6e7c5bc3c..1f760619b 100644 --- a/Source/Engine/Renderer/GBufferPass.cpp +++ b/Source/Engine/Renderer/GBufferPass.cpp @@ -44,6 +44,7 @@ bool GBufferPass::Init() { // Create pipeline state _psDebug = GPUDevice::Instance->CreatePipelineState(); + _psLinearToSrgb = GPUDevice::Instance->CreatePipelineState(); // Load assets _gBufferShader = Content::LoadAsyncInternal(TEXT("Shaders/GBuffer")); @@ -81,6 +82,12 @@ bool GBufferPass::setupResources() if (_psDebug->Init(psDesc)) return true; } + if (!_psLinearToSrgb->IsValid()) + { + psDesc.PS = gbuffer->GetPS("PS_LinearToSrgb"); + if (_psLinearToSrgb->Init(psDesc)) + return true; + } return false; } @@ -92,6 +99,7 @@ void GBufferPass::Dispose() // Cleanup SAFE_DELETE_GPU_RESOURCE(_psDebug); + SAFE_DELETE_GPU_RESOURCE(_psLinearToSrgb); _gBufferShader = nullptr; _skyModel = nullptr; _boxModel = nullptr; @@ -254,6 +262,7 @@ void GBufferPass::RenderDebug(RenderContext& renderContext) switch (renderContext.View.Mode) { case ViewMode::Diffuse: + case ViewMode::Unlit: data.ViewLinear = !Graphics::GammaColorSpace; break; } @@ -277,6 +286,19 @@ void GBufferPass::RenderDebug(RenderContext& renderContext) context->ResetSR(); } +void GBufferPass::DrawLinearToSrgb(RenderContext& renderContext, GPUTexture* input) +{ + auto context = GPUDevice::Instance->GetMainContext(); + if (checkIfSkipPass()) + { + context->Draw(input); + return; + } + context->BindSR(0, input); + context->SetState(_psLinearToSrgb); + context->DrawFullscreenTriangle(); +} + // Custom render buffer for realtime skybox capturing (eg. used by GI). class SkyboxCustomBuffer : public RenderBuffers::CustomBuffer { diff --git a/Source/Engine/Renderer/GBufferPass.h b/Source/Engine/Renderer/GBufferPass.h index d9802af04..893202161 100644 --- a/Source/Engine/Renderer/GBufferPass.h +++ b/Source/Engine/Renderer/GBufferPass.h @@ -16,6 +16,7 @@ private: AssetReference _gBufferShader; GPUPipelineState* _psDebug = nullptr; + GPUPipelineState* _psLinearToSrgb = nullptr; AssetReference _skyModel; AssetReference _boxModel; #if USE_EDITOR @@ -40,6 +41,14 @@ public: /// The rendering context. void RenderDebug(RenderContext& renderContext); + /// + /// Draws the shader that converts texture from Linear to sRGB color space. Can be used to display internal lighting buffer that is not matching gamma of the output display. + /// + /// Assumes the output render target and viewport has been set. + /// The rendering context. + /// The input texture to blit. + void DrawLinearToSrgb(RenderContext& renderContext, GPUTexture* input); + /// /// Renders the sky or skybox into low-resolution cubemap. Can be used to sample realtime sky lighting in GI passes. /// diff --git a/Source/Engine/Renderer/Renderer.cpp b/Source/Engine/Renderer/Renderer.cpp index b76ec2f91..a1f531ac1 100644 --- a/Source/Engine/Renderer/Renderer.cpp +++ b/Source/Engine/Renderer/Renderer.cpp @@ -36,6 +36,7 @@ #include "Engine/Level/Level.h" #include "Engine/Level/Scene/SceneRendering.h" #include "Engine/Core/Config/GraphicsSettings.h" +#include "Engine/Graphics/Graphics.h" #include "Engine/Threading/JobSystem.h" #include "Engine/Profiler/ProfilerMemory.h" #if USE_EDITOR @@ -714,7 +715,10 @@ void RenderInner(SceneRenderTask* task, RenderContext& renderContext, RenderCont { context->SetRenderTarget(task->GetOutputView()); context->SetViewportAndScissors(task->GetOutputViewport()); - context->Draw(frameBuffer); + if (!Graphics::GammaColorSpace) + GBufferPass::Instance()->DrawLinearToSrgb(renderContext, frameBuffer); + else + context->Draw(frameBuffer); RenderTargetPool::Release(frameBuffer); return; } diff --git a/Source/Shaders/GBuffer.shader b/Source/Shaders/GBuffer.shader index bc2730a22..e9b241111 100644 --- a/Source/Shaders/GBuffer.shader +++ b/Source/Shaders/GBuffer.shader @@ -73,3 +73,12 @@ float4 PS_DebugView(Quad_VS2PS input) : SV_Target result = LinearToSrgb(result); return float4(result, 1); } + +// Pixel shader for color space conversion +META_PS(true, FEATURE_LEVEL_ES2) +float4 PS_LinearToSrgb(Quad_VS2PS input) : SV_Target +{ + float4 result = SAMPLE_RT(GBuffer0, input.TexCoord); + result.rgb = LinearToSrgb(result.rgb); + return result; +}