Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[hdEmbree] add distant light support #9

Open
wants to merge 1 commit into
base: pr/hdEmbree-pbrUtils
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions pxr/imaging/plugin/hdEmbree/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ pxr_plugin(hdEmbree
debugCodes
implicitSurfaceSceneIndexPlugin

PRIVATE_HEADERS
pxrPbrt/pbrtUtils.h

RESOURCE_FILES
plugInfo.json

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 @@ -97,6 +97,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 @@ -180,6 +182,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 @@ -449,6 +450,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 @@ -615,6 +661,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