Blender V4.3
eevee_world.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2021 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include "BKE_lib_id.hh"
10#include "BKE_node.hh"
11#include "BKE_world.h"
12#include "BLI_math_rotation.h"
14#include "NOD_shader.h"
15
16#include "eevee_instance.hh"
17
18namespace blender::eevee {
19
20/* -------------------------------------------------------------------- */
24
26{
27 bNodeTree *ntree = bke::node_tree_add_tree(nullptr, "World Nodetree", ntreeType_Shader->idname);
28 bNode *background = bke::node_add_static_node(nullptr, ntree, SH_NODE_BACKGROUND);
30 bNodeSocket *background_out = bke::node_find_socket(background, SOCK_OUT, "Background");
31 bNodeSocket *output_in = bke::node_find_socket(output, SOCK_IN, "Surface");
32 bke::node_add_link(ntree, background, background_out, output, output_in);
34
35 color_socket_ =
36 (bNodeSocketValueRGBA *)bke::node_find_socket(background, SOCK_IN, "Color")->default_value;
37 ntree_ = ntree;
38}
39
45
47{
48 /* WARNING: This function is not thread-safe. Which is not a problem for the moment. */
49 copy_v3_fl3(color_socket_->value, wo->horr, wo->horg, wo->horb);
50 return ntree_;
51}
52
54
55/* -------------------------------------------------------------------- */
59
60World::~World()
61{
62 if (default_world_ != nullptr) {
63 BKE_id_free(nullptr, default_world_);
64 }
65}
66
67::World *World::default_world_get()
68{
69 if (default_world_ == nullptr) {
70 default_world_ = static_cast<::World *>(BKE_id_new_nomain(ID_WO, "EEVEEE default world"));
71 default_world_->horr = default_world_->horg = default_world_->horb = 0.0f;
72 default_world_->use_nodes = 0;
73 default_world_->nodetree = nullptr;
74 BLI_listbase_clear(&default_world_->gpumaterial);
75 }
76 return default_world_;
77}
78
79::World *World::scene_world_get()
80{
81 return (inst_.scene->world != nullptr) ? inst_.scene->world : default_world_get();
82}
83
85{
86 /* No sun extraction during baking. */
87 if (inst_.is_baking()) {
88 return 0.0;
89 }
90
91 float sun_threshold = scene_world_get()->sun_threshold;
92 if (inst_.use_studio_light()) {
93 /* Do not call `lookdev_world_.intensity_get()` as it might not be initialized yet. */
94 sun_threshold *= inst_.v3d->shading.studiolight_intensity;
95 }
96 return sun_threshold;
97}
98
99void World::sync()
100{
101 bool has_update = false;
102
103 WorldHandle wo_handle = {0};
104 if (inst_.scene->world != nullptr) {
105 /* Detect world update before overriding it. */
106 wo_handle = inst_.sync.sync_world(*inst_.scene->world);
107 has_update = wo_handle.recalc != 0;
108 }
109
110 /* Sync volume first since its result can override the surface world. */
111 sync_volume(wo_handle);
112
113 ::World *bl_world;
114 if (inst_.use_studio_light()) {
115 has_update |= lookdev_world_.sync(LookdevParameters(inst_.v3d));
116 bl_world = lookdev_world_.world_get();
117 }
118 else if ((inst_.view_layer->layflag & SCE_LAY_SKY) == 0) {
119 bl_world = default_world_get();
120 }
121 else if (has_volume_absorption_) {
122 bl_world = default_world_get();
123 }
124 else {
125 bl_world = scene_world_get();
126 }
127
128 bNodeTree *ntree = (bl_world->nodetree && bl_world->use_nodes) ?
129 bl_world->nodetree :
130 default_tree.nodetree_get(bl_world);
131
132 {
133 if (has_volume_absorption_) {
134 /* Replace world by black world. */
135 bl_world = default_world_get();
136 }
137 }
138
139 /* We have to manually test here because we have overrides. */
140 ::World *orig_world = (::World *)DEG_get_original_id(&bl_world->id);
141 if (assign_if_different(prev_original_world, orig_world)) {
142 has_update = true;
143 }
144
145 inst_.light_probes.sync_world(bl_world, has_update);
146
147 GPUMaterial *gpumat = inst_.shaders.world_shader_get(bl_world, ntree, MAT_PIPE_DEFERRED);
148
149 inst_.manager->register_layer_attributes(gpumat);
150
151 float opacity = inst_.use_studio_light() ? lookdev_world_.background_opacity_get() :
152 inst_.film.background_opacity_get();
153 float background_blur = inst_.use_studio_light() ? lookdev_world_.background_blur_get() : 0.0;
154
155 inst_.pipelines.background.sync(gpumat, opacity, background_blur);
156 inst_.pipelines.world.sync(gpumat);
157}
158
159void World::sync_volume(const WorldHandle &world_handle)
160{
161 /* Studio lights have no volume shader. */
162 ::World *world = inst_.use_studio_light() ? nullptr : inst_.scene->world;
163
164 GPUMaterial *gpumat = nullptr;
165
166 /* Only the scene world nodetree can have volume shader. */
167 if (world && world->nodetree && world->use_nodes) {
168 gpumat = inst_.shaders.world_shader_get(world, world->nodetree, MAT_PIPE_VOLUME_MATERIAL);
169 }
170
171 bool had_volume = has_volume_;
172
173 if (gpumat && (GPU_material_status(gpumat) == GPU_MAT_SUCCESS)) {
174 has_volume_ = GPU_material_has_volume_output(gpumat);
175 has_volume_scatter_ = GPU_material_flag_get(gpumat, GPU_MATFLAG_VOLUME_SCATTER);
176 has_volume_absorption_ = GPU_material_flag_get(gpumat, GPU_MATFLAG_VOLUME_ABSORPTION);
177 }
178 else {
179 has_volume_ = has_volume_absorption_ = has_volume_scatter_ = false;
180 }
181
182 /* World volume needs to be always synced for correct clearing of parameter buffers. */
183 inst_.pipelines.world_volume.sync(gpumat);
184
185 if (has_volume_ || had_volume) {
186 inst_.volume.world_sync(world_handle);
187 }
188}
189
191
192} // namespace blender::eevee
void BKE_id_free(Main *bmain, void *idv)
void * BKE_id_new_nomain(short type, const char *name)
Definition lib_id.cc:1487
#define SH_NODE_OUTPUT_WORLD
Definition BKE_node.hh:914
#define SH_NODE_BACKGROUND
Definition BKE_node.hh:919
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
MINLINE void copy_v3_fl3(float v[3], float x, float y, float z)
ID * DEG_get_original_id(ID *id)
@ ID_WO
@ SOCK_OUT
@ SOCK_IN
@ SCE_LAY_SKY
bool GPU_material_flag_get(const GPUMaterial *mat, eGPUMaterialFlag flag)
eGPUMaterialStatus GPU_material_status(GPUMaterial *mat)
@ GPU_MATFLAG_VOLUME_SCATTER
@ GPU_MATFLAG_VOLUME_ABSORPTION
@ GPU_MAT_SUCCESS
bool GPU_material_has_volume_output(GPUMaterial *mat)
#define MEM_SAFE_FREE(v)
struct blender::bke::bNodeTreeType * ntreeType_Shader
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Gabor Generate Gabor noise Gradient Generate interpolated color and intensity values based on the input vector Magic Generate a psychedelic color texture Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a or normal between world
#define output
bNodeTree * nodetree_get(::World *world)
GPUMaterial * world_shader_get(::World *blender_world, bNodeTree *nodetree, eMaterialPipeline pipeline_type)
void world_sync(const WorldHandle &world_handle)
World(Instance &inst)
void node_set_active(bNodeTree *ntree, bNode *node)
Definition node.cc:3896
bNode * node_add_static_node(const bContext *C, bNodeTree *ntree, int type)
Definition node.cc:2642
bNodeLink * node_add_link(bNodeTree *ntree, bNode *fromnode, bNodeSocket *fromsock, bNode *tonode, bNodeSocket *tosock)
Definition node.cc:2912
bNodeTree * node_tree_add_tree(Main *bmain, const char *name, const char *idname)
Definition node.cc:3226
bNodeSocket * node_find_socket(bNode *node, eNodeSocketInOut in_out, StringRef identifier)
Definition node.cc:1829
void node_tree_free_embedded_tree(bNodeTree *ntree)
Definition node.cc:3632
bool assign_if_different(T &old_value, T new_value)
struct World * world
struct bNodeTree * nodetree
float horg
short use_nodes
float horb
float sun_threshold
float horr