Skip to content

Commit

Permalink
Hydrogent: improved mesh sorting
Browse files Browse the repository at this point in the history
  • Loading branch information
TheMostDiligent committed Oct 8, 2023
1 parent e72464b commit 53dec6a
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 54 deletions.
21 changes: 20 additions & 1 deletion Hydrogent/include/HnRendererImpl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
#pragma once

#include <memory>
#include <vector>
#include <array>

#include "HnRenderer.hpp"

Expand Down Expand Up @@ -84,7 +86,12 @@ class HnRendererImpl final : public ObjectBase<IHnRenderer>
void RenderPrimId(IDeviceContext* pContext, ITextureView* pDepthBuffer, const float4x4& Transform) override final;

private:
void RenderMesh(IDeviceContext* pCtx, const HnMesh& Mesh, const HnMaterial& Material, const HnDrawAttribs& Attribs);
void RenderMesh(IDeviceContext* pCtx,
const HnMesh& Mesh,
const HnMaterial& Material,
const HnDrawAttribs& Attribs,
USD_Renderer::ALPHA_MODE AlphaMode);
void RenderMeshes(IDeviceContext* pCtx, const HnDrawAttribs& Attribs);

private:
RenderDeviceWithCache_N m_Device;
Expand All @@ -111,6 +118,18 @@ class HnRendererImpl final : public ObjectBase<IHnRenderer>
GPUCompletionAwaitQueue<RefCntAutoPtr<ITexture>> m_MeshIdReadBackQueue;

PBR_Renderer::PSO_FLAGS m_PSOFlags = PBR_Renderer::PSO_FLAG_NONE;

struct MeshRenderInfo
{
const HnMesh& Mesh;
const HnMaterial& Material;

MeshRenderInfo(const HnMesh& _Mesh, const HnMaterial& _Material) noexcept :
Mesh{_Mesh},
Material{_Material}
{}
};
std::array<std::vector<MeshRenderInfo>, USD_Renderer::ALPHA_MODE_NUM_MODES> m_RenderLists;
};

} // namespace USD
Expand Down
108 changes: 55 additions & 53 deletions Hydrogent/src/HnRendererImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -207,15 +207,49 @@ void HnRendererImpl::Update()
}
}

void HnRendererImpl::Draw(IDeviceContext* pCtx, const HnDrawAttribs& Attribs)
void HnRendererImpl::RenderMeshes(IDeviceContext* pCtx, const HnDrawAttribs& Attribs)
{
if (!m_RenderDelegate)
return;
for (auto& List : m_RenderLists)
List.clear();

const auto& Meshes = m_RenderDelegate->GetMeshes();
if (Meshes.empty())
return;

for (auto mesh_it : Meshes)
{
if (!mesh_it.second)
continue;

auto& Mesh = *mesh_it.second;

const auto& MaterialId = Mesh.GetMaterialId();
const auto* pMaterial = m_RenderDelegate->GetMaterial(MaterialId.GetText());
if (pMaterial == nullptr)
return;

const auto& ShaderAttribs = pMaterial->GetShaderAttribs();
const auto AlphaMode = ShaderAttribs.AlphaMode;

m_RenderLists[AlphaMode].emplace_back(Mesh, *pMaterial);
}

// TODO: handle double-sided materials
for (auto AlphaMode : {USD_Renderer::ALPHA_MODE_OPAQUE, USD_Renderer::ALPHA_MODE_MASK, USD_Renderer::ALPHA_MODE_BLEND})
{
const auto& List = m_RenderLists[AlphaMode];
for (const auto& MeshRI : List)
{
RenderMesh(pCtx, MeshRI.Mesh, MeshRI.Material, Attribs, AlphaMode);
}
}
}

void HnRendererImpl::Draw(IDeviceContext* pCtx, const HnDrawAttribs& Attribs)
{
if (!m_RenderDelegate)
return;

if (auto* pEnvMapSRV = m_USDRenderer->GetPrefilteredEnvMapSRV())
{
Diligent::HLSL::ToneMappingAttribs TMAttribs;
Expand All @@ -235,36 +269,14 @@ void HnRendererImpl::Draw(IDeviceContext* pCtx, const HnDrawAttribs& Attribs)
m_EnvMapRenderer->Render(EnvMapAttribs, TMAttribs);
}

// TODO: handle double-sided materials
for (auto AlphaMode : {USD_Renderer::ALPHA_MODE_OPAQUE, USD_Renderer::ALPHA_MODE_MASK, USD_Renderer::ALPHA_MODE_BLEND})
{
if (Attribs.RenderMode == HN_RENDER_MODE_MESH_EDGES)
pCtx->SetPipelineState(m_USDRenderer->GetWireframePSO({m_PSOFlags, PRIMITIVE_TOPOLOGY_LINE_LIST, /*DoubleSided = */ false}, true));
else
pCtx->SetPipelineState(m_USDRenderer->GetPbrPSO({m_PSOFlags, AlphaMode, /*DoubleSided = */ false}, true));

for (auto mesh_it : Meshes)
{
if (!mesh_it.second)
continue;

auto& Mesh = *mesh_it.second;

const auto& MaterialId = Mesh.GetMaterialId();
const auto* pMaterial = m_RenderDelegate->GetMaterial(MaterialId.GetText());
if (pMaterial == nullptr)
return;

const auto& ShaderAttribs = pMaterial->GetShaderAttribs();
if (ShaderAttribs.AlphaMode != AlphaMode)
continue;

RenderMesh(pCtx, Mesh, *pMaterial, Attribs);
}
}
RenderMeshes(pCtx, Attribs);
}

void HnRendererImpl::RenderMesh(IDeviceContext* pCtx, const HnMesh& Mesh, const HnMaterial& Material, const HnDrawAttribs& Attribs)
void HnRendererImpl::RenderMesh(IDeviceContext* pCtx,
const HnMesh& Mesh,
const HnMaterial& Material,
const HnDrawAttribs& Attribs,
USD_Renderer::ALPHA_MODE AlphaMode)
{
auto* pSRB = Material.GetSRB();
auto* pPosVB = Mesh.GetVertexBuffer(pxr::HdTokens->points);
Expand Down Expand Up @@ -304,6 +316,15 @@ void HnRendererImpl::RenderMesh(IDeviceContext* pCtx, const HnMesh& Mesh, const
if (pPosVB == nullptr || pNormalsVB == nullptr || pTexCoordVBs[0] == nullptr || pTexCoordVBs[1] == nullptr || pIB == nullptr || pSRB == nullptr)
return;

IPipelineState* pPSO = nullptr;
if (Attribs.RenderMode == HN_RENDER_MODE_MESH_EDGES)
pPSO = m_USDRenderer->GetWireframePSO({m_PSOFlags, PRIMITIVE_TOPOLOGY_LINE_LIST, /*DoubleSided = */ false}, true);
else if (Attribs.RenderMode == HN_RENDER_MODE_SOLID)
pPSO = m_USDRenderer->GetPbrPSO({m_PSOFlags, AlphaMode, /*DoubleSided = */ false}, true);
else
pPSO = m_USDRenderer->GetMeshIdPSO({m_PSOFlags, /*DoubleSided = */ false}, true);
pCtx->SetPipelineState(pPSO);

// Bind vertex and index buffers
IBuffer* pBuffs[] = {pPosVB, pNormalsVB, pTexCoordVBs[0], pTexCoordVBs[1]};
pCtx->SetVertexBuffers(0, _countof(pBuffs), pBuffs, nullptr, RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
Expand Down Expand Up @@ -448,29 +469,10 @@ void HnRendererImpl::RenderPrimId(IDeviceContext* pContext, ITextureView* pDepth
if (Meshes.empty())
return;

auto* pMeshIdPSO = m_USDRenderer->GetMeshIdPSO({m_PSOFlags, /*DoubleSided = */ false}, true);
if (pMeshIdPSO == nullptr)
return;

// TODO: handle double-sided materials
pContext->SetPipelineState(pMeshIdPSO);

HnDrawAttribs Attribs;
Attribs.Transform = Transform;
for (auto mesh_it : Meshes)
{
if (!mesh_it.second)
continue;

auto& Mesh = *mesh_it.second;

const auto& MaterialId = Mesh.GetMaterialId();
const auto* pMaterial = m_RenderDelegate->GetMaterial(MaterialId.GetText());
if (pMaterial == nullptr)
return;

RenderMesh(pContext, Mesh, *pMaterial, Attribs);
}
Attribs.Transform = Transform;
Attribs.RenderMode = HN_RENDER_MODE_COUNT; // Temporary solution
RenderMeshes(pContext, Attribs);

pContext->SetRenderTargets(0, nullptr, nullptr, RESOURCE_STATE_TRANSITION_MODE_NONE);
}
Expand Down

0 comments on commit 53dec6a

Please sign in to comment.