121 gpu_pass_last_update_ = gpu_pass_next_update_;
122 gpu_pass_next_update_ = next_update;
124 texture_loading_queue_.clear();
125 material_map_.clear();
129void MaterialModule::queue_texture_loading(
GPUMaterial *material)
134 const bool use_tile_mapping = tex->tiled_mapping_name[0];
135 ImageUser *iuser = tex->iuser_available ? &tex->iuser :
nullptr;
137 tex->ima, iuser, use_tile_mapping);
138 if (*gputex.
texture ==
nullptr) {
139 texture_loading_queue_.
append(tex);
147 if (texture_loading_queue_.is_empty()) {
151 if (inst_.is_viewport()) {
153 inst_.sampling.reset();
160 for (auto i : range) {
161 GPUMaterialTexture *tex = texture_loading_queue_[i];
162 ImageUser *iuser = tex->iuser_available ? &tex->iuser : nullptr;
163 BKE_image_get_tile(tex->ima, 0);
164 threading::isolate_task([&]() {
165 ImBuf *imbuf = BKE_image_acquire_ibuf(tex->ima, iuser, nullptr);
166 BKE_image_release_ibuf(tex->ima, imbuf, nullptr);
182 const bool use_tile_mapping = tex->tiled_mapping_name[0];
183 ImageUser *iuser = tex->iuser_available ? &tex->iuser :
nullptr;
185 tex->ima, iuser, use_tile_mapping);
188 inst_.manager->acquire_texture(*gputex.
texture);
196 texture_loading_queue_.clear();
199MaterialPass MaterialModule::material_pass_get(
Object *ob,
201 eMaterialPipeline pipeline_type,
202 eMaterialGeometry geometry_type,
203 eMaterialProbe probe_capture)
206 default_surface->nodetree;
209 bool use_deferred_compilation = !inst_.is_viewport_image_render;
211 const bool is_volume =
ELEM(pipeline_type, MAT_PIPE_VOLUME_OCCUPANCY, MAT_PIPE_VOLUME_MATERIAL);
212 ::Material *default_mat = is_volume ? default_volume : default_surface;
214 MaterialPass matpass = MaterialPass();
215 matpass.gpumat = inst_.shaders.material_shader_get(
216 blender_mat, ntree, pipeline_type, geometry_type, use_deferred_compilation, default_mat);
218 queue_texture_loading(matpass.gpumat);
220 const bool is_forward =
ELEM(pipeline_type,
222 MAT_PIPE_PREPASS_FORWARD,
223 MAT_PIPE_PREPASS_FORWARD_VELOCITY,
224 MAT_PIPE_PREPASS_OVERLAP);
231 queued_optimize_shaders_count++;
236 queued_shaders_count++;
237 matpass.gpumat = inst_.shaders.material_shader_get(
238 default_mat, default_mat->
nodetree, pipeline_type, geometry_type,
false,
nullptr);
242 matpass.gpumat = inst_.shaders.material_shader_get(
243 error_mat_, error_mat_->nodetree, pipeline_type, geometry_type,
false,
nullptr);
249 inst_.manager->register_layer_attributes(matpass.gpumat);
255 if (inst_.is_viewport() && use_deferred_compilation && pass_updated) {
256 inst_.sampling.reset();
262 if (((pipeline_type == MAT_PIPE_SHADOW) && (is_transparent || has_displacement)) || has_volume)
267 inst_.shadows.reset();
271 if (is_volume || (is_forward && is_transparent)) {
273 matpass.sub_pass =
nullptr;
276 ShaderKey shader_key(matpass.gpumat, blender_mat, probe_capture);
278 PassMain::Sub *shader_sub = shader_map_.lookup_or_add_cb(shader_key, [&]() {
280 return inst_.pipelines.material_add(
281 ob, blender_mat, matpass.gpumat, pipeline_type, probe_capture);
284 if (shader_sub !=
nullptr) {
287 matpass.sub_pass->material_set(*inst_.manager, matpass.gpumat,
true);
290 matpass.sub_pass =
nullptr;
299 eMaterialGeometry geometry_type,
304 if (geometry_type == MAT_GEOM_VOLUME) {
305 MaterialKey material_key(
306 blender_mat, geometry_type, MAT_PIPE_VOLUME_MATERIAL, ob->
visibility_flag);
307 Material &mat = material_map_.lookup_or_add_cb(material_key, [&]() {
309 mat.volume_occupancy = material_pass_get(
310 ob, blender_mat, MAT_PIPE_VOLUME_OCCUPANCY, MAT_GEOM_VOLUME);
311 mat.volume_material = material_pass_get(
312 ob, blender_mat, MAT_PIPE_VOLUME_MATERIAL, MAT_GEOM_VOLUME);
317 VolumeLayer *layer = hide_on_camera ?
nullptr :
318 inst_.pipelines.volume.register_and_get_layer(ob);
320 mat.volume_occupancy.sub_pass = layer->occupancy_add(
321 ob, blender_mat, mat.volume_occupancy.gpumat);
322 mat.volume_material.sub_pass = layer->material_add(
323 ob, blender_mat, mat.volume_material.gpumat);
327 mat.volume_occupancy.sub_pass =
nullptr;
328 mat.volume_material.sub_pass =
nullptr;
336 if (use_forward_pipeline) {
345 MaterialKey material_key(blender_mat, geometry_type, surface_pipe, ob->
visibility_flag);
347 Material &mat = material_map_.lookup_or_add_cb(material_key, [&]() {
349 if (inst_.is_baking()) {
351 mat.capture = MaterialPass();
354 mat.capture = material_pass_get(ob, blender_mat, MAT_PIPE_CAPTURE, geometry_type);
356 mat.prepass = MaterialPass();
359 mat.shading = material_pass_get(ob, blender_mat, surface_pipe, geometry_type);
360 mat.overlap_masking = MaterialPass();
361 mat.lightprobe_sphere_prepass = MaterialPass();
362 mat.lightprobe_sphere_shading = MaterialPass();
363 mat.planar_probe_prepass = MaterialPass();
364 mat.planar_probe_shading = MaterialPass();
365 mat.volume_occupancy = MaterialPass();
366 mat.volume_material = MaterialPass();
367 mat.has_volume =
false;
372 if (!hide_on_camera) {
373 mat.prepass = material_pass_get(ob, blender_mat, prepass_pipe, geometry_type);
376 mat.prepass = MaterialPass();
379 mat.shading = material_pass_get(ob, blender_mat, surface_pipe, geometry_type);
380 if (hide_on_camera) {
383 mat.shading.sub_pass =
nullptr;
386 mat.overlap_masking = MaterialPass();
387 mat.capture = MaterialPass();
391 mat.lightprobe_sphere_prepass = material_pass_get(
392 ob, blender_mat, MAT_PIPE_PREPASS_DEFERRED, geometry_type, MAT_PROBE_REFLECTION);
393 mat.lightprobe_sphere_shading = material_pass_get(
394 ob, blender_mat, MAT_PIPE_DEFERRED, geometry_type, MAT_PROBE_REFLECTION);
397 mat.lightprobe_sphere_prepass = MaterialPass();
398 mat.lightprobe_sphere_shading = MaterialPass();
402 mat.planar_probe_prepass = material_pass_get(
403 ob, blender_mat, MAT_PIPE_PREPASS_PLANAR, geometry_type, MAT_PROBE_PLANAR);
404 mat.planar_probe_shading = material_pass_get(
405 ob, blender_mat, MAT_PIPE_DEFERRED, geometry_type, MAT_PROBE_PLANAR);
408 mat.planar_probe_prepass = MaterialPass();
409 mat.planar_probe_shading = MaterialPass();
414 if (mat.has_volume && !hide_on_camera) {
415 mat.volume_occupancy = material_pass_get(
416 ob, blender_mat, MAT_PIPE_VOLUME_OCCUPANCY, geometry_type);
417 mat.volume_material = material_pass_get(
418 ob, blender_mat, MAT_PIPE_VOLUME_MATERIAL, geometry_type);
421 mat.volume_occupancy = MaterialPass();
422 mat.volume_material = MaterialPass();
427 mat.shadow = material_pass_get(ob, blender_mat, MAT_PIPE_SHADOW, geometry_type);
430 mat.shadow = MaterialPass();
433 mat.is_alpha_blend_transparent = use_forward_pipeline &&
443 if (mat.is_alpha_blend_transparent && !hide_on_camera) {
446 mat.overlap_masking.sub_pass = inst_.pipelines.forward.prepass_transparent_add(
447 ob, blender_mat, mat.shading.gpumat);
448 mat.shading.sub_pass = inst_.pipelines.forward.material_transparent_add(
449 ob, blender_mat, mat.shading.gpumat);
452 if (mat.has_volume) {
454 VolumeLayer *layer = hide_on_camera ?
nullptr :
455 inst_.pipelines.volume.register_and_get_layer(ob);
457 mat.volume_occupancy.sub_pass = layer->occupancy_add(
458 ob, blender_mat, mat.volume_occupancy.gpumat);
459 mat.volume_material.sub_pass = layer->material_add(
460 ob, blender_mat, mat.volume_material.gpumat);
464 mat.volume_occupancy.sub_pass =
nullptr;
465 mat.volume_material.sub_pass =
nullptr;
485 material_array_.materials.clear();
486 material_array_.gpu_materials.clear();
495 material_array_.materials.append(mat);
498 return material_array_;
507 material_from_slot(ob, mat_nr);
508 Material &mat = material_sync(ob, blender_mat, geometry_type, has_motion);
512ShaderGroups MaterialModule::default_materials_load(
bool block_until_ready)
514 bool shaders_are_ready =
true;
516 GPUMaterial *gpu_mat = inst_.shaders.material_shader_get(
517 mat, mat->
nodetree, pipeline, geom, !block_until_ready,
nullptr);
521 request_shader(default_surface, MAT_PIPE_PREPASS_DEFERRED, MAT_GEOM_MESH);
522 request_shader(default_surface, MAT_PIPE_PREPASS_DEFERRED_VELOCITY, MAT_GEOM_MESH);
523 request_shader(default_surface, MAT_PIPE_DEFERRED, MAT_GEOM_MESH);
524 request_shader(default_surface, MAT_PIPE_SHADOW, MAT_GEOM_MESH);
526 return shaders_are_ready ? DEFAULT_MATERIALS :
NONE;
ImageGPUTextures BKE_image_get_gpu_material_texture_try(Image *image, ImageUser *iuser, const bool use_tile_mapping)
void BKE_image_tag_time(Image *ima)
ImageGPUTextures BKE_image_get_gpu_material_texture(Image *image, ImageUser *iuser, const bool use_tile_mapping)
void BKE_id_free(Main *bmain, void *idv)
ID * BKE_id_copy_ex(Main *bmain, const ID *id, ID **new_id_p, int flag)
void * BKE_id_new_nomain(short type, const char *name)
General operations, lookup, etc. for materials.
Material * BKE_material_default_surface()
Material * BKE_material_default_volume()
Material * BKE_object_material_get_eval(Object *ob, short act)
int BKE_object_material_used_with_fallback_eval(const Object &ob)
#define SH_NODE_BSDF_DIFFUSE
#define SH_NODE_OUTPUT_MATERIAL
#define SH_NODE_BSDF_GLOSSY
MINLINE void copy_v3_fl3(float v[3], float x, float y, float z)
MINLINE void copy_v3_fl(float r[3], float f)
Platform independent time functions.
T * DEG_get_evaluated(const Depsgraph *depsgraph, T *id)
@ MA_BL_TRANSPARENT_SHADOW
@ MA_SURFACE_METHOD_FORWARD
struct bNodeTree bNodeTree
void GPU_debug_group_end()
void GPU_debug_group_begin(const char *name)
bool GPU_material_has_surface_output(GPUMaterial *mat)
bool GPU_material_flag_get(const GPUMaterial *mat, eGPUMaterialFlag flag)
ListBase GPU_material_textures(GPUMaterial *material)
GPUMaterialStatus GPU_material_status(GPUMaterial *mat)
@ GPU_MATFLAG_TRANSPARENT
uint64_t GPU_material_compilation_timestamp(GPUMaterial *mat)
@ GPU_MAT_OPTIMIZATION_QUEUED
const char * GPU_material_get_name(GPUMaterial *material)
bool GPU_material_has_displacement_output(GPUMaterial *mat)
bool GPU_material_has_volume_output(GPUMaterial *mat)
eGPUMaterialOptimizationStatus GPU_material_optimization_status(GPUMaterial *mat)
uint64_t GPU_pass_global_compilation_count()
struct blender::bke::bNodeTreeType * ntreeType_Shader
unsigned long long int uint64_t
void append(const T &value)
A running instance of the engine.
MaterialModule(Instance &inst)
::Material * default_volume
Material & material_get(Object *ob, bool has_motion, int mat_nr, eMaterialGeometry geometry_type)
::Material * metallic_mat
int64_t queued_textures_count
MaterialArray & material_array_get(Object *ob, bool has_motion)
::Material * default_surface
int64_t queued_optimize_shaders_count
int64_t queued_shaders_count
::Material * material_override
bNodeTree * node_tree_add_tree_embedded(Main *bmain, ID *owner_id, StringRefNull name, StringRefNull idname)
bNodeSocket * node_find_socket(bNode &node, eNodeSocketInOut in_out, StringRef identifier)
bNode * node_add_static_node(const bContext *C, bNodeTree &ntree, int type)
bNodeLink & node_add_link(bNodeTree &ntree, bNode &fromnode, bNodeSocket &fromsock, bNode &tonode, bNodeSocket &tosock)
void node_set_active(bNodeTree &ntree, bNode &node)
static eMaterialGeometry to_material_geometry(const Object *ob)
@ MAT_PIPE_PREPASS_FORWARD_VELOCITY
@ MAT_PIPE_PREPASS_DEFERRED
@ MAT_PIPE_PREPASS_DEFERRED_VELOCITY
@ MAT_PIPE_PREPASS_FORWARD
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
ListBaseWrapperTemplate< ListBase, T > ListBaseWrapper
blender::gpu::Texture ** tile_mapping
blender::gpu::Texture ** texture
struct bNodeTree * nodetree
char surface_render_method