Blender V4.5
io/usd/hydra/world.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2011-2022 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#include "world.hh"
6#include "usd_private.hh"
7
8#include <pxr/base/gf/rotation.h>
9#include <pxr/base/gf/vec2f.h>
10#include <pxr/base/vt/array.h>
11#include <pxr/imaging/hd/light.h>
12#include <pxr/imaging/hd/renderDelegate.h>
13#include <pxr/imaging/hd/tokens.h>
14#include <pxr/usd/usdLux/tokens.h>
15
16#include "DNA_node_types.h"
17#include "DNA_scene_types.h"
18#include "DNA_world_types.h"
19
20#include "BLI_math_rotation.h"
21
22#include "BKE_node.hh"
24#include "BKE_node_runtime.hh"
25#include "BKE_studiolight.h"
26
27#include "NOD_shader.h"
28
30#include "image.hh"
31
32/* TODO: add custom `tftoken` "transparency"? */
33
34/* NOTE: opacity and blur aren't supported by USD */
35
36namespace blender::io::hydra {
37
38WorldData::WorldData(HydraSceneDelegate *scene_delegate, pxr::SdfPath const &prim_id)
39 : LightData(scene_delegate, nullptr, prim_id)
40{
41 prim_type_ = pxr::HdPrimTypeTokens->domeLight;
42}
43
45{
46 data_.clear();
47
48 float intensity = 1.0f;
49 pxr::SdfAssetPath texture_file;
50
51 if (scene_delegate_->shading_settings.use_scene_world) {
52 const World *world = scene_delegate_->scene->world;
53 pxr::GfVec3f color(1.0f, 1.0f, 1.0f);
54 ID_LOG(1, "%s", world->id.name);
55
56 if (world->use_nodes) {
57 /* TODO: Create nodes parsing system */
58
59 bNode *output_node = ntreeShaderOutputNode(world->nodetree, SHD_OUTPUT_ALL);
60 if (!output_node) {
61 return;
62 }
63 const Span<bNodeSocket *> input_sockets = output_node->input_sockets();
64 bNodeSocket *input_socket = nullptr;
65
66 for (auto *socket : input_sockets) {
67 if (STREQ(socket->name, "Surface")) {
68 input_socket = socket;
69 break;
70 }
71 }
72 if (!input_socket) {
73 return;
74 }
75 if (input_socket->directly_linked_links().is_empty()) {
76 return;
77 }
78 bNodeLink const *link = input_socket->directly_linked_links()[0];
79
80 bNode *input_node = link->fromnode;
81 if (input_node->type_legacy != SH_NODE_BACKGROUND) {
82 return;
83 }
84
85 const bNodeSocket &color_input = input_node->input_by_identifier("Color");
86 const bNodeSocket &strength_input = input_node->input_by_identifier("Strength");
87
88 float const *strength = strength_input.default_value_typed<float>();
89 float const *input_color = color_input.default_value_typed<float>();
90 intensity = strength[1];
91 color = pxr::GfVec3f(input_color[0], input_color[1], input_color[2]);
92
93 if (!color_input.directly_linked_links().is_empty()) {
94 bNode *color_input_node = color_input.directly_linked_links()[0]->fromnode;
96 NodeTexImage *tex = static_cast<NodeTexImage *>(color_input_node->storage);
97 Image *image = (Image *)color_input_node->id;
98 if (image) {
99 std::string image_path = cache_or_get_image_file(
100 scene_delegate_->bmain, scene_delegate_->scene, image, &tex->iuser);
101 if (!image_path.empty()) {
102 texture_file = pxr::SdfAssetPath(image_path, image_path);
103 }
104 }
105 }
106 }
107 }
108 else {
109 intensity = 1.0f;
110 color = pxr::GfVec3f(world->horr, world->horg, world->horb);
111 }
112
113 if (texture_file.GetAssetPath().empty()) {
114 float fill_color[4] = {color[0], color[1], color[2], 1.0f};
115 std::string image_path = blender::io::usd::cache_image_color(fill_color);
116 texture_file = pxr::SdfAssetPath(image_path, image_path);
117 }
118 }
119 else {
120 ID_LOG(1, "studiolight: %s", scene_delegate_->shading_settings.studiolight_name.c_str());
121
123 scene_delegate_->shading_settings.studiolight_name.c_str(),
125 if (sl != nullptr && sl->flag & STUDIOLIGHT_TYPE_WORLD) {
126 texture_file = pxr::SdfAssetPath(sl->filepath, sl->filepath);
127 /* coefficient to follow Cycles result */
128 intensity = scene_delegate_->shading_settings.studiolight_intensity / 2;
129 }
130 }
131
132 data_[pxr::UsdLuxTokens->orientToStageUpAxis] = true;
133 data_[pxr::HdLightTokens->intensity] = intensity;
134 data_[pxr::HdLightTokens->exposure] = 0.0f;
135 data_[pxr::HdLightTokens->color] = pxr::GfVec3f(1.0f, 1.0f, 1.0f);
136 data_[pxr::HdLightTokens->textureFile] = texture_file;
137
139}
140
142{
143 ID_LOG(1, "");
144
145 if (!scene_delegate_->shading_settings.use_scene_world ||
146 (scene_delegate_->shading_settings.use_scene_world && scene_delegate_->scene->world))
147 {
148 init();
149 if (data_.empty()) {
150 remove();
151 return;
152 }
153 insert();
154 scene_delegate_->GetRenderIndex().GetChangeTracker().MarkSprimDirty(prim_id,
155 pxr::HdLight::AllDirty);
156 }
157 else {
158 remove();
159 }
160}
161
163{
164 transform = pxr::GfMatrix4d().SetRotate(pxr::GfRotation(pxr::GfVec3d(1.0, 0.0, 0.0), 90.0)) *
165 pxr::GfMatrix4d().SetRotate(pxr::GfRotation(pxr::GfVec3d(0.0, 0.0, 1.0), 90.0));
166 if (!scene_delegate_->shading_settings.use_scene_world) {
167 transform *= pxr::GfMatrix4d().SetRotate(
168 pxr::GfRotation(pxr::GfVec3d(0.0, 0.0, -1.0),
169 RAD2DEGF(scene_delegate_->shading_settings.studiolight_rotation)));
170 }
171}
172
173} // namespace blender::io::hydra
#define SH_NODE_TEX_IMAGE
#define SH_NODE_TEX_ENVIRONMENT
#define SH_NODE_BACKGROUND
@ STUDIOLIGHT_TYPE_WORLD
struct StudioLight * BKE_studiolight_find(const char *name, int flag)
#define STUDIOLIGHT_ORIENTATIONS_MATERIAL_MODE
#define RAD2DEGF(_rad)
#define ELEM(...)
#define STREQ(a, b)
@ SHD_OUTPUT_ALL
struct bNode * ntreeShaderOutputNode(struct bNodeTree *ntree, int target)
pxr::SdfPath prim_id
Definition id.hh:36
HydraSceneDelegate * scene_delegate_
Definition id.hh:39
LightData(HydraSceneDelegate *scene_delegate, const Object *object, pxr::SdfPath const &prim_id)
std::map< pxr::TfToken, pxr::VtValue > data_
Definition light.hh:23
pxr::GfMatrix4d transform
Definition object.hh:24
WorldData(HydraSceneDelegate *scene_delegate, pxr::SdfPath const &prim_id)
#define ID_LOG(level, msg,...)
Definition id.hh:53
std::string cache_or_get_image_file(Main *bmain, Scene *scene, Image *image, ImageUser *iuser)
std::string cache_image_color(const float color[4])
char name[66]
Definition DNA_ID.h:415
char filepath[FILE_MAX]
struct bNodeTree * nodetree
float horg
short use_nodes
float horb
float horr
struct ID * id
int16_t type_legacy
void * storage