Blender V4.3
hydra/session.cpp
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2022 NVIDIA Corporation
2 * SPDX-FileCopyrightText: 2022 Blender Foundation
3 *
4 * SPDX-License-Identifier: Apache-2.0 */
5
6#include "hydra/session.h"
7#include "scene/shader.h"
8// Have to include shader.h before background.h so that 'set_shader' uses the correct 'set'
9// overload taking a 'Node *', rather than the one taking a 'bool'
10#include "scene/background.h"
11#include "scene/light.h"
12#include "scene/shader_graph.h"
13#include "scene/shader_nodes.h"
14#include "session/session.h"
15
17
18namespace {
19
20const std::unordered_map<TfToken, PassType, TfToken::HashFunctor> kAovToPass = {
21 {HdAovTokens->color, PASS_COMBINED},
22 {HdAovTokens->depth, PASS_DEPTH},
23 {HdAovTokens->normal, PASS_NORMAL},
24 {HdAovTokens->primId, PASS_OBJECT_ID},
25 {HdAovTokens->instanceId, PASS_AOV_VALUE},
26};
27
28} // namespace
29
30SceneLock::SceneLock(const HdRenderParam *renderParam)
31 : scene(static_cast<const HdCyclesSession *>(renderParam)->session->scene),
32 sceneLock(scene->mutex)
33{
34}
35
37
38HdCyclesSession::HdCyclesSession(Session *session_, const bool keep_nodes)
39 : session(session_), keep_nodes(true), _ownCyclesSession(false)
40{
41}
42
44 : session(new Session(params, SceneParams())), keep_nodes(false), _ownCyclesSession(true)
45{
46 Scene *const scene = session->scene;
47
48 // Create background with ambient light
49 {
50 ShaderGraph *graph = new ShaderGraph();
51
52 BackgroundNode *bgNode = graph->create_node<BackgroundNode>();
53 bgNode->set_color(one_float3());
54 graph->add(bgNode);
55
56 graph->connect(bgNode->output("Background"), graph->output()->input("Surface"));
57
58 scene->default_background->set_graph(graph);
59 scene->default_background->tag_update(scene);
60 }
61
62 // Wire up object color in default surface material
63 {
64 ShaderGraph *graph = new ShaderGraph();
65
66 ObjectInfoNode *objectNode = graph->create_node<ObjectInfoNode>();
67 graph->add(objectNode);
68
69 DiffuseBsdfNode *diffuseNode = graph->create_node<DiffuseBsdfNode>();
70 graph->add(diffuseNode);
71
72 graph->connect(objectNode->output("Color"), diffuseNode->input("Color"));
73 graph->connect(diffuseNode->output("BSDF"), graph->output()->input("Surface"));
74
75#if 1
76 // Create the instanceId AOV output
77 const ustring instanceId(HdAovTokens->instanceId.GetString());
78
79 OutputAOVNode *aovNode = graph->create_node<OutputAOVNode>();
80 aovNode->set_name(instanceId);
81 graph->add(aovNode);
82
83 AttributeNode *instanceIdNode = graph->create_node<AttributeNode>();
84 instanceIdNode->set_attribute(instanceId);
85 graph->add(instanceIdNode);
86
87 graph->connect(instanceIdNode->output("Fac"), aovNode->input("Value"));
88#endif
89
90 scene->default_surface->set_graph(graph);
91 scene->default_surface->tag_update(scene);
92 }
93}
94
96{
97 if (_ownCyclesSession) {
98 delete session;
99 }
100}
101
103{
104 Scene *const scene = session->scene;
105
106 // Update background depending on presence of a background light
107 if (scene->light_manager->need_update()) {
108 Light *background_light = nullptr;
109 for (Light *light : scene->lights) {
110 if (light->get_light_type() == LIGHT_BACKGROUND) {
111 background_light = light;
112 break;
113 }
114 }
115
116 if (!background_light) {
117 scene->background->set_shader(scene->default_background);
118 scene->background->set_transparent(true);
119
120 /* Set background color depending to non-zero value if there are no
121 * lights in the scene, to match behavior of other renderers. */
122 for (ShaderNode *node : scene->default_background->graph->nodes) {
123 if (node->is_a(BackgroundNode::get_node_type())) {
124 BackgroundNode *bgNode = static_cast<BackgroundNode *>(node);
125 bgNode->set_color((scene->lights.size() == 0) ? make_float3(0.5f) : zero_float3());
126 }
127 }
128 }
129 else {
130 scene->background->set_shader(background_light->get_shader());
131 scene->background->set_transparent(false);
132 }
133
134 scene->background->tag_update(scene);
135 }
136}
137
138void HdCyclesSession::SyncAovBindings(const HdRenderPassAovBindingVector &aovBindings)
139{
140 Scene *const scene = session->scene;
141
142 // Delete all existing passes
143 scene->delete_nodes(set<Pass *>(scene->passes.begin(), scene->passes.end()));
144
145 // Update passes with requested AOV bindings
146 _aovBindings = aovBindings;
147 for (const HdRenderPassAovBinding &aovBinding : aovBindings) {
148 const auto cyclesAov = kAovToPass.find(aovBinding.aovName);
149 if (cyclesAov == kAovToPass.end()) {
150 // TODO: Use PASS_AOV_COLOR and PASS_AOV_VALUE for these?
151 TF_WARN("Unknown pass %s", aovBinding.aovName.GetText());
152 continue;
153 }
154
155 const PassType type = cyclesAov->second;
156 const PassMode mode = PassMode::DENOISED;
157
158 Pass *pass = scene->create_node<Pass>();
159 pass->set_type(type);
160 pass->set_mode(mode);
161 pass->set_name(ustring(aovBinding.aovName.GetString()));
162 }
163}
164
165void HdCyclesSession::RemoveAovBinding(HdRenderBuffer *renderBuffer)
166{
167 for (HdRenderPassAovBinding &aovBinding : _aovBindings) {
168 if (renderBuffer == aovBinding.renderBuffer) {
169 aovBinding.renderBuffer = nullptr;
170 break;
171 }
172 }
173
174 if (renderBuffer == _displayAovBinding.renderBuffer) {
175 _displayAovBinding.renderBuffer = nullptr;
176 }
177}
178
ThreadMutex mutex
HdCyclesSession(CCL_NS::Session *session_, const bool keep_nodes)
~HdCyclesSession() override
CCL_NS::Session * session
void RemoveAovBinding(PXR_NS::HdRenderBuffer *renderBuffer)
void SyncAovBindings(const PXR_NS::HdRenderPassAovBindingVector &aovBindings)
Definition pass.h:49
ShaderInput * input(const char *name)
ShaderOutput * output(const char *name)
OperationNode * node
ccl_device_forceinline float3 make_float3(const float x, const float y, const float z)
#define HDCYCLES_NAMESPACE_CLOSE_SCOPE
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
PassType
@ PASS_DEPTH
@ PASS_COMBINED
@ PASS_OBJECT_ID
@ PASS_NORMAL
@ PASS_AOV_VALUE
@ LIGHT_BACKGROUND
ccl_device_inline float3 one_float3()
Definition math_float3.h:24
CCL_NAMESPACE_BEGIN ccl_device_inline float3 zero_float3()
Definition math_float3.h:15
const std::unordered_map< TfToken, PassType, TfToken::HashFunctor > kAovToPass
PassMode
Definition pass.h:20
SceneLock(const PXR_NS::HdRenderParam *renderParam)
void delete_nodes(const set< T * > &nodes)
Definition scene.h:234