Skip to content

Commit

Permalink
Hydrogent: enabled vertex color packing
Browse files Browse the repository at this point in the history
  • Loading branch information
TheMostDiligent committed Jan 18, 2025
1 parent 95c06a3 commit 398582b
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 20 deletions.
3 changes: 3 additions & 0 deletions Hydrogent/include/HnMeshUtils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,9 @@ class HnMeshUtils final
pxr::GfVec3f& Scale,
pxr::GfVec3f& Bias);

/// Packs float3 vertex colors into 32-bit unsigned integers.
static pxr::VtValue PackVertexColors(const pxr::SdfPath& MeshId, const pxr::VtValue& Colors);

private:
template <typename HandleFaceType>
void ProcessFaces(HandleFaceType&& HandleFace) const;
Expand Down
9 changes: 6 additions & 3 deletions Hydrogent/interface/HnRenderDelegate.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2023-2024 Diligent Graphics LLC
* Copyright 2023-2025 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.
Expand Down Expand Up @@ -181,12 +181,15 @@ class HnRenderDelegate final : public pxr::HdRenderDelegate
/// has no effect and texture loading will be synchronous.
bool AsyncTextureLoading = false;

/// Whether to pack vertex normals into a 32-bit uint.
/// Whether to pack float3 vertex normals into a 32-bit uint.
bool PackVertexNormals = false;

/// Whether to pack vertex positions into two 32-bit uints.
/// Whether to pack float3 vertex positions into two 32-bit uints.
bool PackVertexPositions = false;

/// Whether to pack float3 vertex colors into a 32-bit uint.
bool PackVertexColors = false;

/// When shadows are enabled, the size of the PCF kernel.
/// Allowed values are 2, 3, 5, 7.
Uint32 PCFKernelSize = 3;
Expand Down
3 changes: 2 additions & 1 deletion Hydrogent/src/HnGeometryPool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,8 @@ class HnGeometryPool::VertexData final : public GeometryPoolData
}
else if (SourceName == pxr::HdTokens->displayColor)
{
VERIFY(ElementType.type == pxr::HdTypeFloatVec3 && ElementType.count == 1, "Unexpected vertex color element type");
VERIFY((ElementType.type == pxr::HdTypeFloatVec3 || ElementType.type == pxr::HdTypeInt32) && ElementType.count == 1,
"Unexpected vertex color element type");
}
else if (SourceName == HnTokens->joints)
{
Expand Down
14 changes: 12 additions & 2 deletions Hydrogent/src/HnMesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -335,13 +335,15 @@ static size_t GetPrimvarElementSize(const HnRenderDelegate* RenderDelegate, cons
Role == pxr::HdPrimvarSchemaTokens->normal)
{
return RenderDelegate->GetUSDRenderer()->GetSettings().PackVertexNormals ?
sizeof(uint) : // Normals are packed into a single uint
sizeof(Uint32) : // Normals are packed into a single uint
sizeof(float3);
}
else if (Name == pxr::HdTokens->displayColor ||
Role == pxr::HdPrimvarSchemaTokens->color)
{
return sizeof(float3);
return RenderDelegate->GetUSDRenderer()->GetSettings().PackVertexColors ?
sizeof(Uint32) :
sizeof(float3);
}
else if (Role == pxr::HdPrimvarSchemaTokens->textureCoordinate)
{
Expand Down Expand Up @@ -640,6 +642,14 @@ void HnMesh::PreprocessPrimvar(HnRenderDelegate* RenderDelegate, const pxr::TfTo
Primvar = HnMeshUtils::PackVertexNormals(GetId(), Primvar);
}
}
else if (Name == pxr::HdTokens->displayColor)
{
VERIFY_EXPR(RenderDelegate != nullptr);
if (RenderDelegate != nullptr && RenderDelegate->GetUSDRenderer()->GetSettings().PackVertexColors)
{
Primvar = HnMeshUtils::PackVertexColors(GetId(), Primvar);
}
}
}

bool HnMesh::AddStagingBufferSourceForPrimvar(HnRenderDelegate* RenderDelegate,
Expand Down
20 changes: 20 additions & 0 deletions Hydrogent/src/HnMeshUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include "AdvancedMath.hpp"
#include "GfTypeConversions.hpp"
#include "PBR_Renderer.hpp"
#include "BasicMath.hpp"

#include "pxr/base/gf/vec2i.h"
#include "pxr/base/gf/vec3i.h"
Expand Down Expand Up @@ -524,6 +525,25 @@ pxr::VtValue HnMeshUtils::PackVertexPositions(const pxr::SdfPath& MeshId,
return pxr::VtValue::Take(PackedPositions);
}

pxr::VtValue HnMeshUtils::PackVertexColors(const pxr::SdfPath& MeshId, const pxr::VtValue& Colors)
{
if (!Colors.IsHolding<pxr::VtVec3fArray>())
{
LOG_ERROR_MESSAGE("Failed to pack vertex colors for mesh '", MeshId.GetString(), "': ", Colors.GetTypeName(), " is not supported");
return {};
}

const pxr::VtVec3fArray& ColorsArray = Colors.UncheckedGet<pxr::VtVec3fArray>();
pxr::VtIntArray PackedColors(ColorsArray.size());
Uint32* pPackedColors = reinterpret_cast<Uint32*>(PackedColors.data());
for (size_t i = 0; i < ColorsArray.size(); ++i)
{
const pxr::GfVec3f& Color = ColorsArray[i];
pPackedColors[i] = F4Color_To_RGBA8Unorm(float4{Color[0], Color[1], Color[2], 1.f});
}
return pxr::VtValue::Take(PackedColors);
}

} // namespace USD

} // namespace Diligent
38 changes: 24 additions & 14 deletions Hydrogent/src/HnRenderDelegate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,8 @@ static std::shared_ptr<USD_Renderer> CreateUSDRenderer(const HnRenderDelegate::C
USD_Renderer::VERTEX_POS_PACK_MODE_64_BIT :
USD_Renderer::VERTEX_POS_PACK_MODE_NONE;

USDRendererCI.PackVertexColors = RenderDelegateCI.PackVertexColors;

const RenderDeviceInfo& DeviceInfo = RenderDelegateCI.pDevice->GetDeviceInfo();
// There is a major performance degradation when using row-major matrices
// on Safari/WebGL, so use column-major matrices on OpenGL.
Expand Down Expand Up @@ -261,23 +263,31 @@ static std::shared_ptr<USD_Renderer> CreateUSDRenderer(const HnRenderDelegate::C
}

// clang-format off
constexpr LayoutElement NormalInput {USD_Renderer::VERTEX_ATTRIB_ID_NORMAL, HnRenderPass::VERTEX_BUFFER_SLOT_NORMALS, 3, VT_FLOAT32}; // float3 Normal : ATTRIB1;
constexpr LayoutElement NormalInputPacked{USD_Renderer::VERTEX_ATTRIB_ID_NORMAL, HnRenderPass::VERTEX_BUFFER_SLOT_NORMALS, 1, VT_UINT32, false}; // uint Normal : ATTRIB1;
constexpr LayoutElement PosInput {USD_Renderer::VERTEX_ATTRIB_ID_POSITION, HnRenderPass::VERTEX_BUFFER_SLOT_POSITIONS, 3, VT_FLOAT32}; // float3 Pos : ATTRIB0;
constexpr LayoutElement PosInputPacked64 {USD_Renderer::VERTEX_ATTRIB_ID_POSITION, HnRenderPass::VERTEX_BUFFER_SLOT_POSITIONS, 2, VT_UINT32, false}; // uint2 Pos : ATTRIB0;
// clang-format om
constexpr LayoutElement PosInputF3 {USD_Renderer::VERTEX_ATTRIB_ID_POSITION, HnRenderPass::VERTEX_BUFFER_SLOT_POSITIONS, 3, VT_FLOAT32}; // float3 Pos : ATTRIB0;
constexpr LayoutElement PosInputPacked64 {USD_Renderer::VERTEX_ATTRIB_ID_POSITION, HnRenderPass::VERTEX_BUFFER_SLOT_POSITIONS, 2, VT_UINT32, false}; // uint2 Pos : ATTRIB0;
constexpr LayoutElement NormalInputF3 {USD_Renderer::VERTEX_ATTRIB_ID_NORMAL, HnRenderPass::VERTEX_BUFFER_SLOT_NORMALS, 3, VT_FLOAT32}; // float3 Normal : ATTRIB1;
constexpr LayoutElement NormalInputPacked{USD_Renderer::VERTEX_ATTRIB_ID_NORMAL, HnRenderPass::VERTEX_BUFFER_SLOT_NORMALS, 1, VT_UINT32, false}; // uint Normal : ATTRIB1;
constexpr LayoutElement TexCoord0Input {USD_Renderer::VERTEX_ATTRIB_ID_TEXCOORD0, HnRenderPass::VERTEX_BUFFER_SLOT_TEX_COORDS0, 2, VT_FLOAT32}; // float2 UV0 : ATTRIB2;
constexpr LayoutElement TexCoord1Input {USD_Renderer::VERTEX_ATTRIB_ID_TEXCOORD1, HnRenderPass::VERTEX_BUFFER_SLOT_TEX_COORDS1, 2, VT_FLOAT32}; // float2 UV1 : ATTRIB3;
constexpr LayoutElement ColorInputF3 {USD_Renderer::VERTEX_ATTRIB_ID_COLOR, HnRenderPass::VERTEX_BUFFER_SLOT_VERTEX_COLORS, 3, VT_FLOAT32}; // float3 Color : ATTRIB6;
constexpr LayoutElement ColorInputPacked {USD_Renderer::VERTEX_ATTRIB_ID_COLOR, HnRenderPass::VERTEX_BUFFER_SLOT_VERTEX_COLORS, 4, VT_UINT8, true}; // float4 Color : ATTRIB6;
constexpr LayoutElement JointsInput {USD_Renderer::VERTEX_ATTRIB_ID_JOINTS, HnRenderPass::VERTEX_BUFFER_SLOT_VERTEX_JOINTS, 4, VT_FLOAT32}; // float4 Joint0 : ATTRIB4;
constexpr LayoutElement WeightsInput {USD_Renderer::VERTEX_ATTRIB_ID_WEIGHTS, HnRenderPass::VERTEX_BUFFER_SLOT_VERTEX_JOINTS, 4, VT_FLOAT32}; // float4 Weight0 : ATTRIB5;
// clang-format on

const LayoutElement& PosInput = USDRendererCI.VertexPosPackMode == USD_Renderer::VERTEX_POS_PACK_MODE_64_BIT ? PosInputPacked64 : PosInputF3;
const LayoutElement& NormalInput = USDRendererCI.PackVertexNormals ? NormalInputPacked : NormalInputF3;
const LayoutElement& ColorInput = USDRendererCI.PackVertexColors ? ColorInputPacked : ColorInputF3;

const LayoutElement Inputs[] =
{
// clang-format off
USDRendererCI.VertexPosPackMode == USD_Renderer::VERTEX_POS_PACK_MODE_64_BIT ? PosInputPacked64 : PosInput,
USDRendererCI.PackVertexNormals ? NormalInputPacked : NormalInput,
{USD_Renderer::VERTEX_ATTRIB_ID_TEXCOORD0, HnRenderPass::VERTEX_BUFFER_SLOT_TEX_COORDS0, 2, VT_FLOAT32}, // float2 UV0 : ATTRIB2;
{USD_Renderer::VERTEX_ATTRIB_ID_TEXCOORD1, HnRenderPass::VERTEX_BUFFER_SLOT_TEX_COORDS1, 2, VT_FLOAT32}, // float2 UV1 : ATTRIB3;
{USD_Renderer::VERTEX_ATTRIB_ID_COLOR, HnRenderPass::VERTEX_BUFFER_SLOT_VERTEX_COLORS, 3, VT_FLOAT32}, // float3 Color : ATTRIB6;
{USD_Renderer::VERTEX_ATTRIB_ID_JOINTS, HnRenderPass::VERTEX_BUFFER_SLOT_VERTEX_JOINTS, 4, VT_FLOAT32}, // float4 Joint0 : ATTRIB4;
{USD_Renderer::VERTEX_ATTRIB_ID_WEIGHTS, HnRenderPass::VERTEX_BUFFER_SLOT_VERTEX_JOINTS, 4, VT_FLOAT32}, // float4 Weight0 : ATTRIB5;
// clang-format on
PosInput,
NormalInput,
TexCoord0Input,
TexCoord1Input,
ColorInput,
JointsInput,
WeightsInput,
};

if (DeviceInfo.IsVulkanDevice() ||
Expand Down

0 comments on commit 398582b

Please sign in to comment.