Skip to content

Commit

Permalink
[hdEmbree] add distant light support
Browse files Browse the repository at this point in the history
  • Loading branch information
pmolodo committed Sep 23, 2024
1 parent 82e3adb commit ab8259e
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 0 deletions.
3 changes: 3 additions & 0 deletions pxr/imaging/plugin/hdEmbree/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ pxr_plugin(hdEmbree
context.h
renderParam.h

PRIVATE_HEADERS
pxrPbrt/pbrtUtils.h

PRIVATE_CLASSES
implicitSurfaceSceneIndexPlugin

Expand Down
8 changes: 8 additions & 0 deletions pxr/imaging/plugin/hdEmbree/light.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ HdEmbree_Light::HdEmbree_Light(SdfPath const& id, TfToken const& lightType)
_lightData.lightVariant = HdEmbree_Cylinder();
} else if (lightType == HdSprimTypeTokens->diskLight) {
_lightData.lightVariant = HdEmbree_Disk();
} else if (lightType == HdSprimTypeTokens->distantLight) {
_lightData.lightVariant = HdEmbree_Distant();
} else if (lightType == HdSprimTypeTokens->domeLight) {
_lightData.lightVariant = HdEmbree_Dome();
} else if (lightType == HdSprimTypeTokens->rectLight) {
Expand Down Expand Up @@ -176,6 +178,12 @@ HdEmbree_Light::Sync(HdSceneDelegate *sceneDelegate,
sceneDelegate->GetLightParamValue(id, HdLightTokens->radius)
.GetWithDefault(0.5f),
};
} else if constexpr (std::is_same_v<T, HdEmbree_Distant>) {
typedLight = HdEmbree_Distant{
float(GfDegreesToRadians(
sceneDelegate->GetLightParamValue(id, HdLightTokens->angle)
.GetWithDefault(0.53f) / 2.0f)),
};
} else if constexpr (std::is_same_v<T, HdEmbree_Dome>) {
typedLight = HdEmbree_Dome{};
_SyncLightTexture(id, _lightData, sceneDelegate);
Expand Down
6 changes: 6 additions & 0 deletions pxr/imaging/plugin/hdEmbree/light.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ struct HdEmbree_Disk
float radius;
};

struct HdEmbree_Distant
{
float halfAngleRadians;
};

// Needed for HdEmbree_LightVariant
struct HdEmbree_Dome
{};
Expand All @@ -54,6 +59,7 @@ using HdEmbree_LightVariant = std::variant<
HdEmbree_UnknownLight,
HdEmbree_Cylinder,
HdEmbree_Disk,
HdEmbree_Distant,
HdEmbree_Dome,
HdEmbree_Rect,
HdEmbree_Sphere>;
Expand Down
3 changes: 3 additions & 0 deletions pxr/imaging/plugin/hdEmbree/renderDelegate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ const TfTokenVector HdEmbreeRenderDelegate::SUPPORTED_SPRIM_TYPES =
HdPrimTypeTokens->extComputation,
HdPrimTypeTokens->cylinderLight,
HdPrimTypeTokens->diskLight,
HdPrimTypeTokens->distantLight,
HdPrimTypeTokens->domeLight,
HdPrimTypeTokens->rectLight,
HdPrimTypeTokens->sphereLight,
Expand Down Expand Up @@ -338,6 +339,7 @@ HdEmbreeRenderDelegate::CreateSprim(TfToken const& typeId,
} else if (typeId == HdPrimTypeTokens->extComputation) {
return new HdExtComputation(sprimId);
} else if (typeId == HdPrimTypeTokens->light ||
typeId == HdPrimTypeTokens->distantLight ||
typeId == HdPrimTypeTokens->diskLight ||
typeId == HdPrimTypeTokens->domeLight ||
typeId == HdPrimTypeTokens->rectLight ||
Expand All @@ -361,6 +363,7 @@ HdEmbreeRenderDelegate::CreateFallbackSprim(TfToken const& typeId)
} else if (typeId == HdPrimTypeTokens->extComputation) {
return new HdExtComputation(SdfPath::EmptyPath());
} else if (typeId == HdPrimTypeTokens->light ||
typeId == HdPrimTypeTokens->distantLight ||
typeId == HdPrimTypeTokens->diskLight ||
typeId == HdPrimTypeTokens->domeLight ||
typeId == HdPrimTypeTokens->rectLight ||
Expand Down
50 changes: 50 additions & 0 deletions pxr/imaging/plugin/hdEmbree/renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "pxr/imaging/plugin/hdEmbree/config.h"
#include "pxr/imaging/plugin/hdEmbree/light.h"
#include "pxr/imaging/plugin/hdEmbree/mesh.h"
#include "pxr/imaging/plugin/hdEmbree/pxrPbrt/pbrtUtils.h"
#include "pxr/imaging/plugin/hdEmbree/renderBuffer.h"

#include "pxr/imaging/hd/perfLog.h"
Expand Down Expand Up @@ -369,6 +370,51 @@ _EvalLightBasic(HdEmbree_LightData const& light)
return Le;
}

_LightSample
_EvalDistantLight(HdEmbree_LightData const& light, GfVec3f const& position,
float u1, float u2)
{
auto const& distant = std::get<HdEmbree_Distant>(light.lightVariant);

GfVec3f Le = _EvalLightBasic(light);

if (distant.halfAngleRadians > 0.0f)
{
if (light.normalize)
{
float sinTheta = sinf(distant.halfAngleRadians);
Le /= _Sqr(sinTheta) * _pi<float>;
}

// There's an implicit double-negation of the wI direction here
GfVec3f localDir = pxr_pbrt::SampleUniformCone(GfVec2f(u1, u2),
distant.halfAngleRadians);
GfVec3f wI = light.xformLightToWorld.TransformDir(localDir);
wI.Normalize();

return _LightSample {
Le,
wI,
std::numeric_limits<float>::max(),
pxr_pbrt::InvUniformConePDF(distant.halfAngleRadians)
};
}
else
{
// delta case, infinite pdf
GfVec3f wI = light.xformLightToWorld.TransformDir(
GfVec3f(0.0f, 0.0f, 1.0f));
wI.Normalize();

return _LightSample {
Le,
wI,
std::numeric_limits<float>::max(),
1.0f,
};
}
}

_LightSample
_EvalAreaLight(HdEmbree_LightData const& light, _ShapeSample const& ss,
GfVec3f const& position)
Expand Down Expand Up @@ -535,6 +581,10 @@ class _LightSampler {
return _EvalDomeLight(_lightData, _normal, _u1, _u2);
}

_LightSample operator()(HdEmbree_Distant const& distant) {
return _EvalDistantLight(_lightData, _hitPosition, _u1, _u2);
}

private:
_LightSampler(HdEmbree_LightData const& lightData,
GfVec3f const& hitPosition,
Expand Down

0 comments on commit ab8259e

Please sign in to comment.