Blender V4.5
background.cpp
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
2 *
3 * SPDX-License-Identifier: Apache-2.0 */
4
5#include "scene/background.h"
6#include "device/device.h"
7#include "scene/integrator.h"
8#include "scene/light.h"
9#include "scene/scene.h"
10#include "scene/shader.h"
11#include "scene/shader_graph.h"
12#include "scene/shader_nodes.h"
13#include "scene/stats.h"
14
15#include "util/math.h"
16#include "util/time.h"
17
19
21{
22 NodeType *type = NodeType::add("background", create);
23
24 SOCKET_BOOLEAN(use_shader, "Use Shader", true);
25 SOCKET_UINT(visibility, "Visibility", PATH_RAY_ALL_VISIBILITY);
26
27 SOCKET_BOOLEAN(transparent, "Transparent", false);
28 SOCKET_BOOLEAN(transparent_glass, "Transparent Glass", false);
29 SOCKET_FLOAT(transparent_roughness_threshold, "Transparent Roughness Threshold", 0.0f);
30
31 SOCKET_FLOAT(volume_step_size, "Volume Step Size", 0.1f);
32
33 SOCKET_NODE(shader, "Shader", Shader::get_node_type());
34
35 SOCKET_STRING(lightgroup, "Light Group", ustring());
36
37 return type;
38}
39
40Background::Background() : Node(get_node_type())
41{
42 shader = nullptr;
43}
44
49
50void Background::device_update(Device *device, DeviceScene *dscene, Scene *scene)
51{
52 if (!is_modified()) {
53 return;
54 }
55
56 const scoped_callback_timer timer([scene](double time) {
57 if (scene->update_stats) {
58 scene->update_stats->background.times.add_entry({"device_update", time});
59 }
60 });
61
62 device_free(device, dscene);
63
64 Shader *bg_shader = get_shader(scene);
65
66 /* set shader index and transparent option */
67 KernelBackground *kbackground = &dscene->data.background;
68
69 kbackground->transparent = transparent;
70 kbackground->surface_shader = scene->shader_manager->get_shader_id(bg_shader);
71
72 if (transparent && transparent_glass) {
73 /* Square twice, once for principled BSDF convention, and once for
74 * faster comparison in kernel with anisotropic roughness. */
75 kbackground->transparent_roughness_squared_threshold = sqr(
76 sqr(transparent_roughness_threshold));
77 }
78 else {
79 kbackground->transparent_roughness_squared_threshold = -1.0f;
80 }
81
82 if (bg_shader->has_volume) {
83 kbackground->volume_shader = kbackground->surface_shader;
84 }
85 else {
86 kbackground->volume_shader = SHADER_NONE;
87 }
88
89 kbackground->volume_step_size = volume_step_size * scene->integrator->get_volume_step_rate();
90
91 /* No background node, make world shader invisible to all rays, to skip evaluation in kernel. */
92 if (bg_shader->graph->nodes.size() <= 1) {
93 kbackground->surface_shader |= SHADER_EXCLUDE_ANY;
94 }
95 /* Background present, check visibilities */
96 else {
97 if (!(visibility & PATH_RAY_DIFFUSE)) {
98 kbackground->surface_shader |= SHADER_EXCLUDE_DIFFUSE;
99 }
100 if (!(visibility & PATH_RAY_GLOSSY)) {
101 kbackground->surface_shader |= SHADER_EXCLUDE_GLOSSY;
102 }
103 if (!(visibility & PATH_RAY_TRANSMIT)) {
104 kbackground->surface_shader |= SHADER_EXCLUDE_TRANSMIT;
105 }
106 if (!(visibility & PATH_RAY_VOLUME_SCATTER)) {
107 kbackground->surface_shader |= SHADER_EXCLUDE_SCATTER;
108 }
109 if (!(visibility & PATH_RAY_CAMERA)) {
110 kbackground->surface_shader |= SHADER_EXCLUDE_CAMERA;
111 }
112 }
113
114 /* Light group. */
115 auto it = scene->lightgroups.find(lightgroup);
116 if (it != scene->lightgroups.end()) {
117 kbackground->lightgroup = it->second;
118 }
119 else {
120 kbackground->lightgroup = LIGHTGROUP_NONE;
121 }
122
124}
125
126void Background::device_free(Device * /*device*/, DeviceScene * /*dscene*/) {}
127
129{
130 Shader *bg_shader = get_shader(scene);
131 if (bg_shader && bg_shader->is_modified()) {
132 /* Tag as modified to update the KernelBackground visibility information.
133 * We only tag the use_shader socket as modified as it is related to the shader
134 * and to avoid doing unnecessary updates anywhere else. */
135 tag_use_shader_modified();
136 }
137}
138
140{
141 return (use_shader) ? ((shader) ? shader : scene->default_background) : scene->default_empty;
142}
143
NODE_DECLARE Background()
void device_update(Device *device, DeviceScene *dscene, Scene *scene)
void device_free(Device *device, DeviceScene *dscene)
Shader * get_shader(const Scene *scene)
void tag_update(Scene *scene)
~Background() override
KernelData data
Definition devicescene.h:89
bool has_volume
NODE_DECLARE unique_ptr< ShaderGraph > graph
#define SHADER_NONE
#define LIGHTGROUP_NONE
#define CCL_NAMESPACE_END
@ PATH_RAY_TRANSMIT
@ PATH_RAY_VOLUME_SCATTER
@ PATH_RAY_GLOSSY
@ PATH_RAY_ALL_VISIBILITY
@ PATH_RAY_DIFFUSE
@ PATH_RAY_CAMERA
@ SHADER_EXCLUDE_CAMERA
@ SHADER_EXCLUDE_DIFFUSE
@ SHADER_EXCLUDE_ANY
@ SHADER_EXCLUDE_SCATTER
@ SHADER_EXCLUDE_GLOSSY
@ SHADER_EXCLUDE_TRANSMIT
ccl_device_inline float sqr(const float a)
Definition math_base.h:600
#define SOCKET_FLOAT(name, ui_name, default_value,...)
Definition node_type.h:200
#define SOCKET_NODE(name, ui_name, node_type,...)
Definition node_type.h:229
#define SOCKET_UINT(name, ui_name, default_value,...)
Definition node_type.h:196
#define NODE_DEFINE(structname)
Definition node_type.h:148
#define SOCKET_BOOLEAN(name, ui_name, default_value,...)
Definition node_type.h:192
#define SOCKET_STRING(name, ui_name, default_value,...)
Definition node_type.h:212
static NodeType * add(const char *name, CreateFunc create, Type type=NONE, const NodeType *base=nullptr)
void dereference_all_used_nodes()
void clear_modified()
bool is_modified() const
Node(const NodeType *type, ustring name=ustring())
unique_ptr< SceneUpdateStats > update_stats
Definition scene.h:174
Shader * default_empty
Definition scene.h:160
Shader * default_background
Definition scene.h:159
unique_ptr< ShaderManager > shader_manager
Definition scene.h:148
Integrator * integrator
Definition scene.h:130
map< ustring, int > lightgroups
Definition scene.h:120
wmTimer * timer