15#include <pxr/imaging/hd/sceneDelegate.h>
16#include <pxr/usd/sdf/assetPath.h>
29 : HdLight(sprimId), _lightType(lightType)
37 return DirtyBits::DirtyTransform | DirtyBits::DirtyParams;
41 HdRenderParam *renderParam,
42 HdDirtyBits *dirtyBits)
44 if (*dirtyBits == DirtyBits::Clean) {
48 Initialize(renderParam);
53 const SdfPath &
id = GetId();
55 if (*dirtyBits & DirtyBits::DirtyTransform) {
56 const float metersPerUnit =
60#if PXR_VERSION >= 2011
64 sceneDelegate->GetLightParamValue(
id, HdTokens->transform)
70 if (*dirtyBits & DirtyBits::DirtyParams) {
73 value = sceneDelegate->GetLightParamValue(
id, HdLightTokens->color);
74 if (!value.IsEmpty()) {
75 const auto color = value.Get<GfVec3f>();
76 strength =
make_float3(color[0], color[1], color[2]);
79 value = sceneDelegate->GetLightParamValue(
id, HdLightTokens->exposure);
80 if (!value.IsEmpty()) {
81 strength *= exp2(value.Get<
float>());
84 value = sceneDelegate->GetLightParamValue(
id, HdLightTokens->intensity);
85 if (!value.IsEmpty()) {
86 strength *= value.Get<
float>();
89 if (_lightType == HdPrimTypeTokens->distantLight) {
98 value = sceneDelegate->GetLightParamValue(
id, HdLightTokens->normalize);
99 _light->set_normalize(value.IsHolding<
bool>() && value.UncheckedGet<
bool>());
101 value = sceneDelegate->GetLightParamValue(
id, _tokens->visibleInPrimaryRay);
102 if (!value.IsEmpty()) {
103 _light->set_use_camera(value.Get<
bool>());
106 value = sceneDelegate->GetLightParamValue(
id, HdLightTokens->shadowEnable);
107 if (!value.IsEmpty()) {
108 _light->set_cast_shadow(value.Get<
bool>());
111 if (_lightType == HdPrimTypeTokens->distantLight) {
112 value = sceneDelegate->GetLightParamValue(
id, HdLightTokens->angle);
113 if (!value.IsEmpty()) {
114 _light->set_angle(GfDegreesToRadians(value.Get<
float>()));
117 else if (_lightType == HdPrimTypeTokens->diskLight) {
118 value = sceneDelegate->GetLightParamValue(
id, HdLightTokens->radius);
119 if (!value.IsEmpty()) {
120 const float size = value.Get<
float>() * 2.0f;
121 _light->set_sizeu(size);
122 _light->set_sizev(size);
125 else if (_lightType == HdPrimTypeTokens->rectLight) {
126 value = sceneDelegate->GetLightParamValue(
id, HdLightTokens->width);
127 if (!value.IsEmpty()) {
128 _light->set_sizeu(value.Get<
float>());
131 value = sceneDelegate->GetLightParamValue(
id, HdLightTokens->height);
132 if (!value.IsEmpty()) {
133 _light->set_sizev(value.Get<
float>());
136 else if (_lightType == HdPrimTypeTokens->sphereLight) {
137 value = sceneDelegate->GetLightParamValue(
id, TfToken(
"treatAsPoint"));
138 if (!value.IsEmpty() && value.Get<
bool>()) {
139 _light->set_size(0.0f);
142 value = sceneDelegate->GetLightParamValue(
id, HdLightTokens->radius);
143 if (!value.IsEmpty()) {
144 _light->set_size(value.Get<
float>());
148 bool shaping =
false;
150 value = sceneDelegate->GetLightParamValue(
id, HdLightTokens->shapingConeAngle);
151 if (!value.IsEmpty()) {
152 _light->set_spot_angle(GfDegreesToRadians(value.Get<
float>()) * 2.0f);
156 value = sceneDelegate->GetLightParamValue(
id, HdLightTokens->shapingConeSoftness);
157 if (!value.IsEmpty()) {
158 _light->set_spot_smooth(value.Get<
float>());
165 const bool visible = sceneDelegate->GetVisible(
id);
172 _light->set_strength(strength);
173 _light->set_is_enabled(visible);
175 PopulateShaderGraph(sceneDelegate);
178 else if (_light->tfm_is_modified() && (_lightType == HdPrimTypeTokens->domeLight ||
179 _light->get_shader()->has_surface_spatial_varying))
181 PopulateShaderGraph(sceneDelegate);
184 if (_light->is_modified()) {
185 _light->tag_update(
lock.scene);
188 *dirtyBits = DirtyBits::Clean;
191void HdCyclesLight::PopulateShaderGraph(HdSceneDelegate *sceneDelegate)
196 if (_lightType == HdPrimTypeTokens->domeLight) {
199 bgNode->set_color(_light->get_strength());
202 graph->connect(bgNode->
output(
"Background"), graph->output()->input(
"Surface"));
206 else if (sceneDelegate !=
nullptr) {
208 const SdfPath &
id = GetId();
209 value = sceneDelegate->GetLightParamValue(
id, TfToken(
"falloff"));
210 if (!value.IsEmpty()) {
211 std::string strVal = value.Get<
string>();
212 if (strVal ==
"Constant" || strVal ==
"Linear" || strVal ==
"Quadratic") {
214 lfoNode->set_strength(1.f);
216 graph->connect(lfoNode->
output(strVal.c_str()), graph->output()->input(
"Surface"));
217 outputNode = lfoNode;
222 if (outputNode ==
nullptr) {
225 emissionNode->set_strength(1.0f);
226 graph->add(emissionNode);
228 graph->connect(emissionNode->
output(
"Emission"), graph->output()->input(
"Surface"));
230 outputNode = emissionNode;
234 const SdfPath &
id = GetId();
235 bool hasSpatialVarying =
false;
236 bool hasColorTemperature =
false;
238 if (sceneDelegate !=
nullptr) {
239 value = sceneDelegate->GetLightParamValue(
id, HdLightTokens->enableColorTemperature);
240 const bool enableColorTemperature = value.IsHolding<
bool>() && value.UncheckedGet<
bool>();
242 if (enableColorTemperature) {
243 value = sceneDelegate->GetLightParamValue(
id, HdLightTokens->colorTemperature);
244 if (value.IsHolding<
float>()) {
246 blackbodyNode->set_temperature(value.UncheckedGet<
float>());
247 graph->add(blackbodyNode);
249 if (_lightType == HdPrimTypeTokens->domeLight) {
252 mathNode->set_vector2(_light->get_strength());
253 graph->add(mathNode);
255 graph->connect(blackbodyNode->
output(
"Color"), mathNode->
input(
"Vector1"));
256 graph->connect(mathNode->
output(
"Vector"), outputNode->
input(
"Color"));
259 graph->connect(blackbodyNode->
output(
"Color"), outputNode->
input(
"Color"));
262 hasColorTemperature =
true;
266 value = sceneDelegate->GetLightParamValue(
id, HdLightTokens->shapingIesFile);
267 if (value.IsHolding<SdfAssetPath>()) {
268 std::string filename = value.UncheckedGet<SdfAssetPath>().GetResolvedPath();
269 if (filename.empty()) {
270 filename = value.UncheckedGet<SdfAssetPath>().GetAssetPath();
274 coordNode->set_ob_tfm(_light->get_tfm());
275 coordNode->set_use_transform(
true);
276 graph->add(coordNode);
279 iesNode->set_filename(ustring(filename));
281 graph->connect(coordNode->
output(
"Normal"), iesNode->
input(
"Vector"));
282 graph->connect(iesNode->
output(
"Fac"), outputNode->
input(
"Strength"));
284 hasSpatialVarying =
true;
287 value = sceneDelegate->GetLightParamValue(
id, HdLightTokens->textureFile);
288 if (value.IsHolding<SdfAssetPath>()) {
289 std::string filename = value.UncheckedGet<SdfAssetPath>().GetResolvedPath();
290 if (filename.empty()) {
291 filename = value.UncheckedGet<SdfAssetPath>().GetAssetPath();
295 if (_lightType == HdPrimTypeTokens->domeLight) {
300 coordNode->set_ob_tfm(tfm);
301 coordNode->set_use_transform(
true);
302 graph->add(coordNode);
306 graph->add(textureNode);
308 graph->connect(coordNode->
output(
"Object"), textureNode->
input(
"Vector"));
310 hasSpatialVarying =
true;
314 graph->add(coordNode);
317 static_cast<ImageTextureNode *
>(textureNode)->set_filename(ustring(filename));
318 graph->add(textureNode);
320 graph->connect(coordNode->
output(
"Parametric"), textureNode->
input(
"Vector"));
323 if (hasColorTemperature) {
326 graph->add(mathNode);
328 graph->connect(textureNode->
output(
"Color"), mathNode->
input(
"Vector1"));
330 graph->connect(outputNodeInput->
link, mathNode->
input(
"Vector2"));
332 graph->connect(mathNode->
output(
"Vector"), outputNodeInput);
334 else if (_lightType == HdPrimTypeTokens->domeLight) {
337 mathNode->set_vector2(_light->get_strength());
338 graph->add(mathNode);
340 graph->connect(textureNode->
output(
"Color"), mathNode->
input(
"Vector1"));
341 graph->connect(mathNode->
output(
"Vector"), outputNode->
input(
"Color"));
344 graph->connect(textureNode->
output(
"Color"), outputNode->
input(
"Color"));
349 Shader *
const shader = _light->get_shader();
350 shader->set_graph(graph);
351 shader->tag_update((
Scene *)_light->get_owner());
353 shader->has_surface_spatial_varying = hasSpatialVarying;
363 const bool keep_nodes =
static_cast<const HdCyclesSession *
>(renderParam)->keep_nodes;
366 lock.scene->delete_node(_light);
372void HdCyclesLight::Initialize(HdRenderParam *renderParam)
380 _light =
lock.scene->create_node<
Light>();
381 _light->name = GetId().GetString();
385 if (_lightType == HdPrimTypeTokens->domeLight) {
388 else if (_lightType == HdPrimTypeTokens->distantLight) {
391 else if (_lightType == HdPrimTypeTokens->diskLight) {
393 _light->set_ellipse(
true);
394 _light->set_size(1.0f);
396 else if (_lightType == HdPrimTypeTokens->rectLight) {
398 _light->set_ellipse(
false);
399 _light->set_size(1.0f);
401 else if (_lightType == HdPrimTypeTokens->sphereLight) {
403 _light->set_size(1.0f);
406 _light->set_use_mis(
true);
407 _light->set_use_camera(
false);
410 _light->set_shader(shader);
413 PopulateShaderGraph(
nullptr);
@ NODE_VECTOR_MATH_MULTIPLY
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)
static uint hash_string(const char *str)
ccl_device_inline uint hash_uint2(uint kx, 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)
ccl_device_inline float3 one_float3()
CCL_NAMESPACE_BEGIN ccl_device_inline float3 zero_float3()