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 lighting support for IES files #12

Open
wants to merge 1 commit into
base: pr/hdEmbree-pxrIES
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
36 changes: 36 additions & 0 deletions pxr/imaging/plugin/hdEmbree/light.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,42 @@ HdEmbree_Light::Sync(HdSceneDelegate *sceneDelegate,
_lightData.shaping.coneSoftness = value.UncheckedGet<float>();
}

if (const auto value = sceneDelegate->GetLightParamValue(
id, HdLightTokens->shapingIesFile);
value.IsHolding<SdfAssetPath>()) {
SdfAssetPath iesAssetPath = value.UncheckedGet<SdfAssetPath>();
std::string iesPath = iesAssetPath.GetResolvedPath();
if (iesPath.empty()) {
iesPath = iesAssetPath.GetAssetPath();
}

if (!iesPath.empty()) {
std::ifstream in(iesPath);
if (!in.is_open()) {
TF_WARN("could not open ies file %s", iesPath.c_str());
} else {
std::stringstream buffer;
buffer << in.rdbuf();

if (!_lightData.shaping.ies.iesFile.load(buffer.str())) {
TF_WARN("could not load ies file %s", iesPath.c_str());
}
}
}
}

if (const auto value = sceneDelegate->GetLightParamValue(
id, HdLightTokens->shapingIesNormalize);
value.IsHolding<bool>()) {
_lightData.shaping.ies.normalize = value.UncheckedGet<bool>();
}

if (const auto value = sceneDelegate->GetLightParamValue(
id, HdLightTokens->shapingIesAngleScale);
value.IsHolding<float>()) {
_lightData.shaping.ies.angleScale = value.UncheckedGet<float>();
}

_PopulateRtcLight(device, scene);

HdEmbreeRenderer *renderer = embreeRenderParam->GetRenderer();
Expand Down
10 changes: 10 additions & 0 deletions pxr/imaging/plugin/hdEmbree/light.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
#ifndef PXR_IMAGING_PLUGIN_HD_EMBREE_LIGHT_H
#define PXR_IMAGING_PLUGIN_HD_EMBREE_LIGHT_H

#include "pxr/imaging/plugin/hdEmbree/pxrIES/pxrIES.h"

#include "pxr/base/gf/vec3f.h"
#include "pxr/base/gf/matrix3f.h"
#include "pxr/base/gf/matrix4f.h"
Expand Down Expand Up @@ -71,12 +73,20 @@ struct HdEmbree_LightTexture
int height = 0;
};

struct HdEmbree_IES
{
PxrIESFile iesFile;
bool normalize = false;
float angleScale = 0.0f;
};

struct HdEmbree_Shaping
{
GfVec3f focusTint;
float focus = 0.0f;
float coneAngle = 180.0f;
float coneSoftness = 0.0f;
HdEmbree_IES ies;
};

struct HdEmbree_LightData
Expand Down
24 changes: 24 additions & 0 deletions pxr/imaging/plugin/hdEmbree/renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,27 @@ _IntersectAreaLight(HdEmbree_LightData const& light, RTCRayHit const& rayHit)
};
}

float
_EvalIES(HdEmbree_LightData const& light, GfVec3f const& wI)
{
HdEmbree_IES const& ies = light.shaping.ies;

if (!ies.iesFile.valid()) {
// Either none specified or there was an error loading. In either case,
// just ignore
return 1.0f;
}

// emission direction in light space
GfVec3f wE = light.xformWorldToLight.TransformDir(wI).GetNormalized();

float theta = _Theta(wE);
float phi = _Phi(wE);
float norm = ies.normalize ? ies.iesFile.power() : 1.0f;

return ies.iesFile.eval(theta, phi, ies.angleScale) / norm;
}

GfVec3f
_EvalLightBasic(HdEmbree_LightData const& light)
{
Expand Down Expand Up @@ -495,6 +516,9 @@ _EvalAreaLight(HdEmbree_LightData const& light, _ShapeSample const& ss,
const float thetaOffZ = acosf(cosThetaOffZ);
Le *= 1.0f - _Smoothstep(thetaOffZ, GfRange1f(thetaSoft, thetaCone));

// Apply IES
Le *= _EvalIES(light, wI);

return _LightSample {
Le,
wI,
Expand Down