diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2019-05-04 02:39:35 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2019-05-04 15:11:04 +0300 |
commit | b2f1a6587410d00ad3bbd22e045979f80048afe2 (patch) | |
tree | 8312daea35aed37a1cdba6d6e6e97958b7f21d47 /source/blender/draw/engines/eevee/eevee_materials.c | |
parent | 1d8ed6dcd7cd2b3ccfaaacb59387dca481262eb6 (diff) |
Sculpt: Refactor draw manager sculpt drawing mechanism
Workbench/Eevee now displays multiple multi-materials correctly.
Iterate over pbvh nodes when doing object iteration. This makes the
rendering process more streamlined and allow for using different materials.
This change will make possible to:
- Add culling pass of each pbvh leaf node. (speedup if zoomed on a small
area)
- Reduce number of lead node iteration.
- Reduce code complexity
Diffstat (limited to 'source/blender/draw/engines/eevee/eevee_materials.c')
-rw-r--r-- | source/blender/draw/engines/eevee/eevee_materials.c | 106 |
1 files changed, 41 insertions, 65 deletions
diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c index c6a523e4822..8ee5b51d825 100644 --- a/source/blender/draw/engines/eevee/eevee_materials.c +++ b/source/blender/draw/engines/eevee/eevee_materials.c @@ -1190,17 +1190,12 @@ void EEVEE_materials_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) #define ADD_SHGROUP_CALL(shgrp, ob, ma, geom, oedata) \ do { \ - if (is_sculpt_mode_draw) { \ - DRW_shgroup_call_sculpt_add(shgrp, ob, ob->obmat); \ + if (oedata) { \ + DRW_shgroup_call_object_add_with_callback( \ + shgrp, geom, ob, ma, EEVEE_lightprobes_obj_visibility_cb, oedata); \ } \ else { \ - if (oedata) { \ - DRW_shgroup_call_object_add_with_callback( \ - shgrp, geom, ob, ma, EEVEE_lightprobes_obj_visibility_cb, oedata); \ - } \ - else { \ - DRW_shgroup_call_object_add_ex(shgrp, geom, ob, ma, false); \ - } \ + DRW_shgroup_call_object_add_ex(shgrp, geom, ob, ma, false); \ } \ } while (0) @@ -1604,6 +1599,16 @@ static void material_transparent(Material *ma, } } +/* Return correct material or &defmaterial if slot is empty. */ +BLI_INLINE Material *eevee_object_material_get(Object *ob, int slot) +{ + Material *ma = give_current_material(ob, slot + 1); + if (ma == NULL) { + ma = &defmaterial; + } + return ma; +} + void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_ViewLayerData *sldata, Object *ob, @@ -1617,15 +1622,14 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, const bool do_cull = (draw_ctx->v3d && (draw_ctx->v3d->shading.flag & V3D_SHADING_BACKFACE_CULLING)); - const bool is_sculpt_mode = DRW_object_use_pbvh_drawing(ob); + bool is_sculpt_mode = DRW_object_use_pbvh_drawing(ob); /* For now just force fully shaded with eevee when supported. */ - const bool is_sculpt_mode_draw = ob->sculpt && ob->sculpt->pbvh && - BKE_pbvh_type(ob->sculpt->pbvh) != PBVH_FACES; - const bool is_default_mode_shader = is_sculpt_mode; + is_sculpt_mode = is_sculpt_mode && + !(ob->sculpt->pbvh && BKE_pbvh_type(ob->sculpt->pbvh) == PBVH_FACES); /* First get materials for this mesh. */ if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL)) { - const int materials_len = MAX2(1, (is_sculpt_mode_draw ? 1 : ob->totcol)); + const int materials_len = MAX2(1, ob->totcol); struct DRWShadingGroup **shgrp_array = BLI_array_alloca(shgrp_array, materials_len); struct DRWShadingGroup **shgrp_depth_array = BLI_array_alloca(shgrp_depth_array, @@ -1635,40 +1639,22 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, struct GPUMaterial **gpumat_array = BLI_array_alloca(gpumat_array, materials_len); struct GPUMaterial **gpumat_depth_array = BLI_array_alloca(gpumat_array, materials_len); + struct Material **ma_array = BLI_array_alloca(ma_array, materials_len); bool use_flat_nor = false; - - if (is_default_mode_shader) { - if (is_sculpt_mode_draw) { - use_flat_nor = DRW_object_is_flat_normal(ob); - } - } - for (int i = 0; i < materials_len; ++i) { - Material *ma; - - if (is_sculpt_mode_draw) { - ma = NULL; - } - else { - ma = give_current_material(ob, i + 1); - } - + ma_array[i] = eevee_object_material_get(ob, i); gpumat_array[i] = NULL; gpumat_depth_array[i] = NULL; shgrp_array[i] = NULL; shgrp_depth_array[i] = NULL; shgrp_depth_clip_array[i] = NULL; - if (ma == NULL) { - ma = &defmaterial; - } - - switch (ma->blend_method) { + switch (ma_array[i]->blend_method) { case MA_BM_SOLID: case MA_BM_CLIP: case MA_BM_HASHED: - material_opaque(ma, + material_opaque(ma_array[i], material_hash, sldata, vedata, @@ -1683,7 +1669,7 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, case MA_BM_ADD: case MA_BM_MULTIPLY: case MA_BM_BLEND: - material_transparent(ma, + material_transparent(ma_array[i], sldata, vedata, do_cull, @@ -1725,17 +1711,18 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, &auto_layer_count); } - if (is_sculpt_mode_draw || mat_geom) { + if (is_sculpt_mode) { + /* TODO(fclem): Support Vcol. */ + DRW_shgroup_call_sculpt_with_materials_add(shgrp_array, ma_array, ob, false); + DRW_shgroup_call_sculpt_with_materials_add(shgrp_depth_array, ma_array, ob, false); + DRW_shgroup_call_sculpt_with_materials_add(shgrp_depth_clip_array, ma_array, ob, false); + /* TODO(fclem): Support shadows in sculpt mode. */ + } + else if (mat_geom) { for (int i = 0; i < materials_len; ++i) { - if (!is_sculpt_mode_draw && mat_geom[i] == NULL) { + if (mat_geom[i] == NULL) { continue; } - EEVEE_ObjectEngineData *oedata = NULL; - Material *ma = give_current_material(ob, i + 1); - - if (ma == NULL) { - ma = &defmaterial; - } /* Do not render surface if we are rendering a volume object * and do not have a surface closure. */ @@ -1746,23 +1733,16 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, /* XXX TODO rewrite this to include the dupli objects. * This means we cannot exclude dupli objects from reflections!!! */ + EEVEE_ObjectEngineData *oedata = NULL; if ((ob->base_flag & BASE_FROM_DUPLI) == 0) { oedata = EEVEE_object_data_ensure(ob); oedata->ob = ob; oedata->test_data = &sldata->probes->vis_data; } - /* Shading pass */ - ADD_SHGROUP_CALL(shgrp_array[i], ob, ma, mat_geom[i], oedata); - - /* Depth Prepass */ - ADD_SHGROUP_CALL_SAFE(shgrp_depth_array[i], ob, ma, mat_geom[i], oedata); - ADD_SHGROUP_CALL_SAFE(shgrp_depth_clip_array[i], ob, ma, mat_geom[i], oedata); - - /* TODO(fclem): Don't support shadows in sculpt mode. */ - if (is_sculpt_mode_draw) { - break; - } + ADD_SHGROUP_CALL(shgrp_array[i], ob, ma_array[i], mat_geom[i], oedata); + ADD_SHGROUP_CALL_SAFE(shgrp_depth_array[i], ob, ma_array[i], mat_geom[i], oedata); + ADD_SHGROUP_CALL_SAFE(shgrp_depth_clip_array[i], ob, ma_array[i], mat_geom[i], oedata); char *name = auto_layer_names; for (int j = 0; j < auto_layer_count; ++j) { @@ -1785,19 +1765,19 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, /* Shadow Pass */ struct GPUMaterial *gpumat; - switch (ma->blend_shadow) { + switch (ma_array[i]->blend_shadow) { case MA_BS_SOLID: EEVEE_lights_cache_shcaster_add(sldata, stl, mat_geom[i], ob); *cast_shadow = true; break; case MA_BS_CLIP: - gpumat = EEVEE_material_mesh_depth_get(scene, ma, false, true); + gpumat = EEVEE_material_mesh_depth_get(scene, ma_array[i], false, true); EEVEE_lights_cache_shcaster_material_add( - sldata, psl, gpumat, mat_geom[i], ob, &ma->alpha_threshold); + sldata, psl, gpumat, mat_geom[i], ob, &ma_array[i]->alpha_threshold); *cast_shadow = true; break; case MA_BS_HASHED: - gpumat = EEVEE_material_mesh_depth_get(scene, ma, true, true); + gpumat = EEVEE_material_mesh_depth_get(scene, ma_array[i], true, true); EEVEE_lights_cache_shcaster_material_add(sldata, psl, gpumat, mat_geom[i], ob, NULL); *cast_shadow = true; break; @@ -1845,11 +1825,7 @@ void EEVEE_hair_cache_populate(EEVEE_Data *vedata, } DRWShadingGroup *shgrp = NULL; - Material *ma = give_current_material(ob, part->omat); - - if (ma == NULL) { - ma = &defmaterial; - } + Material *ma = eevee_object_material_get(ob, part->omat - 1); float *color_p = &ma->r; float *metal_p = &ma->metallic; |