Skip to content

Commit

Permalink
Hydrogent: improved selection outline; added desaturation of the non-…
Browse files Browse the repository at this point in the history
…selected area
  • Loading branch information
TheMostDiligent committed Oct 18, 2023
1 parent b78f2b8 commit 9e18569
Show file tree
Hide file tree
Showing 12 changed files with 155 additions and 36 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ target_sources(DiligentFX PRIVATE
# A target created in the same directory (CMakeLists.txt file) that specifies any output of the
# custom command as a source file is given a rule to generate the file using the command at build time.
${SHADERS_INC_LIST}
${SHADERS_LIST_FILE}
)
source_group("generated" FILES
${SHADERS_LIST_FILE}
Expand Down
2 changes: 2 additions & 0 deletions Hydrogent/include/HnRendererImpl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,13 +93,15 @@ class HnRendererImpl final : public ObjectBase<IHnRenderer>

void PrepareRenderTargets(ITextureView* pDstRtv);
void PreparePostProcess(TEXTURE_FORMAT RTVFmt);
void PerformPostProcess(IDeviceContext* pCtx, const HnDrawAttribs& Attribs);

private:
RenderDeviceWithCache_N m_Device;
RefCntAutoPtr<IDeviceContext> m_Context;

RefCntAutoPtr<IBuffer> m_CameraAttribsCB;
RefCntAutoPtr<IBuffer> m_LightAttribsCB;
RefCntAutoPtr<IBuffer> m_PostProcessAttribsCB;

const bool m_ConvertOutputToSRGB;

Expand Down
2 changes: 1 addition & 1 deletion Hydrogent/interface/HnRenderer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ struct HnDrawAttribs
bool EnablePrimIdQueries = false;

float4 WireframeColor = float4{1, 1, 1, 1};
float4 SlectionColor = float4{0.25f, 0.25f, 0.1f, 0.5f};
float4 SlectionColor = float4{0.75f, 0.75f, 0.25f, 0.5f};

HN_RENDER_MODE RenderMode = HN_RENDER_MODE_SOLID;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
#include "HnPostProcessStructures.fxh"

struct PSInput
{
float4 Pos : SV_POSITION;
};

cbuffer cbPostProcessAttribs
{
PostProcessAttribs g_Attribs;
}

Texture2D g_ColorBuffer;
Texture2D g_MeshId;

Expand All @@ -11,22 +18,27 @@ void main(in PSInput PSIn,
{
Color = g_ColorBuffer.Load(int3(PSIn.Pos.xy, 0));

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;
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;

float IsSelected3 = g_MeshId.Load(int3(PSIn.Pos.xy + float2(-1.0, 0.0), 0)).r < 0.0 ? +1.0 : -1.0;
float IsSelected4 = g_MeshId.Load(int3(PSIn.Pos.xy + float2( 0.0, 0.0), 0)).r < 0.0 ? +1.0 : -1.0;
float IsSelected5 = g_MeshId.Load(int3(PSIn.Pos.xy + float2(+1.0, 0.0), 0)).r < 0.0 ? +1.0 : -1.0;
float IsSelected3 = g_MeshId.Load(int3(PSIn.Pos.xy + float2(-1.0, 0.0), 0)).r < 0.0 ? -1.0 : +1.0;
float IsSelected4 = g_MeshId.Load(int3(PSIn.Pos.xy + float2( 0.0, 0.0), 0)).r < 0.0 ? -1.0 : +1.0;
float IsSelected5 = g_MeshId.Load(int3(PSIn.Pos.xy + float2(+1.0, 0.0), 0)).r < 0.0 ? -1.0 : +1.0;

float IsSelected6 = g_MeshId.Load(int3(PSIn.Pos.xy + float2(-1.0, +1.0), 0)).r < 0.0 ? +1.0 : -1.0;
float IsSelected7 = g_MeshId.Load(int3(PSIn.Pos.xy + float2( 0.0, +1.0), 0)).r < 0.0 ? +1.0 : -1.0;
float IsSelected8 = g_MeshId.Load(int3(PSIn.Pos.xy + float2(+1.0, +1.0), 0)).r < 0.0 ? +1.0 : -1.0;
float IsSelected6 = g_MeshId.Load(int3(PSIn.Pos.xy + float2(-1.0, +1.0), 0)).r < 0.0 ? -1.0 : +1.0;
float IsSelected7 = g_MeshId.Load(int3(PSIn.Pos.xy + float2( 0.0, +1.0), 0)).r < 0.0 ? -1.0 : +1.0;
float IsSelected8 = g_MeshId.Load(int3(PSIn.Pos.xy + float2(+1.0, +1.0), 0)).r < 0.0 ? -1.0 : +1.0;

float Outline = IsSelected0 + IsSelected1 + IsSelected2 + IsSelected3 + IsSelected4 + IsSelected5 + IsSelected6 + IsSelected7 + IsSelected8;
Outline = saturate(1.0 - abs(Outline) / 9.0);
//Outline = (9.0 - Outline) * (Outline > 0.0 ? 1.0 / 8.0 : 0.0);
Outline = (Outline > 0.0 && Outline < 9.0) ? 1.0 : 0.0;

float DesatFactor = g_Attribs.NonselectionDesaturationFactor * saturate(IsSelected4);
float Luminance = dot(Color.rgb, float3(0.2126, 0.7152, 0.0722));
Color.rgb = lerp(Color.rgb, float3(Luminance, Luminance, Luminance), DesatFactor);

Color.rgb += Outline * float3(0.25, 0.25, 0.1f);
Color.rgb = lerp(Color.rgb, g_Attribs.SelectionOutlineColor.rgb, Outline);

#if CONVERT_OUTPUT_TO_SRGB
Color.rgb = pow(Color.rgb, float3(1.0/2.2, 1.0/2.2, 1.0/2.2));
Expand Down
File renamed without changes.
14 changes: 14 additions & 0 deletions Hydrogent/shaders/HnPostProcessStructures.fxh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#ifndef _HN_POST_PROCESS_STRUCTURES_FXH_
#define _HN_POST_PROCESS_STRUCTURES_FXH_

struct PostProcessAttribs
{
float4 SelectionOutlineColor;

float NonselectionDesaturationFactor;
float Padding0;
float Padding1;
float Padding2;
};

#endif // _HN_POST_PROCESS_STRUCTURES_FXH_
46 changes: 46 additions & 0 deletions Hydrogent/shaders_inc/HnPostProcess.psh.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
"#include \"HnPostProcessStructures.fxh\"\n"
"\n"
"struct PSInput\n"
"{\n"
" float4 Pos : SV_POSITION;\n"
"};\n"
"\n"
"cbuffer cbPostProcessAttribs\n"
"{\n"
" PostProcessAttribs g_Attribs;\n"
"}\n"
"\n"
"Texture2D g_ColorBuffer;\n"
"Texture2D g_MeshId;\n"
"\n"
"void main(in PSInput PSIn,\n"
" out float4 Color : SV_Target0)\n"
"{\n"
" Color = g_ColorBuffer.Load(int3(PSIn.Pos.xy, 0));\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"
"\n"
" float IsSelected3 = g_MeshId.Load(int3(PSIn.Pos.xy + float2(-1.0, 0.0), 0)).r < 0.0 ? -1.0 : +1.0;\n"
" float IsSelected4 = g_MeshId.Load(int3(PSIn.Pos.xy + float2( 0.0, 0.0), 0)).r < 0.0 ? -1.0 : +1.0;\n"
" float IsSelected5 = g_MeshId.Load(int3(PSIn.Pos.xy + float2(+1.0, 0.0), 0)).r < 0.0 ? -1.0 : +1.0;\n"
"\n"
" float IsSelected6 = g_MeshId.Load(int3(PSIn.Pos.xy + float2(-1.0, +1.0), 0)).r < 0.0 ? -1.0 : +1.0;\n"
" float IsSelected7 = g_MeshId.Load(int3(PSIn.Pos.xy + float2( 0.0, +1.0), 0)).r < 0.0 ? -1.0 : +1.0;\n"
" float IsSelected8 = g_MeshId.Load(int3(PSIn.Pos.xy + float2(+1.0, +1.0), 0)).r < 0.0 ? -1.0 : +1.0;\n"
"\n"
" float Outline = IsSelected0 + IsSelected1 + IsSelected2 + IsSelected3 + IsSelected4 + IsSelected5 + IsSelected6 + IsSelected7 + IsSelected8;\n"
" //Outline = (9.0 - Outline) * (Outline > 0.0 ? 1.0 / 8.0 : 0.0);\n"
" Outline = (Outline > 0.0 && Outline < 9.0) ? 1.0 : 0.0;\n"
"\n"
" float DesatFactor = g_Attribs.NonselectionDesaturationFactor * saturate(IsSelected4);\n"
" float Luminance = dot(Color.rgb, float3(0.2126, 0.7152, 0.0722));\n"
" Color.rgb = lerp(Color.rgb, float3(Luminance, Luminance, Luminance), DesatFactor);\n"
"\n"
" Color.rgb = lerp(Color.rgb, g_Attribs.SelectionOutlineColor.rgb, Outline);\n"
"\n"
"#if CONVERT_OUTPUT_TO_SRGB\n"
" Color.rgb = pow(Color.rgb, float3(1.0/2.2, 1.0/2.2, 1.0/2.2));\n"
"#endif\n"
"}\n"
14 changes: 14 additions & 0 deletions Hydrogent/shaders_inc/HnPostProcess.vsh.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
"struct PSInput\n"
"{\n"
" float4 Pos : SV_POSITION;\n"
"};\n"
"void main(in uint VertID : SV_VertexID,\n"
" out PSInput PSIn)\n"
"{\n"
" float2 ClipXY[3];\n"
" ClipXY[0] = float2(-1.0, -1.0);\n"
" ClipXY[1] = float2(-1.0, 3.0);\n"
" ClipXY[2] = float2( 3.0, -1.0);\n"
"\n"
" PSIn.Pos = float4(ClipXY[VertID], 0.0, 1.0);\n"
"}\n"
14 changes: 14 additions & 0 deletions Hydrogent/shaders_inc/HnPostProcessStructures.fxh.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
"#ifndef _HN_POST_PROCESS_STRUCTURES_FXH_\n"
"#define _HN_POST_PROCESS_STRUCTURES_FXH_\n"
"\n"
"struct PostProcessAttribs\n"
"{\n"
" float4 SelectionOutlineColor;\n"
"\n"
" float NonselectionDesaturationFactor;\n"
" float Padding0;\n"
" float Padding1;\n"
" float Padding2;\n"
"};\n"
"\n"
"#endif // _HN_POST_PROCESS_STRUCTURES_FXH_\n"
21 changes: 11 additions & 10 deletions Hydrogent/shaders_inc/PostProcess.psh.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,21 @@
"{\n"
" Color = g_ColorBuffer.Load(int3(PSIn.Pos.xy, 0));\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"
" 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"
"\n"
" float IsSelected3 = g_MeshId.Load(int3(PSIn.Pos.xy + float2(-1.0, 0.0), 0)).r < 0.0 ? +1.0 : -1.0;\n"
" float IsSelected4 = g_MeshId.Load(int3(PSIn.Pos.xy + float2( 0.0, 0.0), 0)).r < 0.0 ? +1.0 : -1.0;\n"
" float IsSelected5 = g_MeshId.Load(int3(PSIn.Pos.xy + float2(+1.0, 0.0), 0)).r < 0.0 ? +1.0 : -1.0;\n"
" float IsSelected3 = g_MeshId.Load(int3(PSIn.Pos.xy + float2(-1.0, 0.0), 0)).r < 0.0 ? -1.0 : +1.0;\n"
" float IsSelected4 = g_MeshId.Load(int3(PSIn.Pos.xy + float2( 0.0, 0.0), 0)).r < 0.0 ? -1.0 : +1.0;\n"
" float IsSelected5 = g_MeshId.Load(int3(PSIn.Pos.xy + float2(+1.0, 0.0), 0)).r < 0.0 ? -1.0 : +1.0;\n"
"\n"
" float IsSelected6 = g_MeshId.Load(int3(PSIn.Pos.xy + float2(-1.0, +1.0), 0)).r < 0.0 ? +1.0 : -1.0;\n"
" float IsSelected7 = g_MeshId.Load(int3(PSIn.Pos.xy + float2( 0.0, +1.0), 0)).r < 0.0 ? +1.0 : -1.0;\n"
" float IsSelected8 = g_MeshId.Load(int3(PSIn.Pos.xy + float2(+1.0, +1.0), 0)).r < 0.0 ? +1.0 : -1.0;\n"
" float IsSelected6 = g_MeshId.Load(int3(PSIn.Pos.xy + float2(-1.0, +1.0), 0)).r < 0.0 ? -1.0 : +1.0;\n"
" float IsSelected7 = g_MeshId.Load(int3(PSIn.Pos.xy + float2( 0.0, +1.0), 0)).r < 0.0 ? -1.0 : +1.0;\n"
" float IsSelected8 = g_MeshId.Load(int3(PSIn.Pos.xy + float2(+1.0, +1.0), 0)).r < 0.0 ? -1.0 : +1.0;\n"
"\n"
" float Outline = IsSelected0 + IsSelected1 + IsSelected2 + IsSelected3 + IsSelected4 + IsSelected5 + IsSelected6 + IsSelected7 + IsSelected8;\n"
" Outline = saturate(1.0 - abs(Outline) / 9.0);\n"
" //Outline = (9.0 - Outline) * (Outline > 0.0 ? 1.0 / 8.0 : 0.0);\n"
" Outline = (Outline > 0.0 && Outline < 9.0) ? 1.0 : 0.0;\n"
"\n"
" Color.rgb += Outline * float3(0.25, 0.25, 0.1f);\n"
"\n"
Expand Down
12 changes: 8 additions & 4 deletions Hydrogent/shaders_inc/shaders_list.h
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
static const MemoryShaderSourceFileInfo g_Shaders[] =
{
{
"PostProcess.psh",
#include "PostProcess.psh.h"
"HnPostProcess.psh",
#include "HnPostProcess.psh.h"
},
{
"PostProcess.vsh",
#include "PostProcess.vsh.h"
"HnPostProcess.vsh",
#include "HnPostProcess.vsh.h"
},
{
"HnPostProcessStructures.fxh",
#include "HnPostProcessStructures.fxh.h"
},
};
31 changes: 21 additions & 10 deletions Hydrogent/src/HnRendererImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ namespace HLSL
namespace
{
#include "Shaders/PBR/public/PBR_Structures.fxh"
#include "../shaders/HnPostProcessStructures.fxh"
} // namespace

} // namespace HLSL
Expand All @@ -71,6 +72,7 @@ HnRendererImpl::HnRendererImpl(IReferenceCounters* pRefCounters,
m_Context{pContext},
m_CameraAttribsCB{CI.pCameraAttribsCB},
m_LightAttribsCB{CI.pLightAttribsCB},
m_PostProcessAttribsCB{m_Device.CreateBuffer("Post process attribs CB", sizeof(HLSL::PostProcessAttribs))},
m_ConvertOutputToSRGB{CI.ConvertOutputToSRGB},
m_USDRenderer{
std::make_shared<USD_Renderer>(
Expand Down Expand Up @@ -307,7 +309,7 @@ void HnRendererImpl::PreparePostProcess(TEXTURE_FORMAT RTVFmt)
{
ShaderCI.Desc = {"Post process VS", SHADER_TYPE_VERTEX, true};
ShaderCI.EntryPoint = "main";
ShaderCI.FilePath = "PostProcess.vsh";
ShaderCI.FilePath = "HnPostProcess.vsh";

pVS = m_Device.CreateShader(ShaderCI);
}
Expand All @@ -316,7 +318,7 @@ void HnRendererImpl::PreparePostProcess(TEXTURE_FORMAT RTVFmt)
{
ShaderCI.Desc = {"Post process PS", SHADER_TYPE_PIXEL, true};
ShaderCI.EntryPoint = "main";
ShaderCI.FilePath = "PostProcess.psh";
ShaderCI.FilePath = "HnPostProcess.psh";

pPS = m_Device.CreateShader(ShaderCI);
}
Expand All @@ -337,6 +339,7 @@ void HnRendererImpl::PreparePostProcess(TEXTURE_FORMAT RTVFmt)
.SetPrimitiveTopology(PRIMITIVE_TOPOLOGY_TRIANGLE_LIST);

m_PostProcess.PSO = m_Device.CreateGraphicsPipelineState(PsoCI);
m_PostProcess.PSO->GetStaticVariableByName(SHADER_TYPE_PIXEL, "cbPostProcessAttribs")->Set(m_PostProcessAttribsCB);
m_PostProcess.PSO->CreateShaderResourceBinding(&m_PostProcess.SRB, true);
}
}
Expand Down Expand Up @@ -383,17 +386,25 @@ void HnRendererImpl::Draw(IDeviceContext* pCtx, const HnDrawAttribs& Attribs)
}

RenderMeshes(pCtx, Attribs);
PerformPostProcess(pCtx, Attribs);
}

void HnRendererImpl::PerformPostProcess(IDeviceContext* pCtx, const HnDrawAttribs& Attribs)
{
ITextureView* pRTVs[] = {Attribs.pDstRTV};
pCtx->SetRenderTargets(_countof(pRTVs), pRTVs, nullptr, RESOURCE_STATE_TRANSITION_MODE_TRANSITION);

{
ITextureView* pRTVs[] = {Attribs.pDstRTV};
pCtx->SetRenderTargets(_countof(pRTVs), pRTVs, nullptr, RESOURCE_STATE_TRANSITION_MODE_TRANSITION);

pCtx->SetPipelineState(m_PostProcess.PSO);
m_PostProcess.SRB->GetVariableByName(SHADER_TYPE_PIXEL, "g_ColorBuffer")->Set(m_ColorBuffer->GetDefaultView(TEXTURE_VIEW_SHADER_RESOURCE));
m_PostProcess.SRB->GetVariableByName(SHADER_TYPE_PIXEL, "g_MeshId")->Set(m_MeshIdTexture->GetDefaultView(TEXTURE_VIEW_SHADER_RESOURCE));
pCtx->CommitShaderResources(m_PostProcess.SRB, RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
pCtx->Draw({3, DRAW_FLAG_VERIFY_ALL});
MapHelper<HLSL::PostProcessAttribs> pDstShaderAttribs{pCtx, m_PostProcessAttribsCB, MAP_WRITE, MAP_FLAG_DISCARD};
pDstShaderAttribs->SelectionOutlineColor = Attribs.SlectionColor;
pDstShaderAttribs->NonselectionDesaturationFactor = Attribs.SelectedPrim != nullptr && !Attribs.SelectedPrim->IsEmpty() ? 0.5f : 0.f;
}

pCtx->SetPipelineState(m_PostProcess.PSO);
m_PostProcess.SRB->GetVariableByName(SHADER_TYPE_PIXEL, "g_ColorBuffer")->Set(m_ColorBuffer->GetDefaultView(TEXTURE_VIEW_SHADER_RESOURCE));
m_PostProcess.SRB->GetVariableByName(SHADER_TYPE_PIXEL, "g_MeshId")->Set(m_MeshIdTexture->GetDefaultView(TEXTURE_VIEW_SHADER_RESOURCE));
pCtx->CommitShaderResources(m_PostProcess.SRB, RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
pCtx->Draw({3, DRAW_FLAG_VERIFY_ALL});
}

void HnRendererImpl::RenderMesh(IDeviceContext* pCtx,
Expand Down

0 comments on commit 9e18569

Please sign in to comment.