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 light texture support #5

Open
wants to merge 1 commit into
base: pr/hdEmbree-inputs-diffuse
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
56 changes: 56 additions & 0 deletions pxr/imaging/plugin/hdEmbree/light.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,61 @@
#include <sstream>
#include <vector>

namespace {

PXR_NAMESPACE_USING_DIRECTIVE

HdEmbree_LightTexture
_LoadLightTexture(std::string const& path)
{
if (path.empty()) {
return HdEmbree_LightTexture();
}

HioImageSharedPtr img = HioImage::OpenForReading(path);
if (!img) {
return HdEmbree_LightTexture();
}

int width = img->GetWidth();
int height = img->GetHeight();

std::vector<GfVec3f> pixels(width * height * 3.0f);

HioImage::StorageSpec storage;
storage.width = width;
storage.height = height;
storage.depth = 1;
storage.format = HioFormatFloat32Vec3;
storage.data = &pixels.front();

if (img->Read(storage)) {
return {std::move(pixels), width, height};
}
TF_WARN("Could not read image %s", path.c_str());
return { std::vector<GfVec3f>(), 0, 0 };
}


void
_SyncLightTexture(const SdfPath& id, HdEmbree_LightData& light, HdSceneDelegate *sceneDelegate)
{
std::string path;
if (VtValue textureValue = sceneDelegate->GetLightParamValue(
id, HdLightTokens->textureFile);
textureValue.IsHolding<SdfAssetPath>()) {
SdfAssetPath texturePath =
textureValue.UncheckedGet<SdfAssetPath>();
path = texturePath.GetResolvedPath();
if (path.empty()) {
path = texturePath.GetAssetPath();
}
}
light.texture = _LoadLightTexture(path);
}


} // anonymous namespace
PXR_NAMESPACE_OPEN_SCOPE

HdEmbree_Light::HdEmbree_Light(SdfPath const& id, TfToken const& lightType)
Expand Down Expand Up @@ -116,6 +171,7 @@ HdEmbree_Light::Sync(HdSceneDelegate *sceneDelegate,
sceneDelegate->GetLightParamValue(id, HdLightTokens->height)
.Get<float>(),
};
_SyncLightTexture(id, _lightData, sceneDelegate);
} else if constexpr (std::is_same_v<T, HdEmbree_Sphere>) {
typedLight = HdEmbree_Sphere{
sceneDelegate->GetLightParamValue(id, HdLightTokens->radius)
Expand Down
8 changes: 8 additions & 0 deletions pxr/imaging/plugin/hdEmbree/light.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,13 @@ using HdEmbree_LightVariant = std::variant<
HdEmbree_Rect,
HdEmbree_Sphere>;

struct HdEmbree_LightTexture
{
std::vector<GfVec3f> pixels;
int width = 0;
int height = 0;
};

struct HdEmbree_Shaping
{
GfVec3f focusTint;
Expand All @@ -67,6 +74,7 @@ struct HdEmbree_LightData
GfMatrix3f normalXformLightToWorld;
GfMatrix4f xformWorldToLight;
GfVec3f color;
HdEmbree_LightTexture texture;
float intensity = 1.0f;
float diffuse = 1.0f;
float exposure = 0.0f;
Expand Down
19 changes: 19 additions & 0 deletions pxr/imaging/plugin/hdEmbree/renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,19 @@ struct _LightSample {
float invPdfW;
};

GfVec3f
_SampleLightTexture(HdEmbree_LightTexture const& texture, float s, float t)
{
if (texture.pixels.empty()) {
return GfVec3f(0.0f);
}

int x = float(texture.width) * s;
int y = float(texture.height) * t;

return texture.pixels.at(y*texture.width + x);
}

_ShapeSample
_SampleRect(GfMatrix4f const& xf, GfMatrix3f const& normalXform, float width,
float height, float u1, float u2)
Expand Down Expand Up @@ -443,6 +456,12 @@ _EvalAreaLight(HdEmbree_LightData const& light, _ShapeSample const& ss,
_EvalLightBasic(light)
: GfVec3f(0.0f);

// Multiply by the texture, if there is one
if (!light.texture.pixels.empty()) {
Le = GfCompMult(Le, _SampleLightTexture(light.texture, ss.uv[0],
1.0f - ss.uv[1]));
}

// If normalize is enabled, we need to divide the luminance by the surface
// area of the light, which for an area light is equivalent to multiplying
// by the area pdf, which is itself the reciprocal of the surface area
Expand Down