18#include <pxr/imaging/hd/sceneDelegate.h>
19#include <pxr/usd/sdf/assetPath.h>
32 : HdLight(sprimId), _lightType(lightType)
40 return DirtyBits::DirtyTransform | DirtyBits::DirtyParams;
44 HdRenderParam *renderParam,
45 HdDirtyBits *dirtyBits)
47 if (*dirtyBits == DirtyBits::Clean) {
51 Initialize(renderParam);
56 const SdfPath &
id = GetId();
58 if (*dirtyBits & DirtyBits::DirtyTransform) {
59 const float metersPerUnit =
63#if PXR_VERSION >= 2011
67 sceneDelegate->GetLightParamValue(
id, HdTokens->transform)
70 _object->set_tfm(tfm);
73 if (*dirtyBits & DirtyBits::DirtyParams) {
76 value = sceneDelegate->GetLightParamValue(
id, HdLightTokens->color);
77 if (!
value.IsEmpty()) {
78 const auto color =
value.Get<GfVec3f>();
79 strength =
make_float3(color[0], color[1], color[2]);
82 value = sceneDelegate->GetLightParamValue(
id, HdLightTokens->exposure);
83 if (!
value.IsEmpty()) {
87 value = sceneDelegate->GetLightParamValue(
id, HdLightTokens->intensity);
88 if (!
value.IsEmpty()) {
89 strength *=
value.Get<
float>();
92 if (_lightType == HdPrimTypeTokens->distantLight) {
101 value = sceneDelegate->GetLightParamValue(
id, HdLightTokens->normalize);
102 _light->set_normalize(
value.IsHolding<
bool>() &&
value.UncheckedGet<
bool>());
104 value = sceneDelegate->GetLightParamValue(
id, _tokens->visibleInPrimaryRay);
105 if (!
value.IsEmpty()) {
106 if (
value.Get<
bool>()) {
110 _object->set_visibility(_object->get_visibility() & ~PATH_RAY_CAMERA);
114 value = sceneDelegate->GetLightParamValue(
id, HdLightTokens->shadowEnable);
115 if (!
value.IsEmpty()) {
116 _light->set_cast_shadow(
value.Get<
bool>());
119 if (_lightType == HdPrimTypeTokens->distantLight) {
120 value = sceneDelegate->GetLightParamValue(
id, HdLightTokens->angle);
121 if (!
value.IsEmpty()) {
122 _light->set_angle(GfDegreesToRadians(
value.Get<
float>()));
125 else if (_lightType == HdPrimTypeTokens->diskLight) {
126 value = sceneDelegate->GetLightParamValue(
id, HdLightTokens->radius);
127 if (!
value.IsEmpty()) {
128 const float size =
value.Get<
float>() * 2.0f;
129 _light->set_sizeu(
size);
130 _light->set_sizev(
size);
133 else if (_lightType == HdPrimTypeTokens->rectLight) {
134 value = sceneDelegate->GetLightParamValue(
id, HdLightTokens->width);
135 if (!
value.IsEmpty()) {
136 _light->set_sizeu(
value.Get<
float>());
139 value = sceneDelegate->GetLightParamValue(
id, HdLightTokens->height);
140 if (!
value.IsEmpty()) {
141 _light->set_sizev(
value.Get<
float>());
144 else if (_lightType == HdPrimTypeTokens->sphereLight) {
145 value = sceneDelegate->GetLightParamValue(
id, TfToken(
"treatAsPoint"));
147 _light->set_size(0.0f);
150 value = sceneDelegate->GetLightParamValue(
id, HdLightTokens->radius);
151 if (!
value.IsEmpty()) {
152 _light->set_size(
value.Get<
float>());
156 bool shaping =
false;
158 value = sceneDelegate->GetLightParamValue(
id, HdLightTokens->shapingConeAngle);
159 if (!
value.IsEmpty()) {
160 _light->set_spot_angle(GfDegreesToRadians(
value.Get<
float>()) * 2.0f);
164 value = sceneDelegate->GetLightParamValue(
id, HdLightTokens->shapingConeSoftness);
165 if (!
value.IsEmpty()) {
166 _light->set_spot_smooth(
value.Get<
float>());
173 const bool visible = sceneDelegate->GetVisible(
id);
180 _light->set_strength(strength);
181 _light->set_is_enabled(visible);
183 PopulateShaderGraph(sceneDelegate);
186 else if (_object->tfm_is_modified() && (_lightType == HdPrimTypeTokens->domeLight ||
187 _light->get_shader()->has_surface_spatial_varying))
189 PopulateShaderGraph(sceneDelegate);
192 if (_light->is_modified()) {
193 _light->tag_update(
lock.scene);
196 *dirtyBits = DirtyBits::Clean;
199void HdCyclesLight::PopulateShaderGraph(HdSceneDelegate *sceneDelegate)
201 unique_ptr<ShaderGraph>
graph = make_unique<ShaderGraph>();
204 if (_lightType == HdPrimTypeTokens->domeLight) {
207 bgNode->set_color(_light->get_strength());
209 graph->connect(bgNode->
output(
"Background"),
graph->output()->input(
"Surface"));
213 else if (sceneDelegate !=
nullptr) {
215 const SdfPath &
id = GetId();
216 value = sceneDelegate->GetLightParamValue(
id, TfToken(
"falloff"));
217 if (!
value.IsEmpty()) {
218 const std::string strVal =
value.Get<
string>();
219 if (strVal ==
"Constant" || strVal ==
"Linear" || strVal ==
"Quadratic") {
221 lfoNode->set_strength(1.f);
222 graph->connect(lfoNode->
output(strVal.c_str()),
graph->output()->input(
"Surface"));
223 outputNode = lfoNode;
228 if (outputNode ==
nullptr) {
231 emissionNode->set_strength(1.0f);
233 graph->connect(emissionNode->
output(
"Emission"),
graph->output()->input(
"Surface"));
235 outputNode = emissionNode;
239 const SdfPath &
id = GetId();
240 bool hasSpatialVarying =
false;
241 bool hasColorTemperature =
false;
243 if (sceneDelegate !=
nullptr) {
244 value = sceneDelegate->GetLightParamValue(
id, HdLightTokens->enableColorTemperature);
245 const bool enableColorTemperature =
value.IsHolding<
bool>() &&
value.UncheckedGet<
bool>();
247 if (enableColorTemperature) {
248 value = sceneDelegate->GetLightParamValue(
id, HdLightTokens->colorTemperature);
249 if (
value.IsHolding<
float>()) {
251 blackbodyNode->set_temperature(
value.UncheckedGet<
float>());
253 if (_lightType == HdPrimTypeTokens->domeLight) {
256 mathNode->set_vector2(_light->get_strength());
265 hasColorTemperature =
true;
269 value = sceneDelegate->GetLightParamValue(
id, HdLightTokens->shapingIesFile);
270 if (
value.IsHolding<SdfAssetPath>()) {
271 std::string filename =
value.UncheckedGet<SdfAssetPath>().GetResolvedPath();
272 if (filename.empty()) {
273 filename =
value.UncheckedGet<SdfAssetPath>().GetAssetPath();
277 coordNode->set_ob_tfm(_object->get_tfm());
278 coordNode->set_use_transform(
true);
281 iesNode->set_filename(ustring(filename));
286 hasSpatialVarying =
true;
289 value = sceneDelegate->GetLightParamValue(
id, HdLightTokens->textureFile);
290 if (
value.IsHolding<SdfAssetPath>()) {
291 std::string filename =
value.UncheckedGet<SdfAssetPath>().GetResolvedPath();
292 if (filename.empty()) {
293 filename =
value.UncheckedGet<SdfAssetPath>().GetAssetPath();
297 if (_lightType == HdPrimTypeTokens->domeLight) {
302 coordNode->set_ob_tfm(tfm);
303 coordNode->set_use_transform(
true);
310 hasSpatialVarying =
true;
316 static_cast<ImageTextureNode *
>(textureNode)->set_filename(ustring(filename));
318 graph->connect(coordNode->
output(
"Parametric"), textureNode->
input(
"Vector"));
321 if (hasColorTemperature) {
327 graph->connect(outputNodeInput->
link, mathNode->
input(
"Vector2"));
329 graph->connect(mathNode->
output(
"Vector"), outputNodeInput);
331 else if (_lightType == HdPrimTypeTokens->domeLight) {
334 mathNode->set_vector2(_light->get_strength());
345 Shader *
const shader = _light->get_shader();
359 const bool keep_nodes =
static_cast<const HdCyclesSession *
>(renderParam)->keep_nodes;
362 lock.scene->delete_node(_light);
363 lock.scene->delete_node(_object);
370void HdCyclesLight::Initialize(HdRenderParam *renderParam)
379 _object->name = GetId().GetString();
381 _light =
lock.scene->create_node<
Light>();
382 _light->name = GetId().GetString();
383 _object->set_geometry(_light);
387 if (_lightType == HdPrimTypeTokens->domeLight) {
390 else if (_lightType == HdPrimTypeTokens->distantLight) {
393 else if (_lightType == HdPrimTypeTokens->diskLight) {
395 _light->set_ellipse(
true);
396 _light->set_size(1.0f);
398 else if (_lightType == HdPrimTypeTokens->rectLight) {
400 _light->set_ellipse(
false);
401 _light->set_size(1.0f);
403 else if (_lightType == HdPrimTypeTokens->sphereLight) {
405 _light->set_size(1.0f);
408 _light->set_use_mis(
true);
414 _light->set_used_shaders(used_shaders);
417 PopulateShaderGraph(
nullptr);
@ NODE_VECTOR_MATH_MULTIPLY
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
void Finalize(PXR_NS::HdRenderParam *renderParam) override
void Sync(PXR_NS::HdSceneDelegate *sceneDelegate, PXR_NS::HdRenderParam *renderParam, PXR_NS::HdDirtyBits *dirtyBits) override
~HdCyclesLight() override
HdCyclesLight(const PXR_NS::SdfPath &sprimId, const PXR_NS::TfToken &lightType)
PXR_NS::HdDirtyBits GetInitialDirtyBitsMask() const override
ShaderInput * input(const char *name)
ShaderOutput * output(const char *name)
bool has_surface_spatial_varying
void set_graph(unique_ptr< ShaderGraph > &&graph)
void tag_update(Scene *scene)
void push_back_slow(const T &t)
static uint hash_string(const char *str)
ccl_device_inline uint hash_uint2(const uint kx, const uint ky)
HDCYCLES_NAMESPACE_OPEN_SCOPE Transform convert_transform(const GfMatrix4d &matrix)
#define HDCYCLES_NAMESPACE_CLOSE_SCOPE
TF_DEFINE_PRIVATE_TOKENS(_tokens,(visibleInPrimaryRay))
HDCYCLES_NAMESPACE_OPEN_SCOPE Transform convert_transform(const GfMatrix4d &matrix)
@ PATH_RAY_ALL_VISIBILITY
ccl_device_inline float3 one_float3()
CCL_NAMESPACE_BEGIN ccl_device_inline float3 zero_float3()