Skip to content

Commit

Permalink
Hydrogent: load environment map from dome light (close #199)
Browse files Browse the repository at this point in the history
  • Loading branch information
TheMostDiligent committed May 14, 2024
1 parent e35e312 commit b383065
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 5 deletions.
8 changes: 8 additions & 0 deletions Hydrogent/interface/HnLight.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ struct PBRShadowMapInfo;
namespace USD
{

class HnRenderDelegate;

/// Light implementation in Hydrogent.
class HnLight final : public pxr::HdLight
{
Expand Down Expand Up @@ -85,11 +87,14 @@ class HnLight final : public pxr::HdLight
bool IsShadowMapDirty() const { return m_IsShadowMapDirty; }
void SetShadowMapDirty(bool IsDirty) { m_IsShadowMapDirty = IsDirty; }

void PrepareGPUResources(HnRenderDelegate& RenderDelegate);

private:
HnLight(const pxr::SdfPath& Id, const pxr::TfToken& TypeId);

bool ApproximateAreaLight(pxr::HdSceneDelegate& SceneDelegate, float MetersPerUnit);
void ComputeDirectLightProjMatrix(pxr::HdSceneDelegate& SceneDelegate);
void PrecomputeIBLCubemaps(HnRenderDelegate& RenderDelegate);

private:
const pxr::TfToken m_TypeId;
Expand All @@ -105,6 +110,9 @@ class HnLight final : public pxr::HdLight
float4x4 m_ViewProjMatrix;
BoundBox m_SceneBounds;

std::string m_TexturePath;
std::string m_PrecomputedEnvMapPath;

Int32 m_FrameAttribsIndex = 0;
Uint32 m_ShadowMapResolution = 1024;
RefCntAutoPtr<ITextureAtlasSuballocation> m_ShadowMapSuballocation;
Expand Down
1 change: 1 addition & 0 deletions Hydrogent/interface/HnRenderDelegate.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,7 @@ class HnRenderDelegate final : public pxr::HdRenderDelegate
Uint32 m_MeshResourcesVersion = ~0u;
Uint32 m_MaterialResourcesVersion = ~0u;
Uint32 m_ShadowAtlasVersion = ~0u;
Uint32 m_LightResourcesVersion = ~0u;
};

} // namespace USD
Expand Down
71 changes: 71 additions & 0 deletions Hydrogent/src/HnLight.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,10 @@
#include "HnRenderDelegate.hpp"
#include "HnShadowMapManager.hpp"
#include "HnTokens.hpp"
#include "HnTextureUtils.hpp"

#include <array>
#include <vector>

#include "pxr/imaging/hd/sceneDelegate.h"

Expand Down Expand Up @@ -353,6 +355,20 @@ bool HnLight::ApproximateAreaLight(pxr::HdSceneDelegate& SceneDelegate, float Me
return ParamsDirty;
}

static pxr::SdfAssetPath GetTextureFile(pxr::HdSceneDelegate& SceneDelegate, const pxr::SdfPath& Id)
{
pxr::SdfAssetPath FilePath;

const pxr::VtValue TextureFileVal = SceneDelegate.GetLightParamValue(Id, pxr::HdLightTokens->textureFile);
LOG_INFO_MESSAGE("TextureFileVal type: ", TextureFileVal.GetTypeName());
if (TextureFileVal.IsHolding<pxr::SdfAssetPath>())
{
FilePath = TextureFileVal.Get<pxr::SdfAssetPath>();
}

return FilePath;
}

void HnLight::ComputeDirectLightProjMatrix(pxr::HdSceneDelegate& SceneDelegate)
{
pxr::HdRenderIndex& RenderIndex = SceneDelegate.GetRenderIndex();
Expand Down Expand Up @@ -501,6 +517,10 @@ void HnLight::Sync(pxr::HdSceneDelegate* SceneDelegate,
LightDirty = true;
}
}
else if (m_TypeId == pxr::HdPrimTypeTokens->domeLight)
{
m_TexturePath = GetTextureFile(*SceneDelegate, Id).GetAssetPath();
}
else
{
LOG_ERROR_MESSAGE("Unsupported light type: ", m_TypeId);
Expand Down Expand Up @@ -603,6 +623,57 @@ void HnLight::Sync(pxr::HdSceneDelegate* SceneDelegate,
*DirtyBits = HdLight::Clean;
}

void HnLight::PrecomputeIBLCubemaps(HnRenderDelegate& RenderDelegate)
{
VERIFY_EXPR(m_TypeId == pxr::HdPrimTypeTokens->domeLight && m_TexturePath != m_PrecomputedEnvMapPath);

RefCntAutoPtr<ITexture> pEnvMap;
if (!m_TexturePath.empty())
{
TextureLoadInfo LoadInfo;
LoadInfo.Name = m_TexturePath.c_str();
if (RefCntAutoPtr<ITextureLoader> pLoader = CreateTextureLoaderFromSdfPath(m_TexturePath.c_str(), LoadInfo))
{
pLoader->CreateTexture(RenderDelegate.GetDevice(), &pEnvMap);
}
}

if (!pEnvMap)
{
// Create uniform white environment map
TextureDesc EnvMapDesc;
EnvMapDesc.Name = "Default Env Map";
EnvMapDesc.Type = RESOURCE_DIM_TEX_2D;
EnvMapDesc.Format = TEX_FORMAT_RGBA32_FLOAT;
EnvMapDesc.Width = 32;
EnvMapDesc.Height = 32;
EnvMapDesc.BindFlags = BIND_SHADER_RESOURCE;
EnvMapDesc.MipLevels = 1;
EnvMapDesc.Usage = USAGE_IMMUTABLE;

std::vector<float4> EnvMapData(EnvMapDesc.Width * EnvMapDesc.Height, float4{1});
TextureSubResData Mip0Data{EnvMapData.data(), EnvMapDesc.Width * sizeof(float4)};
TextureData InitData = {&Mip0Data, 1};

RenderDelegate.GetDevice()->CreateTexture(EnvMapDesc, &InitData, &pEnvMap);
}

RenderDelegate.GetUSDRenderer()->PrecomputeCubemaps(RenderDelegate.GetDeviceContext(), pEnvMap->GetDefaultView(TEXTURE_VIEW_SHADER_RESOURCE));

m_PrecomputedEnvMapPath = m_TexturePath;
}

void HnLight::PrepareGPUResources(HnRenderDelegate& RenderDelegate)
{
if (m_TypeId == pxr::HdPrimTypeTokens->domeLight)
{
if (m_TexturePath != m_PrecomputedEnvMapPath)
{
PrecomputeIBLCubemaps(RenderDelegate);
}
}
}

} // namespace USD

} // namespace Diligent
20 changes: 18 additions & 2 deletions Hydrogent/src/HnRenderDelegate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ const pxr::TfTokenVector HnRenderDelegate::SupportedSPrimTypes = {
pxr::HdPrimTypeTokens->distantLight,
pxr::HdPrimTypeTokens->rectLight,
pxr::HdPrimTypeTokens->sphereLight,
pxr::HdPrimTypeTokens->domeLight,
};

const pxr::TfTokenVector HnRenderDelegate::SupportedBPrimTypes = {
Expand Down Expand Up @@ -406,7 +407,8 @@ pxr::HdSprim* HnRenderDelegate::CreateSprim(const pxr::TfToken& TypeId,
TypeId == pxr::HdPrimTypeTokens->diskLight ||
TypeId == pxr::HdPrimTypeTokens->distantLight ||
TypeId == pxr::HdPrimTypeTokens->rectLight ||
TypeId == pxr::HdPrimTypeTokens->sphereLight)
TypeId == pxr::HdPrimTypeTokens->sphereLight ||
TypeId == pxr::HdPrimTypeTokens->domeLight)
{
HnLight* Light = HnLight::Create(SPrimId, TypeId);
{
Expand Down Expand Up @@ -440,7 +442,8 @@ pxr::HdSprim* HnRenderDelegate::CreateFallbackSprim(const pxr::TfToken& TypeId)
TypeId == pxr::HdPrimTypeTokens->diskLight ||
TypeId == pxr::HdPrimTypeTokens->distantLight ||
TypeId == pxr::HdPrimTypeTokens->rectLight ||
TypeId == pxr::HdPrimTypeTokens->sphereLight)
TypeId == pxr::HdPrimTypeTokens->sphereLight ||
TypeId == pxr::HdPrimTypeTokens->domeLight)
{
SPrim = nullptr;
}
Expand Down Expand Up @@ -588,6 +591,19 @@ void HnRenderDelegate::CommitResources(pxr::HdChangeTracker* tracker)
}
}

{
const auto LightVersion = m_RenderParam->GetAttribVersion(HnRenderParam::GlobalAttrib::Light);
if (m_LightResourcesVersion != LightVersion)
{
std::lock_guard<std::mutex> Guard{m_LightsMtx};
for (auto* pLight : m_Lights)
{
pLight->PrepareGPUResources(*this);
}
m_LightResourcesVersion = LightVersion;
}
}

{
GLTF::ResourceManager::TransitionResourceStatesInfo TRSInfo;
TRSInfo.VertexBuffers.NewState = RESOURCE_STATE_VERTEX_BUFFER;
Expand Down
10 changes: 7 additions & 3 deletions Hydrogent/src/HnTextureUtils.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2023 Diligent Graphics LLC
* Copyright 2023-2024 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 @@ -38,9 +38,13 @@ namespace USD
RefCntAutoPtr<ITextureLoader> CreateTextureLoaderFromSdfPath(const char* SdfPath,
const TextureLoadInfo& LoadInfo)
{
pxr::ArResolver& Resolver = pxr::ArGetResolver();

pxr::ArResolvedPath ResolvedPath{SdfPath};
std::shared_ptr<pxr::ArAsset> Asset = pxr::ArGetResolver().OpenAsset(ResolvedPath);
pxr::ArResolvedPath ResolvedPath = Resolver.Resolve(SdfPath);
if (ResolvedPath.empty())
return {};

std::shared_ptr<pxr::ArAsset> Asset = Resolver.OpenAsset(ResolvedPath);
if (!Asset)
return {};

Expand Down
6 changes: 6 additions & 0 deletions PBR/src/PBR_Renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -659,6 +659,9 @@ void PBR_Renderer::PrecomputeCubemaps(IDeviceContext* pCtx,
DrawAttribs drawAttrs(4, DRAW_FLAG_VERIFY_ALL);
pCtx->Draw(drawAttrs);
}
// Release reference to the environment map
m_pPrecomputeIrradianceCubeSRB->GetVariableByName(SHADER_TYPE_PIXEL, "g_EnvironmentMap")->Set(nullptr);


pCtx->SetPipelineState(pPrefilterEnvMapPSO);
m_pPrefilterEnvMapSRB->GetVariableByName(SHADER_TYPE_PIXEL, "g_EnvironmentMap")->Set(pEnvironmentMap);
Expand Down Expand Up @@ -691,6 +694,9 @@ void PBR_Renderer::PrecomputeCubemaps(IDeviceContext* pCtx,
pCtx->Draw(drawAttrs);
}
}
// Release reference to the environment map
m_pPrefilterEnvMapSRB->GetVariableByName(SHADER_TYPE_PIXEL, "g_EnvironmentMap")->Set(nullptr);


// clang-format off
StateTransitionDesc Barriers[] =
Expand Down

0 comments on commit b383065

Please sign in to comment.