Skip to content

Commit

Permalink
Hydrogent: reworked material texture attributes handling
Browse files Browse the repository at this point in the history
  • Loading branch information
TheMostDiligent committed Nov 23, 2023
1 parent 90ddefe commit 44aef33
Show file tree
Hide file tree
Showing 10 changed files with 159 additions and 96 deletions.
8 changes: 6 additions & 2 deletions Hydrogent/interface/HnMaterial.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,9 @@ class HnMaterial final : public pxr::HdMaterial
return m_SRB;
}

const HLSL::PBRMaterialShaderInfo& GetShaderAttribs() const { return m_ShaderAttribs; }
const HLSL::PBRMaterialBasicAttribs& GetBasicShaderAttribs() const { return m_BasicShaderAttribs; }
const HLSL::PBRMaterialTextureAttribs* GetShaderTextureAttribs() const { return m_ShaderTextureAttribs.get(); }
Uint32 GetNumShaderTextureAttribs() const { return m_NumShaderTextureAttribs; }

/// Texture coordinate set info
struct TextureCoordinateSetInfo
Expand All @@ -116,7 +118,9 @@ class HnMaterial final : public pxr::HdMaterial
RefCntAutoPtr<IShaderResourceBinding> m_SRB;
IShaderResourceVariable* m_PrimitiveAttribsVar = nullptr; // cbPrimitiveAttribs

HLSL::PBRMaterialShaderInfo m_ShaderAttribs{};
HLSL::PBRMaterialBasicAttribs m_BasicShaderAttribs{};
std::unique_ptr<HLSL::PBRMaterialTextureAttribs[]> m_ShaderTextureAttribs;
Uint32 m_NumShaderTextureAttribs = 0;

std::vector<TextureCoordinateSetInfo> m_TexCoords;

Expand Down
90 changes: 45 additions & 45 deletions Hydrogent/src/HnMaterial.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,6 @@
namespace Diligent
{

namespace HLSL
{

#include "Shaders/Common/public/BasicStructures.fxh"
#include "Shaders/PBR/public/PBR_Structures.fxh"
#include "Shaders/PBR/private/RenderPBR_Structures.fxh"

} // namespace HLSL

namespace USD
{

Expand All @@ -59,9 +50,9 @@ HnMaterial* HnMaterial::Create(const pxr::SdfPath& id)
HnMaterial::HnMaterial(const pxr::SdfPath& id) :
pxr::HdMaterial{id}
{
m_ShaderAttribs.Basic.BaseColorFactor = float4{1, 1, 1, 1};
m_ShaderAttribs.Basic.RoughnessFactor = 1;
m_ShaderAttribs.Basic.OcclusionFactor = 1;
m_BasicShaderAttribs.BaseColorFactor = float4{1, 1, 1, 1};
m_BasicShaderAttribs.RoughnessFactor = 1;
m_BasicShaderAttribs.OcclusionFactor = 1;
}

HnMaterial::~HnMaterial()
Expand Down Expand Up @@ -97,17 +88,22 @@ void HnMaterial::Sync(pxr::HdSceneDelegate* SceneDelegate,
}
}

HnTextureRegistry& TexRegistry = static_cast<HnRenderDelegate*>(SceneDelegate->GetRenderIndex().GetRenderDelegate())->GetTextureRegistry();
HnRenderDelegate* RenderDelegate = static_cast<HnRenderDelegate*>(SceneDelegate->GetRenderIndex().GetRenderDelegate());
HnTextureRegistry& TexRegistry = RenderDelegate->GetTextureRegistry();
const USD_Renderer& UsdRenderer = *RenderDelegate->GetUSDRenderer();

m_NumShaderTextureAttribs = UsdRenderer.GetNumShaderTextureAttribs();
m_ShaderTextureAttribs = std::make_unique<HLSL::PBRMaterialTextureAttribs[]>(m_NumShaderTextureAttribs);

TexNameToCoordSetMapType TexNameToCoordSetMap;
AllocateTextures(TexRegistry, TexNameToCoordSetMap);

m_ShaderAttribs.Basic.BaseColorFactor = float4{1, 1, 1, 1};
m_ShaderAttribs.Basic.EmissiveFactor = float4{1, 1, 1, 1};
m_ShaderAttribs.Basic.SpecularFactor = float4{1, 1, 1, 1};
m_ShaderAttribs.Basic.MetallicFactor = 1;
m_ShaderAttribs.Basic.RoughnessFactor = 1;
m_ShaderAttribs.Basic.OcclusionFactor = 1;
m_BasicShaderAttribs.BaseColorFactor = float4{1, 1, 1, 1};
m_BasicShaderAttribs.EmissiveFactor = float4{1, 1, 1, 1};
m_BasicShaderAttribs.SpecularFactor = float4{1, 1, 1, 1};
m_BasicShaderAttribs.MetallicFactor = 1;
m_BasicShaderAttribs.RoughnessFactor = 1;
m_BasicShaderAttribs.OcclusionFactor = 1;

const auto& MaterialParams = m_Network.GetParameters();

Expand All @@ -126,56 +122,60 @@ void HnMaterial::Sync(pxr::HdSceneDelegate* SceneDelegate,
};

SetFallbackValue(HnTokens->diffuseColor, [this](const pxr::VtValue& Val) {
m_ShaderAttribs.Basic.BaseColorFactor = float4{float3::MakeVector(Val.Get<pxr::GfVec3f>().data()), 1};
m_BasicShaderAttribs.BaseColorFactor = float4{float3::MakeVector(Val.Get<pxr::GfVec3f>().data()), 1};
});
SetFallbackValue(HnTokens->metallic, [this](const pxr::VtValue& Val) {
m_ShaderAttribs.Basic.MetallicFactor = Val.Get<float>();
m_BasicShaderAttribs.MetallicFactor = Val.Get<float>();
});
SetFallbackValue(HnTokens->roughness, [this](const pxr::VtValue& Val) {
m_ShaderAttribs.Basic.RoughnessFactor = Val.Get<float>();
m_BasicShaderAttribs.RoughnessFactor = Val.Get<float>();
});
SetFallbackValue(HnTokens->occlusion, [this](const pxr::VtValue& Val) {
m_ShaderAttribs.Basic.OcclusionFactor = Val.Get<float>();
m_BasicShaderAttribs.OcclusionFactor = Val.Get<float>();
});

m_ShaderAttribs.Basic.Workflow = PBR_Renderer::PBR_WORKFLOW_METALL_ROUGH;
m_ShaderAttribs.Textures[0].UVSelector = static_cast<float>(TexNameToCoordSetMap[HnTokens->diffuseColor]);
m_ShaderAttribs.Textures[1].UVSelector = static_cast<float>(TexNameToCoordSetMap[HnTokens->metallic]);
if (TexNameToCoordSetMap[HnTokens->metallic] != TexNameToCoordSetMap[HnTokens->roughness])
LOG_ERROR_MESSAGE("Metallic and roughness textures must use the same texture coordinates");
m_ShaderAttribs.Textures[2].UVSelector = static_cast<float>(TexNameToCoordSetMap[HnTokens->normal]);
m_ShaderAttribs.Textures[3].UVSelector = static_cast<float>(TexNameToCoordSetMap[HnTokens->occlusion]);
m_ShaderAttribs.Textures[4].UVSelector = static_cast<float>(TexNameToCoordSetMap[HnTokens->emissiveColor]);
m_BasicShaderAttribs.Workflow = PBR_Renderer::PBR_WORKFLOW_METALL_ROUGH;

auto SetTextureParams = [&](const pxr::TfToken& Name, Uint32 Idx) {
if (Idx >= m_NumShaderTextureAttribs)
{
UNEXPECTED("Texture attribute index (", Idx, ") exceeds the number of texture attributes (", m_NumShaderTextureAttribs, ")");
return;
}

m_ShaderTextureAttribs[Idx].UVSelector = static_cast<float>(TexNameToCoordSetMap[Name]);

auto SetAtlasParams = [&](const pxr::TfToken& Name, Uint32 Idx) {
auto tex_it = m_Textures.find(Name);
if (tex_it == m_Textures.end())
return;

ITextureAtlasSuballocation* pAtlasSuballocation = tex_it->second->pAtlasSuballocation;
if (pAtlasSuballocation != nullptr)
{
m_ShaderAttribs.Textures[Idx].TextureSlice = static_cast<float>(pAtlasSuballocation->GetSlice());
m_ShaderAttribs.Textures[Idx].UVScaleBias = pAtlasSuballocation->GetUVScaleBias();
m_ShaderTextureAttribs[Idx].TextureSlice = static_cast<float>(pAtlasSuballocation->GetSlice());
m_ShaderTextureAttribs[Idx].UVScaleBias = pAtlasSuballocation->GetUVScaleBias();

m_UsesAtlas = true;
}
else
{
m_ShaderAttribs.Textures[Idx].TextureSlice = 0;
m_ShaderAttribs.Textures[Idx].UVScaleBias = float4{1, 1, 0, 0};
m_ShaderTextureAttribs[Idx].TextureSlice = 0;
m_ShaderTextureAttribs[Idx].UVScaleBias = float4{1, 1, 0, 0};
}
};
SetAtlasParams(HnTokens->diffuseColor, 0);
SetAtlasParams(HnTokens->metallic, 1);
SetAtlasParams(HnTokens->normal, 2);
SetAtlasParams(HnTokens->occlusion, 3);
SetAtlasParams(HnTokens->emissiveColor, 4);
const auto& TexAttribIndices = UsdRenderer.GetShaderTextureAttributeIndices();

SetTextureParams(HnTokens->diffuseColor, TexAttribIndices.BaseColor);
SetTextureParams(HnTokens->normal, TexAttribIndices.Normal);
SetTextureParams(HnTokens->metallic, TexAttribIndices.Metallic);
SetTextureParams(HnTokens->roughness, TexAttribIndices.Roughness);
SetTextureParams(HnTokens->occlusion, TexAttribIndices.Occlusion);
SetTextureParams(HnTokens->emissiveColor, TexAttribIndices.Emissive);

m_ShaderAttribs.Basic.AlphaMode = MaterialTagToPbrAlphaMode(m_Network.GetTag());
m_BasicShaderAttribs.AlphaMode = MaterialTagToPbrAlphaMode(m_Network.GetTag());

m_ShaderAttribs.Basic.AlphaMaskCutoff = m_Network.GetOpacityThreshold();
m_ShaderAttribs.Basic.BaseColorFactor.a = m_Network.GetOpacity();
m_BasicShaderAttribs.AlphaMaskCutoff = m_Network.GetOpacityThreshold();
m_BasicShaderAttribs.BaseColorFactor.a = m_Network.GetOpacity();
}

*DirtyBits = HdMaterial::Clean;
Expand Down Expand Up @@ -257,7 +257,7 @@ void HnMaterial::UpdateSRB(IRenderDevice* pDevice,
// Primitive attribs buffer is a large buffer that fits multiple primitives.
// In the render loop, we write multiple primitive attribs into this buffer
// and use the SetBufferOffset function to select the attribs for the current primitive.
pVar->SetBufferRange(PbrRenderer.GetPBRPrimitiveAttribsCB(), 0, sizeof(HLSL::PBRPrimitiveAttribs));
pVar->SetBufferRange(PbrRenderer.GetPBRPrimitiveAttribsCB(), 0, PbrRenderer.GetPBRPrimitiveAttribsSize());
}
else
{
Expand Down
2 changes: 1 addition & 1 deletion Hydrogent/src/HnRenderDelegate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ HnRenderDelegate::HnRenderDelegate(const CreateInfo& CI) :
m_FrameAttribsCB{CreateFrameAttribsCB(CI.pDevice)},
m_PrimitiveAttribsCB{CreatePrimitiveAttribsCB(CI.pDevice)},
m_USDRenderer{CreateUSDRenderer(CI.pDevice, CI.pRenderStateCache, CI.pContext, m_PrimitiveAttribsCB, /*UseImmutableSamplers = */ CI.TextureAtlasDim != 0)},
m_PrimitiveAttribsAlignedOffset{AlignUp(Uint32{sizeof(HLSL::PBRPrimitiveAttribs)}, CI.pDevice->GetAdapterInfo().Buffer.ConstantBufferOffsetAlignment)},
m_PrimitiveAttribsAlignedOffset{AlignUp(m_USDRenderer->GetPBRPrimitiveAttribsSize(), CI.pDevice->GetAdapterInfo().Buffer.ConstantBufferOffsetAlignment)},
m_TextureRegistry{CI.pDevice, CI.TextureAtlasDim != 0 ? m_ResourceMgr : nullptr},
m_RenderParam{std::make_unique<HnRenderParam>(CI.UseVertexPool, CI.UseIndexPool, CI.TextureAtlasDim != 0)}
{
Expand Down
33 changes: 18 additions & 15 deletions Hydrogent/src/HnRenderPass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ struct HnRenderPass::RenderState
const HnRenderPassState& RPState;
const pxr::HdRenderIndex& RenderIndex;
const HnRenderDelegate& RenderDelegate;
USD_Renderer& USDRenderer;

IDeviceContext* const pCtx;

Expand All @@ -86,6 +87,7 @@ struct HnRenderPass::RenderState
RPState{_RPState},
RenderIndex{*RenderPass.GetRenderIndex()},
RenderDelegate{*static_cast<HnRenderDelegate*>(RenderIndex.GetRenderDelegate())},
USDRenderer{*RenderDelegate.GetUSDRenderer()},
pCtx{RenderDelegate.GetDeviceContext()},
AlphaMode{MaterialTagToPbrAlphaMode(RenderPass.m_MaterialTag)},
PrimitiveAttribsAlignedOffset{RenderDelegate.GetPrimitiveAttribsAlignedOffset()}
Expand Down Expand Up @@ -145,7 +147,7 @@ struct HnRenderPass::RenderState
{
GraphicsPipelineDesc GraphicsDesc = RenderPass.GetGraphicsDesc(RPState);

PsoCache = RenderDelegate.GetUSDRenderer()->GetPsoCacheAccessor(GraphicsDesc);
PsoCache = USDRenderer.GetPsoCacheAccessor(GraphicsDesc);
VERIFY_EXPR(PsoCache);
}

Expand Down Expand Up @@ -251,26 +253,27 @@ void HnRenderPass::_Execute(const pxr::HdRenderPassStateSharedPtr& RPState,
}

// Write current primitive attributes
float4 CustomData{
static_cast<float>(Mesh.GetUID()),
m_Params.Selection == HnRenderPassParams::SelectionType::Selected ? 1.f : 0.f,
0,
0,
};

pCurrPrimitive->Transforms.NodeMatrix = Mesh.GetTransform() * m_RenderParams.Transform;
pCurrPrimitive->Transforms.JointCount = 0;

const HLSL::PBRMaterialShaderInfo& ShaderAttribs = Geo.pMaterial->GetShaderAttribs();
static_assert(sizeof(pCurrPrimitive->Material) == sizeof(ShaderAttribs), "The sizeof(PBRMaterialShaderInfo) is inconsistent with sizeof(ShaderAttribs)");
memcpy(&pCurrPrimitive->Material, &ShaderAttribs, sizeof(ShaderAttribs));
State.USDRenderer.WritePBRPrimitiveShaderAttribs(
pCurrPrimitive,
Mesh.GetTransform() * m_RenderParams.Transform,
0,
Geo.pMaterial->GetBasicShaderAttribs(),
Geo.pMaterial->GetShaderTextureAttribs(),
Geo.pMaterial->GetNumShaderTextureAttribs(),
&CustomData);

if (Geo.IsFallbackMaterial)
{
pCurrPrimitive->Material.Basic.BaseColorFactor = Mesh.GetDisplayColor();
}

pCurrPrimitive->CustomData = float4{
static_cast<float>(Mesh.GetUID()),
m_Params.Selection == HnRenderPassParams::SelectionType::Selected ? 1.f : 0.f,
0,
0,
};

pCurrPrimitive = reinterpret_cast<HLSL::PBRPrimitiveAttribs*>(reinterpret_cast<Uint8*>(pCurrPrimitive) + State.PrimitiveAttribsAlignedOffset);
m_PendingDrawItems.push_back(&DrawItem);

Expand Down Expand Up @@ -497,7 +500,7 @@ void HnRenderPass::UpdateDrawItemGPUResources(HnDrawItem& DrawItem, RenderState&
if (static_cast<const HnRenderParam*>(State.RenderDelegate.GetRenderParam())->GetUseTextureAtlas())
PSOFlags |= PBR_Renderer::PSO_FLAG_USE_TEXTURE_ATLAS;

VERIFY(Geo.pMaterial->GetShaderAttribs().Basic.AlphaMode == State.AlphaMode || Geo.IsFallbackMaterial,
VERIFY(Geo.pMaterial->GetBasicShaderAttribs().AlphaMode == State.AlphaMode || Geo.IsFallbackMaterial,
"Alpha mode derived from the material tag is not consistent with the alpha mode in the shader attributes. "
"This may indicate an issue in how alpha mode is determined in the material, or (less likely) an issue in Rprim sorting by Hydra.");
pPSO = PsoCache.Get({PSOFlags, static_cast<PBR_Renderer::ALPHA_MODE>(State.AlphaMode), /*DoubleSided = */ false, static_cast<PBR_Renderer::DebugViewType>(m_RenderParams.DebugViewMode)}, true);
Expand Down
4 changes: 4 additions & 0 deletions PBR/interface/PBR_Renderer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,10 @@ class PBR_Renderer
Uint32 NumTextureAttribs,
const float4* CustomData = nullptr);

Uint32 GetNumShaderTextureAttribs() const { return m_NumShaderTextureAttribs; }

Uint32 GetPBRPrimitiveAttribsSize() const;

protected:
ShaderMacroHelper DefineMacros(PSO_FLAGS PSOFlags, DebugViewType DebugView) const;

Expand Down
19 changes: 18 additions & 1 deletion PBR/interface/USD_Renderer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,22 @@ namespace Diligent
class USD_Renderer : public PBR_Renderer
{
public:
struct ShaderTextureAttributeIndices
{
Uint32 BaseColor = 0;
Uint32 Normal = 1;
Uint32 Metallic = 2;
Uint32 Roughness = 3;
Uint32 Occlusion = 4;
Uint32 Emissive = 5;
};

struct CreateInfo : PBR_Renderer::CreateInfo
{
Uint32 ColorTargetIndex = 0;
Uint32 MeshIdTargetIndex = 1;

ShaderTextureAttributeIndices TextureAttribIndices;
};
/// Initializes the renderer
USD_Renderer(IRenderDevice* pDevice,
Expand All @@ -54,12 +66,17 @@ class USD_Renderer : public PBR_Renderer
USD_PSO_FLAG_ENABLE_ALL_OUTPUTS = USD_PSO_FLAG_ENABLE_COLOR_AND_MESH_ID_OUTPUTS
};

const ShaderTextureAttributeIndices& GetShaderTextureAttributeIndices() const { return m_ShaderTextureAttribIndices; }

private:
std::string GetUsdPbrPSMainSource(USD_Renderer::PSO_FLAGS PSOFlags);
std::string GetUsdPbrPSMainSource(USD_Renderer::PSO_FLAGS PSOFlags) const;
struct USDRendererCreateInfoWrapper;

private:
const Uint32 m_ColorTargetIndex;
const Uint32 m_MeshIdTargetIndex;

const ShaderTextureAttributeIndices m_ShaderTextureAttribIndices;
};
DEFINE_FLAG_ENUM_OPERATORS(USD_Renderer::USD_PSO_FLAGS)

Expand Down
41 changes: 22 additions & 19 deletions PBR/src/PBR_Renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,11 @@ static std::vector<std::string> CopyShaderTextureAttribIndexNames(const PBR_Rend
static std::vector<PBR_Renderer::CreateInfo::ShaderTextureAttribIndex> CopyShaderTextureAttribIndices(const PBR_Renderer::CreateInfo& CI,
const std::vector<std::string>& Names)
{
std::vector<PBR_Renderer::CreateInfo::ShaderTextureAttribIndex> Indices(CI.NumShaderTextureAttribIndices);
VERIFY_EXPR(Indices.size() == Names.size());
std::vector<PBR_Renderer::CreateInfo::ShaderTextureAttribIndex> Indices;
if (CI.pShaderTextureAttribIndices != nullptr)
{
Indices = {CI.pShaderTextureAttribIndices, CI.pShaderTextureAttribIndices + CI.NumShaderTextureAttribIndices};
VERIFY_EXPR(Indices.size() == Names.size());
for (size_t i = 0; i < Indices.size(); ++i)
{
Indices[i].Name = Names[i].c_str();
Expand Down Expand Up @@ -224,23 +225,7 @@ PBR_Renderer::PBR_Renderer(IRenderDevice* pDevice,
{
if (!m_PBRPrimitiveAttribsCB)
{
//struct PBRPrimitiveAttribs
//{
// GLTFNodeShaderTransforms Transforms;
// struct PBRMaterialShaderInfo
// {
// PBRMaterialBasicAttribs Basic;
// PBRMaterialTextureAttribs Textures[PBR_NUM_TEXTURE_ATTRIBUTES];
// } Material;
// float4 CustomData;
//};
Uint32 PBRPrimitiveAttribsSize =
sizeof(HLSL::GLTFNodeShaderTransforms) +
sizeof(HLSL::PBRMaterialBasicAttribs) +
sizeof(HLSL::PBRMaterialTextureAttribs) * m_NumShaderTextureAttribs +
sizeof(float4);

CreateUniformBuffer(pDevice, PBRPrimitiveAttribsSize, "PBR primitive attribs CB", &m_PBRPrimitiveAttribsCB);
CreateUniformBuffer(pDevice, GetPBRPrimitiveAttribsSize(), "PBR primitive attribs CB", &m_PBRPrimitiveAttribsCB);
}
if (m_Settings.MaxJointCount > 0)
{
Expand Down Expand Up @@ -1103,6 +1088,24 @@ void PBR_Renderer::SetInternalShaderParameters(HLSL::PBRRendererShaderParameters
Renderer.PrefilteredCubeMipLevels = m_Settings.EnableIBL ? static_cast<float>(m_pPrefilteredEnvMapSRV->GetTexture()->GetDesc().MipLevels) : 0.f;
}

Uint32 PBR_Renderer::GetPBRPrimitiveAttribsSize() const
{
//struct PBRPrimitiveAttribs
//{
// GLTFNodeShaderTransforms Transforms;
// struct PBRMaterialShaderInfo
// {
// PBRMaterialBasicAttribs Basic;
// PBRMaterialTextureAttribs Textures[PBR_NUM_TEXTURE_ATTRIBUTES];
// } Material;
// float4 CustomData;
//};
return (sizeof(HLSL::GLTFNodeShaderTransforms) +
sizeof(HLSL::PBRMaterialBasicAttribs) +
sizeof(HLSL::PBRMaterialTextureAttribs) * m_NumShaderTextureAttribs +
sizeof(float4));
}

void* PBR_Renderer::WritePBRPrimitiveShaderAttribs(void* pDstShaderAttribs,
const float4x4& NodeMatrix,
Uint32 JointCount,
Expand Down
Loading

0 comments on commit 44aef33

Please sign in to comment.