Blender V5.0
scene/shader.h
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
2 *
3 * SPDX-License-Identifier: Apache-2.0 */
4
5#pragma once
6
7#ifdef WITH_OSL
8# include <cstdint> /* Needed before `sdlexec.h` for `int32_t` with GCC 15.1. */
9/* So no context pollution happens from indirectly included windows.h */
10# ifdef _WIN32
11# include "util/windows.h"
12# endif
13# include <OSL/oslexec.h>
14#endif
15
16#include "kernel/types.h"
17#include "scene/attribute.h"
18
19#include "graph/node.h"
20
21#include "util/map.h"
22#include "util/param.h"
23#include "util/string.h"
24#include "util/thread.h"
25#include "util/types.h"
26#include "util/unique_ptr.h"
27
29
30class Device;
31class DeviceScene;
32class Mesh;
33class Progress;
34class Scene;
35class ShaderGraph;
36struct float3;
37
39
40/* Keep those in sync with the python-defined enum. */
41
49
56
64
65/* Shader describing the appearance of a Mesh, Light or Background.
66 *
67 * While there is only a single shader graph, it has three outputs: surface,
68 * volume and displacement, that the shader manager will compile and execute
69 * separately. */
70
71class Shader : public Node {
72 public:
74
75 /* shader graph */
77
78 NODE_SOCKET_API(int, pass_id)
79
80 /* sampling */
81 NODE_SOCKET_API(EmissionSampling, emission_sampling_method)
82 NODE_SOCKET_API(bool, use_transparent_shadow)
83 NODE_SOCKET_API(bool, use_bump_map_correction)
84 NODE_SOCKET_API(VolumeSampling, volume_sampling_method)
85 NODE_SOCKET_API(int, volume_interpolation_method)
86 NODE_SOCKET_API(float, volume_step_rate)
87
88 /* displacement */
89 NODE_SOCKET_API(DisplacementMethod, displacement_method)
90
93
94 /* synchronization */
99
100 /* If the shader has only volume components, the surface is assumed to
101 * be transparent.
102 * However, graph optimization might remove the volume subgraph, but
103 * since the user connected something to the volume output the surface
104 * should still be transparent.
105 * Therefore, has_volume_connected stores whether some volume sub-tree
106 * was connected before optimization. */
108
109 /* information about shader after compiling */
122
126
127 /* requested mesh attributes */
129
130 /* determined before compiling */
132
133#ifdef WITH_OSL
134 /* Compiled osl shading state references. */
135 struct OSLCache {
136 OSL::ShaderGroupRef surface;
137 OSL::ShaderGroupRef bump;
138 OSL::ShaderGroupRef displacement;
139 OSL::ShaderGroupRef volume;
140 };
141 map<Device *, OSLCache> osl_cache;
142#endif
143
144 Shader();
145
146 /* Estimate emission of this shader based on the shader graph. This works only in very simple
147 * cases. But it helps improve light importance sampling in common cases.
148 *
149 * If the emission is fully constant, returns true, so that shader evaluation can be skipped
150 * entirely for a light. */
151 void estimate_emission();
152
154 void tag_update(Scene *scene);
155 void tag_used(Scene *scene);
156
157 /* Return true when either of the surface or displacement socket of the output node is linked.
158 * This should be used to ensure that surface attributes are also requested even when only the
159 * displacement socket is linked. */
160 bool has_surface_link() const
161 {
163 }
164
165 bool need_update_geometry() const;
166
168};
169
170/* Shader Manager virtual base class
171 *
172 * From this the SVM and OSL shader managers are derived, that do the actual
173 * shader compiling and device updating. */
174
176 public:
177 enum : uint32_t {
178 SHADER_ADDED = (1 << 0),
179 SHADER_MODIFIED = (1 << 2),
180
181 /* tag everything in the manager for an update */
183
185 };
186
187 static unique_ptr<ShaderManager> create(const int shadingsystem);
188 virtual ~ShaderManager();
189
190 virtual bool use_osl()
191 {
192 return false;
193 }
194
195 /* device update */
196 void device_update_pre(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress);
197 void device_update_post(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress);
198 virtual void device_free(Device *device, DeviceScene *dscene, Scene *scene) = 0;
199
200 /* get globally unique id for a type of attribute */
201 virtual uint64_t get_attribute_id(ustring name);
203
204 /* get shader id for mesh faces */
205 int get_shader_id(Shader *shader, bool smooth = false);
206
207 /* add default shaders to scene, to use as default for things that don't
208 * have any shader assigned explicitly */
209 static void add_default(Scene *scene);
210
211 /* Selective nodes compilation. */
213
214 float linear_rgb_to_gray(const float3 c);
216
217 string get_cryptomatte_materials(Scene *scene);
218
219 void tag_update(Scene *scene, const uint32_t flag);
220
221 bool need_update() const;
222
223 void init_xyz_transforms();
224
226
231
232 protected:
234
235 uint32_t update_flags;
236
237 using AttributeIDMap = unordered_map<ustring, uint64_t>;
239
241
242 unordered_map<const float *, size_t> bsdf_tables;
244
246
257
258 template<std::size_t n>
259 size_t ensure_bsdf_table(DeviceScene *dscene, Scene *scene, const float (&table)[n])
260 {
261 return ensure_bsdf_table_impl(dscene, scene, table, n);
262 }
263 size_t ensure_bsdf_table_impl(DeviceScene *dscene,
264 Scene *scene,
265 const float *table,
266 const size_t n);
267
269
271
272 virtual void device_update_specific(Device *device,
273 DeviceScene *dscene,
274 Scene *scene,
275 Progress &progress) = 0;
276
277 void device_update_common(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress);
278 void device_free_common(Device *device, DeviceScene *dscene, Scene *scene);
279};
280
unsigned int uint
unsigned long long int uint64_t
unordered_map< ustring, uint64_t > AttributeIDMap
string get_cryptomatte_materials(Scene *scene)
size_t thin_film_table_offset_
float3 rec709_to_scene_linear(const float3 c)
static unique_ptr< ShaderManager > create(const int shadingsystem)
void device_update_common(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress)
SceneLinearSpace scene_linear_space
virtual void device_free(Device *device, DeviceScene *dscene, Scene *scene)=0
size_t ensure_bsdf_table_impl(DeviceScene *dscene, Scene *scene, const float *table, const size_t n)
void device_update_pre(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress)
AttributeIDMap unique_attribute_id
float linear_rgb_to_gray(const float3 c)
virtual uint64_t get_attribute_id(ustring name)
void init_xyz_transforms()
SceneLinearSpace get_scene_linear_space()
virtual void device_update_specific(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress)=0
thread_spin_lock attribute_lock_
virtual ~ShaderManager()
void compute_thin_film_table(const Transform &xyz_to_rgb)
int get_shader_id(Shader *shader, bool smooth=false)
unordered_map< const float *, size_t > bsdf_tables
void device_update_post(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress)
bool need_update() const
void tag_update(Scene *scene, const uint32_t flag)
void device_free_common(Device *device, DeviceScene *dscene, Scene *scene)
static thread_mutex lookup_table_mutex
uint get_kernel_features(Scene *scene)
size_t ensure_bsdf_table(DeviceScene *dscene, Scene *scene, const float(&table)[n])
static void add_default(Scene *scene)
uint32_t update_flags
virtual bool use_osl()
uint get_graph_kernel_features(ShaderGraph *graph)
vector< float > thin_film_table
bool has_surface_spatial_varying
bool has_surface_link() const
bool has_surface_bssrdf
void estimate_emission()
bool need_update_attribute
bool has_volume_attribute_dependency
bool need_update_geometry() const
void set_graph(unique_ptr< ShaderGraph > &&graph)
bool has_volume
bool emission_is_constant
float3 emission_estimate
bool has_surface
bool has_light_path_node
bool has_bssrdf_bump
float prev_volume_step_rate
bool need_update_displacement
EmissionSampling emission_sampling
bool shadow_transparency_needs_realloc
bool has_surface_raytrace
bool need_update_uvs
bool has_displacement
bool has_bump
AttributeRequestSet attributes
bool has_surface_transparent
void tag_update(Scene *scene)
NODE_DECLARE unique_ptr< ShaderGraph > graph
bool prev_has_surface_shadow_transparency
bool has_surface_shadow_transparency() const
bool has_volume_connected
void tag_used(Scene *scene)
bool has_volume_spatial_varying
nullptr float
#define CCL_NAMESPACE_END
#define NODE_SOCKET_API(type_, name)
Definition graph/node.h:55
AttributeStandard
EmissionSampling
color xyz_to_rgb(float x, float y, float z)
Definition node_color.h:73
#define NODE_DECLARE
Definition node_type.h:145
const char * name
VolumeInterpolation
@ VOLUME_NUM_INTERPOLATION
@ VOLUME_INTERPOLATION_LINEAR
@ VOLUME_INTERPOLATION_CUBIC
DisplacementMethod
@ DISPLACE_NUM_METHODS
@ DISPLACE_BUMP
@ DISPLACE_TRUE
@ DISPLACE_BOTH
ShadingSystem
@ SHADINGSYSTEM_OSL
@ SHADINGSYSTEM_SVM
VolumeSampling
@ VOLUME_NUM_SAMPLING
@ VOLUME_SAMPLING_DISTANCE
@ VOLUME_SAMPLING_EQUIANGULAR
@ VOLUME_SAMPLING_MULTIPLE_IMPORTANCE
Node(const NodeType *type, ustring name=ustring())
std::mutex thread_mutex
Definition thread.h:27
tbb::spin_mutex thread_spin_lock
Definition thread.h:53
uint8_t flag
Definition wm_window.cc:145