Blender V4.5
eevee_material.hh
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#pragma once
10
11#include "DNA_material_types.h"
12
13#include "DRW_render.hh"
14
15#include "BLI_map.hh"
16#include "BLI_vector.hh"
17#include "GPU_material.hh"
18
19#include "eevee_sync.hh"
20
23
24namespace blender::eevee {
25
26class Instance;
27
28/* -------------------------------------------------------------------- */
32
49
51 /* These maps directly to object types. */
57
58 /* These maps to special shader. */
60};
61
62static inline bool geometry_type_has_surface(eMaterialGeometry geometry_type)
63{
64 return geometry_type < MAT_GEOM_VOLUME;
65}
66
71
72static inline eMaterialDisplacement to_displacement_type(int displacement_method)
73{
74 switch (displacement_method) {
76 /* Currently unsupported. Revert to vertex displacement + bump. */
80 default:
82 }
83}
84
86 /* These maps directly to thickness mode. */
89};
90
91static inline eMaterialThickness to_thickness_type(int thickness_mode)
92{
93 switch (thickness_mode) {
95 return MAT_THICKNESS_SLAB;
96 default:
98 }
99}
100
106
107static inline void material_type_from_shader_uuid(uint64_t shader_uuid,
108 eMaterialPipeline &pipeline_type,
109 eMaterialGeometry &geometry_type,
110 eMaterialDisplacement &displacement_type,
111 eMaterialThickness &thickness_type,
112 bool &transparent_shadows)
113{
114 const uint64_t geometry_mask = ((1u << 4u) - 1u);
115 const uint64_t pipeline_mask = ((1u << 4u) - 1u);
116 const uint64_t thickness_mask = ((1u << 1u) - 1u);
117 const uint64_t displacement_mask = ((1u << 1u) - 1u);
118 geometry_type = static_cast<eMaterialGeometry>(shader_uuid & geometry_mask);
119 pipeline_type = static_cast<eMaterialPipeline>((shader_uuid >> 4u) & pipeline_mask);
120 displacement_type = static_cast<eMaterialDisplacement>((shader_uuid >> 8u) & displacement_mask);
121 thickness_type = static_cast<eMaterialThickness>((shader_uuid >> 9u) & thickness_mask);
122 transparent_shadows = (shader_uuid >> 10u) & 1u;
123}
124
126 eMaterialPipeline pipeline_type,
127 eMaterialGeometry geometry_type,
130 char blend_flags = 0)
131{
132 BLI_assert(int64_t(displacement_type) < (1 << 1));
133 BLI_assert(int64_t(thickness_type) < (1 << 1));
134 BLI_assert(int64_t(geometry_type) < (1 << 4));
135 BLI_assert(int64_t(pipeline_type) < (1 << 4));
136 uint64_t transparent_shadows = blend_flags & MA_BL_TRANSPARENT_SHADOW ? 1 : 0;
137
138 uint64_t uuid;
139 uuid = geometry_type;
140 uuid |= pipeline_type << 4;
141 uuid |= displacement_type << 8;
142 uuid |= thickness_type << 9;
143 uuid |= transparent_shadows << 10;
144 return uuid;
145}
146
148
150{
151 eClosureBits closure_bits = eClosureBits(0);
153 closure_bits |= CLOSURE_DIFFUSE;
154 }
156 closure_bits |= CLOSURE_TRANSPARENCY;
157 }
159 closure_bits |= CLOSURE_TRANSLUCENT;
160 }
162 closure_bits |= CLOSURE_EMISSION;
163 }
165 closure_bits |= CLOSURE_REFLECTION;
166 }
168 closure_bits |= CLOSURE_CLEARCOAT;
169 }
171 closure_bits |= CLOSURE_SSS;
172 }
174 closure_bits |= CLOSURE_REFRACTION;
175 }
177 closure_bits |= CLOSURE_HOLDOUT;
178 }
180 closure_bits |= CLOSURE_AMBIENT_OCCLUSION;
181 }
183 closure_bits |= CLOSURE_SHADER_TO_RGBA;
184 }
185 return closure_bits;
186}
187
189{
190 switch (ob->type) {
191 case OB_CURVES:
192 return MAT_GEOM_CURVES;
193 case OB_VOLUME:
194 return MAT_GEOM_VOLUME;
195 case OB_GREASE_PENCIL:
196 return MAT_GEOM_GPENCIL;
197 case OB_POINTCLOUD:
198 return MAT_GEOM_POINTCLOUD;
199 default:
200 return MAT_GEOM_MESH;
201 }
202}
203
211
214 eMaterialPipeline pipeline,
215 short visibility_flags)
216 : mat(mat_)
217 {
219 geometry,
222 mat_->blend_flag);
223 options = (options << 1) | (visibility_flags & OB_HIDE_CAMERA ? 0 : 1);
224 options = (options << 1) | (visibility_flags & OB_HIDE_SHADOW ? 0 : 1);
225 options = (options << 1) | (visibility_flags & OB_HIDE_PROBE_CUBEMAP ? 0 : 1);
226 options = (options << 1) | (visibility_flags & OB_HIDE_PROBE_PLANAR ? 0 : 1);
227 }
228
230 {
231 return uint64_t(mat) + options;
232 }
233
234 bool operator<(const MaterialKey &k) const
235 {
236 if (mat == k.mat) {
237 return options < k.options;
238 }
239 return mat < k.mat;
240 }
241
242 bool operator==(const MaterialKey &k) const
243 {
244 return (mat == k.mat) && (options == k.options);
245 }
246};
247
249
250/* -------------------------------------------------------------------- */
254
261struct ShaderKey {
262 GPUShader *shader;
264
265 ShaderKey(GPUMaterial *gpumat, ::Material *blender_mat, eMaterialProbe probe_capture)
266 {
269 options = (options << 8) | blender_mat->blend_flag;
270 options = (options << 2) | uint64_t(probe_capture);
271 }
272
274 {
275 return uint64_t(shader) + options;
276 }
277
278 bool operator<(const ShaderKey &k) const
279 {
280 return (shader == k.shader) ? (options < k.options) : (shader < k.shader);
281 }
282
283 bool operator==(const ShaderKey &k) const
284 {
285 return (shader == k.shader) && (options == k.options);
286 }
287};
288
290
291/* -------------------------------------------------------------------- */
299
301 private:
302 bNodeTree *ntree_;
303 bNodeSocketValueRGBA *color_socket_;
304 bNodeSocketValueFloat *metallic_socket_;
305 bNodeSocketValueFloat *roughness_socket_;
306 bNodeSocketValueFloat *specular_socket_;
307
308 public:
311
314};
315
317
318/* -------------------------------------------------------------------- */
322
327
345
350
352 public:
357
361
362 private:
363 Instance &inst_;
364
365 Map<MaterialKey, Material> material_map_;
367
368 MaterialArray material_array_;
369
370 DefaultSurfaceNodeTree default_surface_ntree_;
371
372 ::Material *error_mat_;
373
374 uint64_t gpu_pass_last_update_ = 0;
375 uint64_t gpu_pass_next_update_ = 0;
376
377 Vector<GPUMaterialTexture *> texture_loading_queue_;
378
379 public:
382
383 void begin_sync();
384 void end_sync();
385
389 MaterialArray &material_array_get(Object *ob, bool has_motion);
394 Material &material_get(Object *ob, bool has_motion, int mat_nr, eMaterialGeometry geometry_type);
395
396 /* Request default materials and return DEFAULT_MATERIALS if they are compiled. */
398 {
399 return default_materials_load(false);
400 }
402 {
403 return default_materials_load(true);
404 }
405
406 private:
407 Material &material_sync(Object *ob,
408 ::Material *blender_mat,
409 eMaterialGeometry geometry_type,
410 bool has_motion);
411
413 ::Material *material_from_slot(Object *ob, int slot);
414 MaterialPass material_pass_get(Object *ob,
415 ::Material *blender_mat,
416 eMaterialPipeline pipeline_type,
417 eMaterialGeometry geometry_type,
418 eMaterialProbe probe_capture = MAT_PROBE_NONE);
419
420 /* Push unloaded texture used by this material to the texture loading queue. */
421 void queue_texture_loading(GPUMaterial *material);
422
423 ShaderGroups default_materials_load(bool block_until_ready = false);
424};
425
427
428} // namespace blender::eevee
#define BLI_assert(a)
Definition BLI_assert.h:46
#define ATTR_FALLTHROUGH
#define ENUM_OPERATORS(_type, _max)
@ MA_THICKNESS_SLAB
@ MA_BL_TRANSPARENT_SHADOW
@ MA_DISPLACEMENT_BOTH
@ MA_DISPLACEMENT_DISPLACE
@ OB_HIDE_CAMERA
@ OB_HIDE_PROBE_PLANAR
@ OB_HIDE_PROBE_CUBEMAP
@ OB_HIDE_SHADOW
@ OB_GREASE_PENCIL
@ OB_POINTCLOUD
@ OB_VOLUME
@ OB_CURVES
GPUShader * GPU_material_get_shader(GPUMaterial *material)
bool GPU_material_flag_get(const GPUMaterial *mat, eGPUMaterialFlag flag)
@ GPU_MATFLAG_SHADER_TO_RGBA
@ GPU_MATFLAG_EMISSION
@ GPU_MATFLAG_GLOSSY
@ GPU_MATFLAG_COAT
@ GPU_MATFLAG_AO
@ GPU_MATFLAG_REFRACT
@ GPU_MATFLAG_TRANSLUCENT
@ GPU_MATFLAG_HOLDOUT
@ GPU_MATFLAG_DIFFUSE
@ GPU_MATFLAG_TRANSPARENT
@ GPU_MATFLAG_SUBSURFACE
long long int int64_t
unsigned long long int uint64_t
detail::PassBase< command::DrawMultiBuf > Sub
Definition draw_pass.hh:490
bNodeTree * nodetree_get(::Material *ma)
A running instance of the engine.
ShaderGroups default_materials_load_async()
Material & material_get(Object *ob, bool has_motion, int mat_nr, eMaterialGeometry geometry_type)
MaterialArray & material_array_get(Object *ob, bool has_motion)
ShaderGroups default_materials_wait_ready()
static eMaterialDisplacement to_displacement_type(int displacement_method)
static bool geometry_type_has_surface(eMaterialGeometry geometry_type)
static eMaterialGeometry to_material_geometry(const Object *ob)
static eClosureBits shader_closure_bits_from_flag(const GPUMaterial *gpumat)
static void material_type_from_shader_uuid(uint64_t shader_uuid, eMaterialPipeline &pipeline_type, eMaterialGeometry &geometry_type, eMaterialDisplacement &displacement_type, eMaterialThickness &thickness_type, bool &transparent_shadows)
static uint64_t shader_uuid_from_material_type(eMaterialPipeline pipeline_type, eMaterialGeometry geometry_type, eMaterialDisplacement displacement_type=MAT_DISPLACEMENT_BUMP, eMaterialThickness thickness_type=MAT_THICKNESS_SPHERE, char blend_flags=0)
static eMaterialThickness to_thickness_type(int thickness_mode)
@ MAT_DISPLACEMENT_VERTEX_WITH_BUMP
@ MAT_PIPE_PREPASS_FORWARD_VELOCITY
@ MAT_PIPE_PREPASS_DEFERRED_VELOCITY
Vector< GPUMaterial * > gpu_materials
bool operator<(const MaterialKey &k) const
MaterialKey(::Material *mat_, eMaterialGeometry geometry, eMaterialPipeline pipeline, short visibility_flags)
bool operator==(const MaterialKey &k) const
MaterialPass lightprobe_sphere_shading
MaterialPass lightprobe_sphere_prepass
ShaderKey(GPUMaterial *gpumat, ::Material *blender_mat, eMaterialProbe probe_capture)
bool operator<(const ShaderKey &k) const
bool operator==(const ShaderKey &k) const