Blender V4.5
blender/light.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/light.h"
6
7#include "DNA_light_types.h"
8
10
11#include "blender/sync.h"
12#include "blender/util.h"
13#include "scene/object.h"
14
16
17void BlenderSync::sync_light(BObjectInfo &b_ob_info, Light *light)
18{
19 BL::Light b_light(b_ob_info.object_data);
20
21 light->name = b_light.name().c_str();
22
23 /* type */
24 switch (b_light.type()) {
25 case BL::Light::type_POINT: {
26 BL::PointLight b_point_light(b_light);
27 light->set_size(b_point_light.shadow_soft_size());
28 light->set_light_type(LIGHT_POINT);
29 light->set_is_sphere(!b_point_light.use_soft_falloff());
30 break;
31 }
32 case BL::Light::type_SPOT: {
33 BL::SpotLight b_spot_light(b_light);
34 light->set_size(b_spot_light.shadow_soft_size());
35 light->set_light_type(LIGHT_SPOT);
36 light->set_spot_angle(b_spot_light.spot_size());
37 light->set_spot_smooth(b_spot_light.spot_blend());
38 light->set_is_sphere(!b_spot_light.use_soft_falloff());
39 break;
40 }
41 /* Hemi were removed from 2.8 */
42 // case BL::Light::type_HEMI: {
43 // light->type = LIGHT_DISTANT;
44 // light->size = 0.0f;
45 // break;
46 // }
47 case BL::Light::type_SUN: {
48 BL::SunLight b_sun_light(b_light);
49 light->set_angle(b_sun_light.angle());
50 light->set_light_type(LIGHT_DISTANT);
51 break;
52 }
53 case BL::Light::type_AREA: {
54 BL::AreaLight b_area_light(b_light);
55 light->set_size(1.0f);
56 light->set_sizeu(b_area_light.size());
57 light->set_spread(b_area_light.spread());
58 switch (b_area_light.shape()) {
59 case BL::AreaLight::shape_SQUARE:
60 light->set_sizev(light->get_sizeu());
61 light->set_ellipse(false);
62 break;
63 case BL::AreaLight::shape_RECTANGLE:
64 light->set_sizev(b_area_light.size_y());
65 light->set_ellipse(false);
66 break;
67 case BL::AreaLight::shape_DISK:
68 light->set_sizev(light->get_sizeu());
69 light->set_ellipse(true);
70 break;
71 case BL::AreaLight::shape_ELLIPSE:
72 light->set_sizev(b_area_light.size_y());
73 light->set_ellipse(true);
74 break;
75 }
76 light->set_light_type(LIGHT_AREA);
77 break;
78 }
79 }
80
81 /* Color and strength. */
82 float3 light_color = get_float3(b_light.color());
83 if (b_light.use_temperature()) {
84 light_color *= get_float3(b_light.temperature_color());
85 }
86
87 const float3 strength = light_color * BL::PointLight(b_light).energy() *
88 exp2f(b_light.exposure());
89 light->set_strength(strength);
90
91 /* normalize */
92 light->set_normalize(b_light.normalize());
93
94 /* shadow */
95 PointerRNA clight = RNA_pointer_get(&b_light.ptr, "cycles");
96 light->set_cast_shadow(b_light.use_shadow());
97 light->set_use_mis(get_boolean(clight, "use_multiple_importance_sampling"));
98
99 /* caustics light */
100 light->set_use_caustics(get_boolean(clight, "is_caustics_light"));
101
102 light->set_max_bounces(get_int(clight, "max_bounces"));
103
104 if (light->get_light_type() == LIGHT_AREA) {
105 light->set_is_portal(get_boolean(clight, "is_portal"));
106 }
107 else {
108 light->set_is_portal(false);
109 }
110
111 if (light->get_is_portal()) {
112 world_use_portal = true;
113 }
114
115 /* tag */
116 light->tag_update(scene);
117}
118
119void BlenderSync::sync_background_light(BL::SpaceView3D &b_v3d)
120{
121 BL::World b_world = view_layer.world_override ? view_layer.world_override : b_scene.world();
122
123 if (b_world) {
124 PointerRNA cworld = RNA_pointer_get(&b_world.ptr, "cycles");
125
126 enum SamplingMethod { SAMPLING_NONE = 0, SAMPLING_AUTOMATIC, SAMPLING_MANUAL, SAMPLING_NUM };
127 const int sampling_method = get_enum(
128 cworld, "sampling_method", SAMPLING_NUM, SAMPLING_AUTOMATIC);
129 const bool sample_as_light = (sampling_method != SAMPLING_NONE);
130
131 if (sample_as_light || world_use_portal) {
132 /* Create object. */
133 Object *object;
134 const ObjectKey object_key(b_world, nullptr, b_world, false);
135 bool update = object_map.add_or_update(&object, b_world, b_world, object_key);
136 if (update) {
137 /* Lights should be shadow catchers by default. */
138 object->set_is_shadow_catcher(true);
139 object->set_lightgroup(ustring(b_world ? b_world.lightgroup() : ""));
140 }
141
142 /* Create geometry. */
143 const GeometryKey geom_key{b_world.ptr.data, Geometry::LIGHT};
144 Geometry *geom = geometry_map.find(geom_key);
145 if (geom) {
146 update |= geometry_map.update(geom, b_world);
147 }
148 else {
149 geom = scene->create_node<Light>();
150 geometry_map.add(geom_key, geom);
151 object->set_geometry(geom);
152 update = true;
153 }
154
155 if (update || world_recalc || b_world.ptr.data != world_map) {
156 /* Initialize light geometry. */
157 Light *light = static_cast<Light *>(geom);
158
159 light->set_light_type(LIGHT_BACKGROUND);
160 if (sampling_method == SAMPLING_MANUAL) {
161 light->set_map_resolution(get_int(cworld, "sample_map_resolution"));
162 }
163 else {
164 light->set_map_resolution(0);
165 }
166 array<Node *> used_shaders;
167 used_shaders.push_back_slow(scene->default_background);
168 light->set_used_shaders(used_shaders);
169 light->set_use_mis(sample_as_light);
170 light->set_max_bounces(get_int(cworld, "max_bounces"));
171
172 /* force enable light again when world is resynced */
173 light->set_is_enabled(true);
174
175 /* caustic light */
176 light->set_use_caustics(get_boolean(cworld, "is_caustics_light"));
177
178 light->tag_update(scene);
179 geometry_map.set_recalc(b_world);
180 }
181 }
182 }
183
184 world_map = b_world.ptr.data;
185 world_recalc = false;
186 viewport_parameters = BlenderViewportParameters(b_v3d, use_developer_ui);
187}
188
struct Light Light
struct Object Object
void push_back_slow(const T &t)
static bool get_boolean(PointerRNA &ptr, const char *name)
static int get_int(PointerRNA &ptr, const char *name)
static float3 get_float3(const BL::Array< float, 2 > &array)
static int get_enum(PointerRNA &ptr, const char *name, int num_values=-1, int default_value=-1)
#define CCL_NAMESPACE_END
VecBase< float, 3 > float3
@ LIGHT_AREA
@ LIGHT_DISTANT
@ LIGHT_SPOT
@ LIGHT_BACKGROUND
@ LIGHT_POINT
static void update(bNodeTree *ntree)
PointerRNA RNA_pointer_get(PointerRNA *ptr, const char *name)
void tag_update(Scene *scene)
ustring name
Definition graph/node.h:177