Skip to content

Commit

Permalink
Light shaders (#1144)
Browse files Browse the repository at this point in the history
* Light shaders (#1141)

* Remove include from imaging

Co-authored-by: Julian Hodgson <julian.hodgson@autodesk.com>
  • Loading branch information
jhodgson and Julian Hodgson authored May 4, 2022
1 parent 3fbf759 commit 574c54f
Show file tree
Hide file tree
Showing 8 changed files with 234 additions and 49 deletions.
16 changes: 16 additions & 0 deletions common/common_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
#include <pxr/base/arch/export.h>

#include <pxr/base/gf/matrix4d.h>
#include <pxr/base/vt/value.h>
#include <pxr/usd/sdf/path.h>

#include <ai.h>

Expand All @@ -40,4 +42,18 @@ std::string ArnoldUsdMakeCamelCase(const std::string &in);
ARCH_HIDDEN
GfMatrix4d ArnoldUsdConvertMatrix(const AtMatrix& in);

template <typename F>
ARCH_HIDDEN
void ArnoldUsdCheckForSdfPathValue(const VtValue& value, F&& f)
{
if (value.IsHolding<SdfPath>()) {
f(value.UncheckedGet<SdfPath>());
} else if (value.IsHolding<std::string>()) {
const auto s = value.UncheckedGet<std::string>();
if (!s.empty() && *s.begin() == '/') {
f(SdfPath{value.UncheckedGet<std::string>()});
}
}
}

PXR_NAMESPACE_CLOSE_SCOPE
47 changes: 46 additions & 1 deletion render_delegate/light.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@

#include <vector>

#include <common_utils.h>
#include <constant_strings.h>

#include "node_graph.h"
#include "utils.h"

Expand Down Expand Up @@ -350,7 +352,7 @@ auto geometryLightSync = [](AtNode* light, AtNode** filter, const AtNodeEntry* n
if (geomValue.IsHolding<SdfPath>()) {
SdfPath geomPath = geomValue.UncheckedGet<SdfPath>();
//const HdArnoldMesh *hdMesh = dynamic_cast<const HdArnoldMesh*>(sceneDelegate->GetRenderIndex().GetRprim(geomPath));
AtNode *mesh = AiNodeLookUpByName(AiNodeGetUniverse(light), geomPath.GetText());
AtNode *mesh = AiNodeLookUpByName(AiNodeGetUniverse(light), AtString(geomPath.GetText()));
if (mesh != nullptr && !AiNodeIs(mesh, str::polymesh))
mesh = nullptr;
AiNodeSetPtr(light, str::mesh,(void*) mesh);
Expand Down Expand Up @@ -443,6 +445,7 @@ class HdArnoldGenericLight : public HdLight {
private:
SyncParams _syncParams; ///< Function object to sync light parameters.
HdArnoldRenderDelegate* _delegate; ///< Pointer to the Render Delegate.
HdArnoldNodeGraphTracker _nodeGraphTracker; ///< Utility to track material assignments of shapes.
AtNode* _light; ///< Pointer to the Arnold Light.
AtNode* _texture = nullptr; ///< Pointer to the Arnold Texture Shader.
AtNode* _filter = nullptr; ///< Pointer to the Arnold Light filter for barndoor effects.
Expand Down Expand Up @@ -484,6 +487,7 @@ HdArnoldGenericLight::~HdArnoldGenericLight()
if (_filter != nullptr) {
AiNodeDestroy(_filter);
}
_nodeGraphTracker.UntrackNodeGraphs(_delegate, GetId());
}

void HdArnoldGenericLight::Sync(HdSceneDelegate* sceneDelegate, HdRenderParam* renderParam, HdDirtyBits* dirtyBits)
Expand Down Expand Up @@ -647,6 +651,47 @@ void HdArnoldGenericLight::Sync(HdSceneDelegate* sceneDelegate, HdRenderParam* r
updateLightLinking(_shadowLink, HdTokens->shadowLink, true);
#endif

// get the sdf path for the light shader arnold node graph container
SdfPath lightShaderPath;
ArnoldUsdCheckForSdfPathValue(sceneDelegate->GetLightParamValue(id, TfToken("primvars:arnold:shaders")),
[&](const SdfPath& p) { lightShaderPath = p; });

AtNode *color = nullptr;
AtNode *shader = nullptr;
std::vector<AtNode *> lightFilters;
if (!lightShaderPath.IsEmpty()) {
color = HdArnoldNodeGraph::GetNodeGraphTerminal(&sceneDelegate->GetRenderIndex(), lightShaderPath,
TfToken("color"));
if (color) {
AiNodeLink(color, str::color, _light);
}

// make sure this is a skydome light otherwise we have no shader parameter
if (AiNodeIs(_light, str::skydome_light)) {
shader = HdArnoldNodeGraph::GetNodeGraphTerminal(&sceneDelegate->GetRenderIndex(), lightShaderPath,
TfToken("shader"));
if (shader) {
AiNodeSetPtr(_light, str::shader, shader);
}
}

lightFilters = HdArnoldNodeGraph::GetNodeGraphTerminals(&sceneDelegate->GetRenderIndex(), lightShaderPath,
TfToken("light_filter"));
if (!lightFilters.empty()) {
AiNodeSetArray(_light, str::filters, AiArrayConvert(static_cast<uint32_t>(lightFilters.size()), 1,
AI_TYPE_NODE, lightFilters.data()));
}

if (color == nullptr)
AiNodeResetParameter(_light, str::color);
if (shader == nullptr)
AiNodeResetParameter(_light, str::shader);
if (lightFilters.empty())
AiNodeResetParameter(_light, str::filters);

_nodeGraphTracker.TrackLightNodeGraph(_delegate, id, lightShaderPath);
}

*dirtyBits = HdLight::Clean;
}

Expand Down
35 changes: 33 additions & 2 deletions render_delegate/node_graph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,10 @@ HdArnoldNodeGraph::HdArnoldNodeGraph(HdArnoldRenderDelegate* renderDelegate, con
{
}

HdArnoldNodeGraph::~HdArnoldNodeGraph() { _renderDelegate->RemoveNodeGraph(GetId()); }
HdArnoldNodeGraph::~HdArnoldNodeGraph() {
_renderDelegate->RemoveNodeGraph(GetId());
_renderDelegate->RemoveLightNodeGraph(GetId());
}

void HdArnoldNodeGraph::Sync(HdSceneDelegate* sceneDelegate, HdRenderParam* renderParam, HdDirtyBits* dirtyBits)
{
Expand All @@ -514,6 +517,7 @@ void HdArnoldNodeGraph::Sync(HdSceneDelegate* sceneDelegate, HdRenderParam* rend
HdArnoldRenderParamInterrupt param(renderParam);
auto value = sceneDelegate->GetMaterialResource(GetId());
auto nodeGraphChanged = false;
bool lightShaders = false;
if (value.IsHolding<HdMaterialNetworkMap>()) {
param.Interrupt();
// Mark all nodes as unused before any translation happens.
Expand Down Expand Up @@ -547,13 +551,21 @@ void HdArnoldNodeGraph::Sync(HdSceneDelegate* sceneDelegate, HdRenderParam* rend
readNetwork(&terminal.second, terminal.first == HdMaterialTerminalTokens->displacement))) {
nodeGraphChanged = true;
}
if (terminal.first == str::color || terminal.first == str::shader || terminal.first.GetString().rfind(
"light_filter", 0) == 0) {
lightShaders = true;
_renderDelegate->DirtyLightNodeGraph(id);
AtNode* terminalNode = _nodeGraph.GetTerminal(terminal.first);
if (terminalNode)
AiUniverseCacheFlush(AiNodeGetUniverse(terminalNode), AI_CACHE_BACKGROUND);
}
}
#endif
ClearUnusedNodes();
}
// We only mark the material dirty if one of the terminals have changed, but ignore the initial sync, because we
// expect Hydra to do the initial assignment correctly.
if (_wasSyncedOnce && nodeGraphChanged) {
if (_wasSyncedOnce && nodeGraphChanged && !lightShaders) {
_renderDelegate->DirtyNodeGraph(id);
}
}
Expand Down Expand Up @@ -1005,4 +1017,23 @@ void HdArnoldNodeGraph::SetNodesUnused()
}
}

AtNode* HdArnoldNodeGraph::GetNodeGraphTerminal(HdRenderIndex* renderIndex, const SdfPath& id, const TfToken& terminal)
{
if (id.IsEmpty()) {
return nullptr;
}
auto* nodeGraph = reinterpret_cast<const HdArnoldNodeGraph*>(renderIndex->GetSprim(HdPrimTypeTokens->material, id));
return nodeGraph == nullptr ? nullptr : nodeGraph->GetTerminal(terminal);
}

std::vector<AtNode*> HdArnoldNodeGraph::GetNodeGraphTerminals(HdRenderIndex* renderIndex, const SdfPath& id, const TfToken& terminalBase)
{
if (id.IsEmpty()) {
return std::vector<AtNode*>();
}
auto* nodeGraph = reinterpret_cast<const HdArnoldNodeGraph*>(renderIndex->GetSprim(HdPrimTypeTokens->material, id));
return nodeGraph == nullptr ? std::vector<AtNode*>() : nodeGraph->GetTerminals(terminalBase);
}


PXR_NAMESPACE_CLOSE_SCOPE
18 changes: 18 additions & 0 deletions render_delegate/node_graph.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,24 @@ class HdArnoldNodeGraph : public HdMaterial {
HDARNOLD_API
std::vector<AtNode*> GetTerminals(const TfToken& terminalBase) const;

/// Utility function to return a shader graph for a given terminal.
///
/// @param renderIndex
/// @param id Path to ArnoldNodeGraph
/// @param terminal Terminal token
/// @return Vector of pointers to the terminal, nullptr if not found.
HDARNOLD_API
static AtNode* GetNodeGraphTerminal(HdRenderIndex* renderIndex, const SdfPath& id, const TfToken& terminal);

/// Utility function to return multiple shader graphs for a given terminal base token.
///
/// @param renderIndex
/// @param id Path to ArnoldNodeGraph
/// @param terminalBase Terminal base token
/// @return Vector of pointers to the terminal, nullptr if not found.
HDARNOLD_API
static std::vector<AtNode*> GetNodeGraphTerminals(HdRenderIndex* renderIndex, const SdfPath& id, const TfToken& terminalBase);

protected:
/// Utility struct to store translated nodes.
struct NodeData {
Expand Down
18 changes: 18 additions & 0 deletions render_delegate/node_graph_tracker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,24 @@ void HdArnoldNodeGraphTracker::TrackSingleNodeGraph(
}
}

void HdArnoldNodeGraphTracker::TrackLightNodeGraph(
HdArnoldRenderDelegate* renderDelegate, const SdfPath& shapeId, const SdfPath& nodeGraphId)
{
// Initial assignment.
if (_nodeGraphs.empty()) {
_nodeGraphs.assign(1, nodeGraphId);
renderDelegate->TrackLightNodeGraphs(shapeId, _nodeGraphs);
// We already have a single material stored, check if it has changed.
} else {
if (_nodeGraphs.cdata()[0] != nodeGraphId) {
renderDelegate->UntrackLightNodeGraphs(shapeId, _nodeGraphs);
_nodeGraphs[0] = nodeGraphId;
renderDelegate->TrackLightNodeGraphs(shapeId, _nodeGraphs);
}
}
}


void HdArnoldNodeGraphTracker::UntrackNodeGraphs(HdArnoldRenderDelegate* renderDelegate, const SdfPath& shapeId)
{
if (!_nodeGraphs.empty()) {
Expand Down
4 changes: 4 additions & 0 deletions render_delegate/node_graph_tracker.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ class HdArnoldNodeGraphTracker {
void TrackSingleNodeGraph(
HdArnoldRenderDelegate* renderDelegate, const SdfPath& shapeId, const SdfPath& nodeGraphId);

HDARNOLD_API
void TrackLightNodeGraph(
HdArnoldRenderDelegate* renderDelegate, const SdfPath& shapeId, const SdfPath& nodeGraphId);

/// Untrack all materials assigned to the shape. Typically used when deleting the shape.
///
/// @param renderDelegate Pointer to the Arnold Render Delegate.
Expand Down
Loading

0 comments on commit 574c54f

Please sign in to comment.