diff --git a/Hydrogent/include/HnRendererImpl.hpp b/Hydrogent/include/HnRendererImpl.hpp index d308fad4..70bf3d2d 100644 --- a/Hydrogent/include/HnRendererImpl.hpp +++ b/Hydrogent/include/HnRendererImpl.hpp @@ -103,7 +103,7 @@ class HnRendererImpl final : public ObjectBase pxr::HdEngine m_Engine; - static constexpr TEXTURE_FORMAT ColorBufferFormat = TEX_FORMAT_R11G11B10_FLOAT; + static constexpr TEXTURE_FORMAT ColorBufferFormat = TEX_FORMAT_RGBA16_FLOAT; static constexpr TEXTURE_FORMAT MeshIdFormat = TEX_FORMAT_R32_FLOAT; static constexpr TEXTURE_FORMAT DepthFormat = TEX_FORMAT_D32_FLOAT; diff --git a/Hydrogent/include/Tasks/HnPostProcessTask.hpp b/Hydrogent/include/Tasks/HnPostProcessTask.hpp index c35c7053..40e19223 100644 --- a/Hydrogent/include/Tasks/HnPostProcessTask.hpp +++ b/Hydrogent/include/Tasks/HnPostProcessTask.hpp @@ -46,11 +46,26 @@ struct HnPostProcessTaskParams float4 SelectionColor = float4{0.75f, 0.75f, 0.25f, 0.5f}; + float NonselectionDesaturationFactor = 0.5f; + + // Tone mappig attribs + int ToneMappingMode = 0; // TONE_MAPPING_MODE enum + float MiddleGray = 0.18f; // Middle gray luminance + float WhitePoint = 3.0f; // White point luminance + float LuminanceSaturation = 1.0; // Luminance saturation factor + float AverageLogLum = 0.3f; // Average log luminance of the scene + constexpr bool operator==(const HnPostProcessTaskParams& rhs) const { // clang-format off return ConvertOutputToSRGB == rhs.ConvertOutputToSRGB && - SelectionColor == rhs.SelectionColor; + SelectionColor == rhs.SelectionColor && + NonselectionDesaturationFactor == rhs.NonselectionDesaturationFactor && + ToneMappingMode == rhs.ToneMappingMode && + MiddleGray == rhs.MiddleGray && + WhitePoint == rhs.WhitePoint && + LuminanceSaturation == rhs.LuminanceSaturation && + AverageLogLum == rhs.AverageLogLum; // clang-format on } diff --git a/Hydrogent/shaders/HnPostProcess.psh b/Hydrogent/shaders/HnPostProcess.psh index 605aedd2..1b6fbc6a 100644 --- a/Hydrogent/shaders/HnPostProcess.psh +++ b/Hydrogent/shaders/HnPostProcess.psh @@ -1,3 +1,4 @@ +#include "ToneMapping.fxh" #include "HnPostProcessStructures.fxh" struct PSInput @@ -18,6 +19,10 @@ void main(in PSInput PSIn, { Color = g_ColorBuffer.Load(int3(PSIn.Pos.xy, 0)); +#if TONE_MAPPING_MODE > TONE_MAPPING_MODE_NONE + Color.rgb = ToneMap(Color.rgb, g_Attribs.ToneMapping, g_Attribs.AverageLogLum); +#endif + float IsSelected0 = g_MeshId.Load(int3(PSIn.Pos.xy + float2(-1.0, -1.0), 0)).r < 0.0 ? -1.0 : +1.0; float IsSelected1 = g_MeshId.Load(int3(PSIn.Pos.xy + float2( 0.0, -1.0), 0)).r < 0.0 ? -1.0 : +1.0; float IsSelected2 = g_MeshId.Load(int3(PSIn.Pos.xy + float2(+1.0, -1.0), 0)).r < 0.0 ? -1.0 : +1.0; diff --git a/Hydrogent/shaders/HnPostProcessStructures.fxh b/Hydrogent/shaders/HnPostProcessStructures.fxh index bbc30427..561aa002 100644 --- a/Hydrogent/shaders/HnPostProcessStructures.fxh +++ b/Hydrogent/shaders/HnPostProcessStructures.fxh @@ -6,9 +6,11 @@ struct PostProcessAttribs float4 SelectionOutlineColor; float NonselectionDesaturationFactor; - float Padding0; + float AverageLogLum; float Padding1; float Padding2; + + ToneMappingAttribs ToneMapping; }; #endif // _HN_POST_PROCESS_STRUCTURES_FXH_ diff --git a/Hydrogent/shaders_inc/HnPostProcess.psh.h b/Hydrogent/shaders_inc/HnPostProcess.psh.h index 97d83db7..8a099c49 100644 --- a/Hydrogent/shaders_inc/HnPostProcess.psh.h +++ b/Hydrogent/shaders_inc/HnPostProcess.psh.h @@ -1,3 +1,4 @@ +"#include \"ToneMapping.fxh\"\n" "#include \"HnPostProcessStructures.fxh\"\n" "\n" "struct PSInput\n" @@ -18,6 +19,10 @@ "{\n" " Color = g_ColorBuffer.Load(int3(PSIn.Pos.xy, 0));\n" "\n" +"#if TONE_MAPPING_MODE > TONE_MAPPING_MODE_NONE\n" +" Color.rgb = ToneMap(Color.rgb, g_Attribs.ToneMapping, g_Attribs.AverageLogLum);\n" +"#endif\n" +"\n" " float IsSelected0 = g_MeshId.Load(int3(PSIn.Pos.xy + float2(-1.0, -1.0), 0)).r < 0.0 ? -1.0 : +1.0;\n" " float IsSelected1 = g_MeshId.Load(int3(PSIn.Pos.xy + float2( 0.0, -1.0), 0)).r < 0.0 ? -1.0 : +1.0;\n" " float IsSelected2 = g_MeshId.Load(int3(PSIn.Pos.xy + float2(+1.0, -1.0), 0)).r < 0.0 ? -1.0 : +1.0;\n" diff --git a/Hydrogent/shaders_inc/HnPostProcessStructures.fxh.h b/Hydrogent/shaders_inc/HnPostProcessStructures.fxh.h index 1a2639e9..0b8e0310 100644 --- a/Hydrogent/shaders_inc/HnPostProcessStructures.fxh.h +++ b/Hydrogent/shaders_inc/HnPostProcessStructures.fxh.h @@ -6,9 +6,11 @@ " float4 SelectionOutlineColor;\n" "\n" " float NonselectionDesaturationFactor;\n" -" float Padding0;\n" +" float AverageLogLum;\n" " float Padding1;\n" " float Padding2;\n" +"\n" +" ToneMappingAttribs ToneMapping;\n" "};\n" "\n" "#endif // _HN_POST_PROCESS_STRUCTURES_FXH_\n" diff --git a/Hydrogent/src/HnRenderPass.cpp b/Hydrogent/src/HnRenderPass.cpp index 8ea5d785..7809b2a4 100644 --- a/Hydrogent/src/HnRenderPass.cpp +++ b/Hydrogent/src/HnRenderPass.cpp @@ -301,9 +301,10 @@ void HnRenderPass::RenderMesh(RenderState& State, RendererParams.WireframeColor = float4{1, 1, 1, 1}; //Attribs.WireframeColor; RendererParams.HighlightColor = float4{0, 0, 0, 0}; - RendererParams.AverageLogLum = 0.3f; //Attribs.AverageLogLum; - RendererParams.MiddleGray = 0.18f; //Attribs.MiddleGray; - RendererParams.WhitePoint = 3.0f; //Attribs.WhitePoint; + // Tone mapping is performed in the post-processing pass + RendererParams.AverageLogLum = 0.3f; + RendererParams.MiddleGray = 0.18f; + RendererParams.WhitePoint = 3.0f; auto CustomData = float4{static_cast(Mesh.GetUID()), 0, 0, 1}; //if (Attribs.SelectedPrim != nullptr && Mesh.GetId() == *Attribs.SelectedPrim) diff --git a/Hydrogent/src/HnRendererImpl.cpp b/Hydrogent/src/HnRendererImpl.cpp index c8edfd2c..a188c3d4 100644 --- a/Hydrogent/src/HnRendererImpl.cpp +++ b/Hydrogent/src/HnRendererImpl.cpp @@ -103,6 +103,7 @@ void HnRendererImpl::LoadUSDStage(pxr::UsdStageRefPtr& Stage) { HnPostProcessTaskParams Params; Params.ConvertOutputToSRGB = m_ConvertOutputToSRGB; + Params.ToneMappingMode = 4; // Uncharted2 m_TaskManager->SetTaskParams(HnTaskManager::TaskUID_PostProcess, Params); } } @@ -137,7 +138,6 @@ void HnRendererImpl::Update() m_RenderParamsChanged = false; } - m_ImagingDelegate->ApplyPendingUpdates(); } diff --git a/Hydrogent/src/Tasks/HnPostProcessTask.cpp b/Hydrogent/src/Tasks/HnPostProcessTask.cpp index aba6bfaf..983edd25 100644 --- a/Hydrogent/src/Tasks/HnPostProcessTask.cpp +++ b/Hydrogent/src/Tasks/HnPostProcessTask.cpp @@ -37,6 +37,8 @@ #include "CommonlyUsedStates.h" #include "GraphicsUtilities.h" #include "MapHelper.hpp" +#include "../../../Utilities/include/DiligentFXShaderSourceStreamFactory.hpp" +#include "ShaderSourceFactoryUtils.h" namespace Diligent { @@ -49,6 +51,7 @@ namespace HLSL namespace { +#include "Shaders/PostProcess/ToneMapping/public/ToneMappingStructures.fxh" #include "Shaders/PBR/public/PBR_Structures.fxh" #include "../shaders/HnPostProcessStructures.fxh" } // namespace @@ -83,11 +86,21 @@ void HnPostProcessTask::PreparePSO(TEXTURE_FORMAT RTVFormat) RenderDeviceWithCache_N Device{RenderDelegate->GetDevice(), RenderDelegate->GetRenderStateCache()}; ShaderCreateInfo ShaderCI; - ShaderCI.SourceLanguage = SHADER_SOURCE_LANGUAGE_HLSL; - ShaderCI.pShaderSourceStreamFactory = &HnShaderSourceFactory::GetInstance(); + ShaderCI.SourceLanguage = SHADER_SOURCE_LANGUAGE_HLSL; + + IShaderSourceInputStreamFactory* ppShaderSourceFactories[] = + { + &HnShaderSourceFactory::GetInstance(), + &DiligentFXShaderSourceStreamFactory::GetInstance(), + }; + CompoundShaderSourceFactoryCreateInfo CompoundSourceFactoryCI{ppShaderSourceFactories, _countof(ppShaderSourceFactories)}; + RefCntAutoPtr pCompoundSourceFactory; + CreateCompoundShaderSourceFactory(CompoundSourceFactoryCI, &pCompoundSourceFactory); + ShaderCI.pShaderSourceStreamFactory = pCompoundSourceFactory; ShaderMacroHelper Macros; Macros.Add("CONVERT_OUTPUT_TO_SRGB", m_Params.ConvertOutputToSRGB); + Macros.Add("TONE_MAPPING_MODE", m_Params.ToneMappingMode); ShaderCI.Macros = Macros; RefCntAutoPtr pVS; @@ -159,7 +172,8 @@ void HnPostProcessTask::Sync(pxr::HdSceneDelegate* Delegate, { HnPostProcessTaskParams Params = ParamsValue.UncheckedGet(); - if (m_Params.ConvertOutputToSRGB != Params.ConvertOutputToSRGB) + if (m_Params.ConvertOutputToSRGB != Params.ConvertOutputToSRGB || + m_Params.ToneMappingMode != Params.ToneMappingMode) { // In OpenGL we can't release PSO in Worker thread m_PsoIsDirty = true; @@ -245,9 +259,16 @@ void HnPostProcessTask::Execute(pxr::HdTaskContext* TaskCtx) { MapHelper pDstShaderAttribs{pCtx, m_PostProcessAttribsCB, MAP_WRITE, MAP_FLAG_DISCARD}; pDstShaderAttribs->SelectionOutlineColor = m_Params.SelectionColor; - pDstShaderAttribs->NonselectionDesaturationFactor = 0; //Attribs.SelectedPrim != nullptr && !Attribs.SelectedPrim->IsEmpty() ? 0.5f : 0.f; + pDstShaderAttribs->NonselectionDesaturationFactor = 0; //m_Params.NonselectionDesaturationFactor; //Attribs.SelectedPrim != nullptr && !Attribs.SelectedPrim->IsEmpty() ? 0.5f : 0.f; + + pDstShaderAttribs->ToneMapping.iToneMappingMode = m_Params.ToneMappingMode; + pDstShaderAttribs->ToneMapping.bAutoExposure = 0; + pDstShaderAttribs->ToneMapping.fMiddleGray = m_Params.MiddleGray; + pDstShaderAttribs->ToneMapping.bLightAdaptation = 0; + pDstShaderAttribs->ToneMapping.fWhitePoint = m_Params.WhitePoint; + pDstShaderAttribs->ToneMapping.fLuminanceSaturation = m_Params.LuminanceSaturation; + pDstShaderAttribs->AverageLogLum = m_Params.AverageLogLum; } - pCtx->SetPipelineState(m_PSO); m_SRB->GetVariableByName(SHADER_TYPE_PIXEL, "g_ColorBuffer")->Set(pOffscreenColorSRV); m_SRB->GetVariableByName(SHADER_TYPE_PIXEL, "g_MeshId")->Set(pMeshIdSRV); diff --git a/Hydrogent/src/Tasks/HnRenderEnvMapTask.cpp b/Hydrogent/src/Tasks/HnRenderEnvMapTask.cpp index 5ff3adb8..193bf513 100644 --- a/Hydrogent/src/Tasks/HnRenderEnvMapTask.cpp +++ b/Hydrogent/src/Tasks/HnRenderEnvMapTask.cpp @@ -118,7 +118,8 @@ void HnRenderEnvMapTask::Execute(pxr::HdTaskContext* TaskCtx) return; Diligent::HLSL::ToneMappingAttribs TMAttribs; - TMAttribs.iToneMappingMode = TONE_MAPPING_MODE_UNCHARTED2; + // Tone mapping is performed in the post-processing pass + TMAttribs.iToneMappingMode = TONE_MAPPING_MODE_NONE; TMAttribs.bAutoExposure = 0; TMAttribs.fMiddleGray = 0.18f; TMAttribs.bLightAdaptation = 0;