This repository has been archived on 2023-10-09. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
blender-archive/intern/cycles/hydra/session.cpp
Brecht Van Lommel 9b92ce9dc0 Cycles: add USD as a file format for Cycles standalone rendering
Long term, this should replace the XML format. This reuses the Hydra render
delegate implementation, and so supports the same features. The same command
line options and GUI work for both XML and USD also.

The implementation of this is still disabled, waiting for some refactoring of
USD library linking. However we want the Cycles code to be in sync between
repositories for the 3.2 release.

Ref T96731
2022-04-29 19:19:19 +02:00

172 lines
4.8 KiB
C++

/* SPDX-License-Identifier: Apache-2.0
* Copyright 2022 NVIDIA Corporation
* Copyright 2022 Blender Foundation */
#include "hydra/session.h"
#include "scene/shader.h"
// Have to include shader.h before background.h so that 'set_shader' uses the correct 'set'
// overload taking a 'Node *', rather than the one taking a 'bool'
#include "scene/background.h"
#include "scene/light.h"
#include "scene/shader_graph.h"
#include "scene/shader_nodes.h"
#include "session/session.h"
HDCYCLES_NAMESPACE_OPEN_SCOPE
namespace {
const std::unordered_map<TfToken, PassType, TfToken::HashFunctor> kAovToPass = {
{HdAovTokens->color, PASS_COMBINED},
{HdAovTokens->depth, PASS_DEPTH},
{HdAovTokens->normal, PASS_NORMAL},
{HdAovTokens->primId, PASS_OBJECT_ID},
{HdAovTokens->instanceId, PASS_AOV_VALUE},
};
} // namespace
SceneLock::SceneLock(const HdRenderParam *renderParam)
: scene(static_cast<const HdCyclesSession *>(renderParam)->session->scene),
sceneLock(scene->mutex)
{
}
SceneLock::~SceneLock()
{
}
HdCyclesSession::HdCyclesSession(Session *session_, const bool keep_nodes)
: session(session_), keep_nodes(true), _ownCyclesSession(false)
{
}
HdCyclesSession::HdCyclesSession(const SessionParams &params)
: session(new Session(params, SceneParams())), keep_nodes(false), _ownCyclesSession(true)
{
Scene *const scene = session->scene;
// Create background with ambient light
{
ShaderGraph *graph = new ShaderGraph();
BackgroundNode *bgNode = graph->create_node<BackgroundNode>();
bgNode->set_color(one_float3());
graph->add(bgNode);
graph->connect(bgNode->output("Background"), graph->output()->input("Surface"));
scene->default_background->set_graph(graph);
scene->default_background->tag_update(scene);
}
// Wire up object color in default surface material
{
ShaderGraph *graph = new ShaderGraph();
ObjectInfoNode *objectNode = graph->create_node<ObjectInfoNode>();
graph->add(objectNode);
DiffuseBsdfNode *diffuseNode = graph->create_node<DiffuseBsdfNode>();
graph->add(diffuseNode);
graph->connect(objectNode->output("Color"), diffuseNode->input("Color"));
graph->connect(diffuseNode->output("BSDF"), graph->output()->input("Surface"));
#if 1
// Create the instanceId AOV output
const ustring instanceId(HdAovTokens->instanceId.GetString());
OutputAOVNode *aovNode = graph->create_node<OutputAOVNode>();
aovNode->set_name(instanceId);
graph->add(aovNode);
AttributeNode *instanceIdNode = graph->create_node<AttributeNode>();
instanceIdNode->set_attribute(instanceId);
graph->add(instanceIdNode);
graph->connect(instanceIdNode->output("Fac"), aovNode->input("Value"));
#endif
scene->default_surface->set_graph(graph);
scene->default_surface->tag_update(scene);
}
}
HdCyclesSession::~HdCyclesSession()
{
if (_ownCyclesSession) {
delete session;
}
}
void HdCyclesSession::UpdateScene()
{
Scene *const scene = session->scene;
// Update background depending on presence of a background light
if (scene->light_manager->need_update()) {
Light *background_light = nullptr;
for (Light *light : scene->lights) {
if (light->get_light_type() == LIGHT_BACKGROUND) {
background_light = light;
break;
}
}
if (!background_light) {
scene->background->set_shader(scene->default_background);
scene->background->set_transparent(true);
}
else {
scene->background->set_shader(background_light->get_shader());
scene->background->set_transparent(false);
}
scene->background->tag_update(scene);
}
}
void HdCyclesSession::SyncAovBindings(const HdRenderPassAovBindingVector &aovBindings)
{
Scene *const scene = session->scene;
// Delete all existing passes
scene->delete_nodes(set<Pass *>(scene->passes.begin(), scene->passes.end()));
// Update passes with requested AOV bindings
_aovBindings = aovBindings;
for (const HdRenderPassAovBinding &aovBinding : aovBindings) {
const auto cyclesAov = kAovToPass.find(aovBinding.aovName);
if (cyclesAov == kAovToPass.end()) {
// TODO: Use PASS_AOV_COLOR and PASS_AOV_VALUE for these?
TF_WARN("Unknown pass %s", aovBinding.aovName.GetText());
continue;
}
const PassType type = cyclesAov->second;
const PassMode mode = PassMode::DENOISED;
Pass *pass = scene->create_node<Pass>();
pass->set_type(type);
pass->set_mode(mode);
pass->set_name(ustring(aovBinding.aovName.GetString()));
}
}
void HdCyclesSession::RemoveAovBinding(HdRenderBuffer *renderBuffer)
{
for (HdRenderPassAovBinding &aovBinding : _aovBindings) {
if (renderBuffer == aovBinding.renderBuffer) {
aovBinding.renderBuffer = nullptr;
break;
}
}
if (renderBuffer == _displayAovBinding.renderBuffer) {
_displayAovBinding.renderBuffer = nullptr;
}
}
HDCYCLES_NAMESPACE_CLOSE_SCOPE