Skip to content

Commit

Permalink
Added environment map renderer
Browse files Browse the repository at this point in the history
  • Loading branch information
TheMostDiligent committed Sep 17, 2023
1 parent 8e70179 commit 8376ce9
Show file tree
Hide file tree
Showing 9 changed files with 334 additions and 1 deletion.
2 changes: 2 additions & 0 deletions Components/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ cmake_minimum_required (VERSION 3.6)

set(SOURCE
"${CMAKE_CURRENT_SOURCE_DIR}/src/ShadowMapManager.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/EnvMapRenderer.cpp"
)

set(INCLUDE
"${CMAKE_CURRENT_SOURCE_DIR}/interface/ShadowMapManager.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/interface/EnvMapRenderer.hpp"
)

target_sources(DiligentFX PRIVATE ${SOURCE} ${INCLUDE})
Expand Down
78 changes: 78 additions & 0 deletions Components/interface/EnvMapRenderer.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
* Copyright 2023 Diligent Graphics LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* In no event and under no legal theory, whether in tort (including negligence),
* contract, or otherwise, unless required by applicable law (such as deliberate
* and grossly negligent acts) or agreed to in writing, shall any Contributor be
* liable for any damages, including any direct, indirect, special, incidental,
* or consequential damages of any character arising as a result of this License or
* out of the use or inability to use the software (including but not limited to damages
* for loss of goodwill, work stoppage, computer failure or malfunction, or any and
* all other commercial damages or losses), even if such Contributor has been advised
* of the possibility of such damages.
*/

#include "../../../DiligentCore/Graphics/GraphicsEngine/interface/RenderDevice.h"
#include "../../../DiligentCore/Graphics/GraphicsEngine/interface/DeviceContext.h"
#include "../../../DiligentCore/Graphics/GraphicsTools/interface/RenderStateCache.h"
#include "../../../DiligentCore/Common/interface/RefCntAutoPtr.hpp"
#include "../../../DiligentCore/Common/interface/BasicMath.hpp"

namespace Diligent
{

namespace HLSL
{
#include "../../Shaders/PostProcess/ToneMapping/public/ToneMappingStructures.fxh"
} // namespace HLSL

/// Renders environment map.
class EnvMapRenderer
{
public:
struct CreateInfo
{
IRenderDevice* pDevice = nullptr;
IRenderStateCache* pStateCache = nullptr;
IBuffer* pCameraAttribsCB = nullptr;

TEXTURE_FORMAT RTVFormat = TEX_FORMAT_RGBA8_UNORM_SRGB;
TEXTURE_FORMAT DSVFormat = TEX_FORMAT_D32_FLOAT;

int ToneMappingMode = TONE_MAPPING_MODE_UNCHARTED2;

/// Manually convert shader output to sRGB color space.
bool ConvertOutputToSRGB = false;
};
EnvMapRenderer(const CreateInfo& CI);

struct RenderAttribs
{
IDeviceContext* pContext = nullptr;
ITextureView* pEnvMap = nullptr;

float AverageLogLum = 1;
float MipLevel = 0;
};
void Render(const RenderAttribs& Attribs, const HLSL::ToneMappingAttribs& ToneMapping);

private:
RefCntAutoPtr<IPipelineState> m_PSO;
RefCntAutoPtr<IShaderResourceBinding> m_SRB;
RefCntAutoPtr<IBuffer> m_RenderAttribsCB;
IShaderResourceVariable* m_pEnvMapVar = nullptr;
};

} // namespace Diligent
149 changes: 149 additions & 0 deletions Components/src/EnvMapRenderer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
/*
* Copyright 2023 Diligent Graphics LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* In no event and under no legal theory, whether in tort (including negligence),
* contract, or otherwise, unless required by applicable law (such as deliberate
* and grossly negligent acts) or agreed to in writing, shall any Contributor be
* liable for any damages, including any direct, indirect, special, incidental,
* or consequential damages of any character arising as a result of this License or
* out of the use or inability to use the software (including but not limited to damages
* for loss of goodwill, work stoppage, computer failure or malfunction, or any and
* all other commercial damages or losses), even if such Contributor has been advised
* of the possibility of such damages.
*/

#include "EnvMapRenderer.hpp"

#include "../../../Utilities/include/DiligentFXShaderSourceStreamFactory.hpp"
#include "ShaderMacroHelper.hpp"
#include "RenderStateCache.hpp"
#include "CommonlyUsedStates.h"
#include "MapHelper.hpp"

namespace Diligent
{

namespace HLSL
{

namespace
{

struct EnvMapRenderAttribs
{
ToneMappingAttribs ToneMapping;

float AverageLogLum;
float MipLevel;
float Unusued1;
float Unusued2;
};

} // namespace

} // namespace HLSL

EnvMapRenderer::EnvMapRenderer(const CreateInfo& CI)
{
DEV_CHECK_ERR(CI.pDevice != nullptr, "Device must not be null");
DEV_CHECK_ERR(CI.pCameraAttribsCB != nullptr, "Camera Attribs CB must not be null");

RenderDeviceWithCache<true> Device{CI.pDevice, CI.pStateCache};

m_RenderAttribsCB = Device.CreateBuffer("EnvMap Render Attribs CB", sizeof(HLSL::EnvMapRenderAttribs));

ShaderCreateInfo ShaderCI;
ShaderCI.SourceLanguage = SHADER_SOURCE_LANGUAGE_HLSL;
ShaderCI.pShaderSourceStreamFactory = &DiligentFXShaderSourceStreamFactory::GetInstance();

ShaderMacroHelper Macros;
Macros
.Add("CONVERT_OUTPUT_TO_SRGB", CI.ConvertOutputToSRGB)
.Add("TONE_MAPPING_MODE", CI.ToneMappingMode);
ShaderCI.Macros = Macros;

RefCntAutoPtr<IShader> pVS;
{
ShaderCI.Desc = {"Environment Map VS", SHADER_TYPE_VERTEX, true};
ShaderCI.EntryPoint = "main";
ShaderCI.FilePath = "EnvMap.vsh";

pVS = Device.CreateShader(ShaderCI);
}

// Create pixel shader
RefCntAutoPtr<IShader> pPS;
{
ShaderCI.Desc = {"Environment Map PS", SHADER_TYPE_PIXEL, true};
ShaderCI.EntryPoint = "main";
ShaderCI.FilePath = "EnvMap.psh";

pPS = Device.CreateShader(ShaderCI);
}

PipelineResourceLayoutDescX ResourceLauout;
ResourceLauout
.AddVariable(SHADER_TYPE_PIXEL, "EnvMap", SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC)
.AddImmutableSampler(SHADER_TYPE_PIXEL, "EnvMap", Sam_LinearClamp);

GraphicsPipelineStateCreateInfoX PsoCI{"Environment Map PSO"};
PsoCI
.SetResourceLayout(ResourceLauout)
.AddShader(pVS)
.AddShader(pPS)
.SetPrimitiveTopology(PRIMITIVE_TOPOLOGY_TRIANGLE_LIST)
.AddRenderTarget(CI.RTVFormat)
.SetDepthFormat(CI.DSVFormat);

PsoCI.GraphicsPipeline.DepthStencilDesc.DepthFunc = COMPARISON_FUNC_LESS_EQUAL;

m_PSO = Device.CreateGraphicsPipelineState(PsoCI);
m_PSO->GetStaticVariableByName(SHADER_TYPE_PIXEL, "cbCameraAttribs")->Set(CI.pCameraAttribsCB);
m_PSO->GetStaticVariableByName(SHADER_TYPE_PIXEL, "cbEnvMapRenderAttribs")->Set(m_RenderAttribsCB);
m_PSO->CreateShaderResourceBinding(&m_SRB, true);
m_pEnvMapVar = m_SRB->GetVariableByName(SHADER_TYPE_PIXEL, "EnvMap");
VERIFY_EXPR(m_pEnvMapVar != nullptr);
}

void EnvMapRenderer::Render(const RenderAttribs& Attribs, const HLSL::ToneMappingAttribs& ToneMapping)
{
if (Attribs.pContext == nullptr)
{
UNEXPECTED("Context must not be null");
return;
}

if (Attribs.pEnvMap == nullptr)
{
UNEXPECTED("Environment map SRB must not be null");
return;
}

m_pEnvMapVar->Set(Attribs.pEnvMap);

{
MapHelper<HLSL::EnvMapRenderAttribs> EnvMapAttribs{Attribs.pContext, m_RenderAttribsCB, MAP_WRITE, MAP_FLAG_DISCARD};
EnvMapAttribs->ToneMapping = ToneMapping;
EnvMapAttribs->AverageLogLum = Attribs.AverageLogLum;
EnvMapAttribs->MipLevel = Attribs.MipLevel;
}

Attribs.pContext->SetPipelineState(m_PSO);
Attribs.pContext->CommitShaderResources(m_SRB, RESOURCE_STATE_TRANSITION_MODE_VERIFY);
DrawAttribs drawAttribs{3, DRAW_FLAG_VERIFY_ALL};
Attribs.pContext->Draw(drawAttribs);
}

} // namespace Diligent
2 changes: 1 addition & 1 deletion PBR/interface/GLTF_PBR_Renderer.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2019-2022 Diligent Graphics LLC
* Copyright 2019-2023 Diligent Graphics LLC
* Copyright 2015-2019 Egor Yusov
*
* Licensed under the Apache License, Version 2.0 (the "License");
Expand Down
34 changes: 34 additions & 0 deletions Shaders/Common/private/EnvMap.psh
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#include "BasicStructures.fxh"
#include "ToneMapping.fxh"

cbuffer cbCameraAttribs
{
CameraAttribs g_CameraAttribs;
}

cbuffer cbEnvMapRenderAttribs
{
ToneMappingAttribs g_ToneMappingAttribs;

float AverageLogLum;
float MipLevel;
float Unusued1;
float Unusued2;
}

TextureCube EnvMap;
SamplerState EnvMap_sampler;

void main(in float4 Pos : SV_Position,
in float4 ClipPos : CLIP_POS,
out float4 Color : SV_Target)
{
float4 WorldPos = mul(ClipPos, g_CameraAttribs.mViewProjInv);
float3 Direction = WorldPos.xyz / WorldPos.w - g_CameraAttribs.f4Position.xyz;
float3 EnvRadiance = EnvMap.SampleLevel(EnvMap_sampler, Direction, MipLevel).rgb;
Color.rgb = ToneMap(EnvRadiance.rgb, g_ToneMappingAttribs, AverageLogLum);
#if CONVERT_OUTPUT_TO_SRGB
Color.rgb = pow(Color.rgb, float3(1.0 / 2.2, 1.0 / 2.2, 1.0 / 2.2));
#endif
Color.a = 1.0;
}
14 changes: 14 additions & 0 deletions Shaders/Common/private/EnvMap.vsh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@

void main(in uint VertexId : SV_VertexID,
out float4 Pos : SV_Position,
out float4 ClipPos : CLIP_POS)
{
float2 PosXY[3];
PosXY[0] = float2(-1.0, -1.0);
PosXY[1] = float2(-1.0, +3.0);
PosXY[2] = float2(+3.0, -1.0);

float2 f2XY = PosXY[VertexId];
Pos = float4(f2XY, 1.0, 1.0);
ClipPos = Pos;
}
34 changes: 34 additions & 0 deletions shaders_inc/EnvMap.psh.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
"#include \"BasicStructures.fxh\"\n"
"#include \"ToneMapping.fxh\"\n"
"\n"
"cbuffer cbCameraAttribs\n"
"{\n"
" CameraAttribs g_CameraAttribs;\n"
"}\n"
"\n"
"cbuffer cbEnvMapRenderAttribs\n"
"{\n"
" ToneMappingAttribs g_ToneMappingAttribs;\n"
"\n"
" float AverageLogLum;\n"
" float MipLevel;\n"
" float Unusued1;\n"
" float Unusued2;\n"
"}\n"
"\n"
"TextureCube EnvMap;\n"
"SamplerState EnvMap_sampler;\n"
"\n"
"void main(in float4 Pos : SV_Position,\n"
" in float4 ClipPos : CLIP_POS,\n"
" out float4 Color : SV_Target)\n"
"{\n"
" float4 WorldPos = mul(ClipPos, g_CameraAttribs.mViewProjInv);\n"
" float3 Direction = WorldPos.xyz / WorldPos.w - g_CameraAttribs.f4Position.xyz;\n"
" float3 EnvRadiance = EnvMap.SampleLevel(EnvMap_sampler, Direction, MipLevel).rgb;\n"
" Color.rgb = ToneMap(EnvRadiance.rgb, g_ToneMappingAttribs, AverageLogLum);\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"
" Color.a = 1.0;\n"
"}\n"
14 changes: 14 additions & 0 deletions shaders_inc/EnvMap.vsh.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
"\n"
"void main(in uint VertexId : SV_VertexID,\n"
" out float4 Pos : SV_Position,\n"
" out float4 ClipPos : CLIP_POS)\n"
"{\n"
" float2 PosXY[3];\n"
" PosXY[0] = float2(-1.0, -1.0);\n"
" PosXY[1] = float2(-1.0, +3.0);\n"
" PosXY[2] = float2(+3.0, -1.0);\n"
"\n"
" float2 f2XY = PosXY[VertexId];\n"
" Pos = float4(f2XY, 1.0, 1.0);\n"
" ClipPos = Pos;\n"
"}\n"
8 changes: 8 additions & 0 deletions shaders_inc/shaders_list.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ struct ShaderIncInfo

static const ShaderIncInfo g_Shaders[] =
{
{
"EnvMap.psh",
#include "EnvMap.psh.h"
},
{
"EnvMap.vsh",
#include "EnvMap.vsh.h"
},
{
"FullScreenTriangleVS.fx",
#include "FullScreenTriangleVS.fx.h"
Expand Down

0 comments on commit 8376ce9

Please sign in to comment.