Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/draw/engines')
-rw-r--r--source/blender/draw/engines/eevee/eevee_cryptomatte.c11
-rw-r--r--source/blender/draw/engines/eevee/eevee_engine.c4
-rw-r--r--source/blender/draw/engines/eevee/eevee_lightcache.c21
-rw-r--r--source/blender/draw/engines/eevee/eevee_materials.c2
-rw-r--r--source/blender/draw/engines/eevee/eevee_private.h4
-rw-r--r--source/blender/draw/engines/eevee/eevee_render.c2
-rw-r--r--source/blender/draw/engines/eevee/eevee_shaders.c12
-rw-r--r--source/blender/draw/engines/eevee/eevee_volumes.c8
-rw-r--r--source/blender/draw/engines/eevee/shaders/closure_type_lib.glsl4
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_dof_resolve_frag.glsl2
-rw-r--r--source/blender/draw/engines/eevee/shaders/lightprobe_filter_diffuse_frag.glsl2
-rw-r--r--source/blender/draw/engines/eevee/shaders/prepass_frag.glsl14
-rw-r--r--source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl3
-rw-r--r--source/blender/draw/engines/eevee/shaders/shadow_vert.glsl4
-rw-r--r--source/blender/draw/engines/eevee/shaders/surface_frag.glsl6
-rw-r--r--source/blender/draw/engines/eevee/shaders/surface_lib.glsl8
-rw-r--r--source/blender/draw/engines/eevee/shaders/surface_vert.glsl4
-rw-r--r--source/blender/draw/engines/eevee/shaders/volumetric_frag.glsl4
-rw-r--r--source/blender/draw/engines/eevee/shaders/volumetric_vert.glsl5
-rw-r--r--source/blender/draw/engines/eevee_next/eevee_cryptomatte.cc132
-rw-r--r--source/blender/draw/engines/eevee_next/eevee_cryptomatte.hh68
-rw-r--r--source/blender/draw/engines/eevee_next/eevee_defines.hh47
-rw-r--r--source/blender/draw/engines/eevee_next/eevee_depth_of_field.cc363
-rw-r--r--source/blender/draw/engines/eevee_next/eevee_depth_of_field.hh39
-rw-r--r--source/blender/draw/engines/eevee_next/eevee_engine.cc22
-rw-r--r--source/blender/draw/engines/eevee_next/eevee_film.cc237
-rw-r--r--source/blender/draw/engines/eevee_next/eevee_film.hh109
-rw-r--r--source/blender/draw/engines/eevee_next/eevee_hizbuffer.cc99
-rw-r--r--source/blender/draw/engines/eevee_next/eevee_hizbuffer.hh88
-rw-r--r--source/blender/draw/engines/eevee_next/eevee_instance.cc117
-rw-r--r--source/blender/draw/engines/eevee_next/eevee_instance.hh10
-rw-r--r--source/blender/draw/engines/eevee_next/eevee_light.cc125
-rw-r--r--source/blender/draw/engines/eevee_next/eevee_light.hh21
-rw-r--r--source/blender/draw/engines/eevee_next/eevee_material.cc93
-rw-r--r--source/blender/draw/engines/eevee_next/eevee_material.hh15
-rw-r--r--source/blender/draw/engines/eevee_next/eevee_motion_blur.cc70
-rw-r--r--source/blender/draw/engines/eevee_next/eevee_motion_blur.hh6
-rw-r--r--source/blender/draw/engines/eevee_next/eevee_pipeline.cc326
-rw-r--r--source/blender/draw/engines/eevee_next/eevee_pipeline.hh84
-rw-r--r--source/blender/draw/engines/eevee_next/eevee_renderbuffers.cc38
-rw-r--r--source/blender/draw/engines/eevee_next/eevee_renderbuffers.hh5
-rw-r--r--source/blender/draw/engines/eevee_next/eevee_sampling.hh6
-rw-r--r--source/blender/draw/engines/eevee_next/eevee_shader.cc42
-rw-r--r--source/blender/draw/engines/eevee_next/eevee_shader.hh4
-rw-r--r--source/blender/draw/engines/eevee_next/eevee_shader_shared.hh92
-rw-r--r--source/blender/draw/engines/eevee_next/eevee_sync.cc87
-rw-r--r--source/blender/draw/engines/eevee_next/eevee_sync.hh12
-rw-r--r--source/blender/draw/engines/eevee_next/eevee_velocity.cc19
-rw-r--r--source/blender/draw/engines/eevee_next/eevee_velocity.hh22
-rw-r--r--source/blender/draw/engines/eevee_next/eevee_view.cc18
-rw-r--r--source/blender/draw/engines/eevee_next/eevee_view.hh3
-rw-r--r--source/blender/draw/engines/eevee_next/eevee_world.cc4
-rw-r--r--source/blender/draw/engines/eevee_next/shaders/eevee_cryptomatte_lib.glsl70
-rw-r--r--source/blender/draw/engines/eevee_next/shaders/eevee_depth_of_field_accumulator_lib.glsl2
-rw-r--r--source/blender/draw/engines/eevee_next/shaders/eevee_depth_of_field_filter_comp.glsl4
-rw-r--r--source/blender/draw/engines/eevee_next/shaders/eevee_depth_of_field_gather_comp.glsl4
-rw-r--r--source/blender/draw/engines/eevee_next/shaders/eevee_depth_of_field_hole_fill_comp.glsl4
-rw-r--r--source/blender/draw/engines/eevee_next/shaders/eevee_depth_of_field_reduce_comp.glsl12
-rw-r--r--source/blender/draw/engines/eevee_next/shaders/eevee_depth_of_field_resolve_comp.glsl6
-rw-r--r--source/blender/draw/engines/eevee_next/shaders/eevee_depth_of_field_stabilize_comp.glsl12
-rw-r--r--source/blender/draw/engines/eevee_next/shaders/eevee_film_cryptomatte_post_comp.glsl77
-rw-r--r--source/blender/draw/engines/eevee_next/shaders/eevee_film_frag.glsl8
-rw-r--r--source/blender/draw/engines/eevee_next/shaders/eevee_film_lib.glsl87
-rw-r--r--source/blender/draw/engines/eevee_next/shaders/eevee_hiz_debug_frag.glsl24
-rw-r--r--source/blender/draw/engines/eevee_next/shaders/eevee_hiz_update_comp.glsl121
-rw-r--r--source/blender/draw/engines/eevee_next/shaders/eevee_light_culling_debug_frag.glsl16
-rw-r--r--source/blender/draw/engines/eevee_next/shaders/eevee_light_culling_sort_comp.glsl2
-rw-r--r--source/blender/draw/engines/eevee_next/shaders/eevee_light_culling_zbin_comp.glsl2
-rw-r--r--source/blender/draw/engines/eevee_next/shaders/eevee_motion_blur_dilate_comp.glsl3
-rw-r--r--source/blender/draw/engines/eevee_next/shaders/eevee_nodetree_lib.glsl28
-rw-r--r--source/blender/draw/engines/eevee_next/shaders/eevee_surf_depth_frag.glsl4
-rw-r--r--source/blender/draw/engines/eevee_next/shaders/eevee_surf_forward_frag.glsl11
-rw-r--r--source/blender/draw/engines/eevee_next/shaders/eevee_surf_lib.glsl6
-rw-r--r--source/blender/draw/engines/eevee_next/shaders/eevee_surf_world_frag.glsl7
-rw-r--r--source/blender/draw/engines/eevee_next/shaders/infos/eevee_depth_of_field_info.hh12
-rw-r--r--source/blender/draw/engines/eevee_next/shaders/infos/eevee_film_info.hh36
-rw-r--r--source/blender/draw/engines/eevee_next/shaders/infos/eevee_hiz_info.hh31
-rw-r--r--source/blender/draw/engines/eevee_next/shaders/infos/eevee_light_culling_info.hh16
-rw-r--r--source/blender/draw/engines/eevee_next/shaders/infos/eevee_material_info.hh64
-rw-r--r--source/blender/draw/engines/eevee_next/shaders/infos/eevee_motion_blur_info.hh4
-rw-r--r--source/blender/draw/engines/eevee_next/shaders/infos/eevee_velocity_info.hh22
-rw-r--r--source/blender/draw/engines/external/external_engine.c12
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_draw_data.c2
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_engine.c2
-rw-r--r--source/blender/draw/engines/gpencil/shaders/infos/gpencil_info.hh2
-rw-r--r--source/blender/draw/engines/overlay/overlay_antialiasing.cc (renamed from source/blender/draw/engines/overlay/overlay_antialiasing.c)13
-rw-r--r--source/blender/draw/engines/overlay/overlay_armature.cc (renamed from source/blender/draw/engines/overlay/overlay_armature.c)207
-rw-r--r--source/blender/draw/engines/overlay/overlay_background.cc (renamed from source/blender/draw/engines/overlay/overlay_background.c)12
-rw-r--r--source/blender/draw/engines/overlay/overlay_edit_curve.cc (renamed from source/blender/draw/engines/overlay/overlay_edit_curve.c)4
-rw-r--r--source/blender/draw/engines/overlay/overlay_edit_curves.cc2
-rw-r--r--source/blender/draw/engines/overlay/overlay_edit_mesh.cc (renamed from source/blender/draw/engines/overlay/overlay_edit_mesh.c)35
-rw-r--r--source/blender/draw/engines/overlay/overlay_edit_text.cc (renamed from source/blender/draw/engines/overlay/overlay_edit_text.c)54
-rw-r--r--source/blender/draw/engines/overlay/overlay_edit_uv.cc (renamed from source/blender/draw/engines/overlay/overlay_edit_uv.c)102
-rw-r--r--source/blender/draw/engines/overlay/overlay_engine.cc (renamed from source/blender/draw/engines/overlay/overlay_engine.c)305
-rw-r--r--source/blender/draw/engines/overlay/overlay_engine.h8
-rw-r--r--source/blender/draw/engines/overlay/overlay_extra.cc (renamed from source/blender/draw/engines/overlay/overlay_extra.c)81
-rw-r--r--source/blender/draw/engines/overlay/overlay_facing.cc (renamed from source/blender/draw/engines/overlay/overlay_facing.c)2
-rw-r--r--source/blender/draw/engines/overlay/overlay_fade.cc (renamed from source/blender/draw/engines/overlay/overlay_fade.c)4
-rw-r--r--source/blender/draw/engines/overlay/overlay_gpencil.cc (renamed from source/blender/draw/engines/overlay/overlay_gpencil.c)61
-rw-r--r--source/blender/draw/engines/overlay/overlay_grid.cc (renamed from source/blender/draw/engines/overlay/overlay_grid.c)34
-rw-r--r--source/blender/draw/engines/overlay/overlay_image.cc (renamed from source/blender/draw/engines/overlay/overlay_image.c)70
-rw-r--r--source/blender/draw/engines/overlay/overlay_lattice.cc (renamed from source/blender/draw/engines/overlay/overlay_lattice.c)2
-rw-r--r--source/blender/draw/engines/overlay/overlay_metaball.cc (renamed from source/blender/draw/engines/overlay/overlay_metaball.c)9
-rw-r--r--source/blender/draw/engines/overlay/overlay_mode_transfer.cc (renamed from source/blender/draw/engines/overlay/overlay_mode_transfer.c)4
-rw-r--r--source/blender/draw/engines/overlay/overlay_motion_path.cc (renamed from source/blender/draw/engines/overlay/overlay_motion_path.c)12
-rw-r--r--source/blender/draw/engines/overlay/overlay_outline.cc (renamed from source/blender/draw/engines/overlay/overlay_outline.c)37
-rw-r--r--source/blender/draw/engines/overlay/overlay_paint.cc (renamed from source/blender/draw/engines/overlay/overlay_paint.c)27
-rw-r--r--source/blender/draw/engines/overlay/overlay_particle.cc (renamed from source/blender/draw/engines/overlay/overlay_particle.c)22
-rw-r--r--source/blender/draw/engines/overlay/overlay_private.hh (renamed from source/blender/draw/engines/overlay/overlay_private.h)12
-rw-r--r--source/blender/draw/engines/overlay/overlay_sculpt.cc (renamed from source/blender/draw/engines/overlay/overlay_sculpt.c)4
-rw-r--r--source/blender/draw/engines/overlay/overlay_sculpt_curves.cc2
-rw-r--r--source/blender/draw/engines/overlay/overlay_shader.cc (renamed from source/blender/draw/engines/overlay/overlay_shader.c)10
-rw-r--r--source/blender/draw/engines/overlay/overlay_shader_shared.h3
-rw-r--r--source/blender/draw/engines/overlay/overlay_volume.cc (renamed from source/blender/draw/engines/overlay/overlay_volume.c)8
-rw-r--r--source/blender/draw/engines/overlay/overlay_wireframe.cc (renamed from source/blender/draw/engines/overlay/overlay_wireframe.c)32
-rw-r--r--source/blender/draw/engines/overlay/shaders/infos/overlay_armature_info.hh21
-rw-r--r--source/blender/draw/engines/overlay/shaders/infos/overlay_background_info.hh2
-rw-r--r--source/blender/draw/engines/overlay/shaders/infos/overlay_edit_mode_info.hh62
-rw-r--r--source/blender/draw/engines/overlay/shaders/infos/overlay_extra_info.hh28
-rw-r--r--source/blender/draw/engines/overlay/shaders/infos/overlay_grid_info.hh2
-rw-r--r--source/blender/draw/engines/overlay/shaders/infos/overlay_paint_info.hh2
-rw-r--r--source/blender/draw/engines/overlay/shaders/overlay_armature_envelope_outline_vert.glsl2
-rw-r--r--source/blender/draw/engines/overlay/shaders/overlay_armature_shape_outline_vert_no_geom.glsl182
-rw-r--r--source/blender/draw/engines/overlay/shaders/overlay_edit_curve_handle_vert_no_geom.glsl16
-rw-r--r--source/blender/draw/engines/overlay/shaders/overlay_edit_mesh_vert_no_geom.glsl236
-rw-r--r--source/blender/draw/engines/overlay/shaders/overlay_edit_uv_stretching_vert.glsl6
-rw-r--r--source/blender/draw/engines/overlay/shaders/overlay_extra_point_vert.glsl2
-rw-r--r--source/blender/draw/engines/overlay/shaders/overlay_grid_frag.glsl99
-rw-r--r--source/blender/draw/engines/overlay/shaders/overlay_motion_path_line_vert_no_geom.glsl188
-rw-r--r--source/blender/draw/engines/overlay/shaders/overlay_particle_vert.glsl4
-rw-r--r--source/blender/draw/engines/overlay/shaders/overlay_uniform_color_frag.glsl2
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_transparent_accum_frag.glsl6
-rw-r--r--source/blender/draw/engines/workbench/workbench_engine.c6
133 files changed, 3687 insertions, 1613 deletions
diff --git a/source/blender/draw/engines/eevee/eevee_cryptomatte.c b/source/blender/draw/engines/eevee/eevee_cryptomatte.c
index 2f4a201637f..d805a039e8f 100644
--- a/source/blender/draw/engines/eevee/eevee_cryptomatte.c
+++ b/source/blender/draw/engines/eevee/eevee_cryptomatte.c
@@ -25,7 +25,6 @@
* they take into account to create the render passes. When accurate mode is off the number of
* levels is used as the number of cryptomatte samples to take. When accuracy mode is on the number
* of render samples is used.
- *
*/
#include "DRW_engine.h"
@@ -422,27 +421,31 @@ void EEVEE_cryptomatte_output_accumulate(EEVEE_ViewLayerData *UNUSED(sldata), EE
void EEVEE_cryptomatte_update_passes(RenderEngine *engine, Scene *scene, ViewLayer *view_layer)
{
+ /* NOTE: Name channels lowercase rgba so that compression rules check in OpenEXR DWA code uses
+ * lossless compression. Reportedly this naming is the only one which works good from the
+ * interoperability point of view. Using XYZW naming is not portable. */
+
char cryptomatte_pass_name[MAX_NAME];
const short num_passes = eevee_cryptomatte_passes_per_layer(view_layer);
if ((view_layer->cryptomatte_flag & VIEW_LAYER_CRYPTOMATTE_OBJECT) != 0) {
for (short pass = 0; pass < num_passes; pass++) {
BLI_snprintf_rlen(cryptomatte_pass_name, MAX_NAME, "CryptoObject%02d", pass);
RE_engine_register_pass(
- engine, scene, view_layer, cryptomatte_pass_name, 4, "RGBA", SOCK_RGBA);
+ engine, scene, view_layer, cryptomatte_pass_name, 4, "rgba", SOCK_RGBA);
}
}
if ((view_layer->cryptomatte_flag & VIEW_LAYER_CRYPTOMATTE_MATERIAL) != 0) {
for (short pass = 0; pass < num_passes; pass++) {
BLI_snprintf_rlen(cryptomatte_pass_name, MAX_NAME, "CryptoMaterial%02d", pass);
RE_engine_register_pass(
- engine, scene, view_layer, cryptomatte_pass_name, 4, "RGBA", SOCK_RGBA);
+ engine, scene, view_layer, cryptomatte_pass_name, 4, "rgba", SOCK_RGBA);
}
}
if ((view_layer->cryptomatte_flag & VIEW_LAYER_CRYPTOMATTE_ASSET) != 0) {
for (short pass = 0; pass < num_passes; pass++) {
BLI_snprintf_rlen(cryptomatte_pass_name, MAX_NAME, "CryptoAsset%02d", pass);
RE_engine_register_pass(
- engine, scene, view_layer, cryptomatte_pass_name, 4, "RGBA", SOCK_RGBA);
+ engine, scene, view_layer, cryptomatte_pass_name, 4, "rgba", SOCK_RGBA);
}
}
}
diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c
index ffe0863fb9f..5ae4b730cfa 100644
--- a/source/blender/draw/engines/eevee/eevee_engine.c
+++ b/source/blender/draw/engines/eevee/eevee_engine.c
@@ -109,7 +109,7 @@ void EEVEE_cache_populate(void *vedata, Object *ob)
}
if (DRW_object_is_renderable(ob) && (ob_visibility & OB_VISIBLE_SELF)) {
- if (ELEM(ob->type, OB_MESH, OB_SURF, OB_MBALL)) {
+ if (ob->type == OB_MESH) {
EEVEE_materials_cache_populate(vedata, sldata, ob, &cast_shadow);
}
else if (ob->type == OB_CURVES) {
@@ -366,7 +366,7 @@ static void eevee_draw_scene(void *vedata)
static void eevee_view_update(void *vedata)
{
EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl;
- if (stl->g_data) {
+ if (stl && stl->g_data) {
stl->g_data->view_updated = true;
}
}
diff --git a/source/blender/draw/engines/eevee/eevee_lightcache.c b/source/blender/draw/engines/eevee/eevee_lightcache.c
index 7f722ff1764..9bf0cce2af2 100644
--- a/source/blender/draw/engines/eevee/eevee_lightcache.c
+++ b/source/blender/draw/engines/eevee/eevee_lightcache.c
@@ -591,23 +591,26 @@ static void eevee_lightbake_context_enable(EEVEE_LightBake *lbake)
if (GPU_use_main_context_workaround() && !BLI_thread_is_main()) {
GPU_context_main_lock();
DRW_opengl_context_enable();
+ GPU_render_begin();
return;
}
if (lbake->gl_context) {
DRW_opengl_render_context_enable(lbake->gl_context);
if (lbake->gpu_context == NULL) {
- lbake->gpu_context = GPU_context_create(NULL);
+ lbake->gpu_context = GPU_context_create(NULL, lbake->gl_context);
}
DRW_gpu_render_context_enable(lbake->gpu_context);
}
else {
DRW_opengl_context_enable();
}
+ GPU_render_begin();
}
static void eevee_lightbake_context_disable(EEVEE_LightBake *lbake)
{
+ GPU_render_end();
if (GPU_use_main_context_workaround() && !BLI_thread_is_main()) {
DRW_opengl_context_disable();
GPU_context_main_unlock();
@@ -636,7 +639,10 @@ static void eevee_lightbake_count_probes(EEVEE_LightBake *lbake)
/* At least one of each for the world */
lbake->grid_len = lbake->cube_len = lbake->total_irr_samples = 1;
- DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN (depsgraph, ob) {
+ DEGObjectIterSettings deg_iter_settings = {0};
+ deg_iter_settings.depsgraph = depsgraph;
+ deg_iter_settings.flags = DEG_OBJECT_ITER_FOR_RENDER_ENGINE_FLAGS;
+ DEG_OBJECT_ITER_BEGIN (&deg_iter_settings, ob) {
const int ob_visibility = BKE_object_visibility(ob, DAG_EVAL_RENDER);
if ((ob_visibility & OB_VISIBLE_SELF) == 0) {
continue;
@@ -655,7 +661,7 @@ static void eevee_lightbake_count_probes(EEVEE_LightBake *lbake)
}
}
}
- DEG_OBJECT_ITER_FOR_RENDER_ENGINE_END;
+ DEG_OBJECT_ITER_END;
}
static void eevee_lightbake_create_render_target(EEVEE_LightBake *lbake, int rt_res)
@@ -849,7 +855,7 @@ static void eevee_lightbake_delete_resources(EEVEE_LightBake *lbake)
DRW_opengl_context_enable();
}
- /* XXX Free the resources contained in the viewlayer data
+ /* XXX: Free the resources contained in the view-layer data
* to be able to free the context before deleting the depsgraph. */
if (lbake->sldata) {
EEVEE_view_layer_data_free(lbake->sldata);
@@ -1279,7 +1285,10 @@ static void eevee_lightbake_gather_probes(EEVEE_LightBake *lbake)
/* Convert all lightprobes to tight UBO data from all lightprobes in the scene.
* This allows a large number of probe to be precomputed (even dupli ones). */
- DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN (depsgraph, ob) {
+ DEGObjectIterSettings deg_iter_settings = {0};
+ deg_iter_settings.depsgraph = depsgraph;
+ deg_iter_settings.flags = DEG_OBJECT_ITER_FOR_RENDER_ENGINE_FLAGS;
+ DEG_OBJECT_ITER_BEGIN (&deg_iter_settings, ob) {
const int ob_visibility = BKE_object_visibility(ob, DAG_EVAL_RENDER);
if ((ob_visibility & OB_VISIBLE_SELF) == 0) {
continue;
@@ -1300,7 +1309,7 @@ static void eevee_lightbake_gather_probes(EEVEE_LightBake *lbake)
}
}
}
- DEG_OBJECT_ITER_FOR_RENDER_ENGINE_END;
+ DEG_OBJECT_ITER_END;
SORT_PROBE(EEVEE_LightGrid,
lbake->grid_prb + 1,
diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c
index efd27c19654..94f29d64628 100644
--- a/source/blender/draw/engines/eevee/eevee_materials.c
+++ b/source/blender/draw/engines/eevee/eevee_materials.c
@@ -806,7 +806,7 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata,
!DRW_state_is_image_render();
/* First get materials for this mesh. */
- if (ELEM(ob->type, OB_MESH, OB_SURF, OB_MBALL)) {
+ if (ELEM(ob->type, OB_MESH, OB_SURF)) {
const int materials_len = DRW_cache_object_material_count_get(ob);
EeveeMaterialCache *matcache = BLI_array_alloca(matcache, materials_len);
diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h
index 8d47d80987c..88e56bdc01c 100644
--- a/source/blender/draw/engines/eevee/eevee_private.h
+++ b/source/blender/draw/engines/eevee/eevee_private.h
@@ -815,7 +815,7 @@ typedef struct EEVEE_EffectsInfo {
struct GPUTexture *dof_reduce_input_color_tx;
/* Other */
float prev_persmat[4][4];
- /* Size used by all fullscreen buffers using mipmaps. */
+ /* Size used by all full-screen buffers using mipmaps. */
int hiz_size[2];
/* Lookdev */
int sphere_size;
@@ -1015,7 +1015,7 @@ typedef struct EEVEE_PrivateData {
struct GHash *material_hash;
float background_alpha; /* TODO: find a better place for this. */
bool disable_ligthprobes;
- /* Chosen lightcache: can come from Lookdev or the viewlayer. */
+ /** Chosen light-cache: can come from Lookdev or the view-layer. */
struct LightCache *light_cache;
/* For planar probes */
float planar_texel_size[2];
diff --git a/source/blender/draw/engines/eevee/eevee_render.c b/source/blender/draw/engines/eevee/eevee_render.c
index 82944f237ea..c3b909f5fb9 100644
--- a/source/blender/draw/engines/eevee/eevee_render.c
+++ b/source/blender/draw/engines/eevee/eevee_render.c
@@ -224,7 +224,7 @@ void EEVEE_render_cache(void *vedata,
}
if (ob_visibility & OB_VISIBLE_SELF) {
- if (ELEM(ob->type, OB_MESH, OB_SURF, OB_MBALL)) {
+ if (ob->type == OB_MESH) {
EEVEE_materials_cache_populate(vedata, sldata, ob, &cast_shadow);
if (do_cryptomatte) {
EEVEE_cryptomatte_cache_populate(data, sldata, ob);
diff --git a/source/blender/draw/engines/eevee/eevee_shaders.c b/source/blender/draw/engines/eevee/eevee_shaders.c
index e7b6cd636ae..04d1168a30d 100644
--- a/source/blender/draw/engines/eevee/eevee_shaders.c
+++ b/source/blender/draw/engines/eevee/eevee_shaders.c
@@ -1192,8 +1192,8 @@ Material *EEVEE_material_default_diffuse_get(void)
if (!e_data.diffuse_mat) {
Material *ma = BKE_id_new_nomain(ID_MA, "EEVEEE default diffuse");
- bNodeTree *ntree = ntreeAddTree(NULL, "Shader Nodetree", ntreeType_Shader->idname);
- ma->nodetree = ntree;
+ bNodeTree *ntree = ntreeAddTreeEmbedded(
+ NULL, &ma->id, "Shader Nodetree", ntreeType_Shader->idname);
ma->use_nodes = true;
bNode *bsdf = nodeAddStaticNode(NULL, ntree, SH_NODE_BSDF_DIFFUSE);
@@ -1219,8 +1219,8 @@ Material *EEVEE_material_default_glossy_get(void)
if (!e_data.glossy_mat) {
Material *ma = BKE_id_new_nomain(ID_MA, "EEVEEE default metal");
- bNodeTree *ntree = ntreeAddTree(NULL, "Shader Nodetree", ntreeType_Shader->idname);
- ma->nodetree = ntree;
+ bNodeTree *ntree = ntreeAddTreeEmbedded(
+ NULL, &ma->id, "Shader Nodetree", ntreeType_Shader->idname);
ma->use_nodes = true;
bNode *bsdf = nodeAddStaticNode(NULL, ntree, SH_NODE_BSDF_GLOSSY);
@@ -1248,8 +1248,8 @@ Material *EEVEE_material_default_error_get(void)
if (!e_data.error_mat) {
Material *ma = BKE_id_new_nomain(ID_MA, "EEVEEE default error");
- bNodeTree *ntree = ntreeAddTree(NULL, "Shader Nodetree", ntreeType_Shader->idname);
- ma->nodetree = ntree;
+ bNodeTree *ntree = ntreeAddTreeEmbedded(
+ NULL, &ma->id, "Shader Nodetree", ntreeType_Shader->idname);
ma->use_nodes = true;
/* Use emission and output material to be compatible with both World and Material. */
diff --git a/source/blender/draw/engines/eevee/eevee_volumes.c b/source/blender/draw/engines/eevee/eevee_volumes.c
index 533e71b9b32..2d96cffb4ba 100644
--- a/source/blender/draw/engines/eevee/eevee_volumes.c
+++ b/source/blender/draw/engines/eevee/eevee_volumes.c
@@ -30,6 +30,7 @@
#include "DEG_depsgraph_query.h"
#include "GPU_capabilities.h"
+#include "GPU_context.h"
#include "GPU_material.h"
#include "GPU_texture.h"
#include "eevee_private.h"
@@ -82,6 +83,13 @@ void EEVEE_volumes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
tex_size[1] = (int)ceilf(fmaxf(1.0f, viewport_size[1] / (float)tile_size));
tex_size[2] = max_ii(scene_eval->eevee.volumetric_samples, 1);
+ /* Clamp 3D texture size based on device maximum. */
+ int maxSize = GPU_max_texture_3d_size();
+ BLI_assert(tex_size[0] <= maxSize);
+ tex_size[0] = tex_size[0] > maxSize ? maxSize : tex_size[0];
+ tex_size[1] = tex_size[1] > maxSize ? maxSize : tex_size[1];
+ tex_size[2] = tex_size[2] > maxSize ? maxSize : tex_size[2];
+
common_data->vol_coord_scale[0] = viewport_size[0] / (float)(tile_size * tex_size[0]);
common_data->vol_coord_scale[1] = viewport_size[1] / (float)(tile_size * tex_size[1]);
common_data->vol_coord_scale[2] = 1.0f / viewport_size[0];
diff --git a/source/blender/draw/engines/eevee/shaders/closure_type_lib.glsl b/source/blender/draw/engines/eevee/shaders/closure_type_lib.glsl
index 4070ede116b..eeccb393a5c 100644
--- a/source/blender/draw/engines/eevee/shaders/closure_type_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/closure_type_lib.glsl
@@ -6,8 +6,8 @@
#ifndef VOLUMETRICS
-uniform int outputSsrId; /*Default = 1;*/
-uniform int outputSssId; /*Default = 1;*/
+uniform int outputSsrId; /* Default = 1; */
+uniform int outputSssId; /* Default = 1; */
#endif
diff --git a/source/blender/draw/engines/eevee/shaders/effect_dof_resolve_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_dof_resolve_frag.glsl
index 688ae4915e1..7dec30a96b1 100644
--- a/source/blender/draw/engines/eevee/shaders/effect_dof_resolve_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/effect_dof_resolve_frag.glsl
@@ -124,7 +124,7 @@ void dof_slight_focus_gather(float radius, out vec4 out_color, out float out_wei
dof_gather_accumulate_resolve(total_sample_count, bg_accum, bg_col, bg_weight, unused_occlusion);
dof_gather_accumulate_resolve(total_sample_count, fg_accum, fg_col, fg_weight, unused_occlusion);
- /* Fix weighting issues on perfectly focus > slight focus transitionning areas. */
+ /* Fix weighting issues on perfectly focus > slight focus transitioning areas. */
if (abs(center_data.coc) < 0.5) {
bg_col = center_data.color;
bg_weight = 1.0;
diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_filter_diffuse_frag.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_filter_diffuse_frag.glsl
index 9ecc50d9df5..c7f6687d2e2 100644
--- a/source/blender/draw/engines/eevee/shaders/lightprobe_filter_diffuse_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lightprobe_filter_diffuse_frag.glsl
@@ -100,7 +100,7 @@ void main()
coef = 0.315392 * (3.0 * cubevec.y * cubevec.y - 1.0) * 1.0 / 4.0;
}
else if (comp == 7) {
- coef = 1.092548 * cubevec.x * cubevec.y * 1.0 / 4.0;
+ coef = -1.092548 * cubevec.x * cubevec.y * 1.0 / 4.0;
}
else { /* (comp == 8) */
coef = 0.546274 * (cubevec.x * cubevec.x - cubevec.z * cubevec.z) * 1.0 / 4.0;
diff --git a/source/blender/draw/engines/eevee/shaders/prepass_frag.glsl b/source/blender/draw/engines/eevee/shaders/prepass_frag.glsl
index 15c68dc5829..87e944a2ac0 100644
--- a/source/blender/draw/engines/eevee/shaders/prepass_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/prepass_frag.glsl
@@ -91,3 +91,17 @@ void main()
}
#endif
}
+
+/* Passthrough. */
+float attr_load_temperature_post(float attr)
+{
+ return attr;
+}
+vec4 attr_load_color_post(vec4 attr)
+{
+ return attr;
+}
+vec4 attr_load_uniform(vec4 attr, const uint attr_hash)
+{
+ return attr;
+}
diff --git a/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl b/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl
index 73c4b521b05..8bd60573078 100644
--- a/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl
@@ -51,7 +51,8 @@ void raytrace_screenspace_ray_finalize(inout ScreenSpaceRay ray)
}
float ray_len_sqr = len_squared(ray.direction.xyz);
/* Make ray.direction cover one pixel. */
- bool is_more_vertical = abs(ray.direction.x) < abs(ray.direction.y);
+ bool is_more_vertical = abs(ray.direction.x / ssrPixelSize.x) <
+ abs(ray.direction.y / ssrPixelSize.y);
ray.direction /= (is_more_vertical) ? abs(ray.direction.y) : abs(ray.direction.x);
ray.direction *= (is_more_vertical) ? ssrPixelSize.y : ssrPixelSize.x;
/* Clip to segment's end. */
diff --git a/source/blender/draw/engines/eevee/shaders/shadow_vert.glsl b/source/blender/draw/engines/eevee/shaders/shadow_vert.glsl
index 57d70334651..062a40f35c2 100644
--- a/source/blender/draw/engines/eevee/shaders/shadow_vert.glsl
+++ b/source/blender/draw/engines/eevee/shaders/shadow_vert.glsl
@@ -152,3 +152,7 @@ vec4 attr_load_color_post(vec4 attr)
{
return attr;
}
+vec4 attr_load_uniform(vec4 attr, const uint attr_hash)
+{
+ return attr;
+}
diff --git a/source/blender/draw/engines/eevee/shaders/surface_frag.glsl b/source/blender/draw/engines/eevee/shaders/surface_frag.glsl
index 2a212b757c2..88755705a53 100644
--- a/source/blender/draw/engines/eevee/shaders/surface_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/surface_frag.glsl
@@ -153,7 +153,7 @@ void main()
vec3 attr_load_orco(vec4 orco)
{
/* Retain precision better than g_data.P (see T99128). */
- return transform_direction(ViewMatrixInverse, normalize(viewPosition));
+ return -normal_view_to_world(viewCameraVec(viewPosition));
}
/* Unsupported. */
vec4 attr_load_tangent(vec4 tangent)
@@ -182,3 +182,7 @@ vec4 attr_load_color_post(vec4 attr)
{
return attr;
}
+vec4 attr_load_uniform(vec4 attr, const uint attr_hash)
+{
+ return attr;
+}
diff --git a/source/blender/draw/engines/eevee/shaders/surface_lib.glsl b/source/blender/draw/engines/eevee/shaders/surface_lib.glsl
index 80c6b935187..69762027643 100644
--- a/source/blender/draw/engines/eevee/shaders/surface_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/surface_lib.glsl
@@ -97,11 +97,12 @@ GlobalData init_globals(void)
GlobalData surf;
# if defined(WORLD_BACKGROUND) || defined(PROBE_CAPTURE)
- surf.P = transform_direction(ViewMatrixInverse, viewCameraVec(viewPosition));
- surf.N = surf.Ng = -surf.P;
+ surf.P = transform_direction(ViewMatrixInverse, -viewCameraVec(viewPosition));
+ surf.N = surf.Ng = surf.Ni = -surf.P;
surf.ray_length = 0.0;
# else
surf.P = worldPosition;
+ surf.Ni = worldNormal;
surf.N = safe_normalize(worldNormal);
surf.Ng = safe_normalize(cross(dFdx(surf.P), dFdy(surf.P)));
surf.ray_length = distance(surf.P, cameraPos);
@@ -109,6 +110,7 @@ GlobalData init_globals(void)
surf.barycentric_coords = vec2(0.0);
surf.barycentric_dists = vec3(0.0);
surf.N = (FrontFacing) ? surf.N : -surf.N;
+ surf.Ni = (FrontFacing) ? surf.Ni : -surf.Ni;
# ifdef HAIR_SHADER
vec3 V = cameraVec(surf.P);
/* Shade as a cylinder. */
@@ -123,7 +125,7 @@ GlobalData init_globals(void)
cos_theta = hairThickTime / hairThickness;
}
float sin_theta = sqrt(max(0.0, 1.0 - cos_theta * cos_theta));
- surf.N = safe_normalize(worldNormal * sin_theta + B * cos_theta);
+ surf.N = surf.Ni = safe_normalize(worldNormal * sin_theta + B * cos_theta);
surf.curve_T = -hairTangent;
/* Costly, but follows cycles per pixel tangent space (not following curve shape). */
surf.curve_B = cross(V, surf.curve_T);
diff --git a/source/blender/draw/engines/eevee/shaders/surface_vert.glsl b/source/blender/draw/engines/eevee/shaders/surface_vert.glsl
index 4a3a91b8534..54aad7891dc 100644
--- a/source/blender/draw/engines/eevee/shaders/surface_vert.glsl
+++ b/source/blender/draw/engines/eevee/shaders/surface_vert.glsl
@@ -165,3 +165,7 @@ vec4 attr_load_color_post(vec4 attr)
{
return attr;
}
+vec4 attr_load_uniform(vec4 attr, const uint attr_hash)
+{
+ return attr;
+}
diff --git a/source/blender/draw/engines/eevee/shaders/volumetric_frag.glsl b/source/blender/draw/engines/eevee/shaders/volumetric_frag.glsl
index c6de723ac25..9ed21fc0bf5 100644
--- a/source/blender/draw/engines/eevee/shaders/volumetric_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/volumetric_frag.glsl
@@ -178,3 +178,7 @@ vec4 attr_load_color_post(vec4 attr)
#endif
return attr;
}
+vec4 attr_load_uniform(vec4 attr, const uint attr_hash)
+{
+ return attr;
+}
diff --git a/source/blender/draw/engines/eevee/shaders/volumetric_vert.glsl b/source/blender/draw/engines/eevee/shaders/volumetric_vert.glsl
index b3b9c7af19c..2d51fbd9edc 100644
--- a/source/blender/draw/engines/eevee/shaders/volumetric_vert.glsl
+++ b/source/blender/draw/engines/eevee/shaders/volumetric_vert.glsl
@@ -87,3 +87,8 @@ vec4 attr_load_color_post(vec4 attr)
{
return attr;
}
+
+vec4 attr_load_uniform(vec4 attr, const uint attr_hash)
+{
+ return attr;
+}
diff --git a/source/blender/draw/engines/eevee_next/eevee_cryptomatte.cc b/source/blender/draw/engines/eevee_next/eevee_cryptomatte.cc
new file mode 100644
index 00000000000..10be121f533
--- /dev/null
+++ b/source/blender/draw/engines/eevee_next/eevee_cryptomatte.cc
@@ -0,0 +1,132 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2022 Blender Foundation. */
+#include "BKE_cryptomatte.hh"
+
+#include "GPU_material.h"
+
+#include "eevee_cryptomatte.hh"
+#include "eevee_instance.hh"
+#include "eevee_renderbuffers.hh"
+
+namespace blender::eevee {
+
+void Cryptomatte::begin_sync()
+{
+ const eViewLayerEEVEEPassType enabled_passes = static_cast<eViewLayerEEVEEPassType>(
+ inst_.film.enabled_passes_get() &
+ (EEVEE_RENDER_PASS_CRYPTOMATTE_OBJECT | EEVEE_RENDER_PASS_CRYPTOMATTE_ASSET |
+ EEVEE_RENDER_PASS_CRYPTOMATTE_ASSET));
+
+ session_.reset();
+ object_layer_ = nullptr;
+ asset_layer_ = nullptr;
+ material_layer_ = nullptr;
+
+ if (enabled_passes && !inst_.is_viewport()) {
+ session_.reset(BKE_cryptomatte_init_from_view_layer(inst_.view_layer));
+
+ for (const std::string &layer_name :
+ bke::cryptomatte::BKE_cryptomatte_layer_names_get(*session_)) {
+ StringRef layer_name_ref = layer_name;
+ bke::cryptomatte::CryptomatteLayer *layer = bke::cryptomatte::BKE_cryptomatte_layer_get(
+ *session_, layer_name);
+ if (layer_name_ref.endswith(RE_PASSNAME_CRYPTOMATTE_OBJECT)) {
+ object_layer_ = layer;
+ }
+ else if (layer_name_ref.endswith(RE_PASSNAME_CRYPTOMATTE_ASSET)) {
+ asset_layer_ = layer;
+ }
+ else if (layer_name_ref.endswith(RE_PASSNAME_CRYPTOMATTE_MATERIAL)) {
+ material_layer_ = layer;
+ }
+ }
+ }
+
+ if (!(enabled_passes &
+ (EEVEE_RENDER_PASS_CRYPTOMATTE_OBJECT | EEVEE_RENDER_PASS_CRYPTOMATTE_ASSET))) {
+ cryptomatte_object_buf.resize(16);
+ }
+}
+
+void Cryptomatte::sync_object(Object *ob, ResourceHandle res_handle)
+{
+ const eViewLayerEEVEEPassType enabled_passes = inst_.film.enabled_passes_get();
+ if (!(enabled_passes &
+ (EEVEE_RENDER_PASS_CRYPTOMATTE_OBJECT | EEVEE_RENDER_PASS_CRYPTOMATTE_ASSET))) {
+ return;
+ }
+
+ uint32_t resource_id = res_handle.resource_index();
+ float2 object_hashes(0.0f, 0.0f);
+
+ if (enabled_passes & EEVEE_RENDER_PASS_CRYPTOMATTE_OBJECT) {
+ object_hashes[0] = register_id(EEVEE_RENDER_PASS_CRYPTOMATTE_OBJECT, ob->id);
+ }
+
+ if (enabled_passes & EEVEE_RENDER_PASS_CRYPTOMATTE_ASSET) {
+ Object *asset = ob;
+ while (asset->parent) {
+ asset = asset->parent;
+ }
+ object_hashes[1] = register_id(EEVEE_RENDER_PASS_CRYPTOMATTE_ASSET, asset->id);
+ }
+ cryptomatte_object_buf.get_or_resize(resource_id) = object_hashes;
+}
+
+void Cryptomatte::sync_material(const ::Material *material)
+{
+ /* Material crypto hashes are generated during shader codegen stage. We only need to register
+ * them to store inside the metadata. */
+ if (material_layer_ && material) {
+ material_layer_->add_ID(material->id);
+ }
+}
+
+void Cryptomatte::end_sync()
+{
+ cryptomatte_object_buf.push_update();
+
+ object_layer_ = nullptr;
+ asset_layer_ = nullptr;
+ material_layer_ = nullptr;
+}
+
+float Cryptomatte::register_id(const eViewLayerEEVEEPassType layer, const ID &id) const
+{
+ BLI_assert(ELEM(layer,
+ EEVEE_RENDER_PASS_CRYPTOMATTE_OBJECT,
+ EEVEE_RENDER_PASS_CRYPTOMATTE_ASSET,
+ EEVEE_RENDER_PASS_CRYPTOMATTE_MATERIAL));
+
+ uint32_t cryptomatte_hash = 0;
+ if (session_) {
+ if (layer == EEVEE_RENDER_PASS_CRYPTOMATTE_OBJECT) {
+ BLI_assert(object_layer_);
+ cryptomatte_hash = object_layer_->add_ID(id);
+ }
+ else if (layer == EEVEE_RENDER_PASS_CRYPTOMATTE_ASSET) {
+ BLI_assert(asset_layer_);
+ cryptomatte_hash = asset_layer_->add_ID(id);
+ }
+ else if (layer == EEVEE_RENDER_PASS_CRYPTOMATTE_MATERIAL) {
+ BLI_assert(material_layer_);
+ cryptomatte_hash = material_layer_->add_ID(id);
+ }
+ }
+ else {
+ const char *name = &id.name[2];
+ const int name_len = BLI_strnlen(name, MAX_NAME - 2);
+ cryptomatte_hash = BKE_cryptomatte_hash(name, name_len);
+ }
+
+ return BKE_cryptomatte_hash_to_float(cryptomatte_hash);
+}
+
+void Cryptomatte::store_metadata(RenderResult *render_result)
+{
+ if (session_) {
+ BKE_cryptomatte_store_metadata(&*session_, render_result, inst_.view_layer);
+ }
+}
+
+} // namespace blender::eevee \ No newline at end of file
diff --git a/source/blender/draw/engines/eevee_next/eevee_cryptomatte.hh b/source/blender/draw/engines/eevee_next/eevee_cryptomatte.hh
new file mode 100644
index 00000000000..86ab3d97b4b
--- /dev/null
+++ b/source/blender/draw/engines/eevee_next/eevee_cryptomatte.hh
@@ -0,0 +1,68 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2022 Blender Foundation. */
+
+/** \file
+ * \ingroup eevee
+ *
+ * Cryptomatte.
+ *
+ * During rasterization, cryptomatte hashes are stored into a single array texture.
+ * The film pass then resamples this texture using pixel filter weighting.
+ * Each cryptomatte layer can hold N samples. These are stored in sequential layers
+ * of the array texture. The samples are sorted and merged only for final rendering.
+ */
+
+#pragma once
+
+#include "eevee_shader_shared.hh"
+
+#include "BKE_cryptomatte.hh"
+
+extern "C" {
+struct Material;
+struct CryptomatteSession;
+}
+
+namespace blender::eevee {
+
+class Instance;
+
+/* -------------------------------------------------------------------- */
+/** \name Cryptomatte
+ * \{ */
+
+class Cryptomatte {
+ private:
+ class Instance &inst_;
+
+ bke::cryptomatte::CryptomatteSessionPtr session_;
+
+ /* Cached pointer to the cryptomatte layer instances. */
+ bke::cryptomatte::CryptomatteLayer *object_layer_ = nullptr;
+ bke::cryptomatte::CryptomatteLayer *asset_layer_ = nullptr;
+ bke::cryptomatte::CryptomatteLayer *material_layer_ = nullptr;
+
+ /** Contains per object hashes (object and asset hash). Indexed by resource ID. */
+ CryptomatteObjectBuf cryptomatte_object_buf;
+
+ public:
+ Cryptomatte(Instance &inst) : inst_(inst){};
+
+ void begin_sync();
+ void sync_object(Object *ob, ResourceHandle res_handle);
+ void sync_material(const ::Material *material);
+ void end_sync();
+
+ template<typename T> void bind_resources(draw::detail::PassBase<T> *pass)
+ {
+ pass->bind_ssbo(CRYPTOMATTE_BUF_SLOT, &cryptomatte_object_buf);
+ }
+
+ /* Register ID to use inside cryptomatte layer and returns associated hash as float. */
+ float register_id(const eViewLayerEEVEEPassType layer, const ID &id) const;
+ void store_metadata(RenderResult *render_result);
+};
+
+/** \} */
+
+} // namespace blender::eevee
diff --git a/source/blender/draw/engines/eevee_next/eevee_defines.hh b/source/blender/draw/engines/eevee_next/eevee_defines.hh
index 96c5095317d..248dfae6df9 100644
--- a/source/blender/draw/engines/eevee_next/eevee_defines.hh
+++ b/source/blender/draw/engines/eevee_next/eevee_defines.hh
@@ -11,6 +11,11 @@
#pragma once
+/* Hierarchical Z down-sampling. */
+#define HIZ_MIP_COUNT 8
+/* NOTE: The shader is written to update 5 mipmaps using LDS. */
+#define HIZ_GROUP_SIZE 32
+
/* Avoid too much overhead caused by resizing the light buffers too many time. */
#define LIGHT_CHUNK 256
@@ -35,10 +40,7 @@
#define SHADOW_MAX_PAGE 4096
#define SHADOW_PAGE_PER_ROW 64
-#define HIZ_MIP_COUNT 6u
-/* Group size is 2x smaller because we simply copy the level 0. */
-#define HIZ_GROUP_SIZE 1u << (HIZ_MIP_COUNT - 2u)
-
+/* Ray-tracing. */
#define RAYTRACE_GROUP_SIZE 16
#define RAYTRACE_MAX_TILES (16384 / RAYTRACE_GROUP_SIZE) * (16384 / RAYTRACE_GROUP_SIZE)
@@ -66,3 +68,40 @@
#define DOF_FILTER_GROUP_SIZE 8
#define DOF_GATHER_GROUP_SIZE DOF_TILES_SIZE
#define DOF_RESOLVE_GROUP_SIZE (DOF_TILES_SIZE * 2)
+
+/* Resource bindings. */
+
+/* Texture. */
+#define RBUFS_UTILITY_TEX_SLOT 14
+
+/* Images. */
+#define RBUFS_NORMAL_SLOT 0
+#define RBUFS_LIGHT_SLOT 1
+#define RBUFS_DIFF_COLOR_SLOT 2
+#define RBUFS_SPEC_COLOR_SLOT 3
+#define RBUFS_EMISSION_SLOT 4
+#define RBUFS_AOV_COLOR_SLOT 5
+#define RBUFS_AOV_VALUE_SLOT 6
+#define RBUFS_CRYPTOMATTE_SLOT 7
+
+/* Uniform Buffers. */
+/* Only during prepass. */
+#define VELOCITY_CAMERA_PREV_BUF 3
+#define VELOCITY_CAMERA_CURR_BUF 4
+#define VELOCITY_CAMERA_NEXT_BUF 5
+
+/* Storage Buffers. */
+#define LIGHT_CULL_BUF_SLOT 0
+#define LIGHT_BUF_SLOT 1
+#define LIGHT_ZBIN_BUF_SLOT 2
+#define LIGHT_TILE_BUF_SLOT 3
+#define RBUFS_AOV_BUF_SLOT 5
+#define SAMPLING_BUF_SLOT 6
+#define CRYPTOMATTE_BUF_SLOT 7
+
+/* Only during pre-pass. */
+#define VELOCITY_OBJ_PREV_BUF_SLOT 0
+#define VELOCITY_OBJ_NEXT_BUF_SLOT 1
+#define VELOCITY_GEO_PREV_BUF_SLOT 2
+#define VELOCITY_GEO_NEXT_BUF_SLOT 3
+#define VELOCITY_INDIRECTION_BUF_SLOT 4
diff --git a/source/blender/draw/engines/eevee_next/eevee_depth_of_field.cc b/source/blender/draw/engines/eevee_next/eevee_depth_of_field.cc
index 3700076153e..bc0891ceb92 100644
--- a/source/blender/draw/engines/eevee_next/eevee_depth_of_field.cc
+++ b/source/blender/draw/engines/eevee_next/eevee_depth_of_field.cc
@@ -237,35 +237,34 @@ void DepthOfField::bokeh_lut_pass_sync()
const bool has_anisotropy = data_.bokeh_anisotropic_scale != float2(1.0f);
if (!has_anisotropy && (data_.bokeh_blades == 0.0)) {
/* No need for LUTs in these cases. */
- bokeh_lut_ps_ = nullptr;
+ use_bokeh_lut_ = false;
return;
}
+ use_bokeh_lut_ = true;
/* Precompute bokeh texture. */
- bokeh_lut_ps_ = DRW_pass_create("Dof.bokeh_lut_ps_", DRW_STATE_NO_DRAW);
- GPUShader *sh = inst_.shaders.static_shader_get(DOF_BOKEH_LUT);
- DRWShadingGroup *grp = DRW_shgroup_create(sh, bokeh_lut_ps_);
- DRW_shgroup_uniform_block(grp, "dof_buf", data_);
- DRW_shgroup_uniform_image_ref(grp, "out_gather_lut_img", &bokeh_gather_lut_tx_);
- DRW_shgroup_uniform_image_ref(grp, "out_scatter_lut_img", &bokeh_scatter_lut_tx_);
- DRW_shgroup_uniform_image_ref(grp, "out_resolve_lut_img", &bokeh_resolve_lut_tx_);
- DRW_shgroup_call_compute(grp, 1, 1, 1);
+ bokeh_lut_ps_.init();
+ bokeh_lut_ps_.shader_set(inst_.shaders.static_shader_get(DOF_BOKEH_LUT));
+ bokeh_lut_ps_.bind_ubo("dof_buf", data_);
+ bokeh_lut_ps_.bind_image("out_gather_lut_img", &bokeh_gather_lut_tx_);
+ bokeh_lut_ps_.bind_image("out_scatter_lut_img", &bokeh_scatter_lut_tx_);
+ bokeh_lut_ps_.bind_image("out_resolve_lut_img", &bokeh_resolve_lut_tx_);
+ bokeh_lut_ps_.dispatch(int3(1, 1, 1));
}
void DepthOfField::setup_pass_sync()
{
RenderBuffers &render_buffers = inst_.render_buffers;
- setup_ps_ = DRW_pass_create("Dof.setup_ps_", DRW_STATE_NO_DRAW);
- GPUShader *sh = inst_.shaders.static_shader_get(DOF_SETUP);
- DRWShadingGroup *grp = DRW_shgroup_create(sh, setup_ps_);
- DRW_shgroup_uniform_texture_ref_ex(grp, "color_tx", &input_color_tx_, no_filter);
- DRW_shgroup_uniform_texture_ref_ex(grp, "depth_tx", &render_buffers.depth_tx, no_filter);
- DRW_shgroup_uniform_block(grp, "dof_buf", data_);
- DRW_shgroup_uniform_image_ref(grp, "out_color_img", &setup_color_tx_);
- DRW_shgroup_uniform_image_ref(grp, "out_coc_img", &setup_coc_tx_);
- DRW_shgroup_call_compute_ref(grp, dispatch_setup_size_);
- DRW_shgroup_barrier(grp, GPU_BARRIER_TEXTURE_FETCH);
+ setup_ps_.init();
+ setup_ps_.shader_set(inst_.shaders.static_shader_get(DOF_SETUP));
+ setup_ps_.bind_texture("color_tx", &input_color_tx_, no_filter);
+ setup_ps_.bind_texture("depth_tx", &render_buffers.depth_tx, no_filter);
+ setup_ps_.bind_ubo("dof_buf", data_);
+ setup_ps_.bind_image("out_color_img", &setup_color_tx_);
+ setup_ps_.bind_image("out_coc_img", &setup_coc_tx_);
+ setup_ps_.dispatch(&dispatch_setup_size_);
+ setup_ps_.barrier(GPU_BARRIER_TEXTURE_FETCH);
}
void DepthOfField::stabilize_pass_sync()
@@ -273,214 +272,203 @@ void DepthOfField::stabilize_pass_sync()
RenderBuffers &render_buffers = inst_.render_buffers;
VelocityModule &velocity = inst_.velocity;
- stabilize_ps_ = DRW_pass_create("Dof.stabilize_ps_", DRW_STATE_NO_DRAW);
- GPUShader *sh = inst_.shaders.static_shader_get(DOF_STABILIZE);
- DRWShadingGroup *grp = DRW_shgroup_create(sh, stabilize_ps_);
- DRW_shgroup_uniform_block_ref(grp, "camera_prev", &(*velocity.camera_steps[STEP_PREVIOUS]));
- DRW_shgroup_uniform_block_ref(grp, "camera_curr", &(*velocity.camera_steps[STEP_CURRENT]));
+ stabilize_ps_.init();
+ stabilize_ps_.shader_set(inst_.shaders.static_shader_get(DOF_STABILIZE));
+ stabilize_ps_.bind_ubo("camera_prev", &(*velocity.camera_steps[STEP_PREVIOUS]));
+ stabilize_ps_.bind_ubo("camera_curr", &(*velocity.camera_steps[STEP_CURRENT]));
/* This is only for temporal stability. The next step is not needed. */
- DRW_shgroup_uniform_block_ref(grp, "camera_next", &(*velocity.camera_steps[STEP_PREVIOUS]));
- DRW_shgroup_uniform_texture_ref_ex(grp, "coc_tx", &setup_coc_tx_, no_filter);
- DRW_shgroup_uniform_texture_ref_ex(grp, "color_tx", &setup_color_tx_, no_filter);
- DRW_shgroup_uniform_texture_ref_ex(grp, "velocity_tx", &render_buffers.vector_tx, no_filter);
- DRW_shgroup_uniform_texture_ref_ex(grp, "in_history_tx", &stabilize_input_, with_filter);
- DRW_shgroup_uniform_texture_ref_ex(grp, "depth_tx", &render_buffers.depth_tx, no_filter);
- DRW_shgroup_uniform_bool(grp, "use_history", &stabilize_valid_history_, 1);
- DRW_shgroup_uniform_block(grp, "dof_buf", data_);
- DRW_shgroup_uniform_image(grp, "out_coc_img", reduced_coc_tx_.mip_view(0));
- DRW_shgroup_uniform_image(grp, "out_color_img", reduced_color_tx_.mip_view(0));
- DRW_shgroup_uniform_image_ref(grp, "out_history_img", &stabilize_output_tx_);
- DRW_shgroup_call_compute_ref(grp, dispatch_stabilize_size_);
- DRW_shgroup_barrier(grp, GPU_BARRIER_TEXTURE_FETCH | GPU_BARRIER_SHADER_IMAGE_ACCESS);
+ stabilize_ps_.bind_ubo("camera_next", &(*velocity.camera_steps[STEP_PREVIOUS]));
+ stabilize_ps_.bind_texture("coc_tx", &setup_coc_tx_, no_filter);
+ stabilize_ps_.bind_texture("color_tx", &setup_color_tx_, no_filter);
+ stabilize_ps_.bind_texture("velocity_tx", &render_buffers.vector_tx, no_filter);
+ stabilize_ps_.bind_texture("in_history_tx", &stabilize_input_, with_filter);
+ stabilize_ps_.bind_texture("depth_tx", &render_buffers.depth_tx, no_filter);
+ stabilize_ps_.bind_ubo("dof_buf", data_);
+ stabilize_ps_.push_constant("use_history", &stabilize_valid_history_, 1);
+ stabilize_ps_.bind_image("out_coc_img", reduced_coc_tx_.mip_view(0));
+ stabilize_ps_.bind_image("out_color_img", reduced_color_tx_.mip_view(0));
+ stabilize_ps_.bind_image("out_history_img", &stabilize_output_tx_);
+ stabilize_ps_.dispatch(&dispatch_stabilize_size_);
+ stabilize_ps_.barrier(GPU_BARRIER_TEXTURE_FETCH | GPU_BARRIER_SHADER_IMAGE_ACCESS);
}
void DepthOfField::downsample_pass_sync()
{
- downsample_ps_ = DRW_pass_create("Dof.downsample_ps_", DRW_STATE_NO_DRAW);
- GPUShader *sh = inst_.shaders.static_shader_get(DOF_DOWNSAMPLE);
- DRWShadingGroup *grp = DRW_shgroup_create(sh, downsample_ps_);
- DRW_shgroup_uniform_texture_ex(grp, "color_tx", reduced_color_tx_.mip_view(0), no_filter);
- DRW_shgroup_uniform_texture_ex(grp, "coc_tx", reduced_coc_tx_.mip_view(0), no_filter);
- DRW_shgroup_uniform_image_ref(grp, "out_color_img", &downsample_tx_);
- DRW_shgroup_call_compute_ref(grp, dispatch_downsample_size_);
- DRW_shgroup_barrier(grp, GPU_BARRIER_TEXTURE_FETCH);
+ downsample_ps_.init();
+ downsample_ps_.shader_set(inst_.shaders.static_shader_get(DOF_DOWNSAMPLE));
+ downsample_ps_.bind_texture("color_tx", reduced_color_tx_.mip_view(0), no_filter);
+ downsample_ps_.bind_texture("coc_tx", reduced_coc_tx_.mip_view(0), no_filter);
+ downsample_ps_.bind_image("out_color_img", &downsample_tx_);
+ downsample_ps_.dispatch(&dispatch_downsample_size_);
+ downsample_ps_.barrier(GPU_BARRIER_TEXTURE_FETCH);
}
void DepthOfField::reduce_pass_sync()
{
- reduce_ps_ = DRW_pass_create("Dof.reduce_ps_", DRW_STATE_NO_DRAW);
- GPUShader *sh = inst_.shaders.static_shader_get(DOF_REDUCE);
- DRWShadingGroup *grp = DRW_shgroup_create(sh, reduce_ps_);
- DRW_shgroup_uniform_block(grp, "dof_buf", data_);
- DRW_shgroup_uniform_texture_ref_ex(grp, "downsample_tx", &downsample_tx_, no_filter);
- DRW_shgroup_storage_block(grp, "scatter_fg_list_buf", scatter_fg_list_buf_);
- DRW_shgroup_storage_block(grp, "scatter_bg_list_buf", scatter_bg_list_buf_);
- DRW_shgroup_storage_block(grp, "scatter_fg_indirect_buf", scatter_fg_indirect_buf_);
- DRW_shgroup_storage_block(grp, "scatter_bg_indirect_buf", scatter_bg_indirect_buf_);
- DRW_shgroup_uniform_image(grp, "inout_color_lod0_img", reduced_color_tx_.mip_view(0));
- DRW_shgroup_uniform_image(grp, "out_color_lod1_img", reduced_color_tx_.mip_view(1));
- DRW_shgroup_uniform_image(grp, "out_color_lod2_img", reduced_color_tx_.mip_view(2));
- DRW_shgroup_uniform_image(grp, "out_color_lod3_img", reduced_color_tx_.mip_view(3));
- DRW_shgroup_uniform_image(grp, "in_coc_lod0_img", reduced_coc_tx_.mip_view(0));
- DRW_shgroup_uniform_image(grp, "out_coc_lod1_img", reduced_coc_tx_.mip_view(1));
- DRW_shgroup_uniform_image(grp, "out_coc_lod2_img", reduced_coc_tx_.mip_view(2));
- DRW_shgroup_uniform_image(grp, "out_coc_lod3_img", reduced_coc_tx_.mip_view(3));
- DRW_shgroup_call_compute_ref(grp, dispatch_reduce_size_);
+ reduce_ps_.init();
+ reduce_ps_.shader_set(inst_.shaders.static_shader_get(DOF_REDUCE));
+ reduce_ps_.bind_ubo("dof_buf", data_);
+ reduce_ps_.bind_texture("downsample_tx", &downsample_tx_, no_filter);
+ reduce_ps_.bind_ssbo("scatter_fg_list_buf", scatter_fg_list_buf_);
+ reduce_ps_.bind_ssbo("scatter_bg_list_buf", scatter_bg_list_buf_);
+ reduce_ps_.bind_ssbo("scatter_fg_indirect_buf", scatter_fg_indirect_buf_);
+ reduce_ps_.bind_ssbo("scatter_bg_indirect_buf", scatter_bg_indirect_buf_);
+ reduce_ps_.bind_image("inout_color_lod0_img", reduced_color_tx_.mip_view(0));
+ reduce_ps_.bind_image("out_color_lod1_img", reduced_color_tx_.mip_view(1));
+ reduce_ps_.bind_image("out_color_lod2_img", reduced_color_tx_.mip_view(2));
+ reduce_ps_.bind_image("out_color_lod3_img", reduced_color_tx_.mip_view(3));
+ reduce_ps_.bind_image("in_coc_lod0_img", reduced_coc_tx_.mip_view(0));
+ reduce_ps_.bind_image("out_coc_lod1_img", reduced_coc_tx_.mip_view(1));
+ reduce_ps_.bind_image("out_coc_lod2_img", reduced_coc_tx_.mip_view(2));
+ reduce_ps_.bind_image("out_coc_lod3_img", reduced_coc_tx_.mip_view(3));
+ reduce_ps_.dispatch(&dispatch_reduce_size_);
/* NOTE: Command buffer barrier is done automatically by the GPU backend. */
- DRW_shgroup_barrier(grp, GPU_BARRIER_TEXTURE_FETCH | GPU_BARRIER_SHADER_STORAGE);
+ reduce_ps_.barrier(GPU_BARRIER_TEXTURE_FETCH | GPU_BARRIER_SHADER_STORAGE);
}
void DepthOfField::tiles_flatten_pass_sync()
{
- tiles_flatten_ps_ = DRW_pass_create("Dof.tiles_flatten_ps_", DRW_STATE_NO_DRAW);
- GPUShader *sh = inst_.shaders.static_shader_get(DOF_TILES_FLATTEN);
- DRWShadingGroup *grp = DRW_shgroup_create(sh, tiles_flatten_ps_);
+ tiles_flatten_ps_.init();
+ tiles_flatten_ps_.shader_set(inst_.shaders.static_shader_get(DOF_TILES_FLATTEN));
/* NOTE(fclem): We should use the reduced_coc_tx_ as it is stable, but we need the slight focus
* flag from the setup pass. A better way would be to do the brute-force in focus gather without
* this. */
- DRW_shgroup_uniform_texture_ref_ex(grp, "coc_tx", &setup_coc_tx_, no_filter);
- DRW_shgroup_uniform_image_ref(grp, "out_tiles_fg_img", &tiles_fg_tx_.current());
- DRW_shgroup_uniform_image_ref(grp, "out_tiles_bg_img", &tiles_bg_tx_.current());
- DRW_shgroup_call_compute_ref(grp, dispatch_tiles_flatten_size_);
- DRW_shgroup_barrier(grp, GPU_BARRIER_SHADER_IMAGE_ACCESS);
+ tiles_flatten_ps_.bind_texture("coc_tx", &setup_coc_tx_, no_filter);
+ tiles_flatten_ps_.bind_image("out_tiles_fg_img", &tiles_fg_tx_.current());
+ tiles_flatten_ps_.bind_image("out_tiles_bg_img", &tiles_bg_tx_.current());
+ tiles_flatten_ps_.dispatch(&dispatch_tiles_flatten_size_);
+ tiles_flatten_ps_.barrier(GPU_BARRIER_SHADER_IMAGE_ACCESS);
}
void DepthOfField::tiles_dilate_pass_sync()
{
- tiles_dilate_minmax_ps_ = DRW_pass_create("Dof.tiles_dilate_minmax_ps_", DRW_STATE_NO_DRAW);
- tiles_dilate_minabs_ps_ = DRW_pass_create("Dof.tiles_dilate_minabs_ps_", DRW_STATE_NO_DRAW);
for (int pass = 0; pass < 2; pass++) {
- DRWPass *drw_pass = (pass == 0) ? tiles_dilate_minmax_ps_ : tiles_dilate_minabs_ps_;
- GPUShader *sh = inst_.shaders.static_shader_get((pass == 0) ? DOF_TILES_DILATE_MINMAX :
- DOF_TILES_DILATE_MINABS);
- DRWShadingGroup *grp = DRW_shgroup_create(sh, drw_pass);
- DRW_shgroup_uniform_image_ref(grp, "in_tiles_fg_img", &tiles_fg_tx_.previous());
- DRW_shgroup_uniform_image_ref(grp, "in_tiles_bg_img", &tiles_bg_tx_.previous());
- DRW_shgroup_uniform_image_ref(grp, "out_tiles_fg_img", &tiles_fg_tx_.current());
- DRW_shgroup_uniform_image_ref(grp, "out_tiles_bg_img", &tiles_bg_tx_.current());
- DRW_shgroup_uniform_int(grp, "ring_count", &tiles_dilate_ring_count_, 1);
- DRW_shgroup_uniform_int(grp, "ring_width_multiplier", &tiles_dilate_ring_width_mul_, 1);
- DRW_shgroup_call_compute_ref(grp, dispatch_tiles_dilate_size_);
- DRW_shgroup_barrier(grp, GPU_BARRIER_SHADER_IMAGE_ACCESS);
+ PassSimple &drw_pass = (pass == 0) ? tiles_dilate_minmax_ps_ : tiles_dilate_minabs_ps_;
+ eShaderType sh_type = (pass == 0) ? DOF_TILES_DILATE_MINMAX : DOF_TILES_DILATE_MINABS;
+ drw_pass.init();
+ drw_pass.shader_set(inst_.shaders.static_shader_get(sh_type));
+ drw_pass.bind_image("in_tiles_fg_img", &tiles_fg_tx_.previous());
+ drw_pass.bind_image("in_tiles_bg_img", &tiles_bg_tx_.previous());
+ drw_pass.bind_image("out_tiles_fg_img", &tiles_fg_tx_.current());
+ drw_pass.bind_image("out_tiles_bg_img", &tiles_bg_tx_.current());
+ drw_pass.push_constant("ring_count", &tiles_dilate_ring_count_, 1);
+ drw_pass.push_constant("ring_width_multiplier", &tiles_dilate_ring_width_mul_, 1);
+ drw_pass.dispatch(&dispatch_tiles_dilate_size_);
+ drw_pass.barrier(GPU_BARRIER_SHADER_IMAGE_ACCESS);
}
}
void DepthOfField::gather_pass_sync()
{
- gather_fg_ps_ = DRW_pass_create("Dof.gather_fg_ps_", DRW_STATE_NO_DRAW);
- gather_bg_ps_ = DRW_pass_create("Dof.gather_bg_ps_", DRW_STATE_NO_DRAW);
for (int pass = 0; pass < 2; pass++) {
+ PassSimple &drw_pass = (pass == 0) ? gather_fg_ps_ : gather_bg_ps_;
SwapChain<TextureFromPool, 2> &color_chain = (pass == 0) ? color_fg_tx_ : color_bg_tx_;
SwapChain<TextureFromPool, 2> &weight_chain = (pass == 0) ? weight_fg_tx_ : weight_bg_tx_;
- bool use_lut = bokeh_lut_ps_ != nullptr;
eShaderType sh_type = (pass == 0) ?
- (use_lut ? DOF_GATHER_FOREGROUND_LUT : DOF_GATHER_FOREGROUND) :
- (use_lut ? DOF_GATHER_BACKGROUND_LUT : DOF_GATHER_BACKGROUND);
- GPUShader *sh = inst_.shaders.static_shader_get(sh_type);
- DRWShadingGroup *grp = DRW_shgroup_create(sh, (pass == 0) ? gather_fg_ps_ : gather_bg_ps_);
- inst_.sampling.bind_resources(grp);
- DRW_shgroup_uniform_block(grp, "dof_buf", data_);
- DRW_shgroup_uniform_texture_ex(grp, "color_bilinear_tx", reduced_color_tx_, gather_bilinear);
- DRW_shgroup_uniform_texture_ex(grp, "color_tx", reduced_color_tx_, gather_nearest);
- DRW_shgroup_uniform_texture_ex(grp, "coc_tx", reduced_coc_tx_, gather_nearest);
- DRW_shgroup_uniform_image_ref(grp, "in_tiles_fg_img", &tiles_fg_tx_.current());
- DRW_shgroup_uniform_image_ref(grp, "in_tiles_bg_img", &tiles_bg_tx_.current());
- DRW_shgroup_uniform_image_ref(grp, "out_color_img", &color_chain.current());
- DRW_shgroup_uniform_image_ref(grp, "out_weight_img", &weight_chain.current());
- DRW_shgroup_uniform_image_ref(grp, "out_occlusion_img", &occlusion_tx_);
- DRW_shgroup_uniform_texture_ref(grp, "bokeh_lut_tx", &bokeh_gather_lut_tx_);
- DRW_shgroup_call_compute_ref(grp, dispatch_gather_size_);
- DRW_shgroup_barrier(grp, GPU_BARRIER_TEXTURE_FETCH);
+ (use_bokeh_lut_ ? DOF_GATHER_FOREGROUND_LUT :
+ DOF_GATHER_FOREGROUND) :
+ (use_bokeh_lut_ ? DOF_GATHER_BACKGROUND_LUT : DOF_GATHER_BACKGROUND);
+ drw_pass.init();
+ inst_.sampling.bind_resources(&drw_pass);
+ drw_pass.shader_set(inst_.shaders.static_shader_get(sh_type));
+ drw_pass.bind_ubo("dof_buf", data_);
+ drw_pass.bind_texture("color_bilinear_tx", reduced_color_tx_, gather_bilinear);
+ drw_pass.bind_texture("color_tx", reduced_color_tx_, gather_nearest);
+ drw_pass.bind_texture("coc_tx", reduced_coc_tx_, gather_nearest);
+ drw_pass.bind_image("in_tiles_fg_img", &tiles_fg_tx_.current());
+ drw_pass.bind_image("in_tiles_bg_img", &tiles_bg_tx_.current());
+ drw_pass.bind_image("out_color_img", &color_chain.current());
+ drw_pass.bind_image("out_weight_img", &weight_chain.current());
+ drw_pass.bind_image("out_occlusion_img", &occlusion_tx_);
+ drw_pass.bind_texture("bokeh_lut_tx", &bokeh_gather_lut_tx_);
+ drw_pass.dispatch(&dispatch_gather_size_);
+ drw_pass.barrier(GPU_BARRIER_TEXTURE_FETCH);
}
}
void DepthOfField::filter_pass_sync()
{
- filter_fg_ps_ = DRW_pass_create("Dof.filter_fg_ps_", DRW_STATE_NO_DRAW);
- filter_bg_ps_ = DRW_pass_create("Dof.filter_bg_ps_", DRW_STATE_NO_DRAW);
for (int pass = 0; pass < 2; pass++) {
+ PassSimple &drw_pass = (pass == 0) ? filter_fg_ps_ : filter_bg_ps_;
SwapChain<TextureFromPool, 2> &color_chain = (pass == 0) ? color_fg_tx_ : color_bg_tx_;
SwapChain<TextureFromPool, 2> &weight_chain = (pass == 0) ? weight_fg_tx_ : weight_bg_tx_;
- GPUShader *sh = inst_.shaders.static_shader_get(DOF_FILTER);
- DRWShadingGroup *grp = DRW_shgroup_create(sh, (pass == 0) ? filter_fg_ps_ : filter_bg_ps_);
- DRW_shgroup_uniform_texture_ref(grp, "color_tx", &color_chain.previous());
- DRW_shgroup_uniform_texture_ref(grp, "weight_tx", &weight_chain.previous());
- DRW_shgroup_uniform_image_ref(grp, "out_color_img", &color_chain.current());
- DRW_shgroup_uniform_image_ref(grp, "out_weight_img", &weight_chain.current());
- DRW_shgroup_call_compute_ref(grp, dispatch_filter_size_);
- DRW_shgroup_barrier(grp, GPU_BARRIER_TEXTURE_FETCH);
+ drw_pass.init();
+ drw_pass.shader_set(inst_.shaders.static_shader_get(DOF_FILTER));
+ drw_pass.bind_texture("color_tx", &color_chain.previous());
+ drw_pass.bind_texture("weight_tx", &weight_chain.previous());
+ drw_pass.bind_image("out_color_img", &color_chain.current());
+ drw_pass.bind_image("out_weight_img", &weight_chain.current());
+ drw_pass.dispatch(&dispatch_filter_size_);
+ drw_pass.barrier(GPU_BARRIER_TEXTURE_FETCH);
}
}
void DepthOfField::scatter_pass_sync()
{
- DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ADD_FULL;
- scatter_fg_ps_ = DRW_pass_create("Dof.scatter_fg_ps_", state);
- scatter_bg_ps_ = DRW_pass_create("Dof.scatter_bg_ps_", state);
for (int pass = 0; pass < 2; pass++) {
- GPUStorageBuf *scatter_buf = (pass == 0) ? scatter_fg_indirect_buf_ : scatter_bg_indirect_buf_;
- GPUStorageBuf *rect_list_buf = (pass == 0) ? scatter_fg_list_buf_ : scatter_bg_list_buf_;
-
- GPUShader *sh = inst_.shaders.static_shader_get(DOF_SCATTER);
- DRWShadingGroup *grp = DRW_shgroup_create(sh, (pass == 0) ? scatter_fg_ps_ : scatter_bg_ps_);
- DRW_shgroup_uniform_bool_copy(grp, "use_bokeh_lut", bokeh_lut_ps_ != nullptr);
- DRW_shgroup_storage_block(grp, "scatter_list_buf", rect_list_buf);
- DRW_shgroup_uniform_texture_ref(grp, "bokeh_lut_tx", &bokeh_scatter_lut_tx_);
- DRW_shgroup_uniform_texture_ref(grp, "occlusion_tx", &occlusion_tx_);
- DRW_shgroup_call_procedural_indirect(grp, GPU_PRIM_TRI_STRIP, nullptr, scatter_buf);
+ PassSimple &drw_pass = (pass == 0) ? scatter_fg_ps_ : scatter_bg_ps_;
+ drw_pass.init();
+ drw_pass.state_set(DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ADD_FULL);
+ drw_pass.shader_set(inst_.shaders.static_shader_get(DOF_SCATTER));
+ drw_pass.push_constant("use_bokeh_lut", use_bokeh_lut_);
+ drw_pass.bind_texture("bokeh_lut_tx", &bokeh_scatter_lut_tx_);
+ drw_pass.bind_texture("occlusion_tx", &occlusion_tx_);
if (pass == 0) {
+ drw_pass.bind_ssbo("scatter_list_buf", scatter_fg_list_buf_);
+ drw_pass.draw_procedural_indirect(GPU_PRIM_TRI_STRIP, scatter_fg_indirect_buf_);
/* Avoid background gather pass writing to the occlusion_tx mid pass. */
- DRW_shgroup_barrier(grp, GPU_BARRIER_SHADER_IMAGE_ACCESS);
+ drw_pass.barrier(GPU_BARRIER_SHADER_IMAGE_ACCESS);
+ }
+ else {
+ drw_pass.bind_ssbo("scatter_list_buf", scatter_bg_list_buf_);
+ drw_pass.draw_procedural_indirect(GPU_PRIM_TRI_STRIP, scatter_bg_indirect_buf_);
}
}
}
void DepthOfField::hole_fill_pass_sync()
{
- hole_fill_ps_ = DRW_pass_create("Dof.hole_fill_ps_", DRW_STATE_NO_DRAW);
- GPUShader *sh = inst_.shaders.static_shader_get(DOF_GATHER_HOLE_FILL);
- DRWShadingGroup *grp = DRW_shgroup_create(sh, hole_fill_ps_);
- inst_.sampling.bind_resources(grp);
- DRW_shgroup_uniform_block(grp, "dof_buf", data_);
- DRW_shgroup_uniform_texture_ex(grp, "color_bilinear_tx", reduced_color_tx_, gather_bilinear);
- DRW_shgroup_uniform_texture_ex(grp, "color_tx", reduced_color_tx_, gather_nearest);
- DRW_shgroup_uniform_texture_ex(grp, "coc_tx", reduced_coc_tx_, gather_nearest);
- DRW_shgroup_uniform_image_ref(grp, "in_tiles_fg_img", &tiles_fg_tx_.current());
- DRW_shgroup_uniform_image_ref(grp, "in_tiles_bg_img", &tiles_bg_tx_.current());
- DRW_shgroup_uniform_image_ref(grp, "out_color_img", &hole_fill_color_tx_);
- DRW_shgroup_uniform_image_ref(grp, "out_weight_img", &hole_fill_weight_tx_);
- DRW_shgroup_call_compute_ref(grp, dispatch_gather_size_);
- DRW_shgroup_barrier(grp, GPU_BARRIER_TEXTURE_FETCH);
+ hole_fill_ps_.init();
+ inst_.sampling.bind_resources(&hole_fill_ps_);
+ hole_fill_ps_.shader_set(inst_.shaders.static_shader_get(DOF_GATHER_HOLE_FILL));
+ hole_fill_ps_.bind_ubo("dof_buf", data_);
+ hole_fill_ps_.bind_texture("color_bilinear_tx", reduced_color_tx_, gather_bilinear);
+ hole_fill_ps_.bind_texture("color_tx", reduced_color_tx_, gather_nearest);
+ hole_fill_ps_.bind_texture("coc_tx", reduced_coc_tx_, gather_nearest);
+ hole_fill_ps_.bind_image("in_tiles_fg_img", &tiles_fg_tx_.current());
+ hole_fill_ps_.bind_image("in_tiles_bg_img", &tiles_bg_tx_.current());
+ hole_fill_ps_.bind_image("out_color_img", &hole_fill_color_tx_);
+ hole_fill_ps_.bind_image("out_weight_img", &hole_fill_weight_tx_);
+ hole_fill_ps_.dispatch(&dispatch_gather_size_);
+ hole_fill_ps_.barrier(GPU_BARRIER_TEXTURE_FETCH);
}
void DepthOfField::resolve_pass_sync()
{
eGPUSamplerState with_filter = GPU_SAMPLER_FILTER;
RenderBuffers &render_buffers = inst_.render_buffers;
-
- resolve_ps_ = DRW_pass_create("Dof.resolve_ps_", DRW_STATE_NO_DRAW);
- bool use_lut = bokeh_lut_ps_ != nullptr;
- eShaderType sh_type = use_lut ? DOF_RESOLVE_LUT : DOF_RESOLVE;
- GPUShader *sh = inst_.shaders.static_shader_get(sh_type);
- DRWShadingGroup *grp = DRW_shgroup_create(sh, resolve_ps_);
- inst_.sampling.bind_resources(grp);
- DRW_shgroup_uniform_block(grp, "dof_buf", data_);
- DRW_shgroup_uniform_texture_ref_ex(grp, "depth_tx", &render_buffers.depth_tx, no_filter);
- DRW_shgroup_uniform_texture_ref_ex(grp, "color_tx", &input_color_tx_, no_filter);
- DRW_shgroup_uniform_texture_ref_ex(grp, "stable_color_tx", &resolve_stable_color_tx_, no_filter);
- DRW_shgroup_uniform_texture_ref_ex(grp, "color_bg_tx", &color_bg_tx_.current(), with_filter);
- DRW_shgroup_uniform_texture_ref_ex(grp, "color_fg_tx", &color_fg_tx_.current(), with_filter);
- DRW_shgroup_uniform_image_ref(grp, "in_tiles_fg_img", &tiles_fg_tx_.current());
- DRW_shgroup_uniform_image_ref(grp, "in_tiles_bg_img", &tiles_bg_tx_.current());
- DRW_shgroup_uniform_texture_ref(grp, "weight_bg_tx", &weight_bg_tx_.current());
- DRW_shgroup_uniform_texture_ref(grp, "weight_fg_tx", &weight_fg_tx_.current());
- DRW_shgroup_uniform_texture_ref(grp, "color_hole_fill_tx", &hole_fill_color_tx_);
- DRW_shgroup_uniform_texture_ref(grp, "weight_hole_fill_tx", &hole_fill_weight_tx_);
- DRW_shgroup_uniform_texture_ref(grp, "bokeh_lut_tx", &bokeh_resolve_lut_tx_);
- DRW_shgroup_uniform_image_ref(grp, "out_color_img", &output_color_tx_);
- DRW_shgroup_barrier(grp, GPU_BARRIER_TEXTURE_FETCH);
- DRW_shgroup_call_compute_ref(grp, dispatch_resolve_size_);
- DRW_shgroup_barrier(grp, GPU_BARRIER_TEXTURE_FETCH);
+ eShaderType sh_type = use_bokeh_lut_ ? DOF_RESOLVE_LUT : DOF_RESOLVE;
+
+ resolve_ps_.init();
+ inst_.sampling.bind_resources(&resolve_ps_);
+ resolve_ps_.shader_set(inst_.shaders.static_shader_get(sh_type));
+ resolve_ps_.bind_ubo("dof_buf", data_);
+ resolve_ps_.bind_texture("depth_tx", &render_buffers.depth_tx, no_filter);
+ resolve_ps_.bind_texture("color_tx", &input_color_tx_, no_filter);
+ resolve_ps_.bind_texture("stable_color_tx", &resolve_stable_color_tx_, no_filter);
+ resolve_ps_.bind_texture("color_bg_tx", &color_bg_tx_.current(), with_filter);
+ resolve_ps_.bind_texture("color_fg_tx", &color_fg_tx_.current(), with_filter);
+ resolve_ps_.bind_image("in_tiles_fg_img", &tiles_fg_tx_.current());
+ resolve_ps_.bind_image("in_tiles_bg_img", &tiles_bg_tx_.current());
+ resolve_ps_.bind_texture("weight_bg_tx", &weight_bg_tx_.current());
+ resolve_ps_.bind_texture("weight_fg_tx", &weight_fg_tx_.current());
+ resolve_ps_.bind_texture("color_hole_fill_tx", &hole_fill_color_tx_);
+ resolve_ps_.bind_texture("weight_hole_fill_tx", &hole_fill_weight_tx_);
+ resolve_ps_.bind_texture("bokeh_lut_tx", &bokeh_resolve_lut_tx_);
+ resolve_ps_.bind_image("out_color_img", &output_color_tx_);
+ resolve_ps_.barrier(GPU_BARRIER_TEXTURE_FETCH);
+ resolve_ps_.dispatch(&dispatch_resolve_size_);
+ resolve_ps_.barrier(GPU_BARRIER_TEXTURE_FETCH);
}
/** \} */
@@ -509,7 +497,8 @@ void DepthOfField::update_sample_table()
data_.filter_center_weight = film_filter_weight(radius, math::length_squared(subpixel_offset));
}
-void DepthOfField::render(GPUTexture **input_tx,
+void DepthOfField::render(View &view,
+ GPUTexture **input_tx,
GPUTexture **output_tx,
DepthOfFieldBuffer &dof_buffer)
{
@@ -580,6 +569,8 @@ void DepthOfField::render(GPUTexture **input_tx,
DRW_stats_group_start("Depth of Field");
+ Manager &drw = *inst_.manager;
+
{
DRW_stats_group_start("Setup");
{
@@ -587,13 +578,15 @@ void DepthOfField::render(GPUTexture **input_tx,
bokeh_scatter_lut_tx_.acquire(int2(DOF_BOKEH_LUT_SIZE), GPU_R16F);
bokeh_resolve_lut_tx_.acquire(int2(DOF_MAX_SLIGHT_FOCUS_RADIUS * 2 + 1), GPU_R16F);
- DRW_draw_pass(bokeh_lut_ps_);
+ if (use_bokeh_lut_) {
+ drw.submit(bokeh_lut_ps_, view);
+ }
}
{
setup_color_tx_.acquire(half_res, GPU_RGBA16F);
setup_coc_tx_.acquire(half_res, GPU_R16F);
- DRW_draw_pass(setup_ps_);
+ drw.submit(setup_ps_, view);
}
{
stabilize_output_tx_.acquire(half_res, GPU_RGBA16F);
@@ -607,7 +600,7 @@ void DepthOfField::render(GPUTexture **input_tx,
stabilize_input_ = dof_buffer.stabilize_history_tx_;
/* Outputs to reduced_*_tx_ mip 0. */
- DRW_draw_pass(stabilize_ps_);
+ drw.submit(stabilize_ps_, view);
/* WATCH(fclem): Swap Texture an TextureFromPool internal GPUTexture in order to reuse
* the one that we just consumed. */
@@ -626,7 +619,7 @@ void DepthOfField::render(GPUTexture **input_tx,
tiles_fg_tx_.current().acquire(tile_res, GPU_R11F_G11F_B10F);
tiles_bg_tx_.current().acquire(tile_res, GPU_R11F_G11F_B10F);
- DRW_draw_pass(tiles_flatten_ps_);
+ drw.submit(tiles_flatten_ps_, view);
/* Used by tile_flatten and stabilize_ps pass. */
setup_coc_tx_.release();
@@ -655,7 +648,7 @@ void DepthOfField::render(GPUTexture **input_tx,
tiles_fg_tx_.swap();
tiles_bg_tx_.swap();
- DRW_draw_pass((pass == 0) ? tiles_dilate_minmax_ps_ : tiles_dilate_minabs_ps_);
+ drw.submit((pass == 0) ? tiles_dilate_minmax_ps_ : tiles_dilate_minabs_ps_, view);
}
}
@@ -667,12 +660,12 @@ void DepthOfField::render(GPUTexture **input_tx,
downsample_tx_.acquire(quarter_res, GPU_RGBA16F);
- DRW_draw_pass(downsample_ps_);
+ drw.submit(downsample_ps_, view);
scatter_fg_indirect_buf_.clear_to_zero();
scatter_bg_indirect_buf_.clear_to_zero();
- DRW_draw_pass(reduce_ps_);
+ drw.submit(reduce_ps_, view);
/* Used by reduce pass. */
downsample_tx_.release();
@@ -686,15 +679,15 @@ void DepthOfField::render(GPUTexture **input_tx,
SwapChain<TextureFromPool, 2> &color_tx = is_background ? color_bg_tx_ : color_fg_tx_;
SwapChain<TextureFromPool, 2> &weight_tx = is_background ? weight_bg_tx_ : weight_fg_tx_;
Framebuffer &scatter_fb = is_background ? scatter_bg_fb_ : scatter_fg_fb_;
- DRWPass *gather_ps = is_background ? gather_bg_ps_ : gather_fg_ps_;
- DRWPass *filter_ps = is_background ? filter_bg_ps_ : filter_fg_ps_;
- DRWPass *scatter_ps = is_background ? scatter_bg_ps_ : scatter_fg_ps_;
+ PassSimple &gather_ps = is_background ? gather_bg_ps_ : gather_fg_ps_;
+ PassSimple &filter_ps = is_background ? filter_bg_ps_ : filter_fg_ps_;
+ PassSimple &scatter_ps = is_background ? scatter_bg_ps_ : scatter_fg_ps_;
color_tx.current().acquire(half_res, GPU_RGBA16F);
weight_tx.current().acquire(half_res, GPU_R16F);
occlusion_tx_.acquire(half_res, GPU_RG16F);
- DRW_draw_pass(gather_ps);
+ drw.submit(gather_ps, view);
{
/* Filtering pass. */
@@ -704,7 +697,7 @@ void DepthOfField::render(GPUTexture **input_tx,
color_tx.current().acquire(half_res, GPU_RGBA16F);
weight_tx.current().acquire(half_res, GPU_R16F);
- DRW_draw_pass(filter_ps);
+ drw.submit(filter_ps, view);
color_tx.previous().release();
weight_tx.previous().release();
@@ -715,7 +708,7 @@ void DepthOfField::render(GPUTexture **input_tx,
scatter_fb.ensure(GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(color_tx.current()));
GPU_framebuffer_bind(scatter_fb);
- DRW_draw_pass(scatter_ps);
+ drw.submit(scatter_ps, view);
/* Used by scatter pass. */
occlusion_tx_.release();
@@ -731,7 +724,7 @@ void DepthOfField::render(GPUTexture **input_tx,
hole_fill_color_tx_.acquire(half_res, GPU_RGBA16F);
hole_fill_weight_tx_.acquire(half_res, GPU_R16F);
- DRW_draw_pass(hole_fill_ps_);
+ drw.submit(hole_fill_ps_, view);
/* NOTE: We do not filter the hole-fill pass as effect is likely to not be noticeable. */
@@ -742,7 +735,7 @@ void DepthOfField::render(GPUTexture **input_tx,
resolve_stable_color_tx_ = dof_buffer.stabilize_history_tx_;
- DRW_draw_pass(resolve_ps_);
+ drw.submit(resolve_ps_, view);
color_bg_tx_.current().release();
color_fg_tx_.current().release();
@@ -765,4 +758,4 @@ void DepthOfField::render(GPUTexture **input_tx,
/** \} */
-} // namespace blender::eevee \ No newline at end of file
+} // namespace blender::eevee
diff --git a/source/blender/draw/engines/eevee_next/eevee_depth_of_field.hh b/source/blender/draw/engines/eevee_next/eevee_depth_of_field.hh
index 8c291b241bd..bac0e394d66 100644
--- a/source/blender/draw/engines/eevee_next/eevee_depth_of_field.hh
+++ b/source/blender/draw/engines/eevee_next/eevee_depth_of_field.hh
@@ -56,13 +56,13 @@ class DepthOfField {
TextureFromPool bokeh_gather_lut_tx_ = {"dof_bokeh_gather_lut"};
TextureFromPool bokeh_resolve_lut_tx_ = {"dof_bokeh_resolve_lut"};
TextureFromPool bokeh_scatter_lut_tx_ = {"dof_bokeh_scatter_lut"};
- DRWPass *bokeh_lut_ps_ = nullptr;
+ PassSimple bokeh_lut_ps_ = {"BokehLut"};
/** Outputs half-resolution color and Circle Of Confusion. */
TextureFromPool setup_coc_tx_ = {"dof_setup_coc"};
TextureFromPool setup_color_tx_ = {"dof_setup_color"};
int3 dispatch_setup_size_ = int3(-1);
- DRWPass *setup_ps_ = nullptr;
+ PassSimple setup_ps_ = {"Setup"};
/** Allocated because we need mip chain. Which isn't supported by TextureFromPool. */
Texture reduced_coc_tx_ = {"dof_reduced_coc"};
@@ -73,12 +73,12 @@ class DepthOfField {
GPUTexture *stabilize_input_ = nullptr;
bool1 stabilize_valid_history_ = false;
int3 dispatch_stabilize_size_ = int3(-1);
- DRWPass *stabilize_ps_ = nullptr;
+ PassSimple stabilize_ps_ = {"Stabilize"};
/** 1/4th res color buffer used to speedup the local contrast test in the first reduce pass. */
TextureFromPool downsample_tx_ = {"dof_downsample"};
int3 dispatch_downsample_size_ = int3(-1);
- DRWPass *downsample_ps_ = nullptr;
+ PassSimple downsample_ps_ = {"Downsample"};
/** Create mip-mapped color & COC textures for gather passes as well as scatter rect list. */
DepthOfFieldScatterListBuf scatter_fg_list_buf_;
@@ -86,20 +86,20 @@ class DepthOfField {
DrawIndirectBuf scatter_fg_indirect_buf_;
DrawIndirectBuf scatter_bg_indirect_buf_;
int3 dispatch_reduce_size_ = int3(-1);
- DRWPass *reduce_ps_ = nullptr;
+ PassSimple reduce_ps_ = {"Reduce"};
/** Outputs min & max COC in each 8x8 half res pixel tiles (so 1/16th of full resolution). */
SwapChain<TextureFromPool, 2> tiles_fg_tx_;
SwapChain<TextureFromPool, 2> tiles_bg_tx_;
int3 dispatch_tiles_flatten_size_ = int3(-1);
- DRWPass *tiles_flatten_ps_ = nullptr;
+ PassSimple tiles_flatten_ps_ = {"TilesFlatten"};
/** Dilates the min & max CoCs to cover maximum COC values. */
int tiles_dilate_ring_count_ = -1;
int tiles_dilate_ring_width_mul_ = -1;
int3 dispatch_tiles_dilate_size_ = int3(-1);
- DRWPass *tiles_dilate_minmax_ps_ = nullptr;
- DRWPass *tiles_dilate_minabs_ps_ = nullptr;
+ PassSimple tiles_dilate_minmax_ps_ = {"TilesDilateMinmax"};
+ PassSimple tiles_dilate_minabs_ps_ = {"TilesDilateMinabs"};
/** Gather convolution for low intensity pixels and low contrast areas. */
SwapChain<TextureFromPool, 2> color_bg_tx_;
@@ -108,29 +108,29 @@ class DepthOfField {
SwapChain<TextureFromPool, 2> weight_fg_tx_;
TextureFromPool occlusion_tx_ = {"dof_occlusion"};
int3 dispatch_gather_size_ = int3(-1);
- DRWPass *gather_fg_ps_ = nullptr;
- DRWPass *gather_bg_ps_ = nullptr;
+ PassSimple gather_fg_ps_ = {"GatherFg"};
+ PassSimple gather_bg_ps_ = {"GatherBg"};
/** Hole-fill convolution: Gather pass meant to fill areas of foreground dis-occlusion. */
TextureFromPool hole_fill_color_tx_ = {"dof_color_hole_fill"};
TextureFromPool hole_fill_weight_tx_ = {"dof_weight_hole_fill"};
- DRWPass *hole_fill_ps_ = nullptr;
+ PassSimple hole_fill_ps_ = {"HoleFill"};
/** Small Filter pass to reduce noise out of gather passes. */
int3 dispatch_filter_size_ = int3(-1);
- DRWPass *filter_fg_ps_ = nullptr;
- DRWPass *filter_bg_ps_ = nullptr;
+ PassSimple filter_fg_ps_ = {"FilterFg"};
+ PassSimple filter_bg_ps_ = {"FilterBg"};
/** Scatter convolution: A quad is emitted for every 4 bright enough half pixels. */
Framebuffer scatter_fg_fb_ = {"dof_scatter_fg"};
Framebuffer scatter_bg_fb_ = {"dof_scatter_bg"};
- DRWPass *scatter_fg_ps_ = nullptr;
- DRWPass *scatter_bg_ps_ = nullptr;
+ PassSimple scatter_fg_ps_ = {"ScatterFg"};
+ PassSimple scatter_bg_ps_ = {"ScatterBg"};
/** Recombine the results and also perform a slight out of focus gather. */
GPUTexture *resolve_stable_color_tx_ = nullptr;
int3 dispatch_resolve_size_ = int3(-1);
- DRWPass *resolve_ps_ = nullptr;
+ PassSimple resolve_ps_ = {"Resolve"};
DepthOfFieldDataBuf data_;
@@ -139,6 +139,8 @@ class DepthOfField {
float fx_max_coc_;
/** Use jittered depth of field where we randomize camera location. */
bool do_jitter_;
+ /** Enable bokeh lookup texture. */
+ bool use_bokeh_lut_;
/** Circle of Confusion radius for FX DoF passes. Is in view X direction in [0..1] range. */
float fx_radius_;
@@ -166,7 +168,10 @@ class DepthOfField {
* Will swap input and output texture if rendering happens. The actual output of this function
* is in input_tx.
*/
- void render(GPUTexture **input_tx, GPUTexture **output_tx, DepthOfFieldBuffer &dof_buffer);
+ void render(View &view,
+ GPUTexture **input_tx,
+ GPUTexture **output_tx,
+ DepthOfFieldBuffer &dof_buffer);
bool postfx_enabled() const
{
diff --git a/source/blender/draw/engines/eevee_next/eevee_engine.cc b/source/blender/draw/engines/eevee_next/eevee_engine.cc
index 37b4bde324e..5ef198838c9 100644
--- a/source/blender/draw/engines/eevee_next/eevee_engine.cc
+++ b/source/blender/draw/engines/eevee_next/eevee_engine.cc
@@ -140,7 +140,7 @@ static void eevee_instance_free(void *instance)
delete reinterpret_cast<eevee::Instance *>(instance);
}
-static void eevee_render_to_image(void *UNUSED(vedata),
+static void eevee_render_to_image(void *vedata,
struct RenderEngine *engine,
struct RenderLayer *layer,
const struct rcti *UNUSED(rect))
@@ -164,7 +164,23 @@ static void eevee_render_to_image(void *UNUSED(vedata),
instance->init(size, &rect, engine, depsgraph, nullptr, camera_original_ob, layer);
instance->render_frame(layer, viewname);
+ EEVEE_Data *ved = static_cast<EEVEE_Data *>(vedata);
+ if (ved->instance) {
+ delete ved->instance;
+ }
+ ved->instance = instance;
+}
+
+static void eevee_store_metadata(void *vedata, struct RenderResult *render_result)
+{
+ if (!GPU_shader_storage_buffer_objects_support()) {
+ return;
+ }
+ EEVEE_Data *ved = static_cast<EEVEE_Data *>(vedata);
+ eevee::Instance *instance = ved->instance;
+ instance->store_metadata(render_result);
delete instance;
+ ved->instance = nullptr;
}
static void eevee_render_update_passes(RenderEngine *engine, Scene *scene, ViewLayer *view_layer)
@@ -172,7 +188,7 @@ static void eevee_render_update_passes(RenderEngine *engine, Scene *scene, ViewL
if (!GPU_shader_storage_buffer_objects_support()) {
return;
}
- UNUSED_VARS(engine, scene, view_layer);
+ eevee::Instance::update_passes(engine, scene, view_layer);
}
static const DrawEngineDataSize eevee_data_size = DRW_VIEWPORT_DATA_SIZE(EEVEE_Data);
@@ -194,7 +210,7 @@ DrawEngineType draw_engine_eevee_next_type = {
nullptr,
nullptr,
&eevee_render_to_image,
- nullptr,
+ &eevee_store_metadata,
};
RenderEngineType DRW_engine_viewport_eevee_next_type = {
diff --git a/source/blender/draw/engines/eevee_next/eevee_film.cc b/source/blender/draw/engines/eevee_next/eevee_film.cc
index b3fbe088471..244eb1e54ef 100644
--- a/source/blender/draw/engines/eevee_next/eevee_film.cc
+++ b/source/blender/draw/engines/eevee_next/eevee_film.cc
@@ -5,7 +5,7 @@
/** \file
* \ingroup eevee
*
- * A film is a fullscreen buffer (usually at output extent)
+ * A film is a full-screen buffer (usually at output extent)
* that will be able to accumulate sample in any distorted camera_type
* using a pixel filter.
*
@@ -162,6 +162,45 @@ inline bool operator!=(const FilmData &a, const FilmData &b)
/** \name Film
* \{ */
+static eViewLayerEEVEEPassType enabled_passes(const ViewLayer *view_layer)
+{
+ eViewLayerEEVEEPassType result = eViewLayerEEVEEPassType(view_layer->eevee.render_passes);
+
+#define ENABLE_FROM_LEGACY(name_legacy, name_eevee) \
+ SET_FLAG_FROM_TEST(result, \
+ (view_layer->passflag & SCE_PASS_##name_legacy) != 0, \
+ EEVEE_RENDER_PASS_##name_eevee);
+
+ ENABLE_FROM_LEGACY(COMBINED, COMBINED)
+ ENABLE_FROM_LEGACY(Z, Z)
+ ENABLE_FROM_LEGACY(MIST, MIST)
+ ENABLE_FROM_LEGACY(NORMAL, NORMAL)
+ ENABLE_FROM_LEGACY(SHADOW, SHADOW)
+ ENABLE_FROM_LEGACY(AO, AO)
+ ENABLE_FROM_LEGACY(EMIT, EMIT)
+ ENABLE_FROM_LEGACY(ENVIRONMENT, ENVIRONMENT)
+ ENABLE_FROM_LEGACY(DIFFUSE_COLOR, DIFFUSE_COLOR)
+ ENABLE_FROM_LEGACY(GLOSSY_COLOR, SPECULAR_COLOR)
+ ENABLE_FROM_LEGACY(DIFFUSE_DIRECT, DIFFUSE_LIGHT)
+ ENABLE_FROM_LEGACY(GLOSSY_DIRECT, SPECULAR_LIGHT)
+ ENABLE_FROM_LEGACY(ENVIRONMENT, ENVIRONMENT)
+ ENABLE_FROM_LEGACY(VECTOR, VECTOR)
+
+#undef ENABLE_FROM_LEGACY
+
+ SET_FLAG_FROM_TEST(result,
+ view_layer->cryptomatte_flag & VIEW_LAYER_CRYPTOMATTE_OBJECT,
+ EEVEE_RENDER_PASS_CRYPTOMATTE_OBJECT);
+ SET_FLAG_FROM_TEST(result,
+ view_layer->cryptomatte_flag & VIEW_LAYER_CRYPTOMATTE_ASSET,
+ EEVEE_RENDER_PASS_CRYPTOMATTE_ASSET);
+ SET_FLAG_FROM_TEST(result,
+ view_layer->cryptomatte_flag & VIEW_LAYER_CRYPTOMATTE_MATERIAL,
+ EEVEE_RENDER_PASS_CRYPTOMATTE_MATERIAL);
+
+ return result;
+}
+
void Film::init(const int2 &extent, const rcti *output_rect)
{
Sampling &sampling = inst_.sampling;
@@ -186,29 +225,7 @@ void Film::init(const int2 &extent, const rcti *output_rect)
}
else {
/* Render Case. */
- render_passes = eViewLayerEEVEEPassType(inst_.view_layer->eevee.render_passes);
-
-#define ENABLE_FROM_LEGACY(name_legacy, name_eevee) \
- SET_FLAG_FROM_TEST(render_passes, \
- (inst_.view_layer->passflag & SCE_PASS_##name_legacy) != 0, \
- EEVEE_RENDER_PASS_##name_eevee);
-
- ENABLE_FROM_LEGACY(COMBINED, COMBINED)
- ENABLE_FROM_LEGACY(Z, Z)
- ENABLE_FROM_LEGACY(MIST, MIST)
- ENABLE_FROM_LEGACY(NORMAL, NORMAL)
- ENABLE_FROM_LEGACY(SHADOW, SHADOW)
- ENABLE_FROM_LEGACY(AO, AO)
- ENABLE_FROM_LEGACY(EMIT, EMIT)
- ENABLE_FROM_LEGACY(ENVIRONMENT, ENVIRONMENT)
- ENABLE_FROM_LEGACY(DIFFUSE_COLOR, DIFFUSE_COLOR)
- ENABLE_FROM_LEGACY(GLOSSY_COLOR, SPECULAR_COLOR)
- ENABLE_FROM_LEGACY(DIFFUSE_DIRECT, DIFFUSE_LIGHT)
- ENABLE_FROM_LEGACY(GLOSSY_DIRECT, SPECULAR_LIGHT)
- ENABLE_FROM_LEGACY(ENVIRONMENT, ENVIRONMENT)
- ENABLE_FROM_LEGACY(VECTOR, VECTOR)
-
-#undef ENABLE_FROM_LEGACY
+ render_passes = enabled_passes(inst_.view_layer);
}
/* Filter obsolete passes. */
@@ -241,6 +258,7 @@ void Film::init(const int2 &extent, const rcti *output_rect)
/* TODO(fclem): parameter hidden in experimental.
* We need to figure out LOD bias first in order to preserve texture crispiness. */
data.scaling_factor = 1;
+ data.cryptomatte_samples_len = inst_.view_layer->cryptomatte_levels;
data.background_opacity = (scene.r.alphamode == R_ALPHAPREMUL) ? 0.0f : 1.0f;
if (inst_.is_viewport() && false /* TODO(fclem): StudioLight */) {
@@ -270,10 +288,11 @@ void Film::init(const int2 &extent, const rcti *output_rect)
data_.any_render_pass_2 = (enabled_passes_ & color_passes_2) != 0;
}
{
- /* Set pass offsets. */
+ /* Set pass offsets. */
data_.display_id = aovs_info.display_id;
- data_.display_is_value = aovs_info.display_is_value;
+ data_.display_storage_type = aovs_info.display_is_value ? PASS_STORAGE_VALUE :
+ PASS_STORAGE_COLOR;
/* Combined is in a separate buffer. */
data_.combined_id = (enabled_passes_ & EEVEE_RENDER_PASS_COMBINED) ? 0 : -1;
@@ -284,13 +303,13 @@ void Film::init(const int2 &extent, const rcti *output_rect)
data_.value_len = 0;
auto pass_index_get = [&](eViewLayerEEVEEPassType pass_type) {
- bool is_value = pass_is_value(pass_type);
+ ePassStorageType storage_type = pass_storage_type(pass_type);
int index = (enabled_passes_ & pass_type) ?
- (is_value ? data_.value_len : data_.color_len)++ :
+ (storage_type == PASS_STORAGE_VALUE ? data_.value_len : data_.color_len)++ :
-1;
if (inst_.is_viewport() && inst_.v3d->shading.render_pass == pass_type) {
data_.display_id = index;
- data_.display_is_value = is_value;
+ data_.display_storage_type = storage_type;
}
return index;
};
@@ -316,6 +335,24 @@ void Film::init(const int2 &extent, const rcti *output_rect)
data_.color_len += data_.aov_color_len;
data_.value_len += data_.aov_value_len;
+
+ int cryptomatte_id = 0;
+ auto cryptomatte_index_get = [&](eViewLayerEEVEEPassType pass_type) {
+ int index = -1;
+ if (enabled_passes_ & pass_type) {
+ index = cryptomatte_id;
+ cryptomatte_id += data_.cryptomatte_samples_len / 2;
+
+ if (inst_.is_viewport() && inst_.v3d->shading.render_pass == pass_type) {
+ data_.display_id = index;
+ data_.display_storage_type = PASS_STORAGE_CRYPTOMATTE;
+ }
+ }
+ return index;
+ };
+ data_.cryptomatte_object_id = cryptomatte_index_get(EEVEE_RENDER_PASS_CRYPTOMATTE_OBJECT);
+ data_.cryptomatte_asset_id = cryptomatte_index_get(EEVEE_RENDER_PASS_CRYPTOMATTE_ASSET);
+ data_.cryptomatte_material_id = cryptomatte_index_get(EEVEE_RENDER_PASS_CRYPTOMATTE_MATERIAL);
}
{
/* TODO(@fclem): Over-scans. */
@@ -327,6 +364,7 @@ void Film::init(const int2 &extent, const rcti *output_rect)
eGPUTextureFormat float_format = GPU_R16F;
eGPUTextureFormat weight_format = GPU_R32F;
eGPUTextureFormat depth_format = GPU_R32F;
+ eGPUTextureFormat cryptomatte_format = GPU_RGBA32F;
int reset = 0;
reset += depth_tx_.ensure_2d(depth_format, data_.extent);
@@ -341,6 +379,12 @@ void Film::init(const int2 &extent, const rcti *output_rect)
reset += value_accum_tx_.ensure_2d_array(float_format,
(data_.value_len > 0) ? data_.extent : int2(1),
(data_.value_len > 0) ? data_.value_len : 1);
+ /* Divided by two as two cryptomatte samples fit in pixel (RG, BA). */
+ int cryptomatte_array_len = cryptomatte_layer_len_get() * data_.cryptomatte_samples_len / 2;
+ reset += cryptomatte_tx_.ensure_2d_array(cryptomatte_format,
+ (cryptomatte_array_len > 0) ? data_.extent : int2(1),
+ (cryptomatte_array_len > 0) ? cryptomatte_array_len :
+ 1);
if (reset > 0) {
sampling.reset();
@@ -353,6 +397,7 @@ void Film::init(const int2 &extent, const rcti *output_rect)
combined_tx_.current().clear(float4(0.0f));
weight_tx_.current().clear(float4(0.0f));
depth_tx_.clear(float4(0.0f));
+ cryptomatte_tx_.clear(float4(0.0f));
}
}
@@ -377,49 +422,62 @@ void Film::sync()
* Still bind previous step to avoid undefined behavior. */
eVelocityStep step_next = inst_.is_viewport() ? STEP_PREVIOUS : STEP_NEXT;
- DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_ALWAYS;
- accumulate_ps_ = DRW_pass_create("Film.Accumulate", state);
- GPUShader *sh = inst_.shaders.static_shader_get(shader);
- DRWShadingGroup *grp = DRW_shgroup_create(sh, accumulate_ps_);
- DRW_shgroup_uniform_block_ref(grp, "film_buf", &data_);
- DRW_shgroup_uniform_block_ref(grp, "camera_prev", &(*velocity.camera_steps[STEP_PREVIOUS]));
- DRW_shgroup_uniform_block_ref(grp, "camera_curr", &(*velocity.camera_steps[STEP_CURRENT]));
- DRW_shgroup_uniform_block_ref(grp, "camera_next", &(*velocity.camera_steps[step_next]));
- DRW_shgroup_uniform_texture_ref(grp, "depth_tx", &rbuffers.depth_tx);
- DRW_shgroup_uniform_texture_ref(grp, "combined_tx", &combined_final_tx_);
- DRW_shgroup_uniform_texture_ref(grp, "normal_tx", &rbuffers.normal_tx);
- DRW_shgroup_uniform_texture_ref(grp, "vector_tx", &rbuffers.vector_tx);
- DRW_shgroup_uniform_texture_ref(grp, "diffuse_light_tx", &rbuffers.diffuse_light_tx);
- DRW_shgroup_uniform_texture_ref(grp, "diffuse_color_tx", &rbuffers.diffuse_color_tx);
- DRW_shgroup_uniform_texture_ref(grp, "specular_light_tx", &rbuffers.specular_light_tx);
- DRW_shgroup_uniform_texture_ref(grp, "specular_color_tx", &rbuffers.specular_color_tx);
- DRW_shgroup_uniform_texture_ref(grp, "volume_light_tx", &rbuffers.volume_light_tx);
- DRW_shgroup_uniform_texture_ref(grp, "emission_tx", &rbuffers.emission_tx);
- DRW_shgroup_uniform_texture_ref(grp, "environment_tx", &rbuffers.environment_tx);
- DRW_shgroup_uniform_texture_ref(grp, "shadow_tx", &rbuffers.shadow_tx);
- DRW_shgroup_uniform_texture_ref(grp, "ambient_occlusion_tx", &rbuffers.ambient_occlusion_tx);
- DRW_shgroup_uniform_texture_ref(grp, "aov_color_tx", &rbuffers.aov_color_tx);
- DRW_shgroup_uniform_texture_ref(grp, "aov_value_tx", &rbuffers.aov_value_tx);
+ accumulate_ps_.init();
+ accumulate_ps_.state_set(DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_ALWAYS);
+ accumulate_ps_.shader_set(inst_.shaders.static_shader_get(shader));
+ accumulate_ps_.bind_ubo("film_buf", &data_);
+ accumulate_ps_.bind_ubo("camera_prev", &(*velocity.camera_steps[STEP_PREVIOUS]));
+ accumulate_ps_.bind_ubo("camera_curr", &(*velocity.camera_steps[STEP_CURRENT]));
+ accumulate_ps_.bind_ubo("camera_next", &(*velocity.camera_steps[step_next]));
+ accumulate_ps_.bind_texture("depth_tx", &rbuffers.depth_tx);
+ accumulate_ps_.bind_texture("combined_tx", &combined_final_tx_);
+ accumulate_ps_.bind_texture("normal_tx", &rbuffers.normal_tx);
+ accumulate_ps_.bind_texture("vector_tx", &rbuffers.vector_tx);
+ accumulate_ps_.bind_texture("light_tx", &rbuffers.light_tx);
+ accumulate_ps_.bind_texture("diffuse_color_tx", &rbuffers.diffuse_color_tx);
+ accumulate_ps_.bind_texture("specular_color_tx", &rbuffers.specular_color_tx);
+ accumulate_ps_.bind_texture("volume_light_tx", &rbuffers.volume_light_tx);
+ accumulate_ps_.bind_texture("emission_tx", &rbuffers.emission_tx);
+ accumulate_ps_.bind_texture("environment_tx", &rbuffers.environment_tx);
+ accumulate_ps_.bind_texture("shadow_tx", &rbuffers.shadow_tx);
+ accumulate_ps_.bind_texture("ambient_occlusion_tx", &rbuffers.ambient_occlusion_tx);
+ accumulate_ps_.bind_texture("aov_color_tx", &rbuffers.aov_color_tx);
+ accumulate_ps_.bind_texture("aov_value_tx", &rbuffers.aov_value_tx);
+ accumulate_ps_.bind_texture("cryptomatte_tx", &rbuffers.cryptomatte_tx);
/* NOTE(@fclem): 16 is the max number of sampled texture in many implementations.
* If we need more, we need to pack more of the similar passes in the same textures as arrays or
* use image binding instead. */
- DRW_shgroup_uniform_image_ref(grp, "in_weight_img", &weight_tx_.current());
- DRW_shgroup_uniform_image_ref(grp, "out_weight_img", &weight_tx_.next());
- DRW_shgroup_uniform_texture_ref_ex(grp, "in_combined_tx", &combined_tx_.current(), filter);
- DRW_shgroup_uniform_image_ref(grp, "out_combined_img", &combined_tx_.next());
- DRW_shgroup_uniform_image_ref(grp, "depth_img", &depth_tx_);
- DRW_shgroup_uniform_image_ref(grp, "color_accum_img", &color_accum_tx_);
- DRW_shgroup_uniform_image_ref(grp, "value_accum_img", &value_accum_tx_);
- /* Sync with rendering passes. */
- DRW_shgroup_barrier(grp, GPU_BARRIER_TEXTURE_FETCH);
+ accumulate_ps_.bind_image("in_weight_img", &weight_tx_.current());
+ accumulate_ps_.bind_image("out_weight_img", &weight_tx_.next());
+ accumulate_ps_.bind_texture("in_combined_tx", &combined_tx_.current(), filter);
+ accumulate_ps_.bind_image("out_combined_img", &combined_tx_.next());
+ accumulate_ps_.bind_image("depth_img", &depth_tx_);
+ accumulate_ps_.bind_image("color_accum_img", &color_accum_tx_);
+ accumulate_ps_.bind_image("value_accum_img", &value_accum_tx_);
+ accumulate_ps_.bind_image("cryptomatte_img", &cryptomatte_tx_);
/* Sync with rendering passes. */
- DRW_shgroup_barrier(grp, GPU_BARRIER_SHADER_IMAGE_ACCESS);
+ accumulate_ps_.barrier(GPU_BARRIER_TEXTURE_FETCH | GPU_BARRIER_SHADER_IMAGE_ACCESS);
if (use_compute) {
- int2 dispatch_size = math::divide_ceil(data_.extent, int2(FILM_GROUP_SIZE));
- DRW_shgroup_call_compute(grp, UNPACK2(dispatch_size), 1);
+ accumulate_ps_.dispatch(int3(math::divide_ceil(data_.extent, int2(FILM_GROUP_SIZE)), 1));
}
else {
- DRW_shgroup_call_procedural_triangles(grp, nullptr, 1);
+ accumulate_ps_.draw_procedural(GPU_PRIM_TRIS, 1, 3);
+ }
+
+ const int cryptomatte_layer_count = cryptomatte_layer_len_get();
+ const bool is_cryptomatte_pass_enabled = cryptomatte_layer_count > 0;
+ const bool do_cryptomatte_sorting = inst_.is_viewport() == false;
+ cryptomatte_post_ps_.init();
+ if (is_cryptomatte_pass_enabled && do_cryptomatte_sorting) {
+ cryptomatte_post_ps_.state_set(DRW_STATE_NO_DRAW);
+ cryptomatte_post_ps_.shader_set(inst_.shaders.static_shader_get(FILM_CRYPTOMATTE_POST));
+ cryptomatte_post_ps_.bind_image("cryptomatte_img", &cryptomatte_tx_);
+ cryptomatte_post_ps_.bind_image("weight_img", &weight_tx_.current());
+ cryptomatte_post_ps_.push_constant("cryptomatte_layer_len", cryptomatte_layer_count);
+ cryptomatte_post_ps_.push_constant("cryptomatte_samples_per_layer",
+ inst_.view_layer->cryptomatte_levels);
+ int2 dispatch_size = math::divide_ceil(int2(cryptomatte_tx_.size()), int2(FILM_GROUP_SIZE));
+ cryptomatte_post_ps_.dispatch(int3(UNPACK2(dispatch_size), 1));
}
}
@@ -468,6 +526,29 @@ eViewLayerEEVEEPassType Film::enabled_passes_get() const
return enabled_passes_;
}
+int Film::cryptomatte_layer_len_get() const
+{
+ int result = 0;
+ result += data_.cryptomatte_object_id == -1 ? 0 : 1;
+ result += data_.cryptomatte_asset_id == -1 ? 0 : 1;
+ result += data_.cryptomatte_material_id == -1 ? 0 : 1;
+ return result;
+}
+
+int Film::cryptomatte_layer_max_get() const
+{
+ if (data_.cryptomatte_material_id != -1) {
+ return 3;
+ }
+ if (data_.cryptomatte_asset_id != -1) {
+ return 2;
+ }
+ if (data_.cryptomatte_object_id != -1) {
+ return 1;
+ }
+ return 0;
+}
+
void Film::update_sample_table()
{
data_.subpixel_offset = pixel_jitter_get();
@@ -566,8 +647,9 @@ void Film::accumulate(const DRWView *view, GPUTexture *combined_final_tx)
data_.display_only = false;
data_.push_update();
- DRW_view_set_active(view);
- DRW_draw_pass(accumulate_ps_);
+ draw::View drw_view("MainView", view);
+
+ DRW_manager_get()->submit(accumulate_ps_, drw_view);
combined_tx_.swap();
weight_tx_.swap();
@@ -594,28 +676,37 @@ void Film::display()
data_.display_only = true;
data_.push_update();
- DRW_view_set_active(nullptr);
- DRW_draw_pass(accumulate_ps_);
+ draw::View drw_view("MainView", DRW_view_default_get());
+
+ DRW_manager_get()->submit(accumulate_ps_, drw_view);
inst_.render_buffers.release();
/* IMPORTANT: Do not swap! No accumulation has happened. */
}
-float *Film::read_pass(eViewLayerEEVEEPassType pass_type)
+void Film::cryptomatte_sort()
{
+ DRW_manager_get()->submit(cryptomatte_post_ps_);
+}
+
+float *Film::read_pass(eViewLayerEEVEEPassType pass_type, int layer_offset)
+{
+ ePassStorageType storage_type = pass_storage_type(pass_type);
+ const bool is_value = storage_type == PASS_STORAGE_VALUE;
+ const bool is_cryptomatte = storage_type == PASS_STORAGE_CRYPTOMATTE;
- bool is_value = pass_is_value(pass_type);
Texture &accum_tx = (pass_type == EEVEE_RENDER_PASS_COMBINED) ?
combined_tx_.current() :
(pass_type == EEVEE_RENDER_PASS_Z) ?
depth_tx_ :
- (is_value ? value_accum_tx_ : color_accum_tx_);
+ (is_cryptomatte ? cryptomatte_tx_ :
+ (is_value ? value_accum_tx_ : color_accum_tx_));
accum_tx.ensure_layer_views();
int index = pass_id_get(pass_type);
- GPUTexture *pass_tx = accum_tx.layer_view(index);
+ GPUTexture *pass_tx = accum_tx.layer_view(index + layer_offset);
GPU_memory_barrier(GPU_BARRIER_TEXTURE_UPDATE);
diff --git a/source/blender/draw/engines/eevee_next/eevee_film.hh b/source/blender/draw/engines/eevee_next/eevee_film.hh
index 3e368782d31..5478c20aff2 100644
--- a/source/blender/draw/engines/eevee_next/eevee_film.hh
+++ b/source/blender/draw/engines/eevee_next/eevee_film.hh
@@ -43,11 +43,16 @@ class Film {
/** Incoming combined buffer with post FX applied (motion blur + depth of field). */
GPUTexture *combined_final_tx_ = nullptr;
- /** Main accumulation textures containing every render-pass except depth and combined. */
+ /**
+ * Main accumulation textures containing every render-pass except depth, cryptomatte and
+ * combined.
+ */
Texture color_accum_tx_;
Texture value_accum_tx_;
/** Depth accumulation texture. Separated because using a different format. */
Texture depth_tx_;
+ /** Cryptomatte texture. Separated because it requires full floats. */
+ Texture cryptomatte_tx_;
/** Combined "Color" buffer. Double buffered to allow re-projection. */
SwapChain<Texture, 2> combined_tx_;
/** Weight buffers. Double buffered to allow updating it during accumulation. */
@@ -55,7 +60,8 @@ class Film {
/** User setting to disable reprojection. Useful for debugging or have a more precise render. */
bool force_disable_reprojection_ = false;
- DRWPass *accumulate_ps_ = nullptr;
+ PassSimple accumulate_ps_ = {"Film.Accumulate"};
+ PassSimple cryptomatte_post_ps_ = {"Film.Cryptomatte.Post"};
FilmDataBuf data_;
@@ -73,10 +79,13 @@ class Film {
/** Accumulate the newly rendered sample contained in #RenderBuffers and blit to display. */
void accumulate(const DRWView *view, GPUTexture *combined_final_tx);
+ /** Sort and normalize cryptomatte samples. */
+ void cryptomatte_sort();
+
/** Blit to display. No rendered sample needed. */
void display();
- float *read_pass(eViewLayerEEVEEPassType pass_type);
+ float *read_pass(eViewLayerEEVEEPassType pass_type, int layer_offset);
float *read_aov(ViewLayerAOV *aov);
/** Returns shading views internal resolution. */
@@ -93,17 +102,23 @@ class Film {
}
eViewLayerEEVEEPassType enabled_passes_get() const;
+ int cryptomatte_layer_max_get() const;
+ int cryptomatte_layer_len_get() const;
- static bool pass_is_value(eViewLayerEEVEEPassType pass_type)
+ static ePassStorageType pass_storage_type(eViewLayerEEVEEPassType pass_type)
{
switch (pass_type) {
case EEVEE_RENDER_PASS_Z:
case EEVEE_RENDER_PASS_MIST:
case EEVEE_RENDER_PASS_SHADOW:
case EEVEE_RENDER_PASS_AO:
- return true;
+ return PASS_STORAGE_VALUE;
+ case EEVEE_RENDER_PASS_CRYPTOMATTE_OBJECT:
+ case EEVEE_RENDER_PASS_CRYPTOMATTE_ASSET:
+ case EEVEE_RENDER_PASS_CRYPTOMATTE_MATERIAL:
+ return PASS_STORAGE_CRYPTOMATTE;
default:
- return false;
+ return PASS_STORAGE_COLOR;
}
}
@@ -154,8 +169,12 @@ class Film {
return data_.shadow_id;
case EEVEE_RENDER_PASS_AO:
return data_.ambient_occlusion_id;
- case EEVEE_RENDER_PASS_CRYPTOMATTE:
- return -1; /* TODO */
+ case EEVEE_RENDER_PASS_CRYPTOMATTE_OBJECT:
+ return data_.cryptomatte_object_id;
+ case EEVEE_RENDER_PASS_CRYPTOMATTE_ASSET:
+ return data_.cryptomatte_asset_id;
+ case EEVEE_RENDER_PASS_CRYPTOMATTE_MATERIAL:
+ return data_.cryptomatte_material_id;
case EEVEE_RENDER_PASS_VECTOR:
return data_.vector_id;
default:
@@ -163,44 +182,80 @@ class Film {
}
}
- static const char *pass_to_render_pass_name(eViewLayerEEVEEPassType pass_type)
+ static const Vector<std::string> pass_to_render_pass_names(eViewLayerEEVEEPassType pass_type,
+ const ViewLayer *view_layer)
{
+ Vector<std::string> result;
+
+ auto build_cryptomatte_passes = [&](const char *pass_name) {
+ const int num_cryptomatte_passes = (view_layer->cryptomatte_levels + 1) / 2;
+ for (int pass = 0; pass < num_cryptomatte_passes; pass++) {
+ std::stringstream ss;
+ ss.fill('0');
+ ss << pass_name;
+ ss.width(2);
+ ss << pass;
+ result.append(ss.str());
+ }
+ };
+
switch (pass_type) {
case EEVEE_RENDER_PASS_COMBINED:
- return RE_PASSNAME_COMBINED;
+ result.append(RE_PASSNAME_COMBINED);
+ break;
case EEVEE_RENDER_PASS_Z:
- return RE_PASSNAME_Z;
+ result.append(RE_PASSNAME_Z);
+ break;
case EEVEE_RENDER_PASS_MIST:
- return RE_PASSNAME_MIST;
+ result.append(RE_PASSNAME_MIST);
+ break;
case EEVEE_RENDER_PASS_NORMAL:
- return RE_PASSNAME_NORMAL;
+ result.append(RE_PASSNAME_NORMAL);
+ break;
case EEVEE_RENDER_PASS_DIFFUSE_LIGHT:
- return RE_PASSNAME_DIFFUSE_DIRECT;
+ result.append(RE_PASSNAME_DIFFUSE_DIRECT);
+ break;
case EEVEE_RENDER_PASS_DIFFUSE_COLOR:
- return RE_PASSNAME_DIFFUSE_COLOR;
+ result.append(RE_PASSNAME_DIFFUSE_COLOR);
+ break;
case EEVEE_RENDER_PASS_SPECULAR_LIGHT:
- return RE_PASSNAME_GLOSSY_DIRECT;
+ result.append(RE_PASSNAME_GLOSSY_DIRECT);
+ break;
case EEVEE_RENDER_PASS_SPECULAR_COLOR:
- return RE_PASSNAME_GLOSSY_COLOR;
+ result.append(RE_PASSNAME_GLOSSY_COLOR);
+ break;
case EEVEE_RENDER_PASS_VOLUME_LIGHT:
- return RE_PASSNAME_VOLUME_LIGHT;
+ result.append(RE_PASSNAME_VOLUME_LIGHT);
+ break;
case EEVEE_RENDER_PASS_EMIT:
- return RE_PASSNAME_EMIT;
+ result.append(RE_PASSNAME_EMIT);
+ break;
case EEVEE_RENDER_PASS_ENVIRONMENT:
- return RE_PASSNAME_ENVIRONMENT;
+ result.append(RE_PASSNAME_ENVIRONMENT);
+ break;
case EEVEE_RENDER_PASS_SHADOW:
- return RE_PASSNAME_SHADOW;
+ result.append(RE_PASSNAME_SHADOW);
+ break;
case EEVEE_RENDER_PASS_AO:
- return RE_PASSNAME_AO;
- case EEVEE_RENDER_PASS_CRYPTOMATTE:
- BLI_assert_msg(0, "Cryptomatte is not implemented yet.");
- return ""; /* TODO */
+ result.append(RE_PASSNAME_AO);
+ break;
+ case EEVEE_RENDER_PASS_CRYPTOMATTE_OBJECT:
+ build_cryptomatte_passes(RE_PASSNAME_CRYPTOMATTE_OBJECT);
+ break;
+ case EEVEE_RENDER_PASS_CRYPTOMATTE_ASSET:
+ build_cryptomatte_passes(RE_PASSNAME_CRYPTOMATTE_ASSET);
+ break;
+ case EEVEE_RENDER_PASS_CRYPTOMATTE_MATERIAL:
+ build_cryptomatte_passes(RE_PASSNAME_CRYPTOMATTE_MATERIAL);
+ break;
case EEVEE_RENDER_PASS_VECTOR:
- return RE_PASSNAME_VECTOR;
+ result.append(RE_PASSNAME_VECTOR);
+ break;
default:
BLI_assert(0);
- return "";
+ break;
}
+ return result;
}
private:
diff --git a/source/blender/draw/engines/eevee_next/eevee_hizbuffer.cc b/source/blender/draw/engines/eevee_next/eevee_hizbuffer.cc
new file mode 100644
index 00000000000..cf9049da514
--- /dev/null
+++ b/source/blender/draw/engines/eevee_next/eevee_hizbuffer.cc
@@ -0,0 +1,99 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2022 Blender Foundation.
+ */
+
+#include "BKE_global.h"
+
+#include "eevee_instance.hh"
+
+#include "eevee_hizbuffer.hh"
+
+namespace blender::eevee {
+
+/* -------------------------------------------------------------------- */
+/** \name Hierarchical-Z buffer
+ *
+ * \{ */
+
+void HiZBuffer::sync()
+{
+ RenderBuffers &render_buffers = inst_.render_buffers;
+
+ int2 render_extent = inst_.film.render_extent_get();
+ /* Padding to avoid complexity during down-sampling and screen tracing. */
+ int2 hiz_extent = math::ceil_to_multiple(render_extent, int2(1u << (HIZ_MIP_COUNT - 1)));
+ int2 dispatch_size = math::divide_ceil(hiz_extent, int2(HIZ_GROUP_SIZE));
+
+ hiz_tx_.ensure_2d(GPU_R32F, hiz_extent, nullptr, HIZ_MIP_COUNT);
+ hiz_tx_.ensure_mip_views();
+ GPU_texture_mipmap_mode(hiz_tx_, true, false);
+
+ data_.uv_scale = float2(render_extent) / float2(hiz_extent);
+ data_.push_update();
+
+ {
+ hiz_update_ps_.init();
+ hiz_update_ps_.shader_set(inst_.shaders.static_shader_get(HIZ_UPDATE));
+ hiz_update_ps_.bind_ssbo("finished_tile_counter", atomic_tile_counter_);
+ hiz_update_ps_.bind_texture("depth_tx", &render_buffers.depth_tx, with_filter);
+ hiz_update_ps_.bind_image("out_mip_0", hiz_tx_.mip_view(0));
+ hiz_update_ps_.bind_image("out_mip_1", hiz_tx_.mip_view(1));
+ hiz_update_ps_.bind_image("out_mip_2", hiz_tx_.mip_view(2));
+ hiz_update_ps_.bind_image("out_mip_3", hiz_tx_.mip_view(3));
+ hiz_update_ps_.bind_image("out_mip_4", hiz_tx_.mip_view(4));
+ hiz_update_ps_.bind_image("out_mip_5", hiz_tx_.mip_view(5));
+ hiz_update_ps_.bind_image("out_mip_6", hiz_tx_.mip_view(6));
+ hiz_update_ps_.bind_image("out_mip_7", hiz_tx_.mip_view(7));
+ /* TODO(@fclem): There might be occasions where we might not want to
+ * copy mip 0 for performance reasons if there is no need for it. */
+ hiz_update_ps_.push_constant("update_mip_0", true);
+ hiz_update_ps_.dispatch(int3(dispatch_size, 1));
+ hiz_update_ps_.barrier(GPU_BARRIER_TEXTURE_FETCH);
+ }
+
+ if (inst_.debug_mode == eDebugMode::DEBUG_HIZ_VALIDATION) {
+ debug_draw_ps_.init();
+ debug_draw_ps_.state_set(DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_CUSTOM);
+ debug_draw_ps_.shader_set(inst_.shaders.static_shader_get(HIZ_DEBUG));
+ this->bind_resources(&debug_draw_ps_);
+ debug_draw_ps_.draw_procedural(GPU_PRIM_TRIS, 1, 3);
+ }
+}
+
+void HiZBuffer::update()
+{
+ if (!is_dirty_) {
+ return;
+ }
+
+ /* Bind another framebuffer in order to avoid triggering the feedback loop check.
+ * This is safe because we only use compute shaders in this section of the code.
+ * Ideally the check should be smarter. */
+ GPUFrameBuffer *fb = GPU_framebuffer_active_get();
+ if (G.debug & G_DEBUG_GPU) {
+ GPU_framebuffer_restore();
+ }
+
+ inst_.manager->submit(hiz_update_ps_);
+
+ if (G.debug & G_DEBUG_GPU) {
+ GPU_framebuffer_bind(fb);
+ }
+}
+
+void HiZBuffer::debug_draw(View &view, GPUFrameBuffer *view_fb)
+{
+ if (inst_.debug_mode == eDebugMode::DEBUG_HIZ_VALIDATION) {
+ inst_.info =
+ "Debug Mode: HiZ Validation\n"
+ " - Red: pixel in front of HiZ tile value.\n"
+ " - Blue: No error.";
+ inst_.hiz_buffer.update();
+ GPU_framebuffer_bind(view_fb);
+ inst_.manager->submit(debug_draw_ps_, view);
+ }
+}
+
+/** \} */
+
+} // namespace blender::eevee
diff --git a/source/blender/draw/engines/eevee_next/eevee_hizbuffer.hh b/source/blender/draw/engines/eevee_next/eevee_hizbuffer.hh
new file mode 100644
index 00000000000..8b8e4de55b1
--- /dev/null
+++ b/source/blender/draw/engines/eevee_next/eevee_hizbuffer.hh
@@ -0,0 +1,88 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2021 Blender Foundation.
+ */
+
+/** \file
+ * \ingroup eevee
+ *
+ * The Hierarchical-Z buffer is texture containing a copy of the depth buffer with mipmaps.
+ * Each mip contains the maximum depth of each 4 pixels on the upper level.
+ * The size of the texture is padded to avoid messing with the mipmap pixels alignments.
+ */
+
+#pragma once
+
+#include "DRW_render.h"
+
+#include "eevee_shader_shared.hh"
+
+namespace blender::eevee {
+
+class Instance;
+
+/* -------------------------------------------------------------------- */
+/** \name Hierarchical-Z buffer
+ * \{ */
+
+class HiZBuffer {
+ private:
+ Instance &inst_;
+
+ /** The texture containing the hiz mip chain. */
+ Texture hiz_tx_ = {"hiz_tx_"};
+ /**
+ * Atomic counter counting the number of tile that have finished down-sampling.
+ * The last one will process the last few mip level.
+ */
+ draw::StorageBuffer<uint4, true> atomic_tile_counter_ = {"atomic_tile_counter"};
+ /** Single pass recursive downsample. */
+ PassSimple hiz_update_ps_ = {"HizUpdate"};
+ /** Debug pass. */
+ PassSimple debug_draw_ps_ = {"HizUpdate.Debug"};
+ /** Dirty flag to check if the update is necessary. */
+ bool is_dirty_ = true;
+
+ HiZDataBuf data_;
+
+ public:
+ HiZBuffer(Instance &inst) : inst_(inst)
+ {
+ atomic_tile_counter_.clear_to_zero();
+ };
+
+ void sync();
+
+ /**
+ * Tag the buffer for update if needed.
+ */
+ void set_dirty()
+ {
+ is_dirty_ = true;
+ }
+
+ /**
+ * Update the content of the HiZ buffer with the depth render target.
+ * Noop if the buffer has not been tagged as dirty.
+ * Should be called before each passes that needs to read the hiz buffer.
+ */
+ void update();
+
+ void debug_draw(View &view, GPUFrameBuffer *view_fb);
+
+ void bind_resources(DRWShadingGroup *grp)
+ {
+ DRW_shgroup_uniform_texture_ref(grp, "hiz_tx", &hiz_tx_);
+ DRW_shgroup_uniform_block_ref(grp, "hiz_buf", &data_);
+ }
+
+ /* TODO(fclem): Hardcoded bind slots. */
+ template<typename T> void bind_resources(draw::detail::PassBase<T> *pass)
+ {
+ pass->bind_texture("hiz_tx", &hiz_tx_);
+ pass->bind_ubo("hiz_buf", &data_);
+ }
+};
+
+/** \} */
+
+} // namespace blender::eevee
diff --git a/source/blender/draw/engines/eevee_next/eevee_instance.cc b/source/blender/draw/engines/eevee_next/eevee_instance.cc
index 57786adb657..8005b27c30e 100644
--- a/source/blender/draw/engines/eevee_next/eevee_instance.cc
+++ b/source/blender/draw/engines/eevee_next/eevee_instance.cc
@@ -52,6 +52,7 @@ void Instance::init(const int2 &output_res,
drw_view = drw_view_;
v3d = v3d_;
rv3d = rv3d_;
+ manager = DRW_manager_get();
if (assign_if_different(debug_mode, (eDebugMode)G.debug_value)) {
sampling.reset();
@@ -101,11 +102,13 @@ void Instance::begin_sync()
materials.begin_sync();
velocity.begin_sync(); /* NOTE: Also syncs camera. */
lights.begin_sync();
+ cryptomatte.begin_sync();
gpencil_engine_enabled = false;
depth_of_field.sync();
motion_blur.sync();
+ hiz_buffer.sync();
pipelines.sync();
main_view.sync();
world.sync();
@@ -125,12 +128,16 @@ void Instance::object_sync(Object *ob)
return;
}
+ /* TODO cleanup. */
+ ObjectRef ob_ref = DRW_object_ref_get(ob);
+ ResourceHandle res_handle = manager->resource_handle(ob_ref);
+
ObjectHandle &ob_handle = sync.sync_object(ob);
if (partsys_is_visible && ob != DRW_context_state_get()->object_edit) {
LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) {
if (md->type == eModifierType_ParticleSystem) {
- sync.sync_curves(ob, ob_handle, md);
+ sync.sync_curves(ob, ob_handle, res_handle, md);
}
}
}
@@ -141,20 +148,15 @@ void Instance::object_sync(Object *ob)
lights.sync_light(ob, ob_handle);
break;
case OB_MESH:
- case OB_CURVES_LEGACY:
- case OB_SURF:
- case OB_FONT:
- case OB_MBALL: {
- sync.sync_mesh(ob, ob_handle);
+ sync.sync_mesh(ob, ob_handle, res_handle, ob_ref);
break;
- }
case OB_VOLUME:
break;
case OB_CURVES:
- sync.sync_curves(ob, ob_handle);
+ sync.sync_curves(ob, ob_handle, res_handle);
break;
case OB_GPENCIL:
- sync.sync_gpencil(ob, ob_handle);
+ sync.sync_gpencil(ob, ob_handle, res_handle);
break;
default:
break;
@@ -181,6 +183,7 @@ void Instance::end_sync()
lights.end_sync();
sampling.end_sync();
film.end_sync();
+ cryptomatte.end_sync();
}
void Instance::render_sync()
@@ -235,10 +238,15 @@ void Instance::render_read_result(RenderLayer *render_layer, const char *view_na
continue;
}
- const char *pass_name = Film::pass_to_render_pass_name(pass_type);
- RenderPass *rp = RE_pass_find_by_name(render_layer, pass_name, view_name);
- if (rp) {
- float *result = film.read_pass(pass_type);
+ Vector<std::string> pass_names = Film::pass_to_render_pass_names(pass_type, view_layer);
+ for (int64_t pass_offset : IndexRange(pass_names.size())) {
+ RenderPass *rp = RE_pass_find_by_name(
+ render_layer, pass_names[pass_offset].c_str(), view_name);
+ if (!rp) {
+ continue;
+ }
+ float *result = film.read_pass(pass_type, pass_offset);
+
if (result) {
BLI_mutex_lock(&render->update_render_passes_mutex);
/* WORKAROUND: We use texture read to avoid using a framebuffer to get the render result.
@@ -254,10 +262,13 @@ void Instance::render_read_result(RenderLayer *render_layer, const char *view_na
/* The vector pass is initialized to weird values. Set it to neutral value if not rendered. */
if ((pass_bits & EEVEE_RENDER_PASS_VECTOR) == 0) {
- const char *vector_pass_name = Film::pass_to_render_pass_name(EEVEE_RENDER_PASS_VECTOR);
- RenderPass *vector_rp = RE_pass_find_by_name(render_layer, vector_pass_name, view_name);
- if (vector_rp) {
- memset(vector_rp->rect, 0, sizeof(float) * 4 * vector_rp->rectx * vector_rp->recty);
+ for (std::string vector_pass_name :
+ Film::pass_to_render_pass_names(EEVEE_RENDER_PASS_VECTOR, view_layer)) {
+ RenderPass *vector_rp = RE_pass_find_by_name(
+ render_layer, vector_pass_name.c_str(), view_name);
+ if (vector_rp) {
+ memset(vector_rp->rect, 0, sizeof(float) * 4 * vector_rp->rectx * vector_rp->recty);
+ }
}
}
}
@@ -289,6 +300,8 @@ void Instance::render_frame(RenderLayer *render_layer, const char *view_name)
#endif
}
+ this->film.cryptomatte_sort();
+
this->render_read_result(render_layer, view_name);
}
@@ -312,6 +325,76 @@ void Instance::draw_viewport(DefaultFramebufferList *dfbl)
}
}
+void Instance::store_metadata(RenderResult *render_result)
+{
+ cryptomatte.store_metadata(render_result);
+}
+
+void Instance::update_passes(RenderEngine *engine, Scene *scene, ViewLayer *view_layer)
+{
+ RE_engine_register_pass(engine, scene, view_layer, RE_PASSNAME_COMBINED, 4, "RGBA", SOCK_RGBA);
+
+#define CHECK_PASS_LEGACY(name, type, channels, chanid) \
+ if (view_layer->passflag & (SCE_PASS_##name)) { \
+ RE_engine_register_pass( \
+ engine, scene, view_layer, RE_PASSNAME_##name, channels, chanid, type); \
+ } \
+ ((void)0)
+#define CHECK_PASS_EEVEE(name, type, channels, chanid) \
+ if (view_layer->eevee.render_passes & (EEVEE_RENDER_PASS_##name)) { \
+ RE_engine_register_pass( \
+ engine, scene, view_layer, RE_PASSNAME_##name, channels, chanid, type); \
+ } \
+ ((void)0)
+
+ CHECK_PASS_LEGACY(Z, SOCK_FLOAT, 1, "Z");
+ CHECK_PASS_LEGACY(MIST, SOCK_FLOAT, 1, "Z");
+ CHECK_PASS_LEGACY(NORMAL, SOCK_VECTOR, 3, "XYZ");
+ CHECK_PASS_LEGACY(DIFFUSE_DIRECT, SOCK_RGBA, 3, "RGB");
+ CHECK_PASS_LEGACY(DIFFUSE_COLOR, SOCK_RGBA, 3, "RGB");
+ CHECK_PASS_LEGACY(GLOSSY_DIRECT, SOCK_RGBA, 3, "RGB");
+ CHECK_PASS_LEGACY(GLOSSY_COLOR, SOCK_RGBA, 3, "RGB");
+ CHECK_PASS_EEVEE(VOLUME_LIGHT, SOCK_RGBA, 3, "RGB");
+ CHECK_PASS_LEGACY(EMIT, SOCK_RGBA, 3, "RGB");
+ CHECK_PASS_LEGACY(ENVIRONMENT, SOCK_RGBA, 3, "RGB");
+ /* TODO: CHECK_PASS_LEGACY(SHADOW, SOCK_RGBA, 3, "RGB");
+ * CHECK_PASS_LEGACY(AO, SOCK_RGBA, 3, "RGB");
+ * When available they should be converted from Value textures to RGB. */
+
+ LISTBASE_FOREACH (ViewLayerAOV *, aov, &view_layer->aovs) {
+ if ((aov->flag & AOV_CONFLICT) != 0) {
+ continue;
+ }
+ switch (aov->type) {
+ case AOV_TYPE_COLOR:
+ RE_engine_register_pass(engine, scene, view_layer, aov->name, 4, "RGBA", SOCK_RGBA);
+ break;
+ case AOV_TYPE_VALUE:
+ RE_engine_register_pass(engine, scene, view_layer, aov->name, 1, "X", SOCK_FLOAT);
+ break;
+ default:
+ break;
+ }
+ }
+
+ /* NOTE: Name channels lowercase `rgba` so that compression rules check in OpenEXR DWA code uses
+ * lossless compression. Reportedly this naming is the only one which works good from the
+ * interoperability point of view. Using `xyzw` naming is not portable. */
+ auto register_cryptomatte_passes = [&](eViewLayerCryptomatteFlags cryptomatte_layer,
+ eViewLayerEEVEEPassType eevee_pass) {
+ if (view_layer->cryptomatte_flag & cryptomatte_layer) {
+ for (std::string pass_name : Film::pass_to_render_pass_names(eevee_pass, view_layer)) {
+ RE_engine_register_pass(
+ engine, scene, view_layer, pass_name.c_str(), 4, "rgba", SOCK_RGBA);
+ }
+ }
+ };
+ register_cryptomatte_passes(VIEW_LAYER_CRYPTOMATTE_OBJECT, EEVEE_RENDER_PASS_CRYPTOMATTE_OBJECT);
+ register_cryptomatte_passes(VIEW_LAYER_CRYPTOMATTE_ASSET, EEVEE_RENDER_PASS_CRYPTOMATTE_ASSET);
+ register_cryptomatte_passes(VIEW_LAYER_CRYPTOMATTE_MATERIAL,
+ EEVEE_RENDER_PASS_CRYPTOMATTE_MATERIAL);
+}
+
/** \} */
} // namespace blender::eevee
diff --git a/source/blender/draw/engines/eevee_next/eevee_instance.hh b/source/blender/draw/engines/eevee_next/eevee_instance.hh
index d52e4a8e43b..c8eecbd812d 100644
--- a/source/blender/draw/engines/eevee_next/eevee_instance.hh
+++ b/source/blender/draw/engines/eevee_next/eevee_instance.hh
@@ -16,8 +16,10 @@
#include "DRW_render.h"
#include "eevee_camera.hh"
+#include "eevee_cryptomatte.hh"
#include "eevee_depth_of_field.hh"
#include "eevee_film.hh"
+#include "eevee_hizbuffer.hh"
#include "eevee_light.hh"
#include "eevee_material.hh"
#include "eevee_motion_blur.hh"
@@ -48,6 +50,8 @@ class Instance {
VelocityModule velocity;
MotionBlurModule motion_blur;
DepthOfField depth_of_field;
+ Cryptomatte cryptomatte;
+ HiZBuffer hiz_buffer;
Sampling sampling;
Camera camera;
Film film;
@@ -57,6 +61,7 @@ class Instance {
/** Input data. */
Depsgraph *depsgraph;
+ Manager *manager;
/** Evaluated IDs. */
Scene *scene;
ViewLayer *view_layer;
@@ -88,6 +93,8 @@ class Instance {
velocity(*this),
motion_blur(*this),
depth_of_field(*this),
+ cryptomatte(*this),
+ hiz_buffer(*this),
sampling(*this),
camera(*this),
film(*this),
@@ -113,9 +120,12 @@ class Instance {
void render_sync();
void render_frame(RenderLayer *render_layer, const char *view_name);
+ void store_metadata(RenderResult *render_result);
void draw_viewport(DefaultFramebufferList *dfbl);
+ static void update_passes(RenderEngine *engine, Scene *scene, ViewLayer *view_layer);
+
bool is_viewport() const
{
return render == nullptr;
diff --git a/source/blender/draw/engines/eevee_next/eevee_light.cc b/source/blender/draw/engines/eevee_next/eevee_light.cc
index dbbf481f3f4..b60246fa3ab 100644
--- a/source/blender/draw/engines/eevee_next/eevee_light.cc
+++ b/source/blender/draw/engines/eevee_next/eevee_light.cc
@@ -333,11 +333,11 @@ void LightModule::end_sync()
/* This scene data buffer is then immutable after this point. */
light_buf_.push_update();
- for (auto key : deleted_keys) {
+ for (auto &key : deleted_keys) {
light_map_.remove(key);
}
- /* Update sampling on deletion or un-hidding (use_scene_lights). */
+ /* Update sampling on deletion or un-hiding (use_scene_lights). */
if (assign_if_different(light_map_size_, light_map_.size())) {
inst_.sampling.reset();
}
@@ -399,74 +399,70 @@ void LightModule::culling_pass_sync()
uint culling_tile_dispatch_size = divide_ceil_u(total_word_count_, CULLING_TILE_GROUP_SIZE);
/* NOTE: We reference the buffers that may be resized or updated later. */
+
+ culling_ps_.init();
{
- DRW_PASS_CREATE(culling_select_ps_, DRW_STATE_NO_DRAW);
- GPUShader *sh = inst_.shaders.static_shader_get(LIGHT_CULLING_SELECT);
- DRWShadingGroup *grp = DRW_shgroup_create(sh, culling_select_ps_);
- DRW_shgroup_storage_block_ref(grp, "light_cull_buf", &culling_data_buf_);
- DRW_shgroup_storage_block(grp, "in_light_buf", light_buf_);
- DRW_shgroup_storage_block(grp, "out_light_buf", culling_light_buf_);
- DRW_shgroup_storage_block(grp, "out_zdist_buf", culling_zdist_buf_);
- DRW_shgroup_storage_block(grp, "out_key_buf", culling_key_buf_);
- DRW_shgroup_call_compute(grp, culling_select_dispatch_size, 1, 1);
- DRW_shgroup_barrier(grp, GPU_BARRIER_SHADER_STORAGE);
+ auto &sub = culling_ps_.sub("Select");
+ sub.shader_set(inst_.shaders.static_shader_get(LIGHT_CULLING_SELECT));
+ sub.bind_ssbo("light_cull_buf", &culling_data_buf_);
+ sub.bind_ssbo("in_light_buf", light_buf_);
+ sub.bind_ssbo("out_light_buf", culling_light_buf_);
+ sub.bind_ssbo("out_zdist_buf", culling_zdist_buf_);
+ sub.bind_ssbo("out_key_buf", culling_key_buf_);
+ sub.dispatch(int3(culling_select_dispatch_size, 1, 1));
+ sub.barrier(GPU_BARRIER_SHADER_STORAGE);
}
{
- DRW_PASS_CREATE(culling_sort_ps_, DRW_STATE_NO_DRAW);
- GPUShader *sh = inst_.shaders.static_shader_get(LIGHT_CULLING_SORT);
- DRWShadingGroup *grp = DRW_shgroup_create(sh, culling_sort_ps_);
- DRW_shgroup_storage_block_ref(grp, "light_cull_buf", &culling_data_buf_);
- DRW_shgroup_storage_block(grp, "in_light_buf", light_buf_);
- DRW_shgroup_storage_block(grp, "out_light_buf", culling_light_buf_);
- DRW_shgroup_storage_block(grp, "in_zdist_buf", culling_zdist_buf_);
- DRW_shgroup_storage_block(grp, "in_key_buf", culling_key_buf_);
- DRW_shgroup_call_compute(grp, culling_sort_dispatch_size, 1, 1);
- DRW_shgroup_barrier(grp, GPU_BARRIER_SHADER_STORAGE);
+ auto &sub = culling_ps_.sub("Sort");
+ sub.shader_set(inst_.shaders.static_shader_get(LIGHT_CULLING_SORT));
+ sub.bind_ssbo("light_cull_buf", &culling_data_buf_);
+ sub.bind_ssbo("in_light_buf", light_buf_);
+ sub.bind_ssbo("out_light_buf", culling_light_buf_);
+ sub.bind_ssbo("in_zdist_buf", culling_zdist_buf_);
+ sub.bind_ssbo("in_key_buf", culling_key_buf_);
+ sub.dispatch(int3(culling_sort_dispatch_size, 1, 1));
+ sub.barrier(GPU_BARRIER_SHADER_STORAGE);
}
{
- DRW_PASS_CREATE(culling_zbin_ps_, DRW_STATE_NO_DRAW);
- GPUShader *sh = inst_.shaders.static_shader_get(LIGHT_CULLING_ZBIN);
- DRWShadingGroup *grp = DRW_shgroup_create(sh, culling_zbin_ps_);
- DRW_shgroup_storage_block_ref(grp, "light_cull_buf", &culling_data_buf_);
- DRW_shgroup_storage_block(grp, "light_buf", culling_light_buf_);
- DRW_shgroup_storage_block(grp, "out_zbin_buf", culling_zbin_buf_);
- DRW_shgroup_call_compute(grp, 1, 1, 1);
- DRW_shgroup_barrier(grp, GPU_BARRIER_SHADER_STORAGE);
+ auto &sub = culling_ps_.sub("Zbin");
+ sub.shader_set(inst_.shaders.static_shader_get(LIGHT_CULLING_ZBIN));
+ sub.bind_ssbo("light_cull_buf", &culling_data_buf_);
+ sub.bind_ssbo("light_buf", culling_light_buf_);
+ sub.bind_ssbo("out_zbin_buf", culling_zbin_buf_);
+ sub.dispatch(int3(1, 1, 1));
+ sub.barrier(GPU_BARRIER_SHADER_STORAGE);
}
{
- DRW_PASS_CREATE(culling_tile_ps_, DRW_STATE_NO_DRAW);
- GPUShader *sh = inst_.shaders.static_shader_get(LIGHT_CULLING_TILE);
- DRWShadingGroup *grp = DRW_shgroup_create(sh, culling_tile_ps_);
- DRW_shgroup_storage_block_ref(grp, "light_cull_buf", &culling_data_buf_);
- DRW_shgroup_storage_block(grp, "light_buf", culling_light_buf_);
- DRW_shgroup_storage_block(grp, "out_light_tile_buf", culling_tile_buf_);
- DRW_shgroup_call_compute(grp, culling_tile_dispatch_size, 1, 1);
- DRW_shgroup_barrier(grp, GPU_BARRIER_SHADER_STORAGE);
+ auto &sub = culling_ps_.sub("Tiles");
+ sub.shader_set(inst_.shaders.static_shader_get(LIGHT_CULLING_TILE));
+ sub.bind_ssbo("light_cull_buf", &culling_data_buf_);
+ sub.bind_ssbo("light_buf", culling_light_buf_);
+ sub.bind_ssbo("out_light_tile_buf", culling_tile_buf_);
+ sub.dispatch(int3(culling_tile_dispatch_size, 1, 1));
+ sub.barrier(GPU_BARRIER_SHADER_STORAGE);
}
}
void LightModule::debug_pass_sync()
{
- if (inst_.debug_mode != eDebugMode::DEBUG_LIGHT_CULLING) {
- debug_draw_ps_ = nullptr;
- return;
+ if (inst_.debug_mode == eDebugMode::DEBUG_LIGHT_CULLING) {
+ debug_draw_ps_.init();
+ debug_draw_ps_.state_set(DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_CUSTOM);
+ debug_draw_ps_.shader_set(inst_.shaders.static_shader_get(LIGHT_CULLING_DEBUG));
+ inst_.hiz_buffer.bind_resources(&debug_draw_ps_);
+ debug_draw_ps_.bind_ssbo("light_buf", &culling_light_buf_);
+ debug_draw_ps_.bind_ssbo("light_cull_buf", &culling_data_buf_);
+ debug_draw_ps_.bind_ssbo("light_zbin_buf", &culling_zbin_buf_);
+ debug_draw_ps_.bind_ssbo("light_tile_buf", &culling_tile_buf_);
+ debug_draw_ps_.bind_texture("depth_tx", &inst_.render_buffers.depth_tx);
+ debug_draw_ps_.draw_procedural(GPU_PRIM_TRIS, 1, 3);
}
-
- debug_draw_ps_ = DRW_pass_create("LightCulling.Debug", DRW_STATE_WRITE_COLOR);
- GPUShader *sh = inst_.shaders.static_shader_get(LIGHT_CULLING_DEBUG);
- DRWShadingGroup *grp = DRW_shgroup_create(sh, debug_draw_ps_);
- DRW_shgroup_storage_block_ref(grp, "light_buf", &culling_light_buf_);
- DRW_shgroup_storage_block_ref(grp, "light_cull_buf", &culling_data_buf_);
- DRW_shgroup_storage_block_ref(grp, "light_zbin_buf", &culling_zbin_buf_);
- DRW_shgroup_storage_block_ref(grp, "light_tile_buf", &culling_tile_buf_);
- DRW_shgroup_uniform_texture_ref(grp, "depth_tx", &inst_.render_buffers.depth_tx);
- DRW_shgroup_call_procedural_triangles(grp, nullptr, 1);
}
-void LightModule::set_view(const DRWView *view, const int2 extent)
+void LightModule::set_view(View &view, const int2 extent)
{
- float far_z = DRW_view_far_distance_get(view);
- float near_z = DRW_view_near_distance_get(view);
+ float far_z = view.far_clip();
+ float near_z = view.near_clip();
culling_data_buf_.zbin_scale = -CULLING_ZBIN_COUNT / fabsf(far_z - near_z);
culling_data_buf_.zbin_bias = -near_z * culling_data_buf_.zbin_scale;
@@ -474,24 +470,17 @@ void LightModule::set_view(const DRWView *view, const int2 extent)
culling_data_buf_.visible_count = 0;
culling_data_buf_.push_update();
- DRW_stats_group_start("Light Culling");
-
- DRW_view_set_active(view);
- DRW_draw_pass(culling_select_ps_);
- DRW_draw_pass(culling_sort_ps_);
- DRW_draw_pass(culling_zbin_ps_);
- DRW_draw_pass(culling_tile_ps_);
-
- DRW_stats_group_end();
+ inst_.manager->submit(culling_ps_, view);
}
-void LightModule::debug_draw(GPUFrameBuffer *view_fb)
+void LightModule::debug_draw(View &view, GPUFrameBuffer *view_fb)
{
- if (debug_draw_ps_ == nullptr) {
- return;
+ if (inst_.debug_mode == eDebugMode::DEBUG_LIGHT_CULLING) {
+ inst_.info = "Debug Mode: Light Culling Validation";
+ inst_.hiz_buffer.update();
+ GPU_framebuffer_bind(view_fb);
+ inst_.manager->submit(debug_draw_ps_, view);
}
- GPU_framebuffer_bind(view_fb);
- DRW_draw_pass(debug_draw_ps_);
}
/** \} */
diff --git a/source/blender/draw/engines/eevee_next/eevee_light.hh b/source/blender/draw/engines/eevee_next/eevee_light.hh
index c2d7aad34ae..9bacc180ea8 100644
--- a/source/blender/draw/engines/eevee_next/eevee_light.hh
+++ b/source/blender/draw/engines/eevee_next/eevee_light.hh
@@ -116,16 +116,12 @@ class LightModule {
/** Bitmap of lights touching each tiles. */
LightCullingTileBuf culling_tile_buf_ = {"LightCull_tile"};
/** Culling compute passes. */
- DRWPass *culling_select_ps_ = nullptr;
- DRWPass *culling_sort_ps_ = nullptr;
- DRWPass *culling_zbin_ps_ = nullptr;
- DRWPass *culling_tile_ps_ = nullptr;
+ PassSimple culling_ps_ = {"LightCulling"};
/** Total number of words the tile buffer needs to contain for the render resolution. */
uint total_word_count_ = 0;
/** Debug Culling visualization. */
- DRWPass *debug_draw_ps_ = nullptr;
- GPUTexture *input_depth_tx_ = nullptr;
+ PassSimple debug_draw_ps_ = {"LightCulling.Debug"};
public:
LightModule(Instance &inst) : inst_(inst){};
@@ -138,9 +134,9 @@ class LightModule {
/**
* Update acceleration structure for the given view.
*/
- void set_view(const DRWView *view, const int2 extent);
+ void set_view(View &view, const int2 extent);
- void debug_draw(GPUFrameBuffer *view_fb);
+ void debug_draw(View &view, GPUFrameBuffer *view_fb);
void bind_resources(DRWShadingGroup *grp)
{
@@ -154,6 +150,15 @@ class LightModule {
#endif
}
+ template<typename T> void bind_resources(draw::detail::PassBase<T> *pass)
+ {
+ /* Storage Buf. */
+ pass->bind_ssbo(LIGHT_CULL_BUF_SLOT, &culling_data_buf_);
+ pass->bind_ssbo(LIGHT_BUF_SLOT, &culling_light_buf_);
+ pass->bind_ssbo(LIGHT_ZBIN_BUF_SLOT, &culling_zbin_buf_);
+ pass->bind_ssbo(LIGHT_TILE_BUF_SLOT, &culling_tile_buf_);
+ }
+
private:
void culling_pass_sync();
void debug_pass_sync();
diff --git a/source/blender/draw/engines/eevee_next/eevee_material.cc b/source/blender/draw/engines/eevee_next/eevee_material.cc
index b3161a67092..a92f96e8c70 100644
--- a/source/blender/draw/engines/eevee_next/eevee_material.cc
+++ b/source/blender/draw/engines/eevee_next/eevee_material.cc
@@ -72,10 +72,9 @@ bNodeTree *DefaultSurfaceNodeTree::nodetree_get(::Material *ma)
MaterialModule::MaterialModule(Instance &inst) : inst_(inst)
{
{
- bNodeTree *ntree = ntreeAddTree(nullptr, "Shader Nodetree", ntreeType_Shader->idname);
-
diffuse_mat = (::Material *)BKE_id_new_nomain(ID_MA, "EEVEE default diffuse");
- diffuse_mat->nodetree = ntree;
+ bNodeTree *ntree = ntreeAddTreeEmbedded(
+ nullptr, &diffuse_mat->id, "Shader Nodetree", ntreeType_Shader->idname);
diffuse_mat->use_nodes = true;
/* To use the forward pipeline. */
diffuse_mat->blend_method = MA_BM_BLEND;
@@ -95,10 +94,9 @@ MaterialModule::MaterialModule(Instance &inst) : inst_(inst)
nodeSetActive(ntree, output);
}
{
- bNodeTree *ntree = ntreeAddTree(nullptr, "Shader Nodetree", ntreeType_Shader->idname);
-
glossy_mat = (::Material *)BKE_id_new_nomain(ID_MA, "EEVEE default metal");
- glossy_mat->nodetree = ntree;
+ bNodeTree *ntree = ntreeAddTreeEmbedded(
+ nullptr, &glossy_mat->id, "Shader Nodetree", ntreeType_Shader->idname);
glossy_mat->use_nodes = true;
/* To use the forward pipeline. */
glossy_mat->blend_method = MA_BM_BLEND;
@@ -120,10 +118,9 @@ MaterialModule::MaterialModule(Instance &inst) : inst_(inst)
nodeSetActive(ntree, output);
}
{
- bNodeTree *ntree = ntreeAddTree(nullptr, "Shader Nodetree", ntreeType_Shader->idname);
-
error_mat_ = (::Material *)BKE_id_new_nomain(ID_MA, "EEVEE default error");
- error_mat_->nodetree = ntree;
+ bNodeTree *ntree = ntreeAddTreeEmbedded(
+ nullptr, &error_mat_->id, "Shader Nodetree", ntreeType_Shader->idname);
error_mat_->use_nodes = true;
/* Use emission and output material to be compatible with both World and Material. */
@@ -145,9 +142,6 @@ MaterialModule::MaterialModule(Instance &inst) : inst_(inst)
MaterialModule::~MaterialModule()
{
- for (Material *mat : material_map_.values()) {
- delete mat;
- }
BKE_id_free(nullptr, glossy_mat);
BKE_id_free(nullptr, diffuse_mat);
BKE_id_free(nullptr, error_mat_);
@@ -157,13 +151,12 @@ void MaterialModule::begin_sync()
{
queued_shaders_count = 0;
- for (Material *mat : material_map_.values()) {
- mat->init = false;
- }
+ material_map_.clear();
shader_map_.clear();
}
-MaterialPass MaterialModule::material_pass_get(::Material *blender_mat,
+MaterialPass MaterialModule::material_pass_get(Object *ob,
+ ::Material *blender_mat,
eMaterialPipeline pipeline_type,
eMaterialGeometry geometry_type)
{
@@ -203,35 +196,34 @@ MaterialPass MaterialModule::material_pass_get(::Material *blender_mat,
pipeline_type = MAT_PIPE_FORWARD;
}
- if ((pipeline_type == MAT_PIPE_FORWARD) &&
+ if (ELEM(pipeline_type,
+ MAT_PIPE_FORWARD,
+ MAT_PIPE_FORWARD_PREPASS,
+ MAT_PIPE_FORWARD_PREPASS_VELOCITY) &&
GPU_material_flag_get(matpass.gpumat, GPU_MATFLAG_TRANSPARENT)) {
- /* Transparent needs to use one shgroup per object to support reordering. */
- matpass.shgrp = inst_.pipelines.material_add(blender_mat, matpass.gpumat, pipeline_type);
+ /* Transparent pass is generated later. */
+ matpass.sub_pass = nullptr;
}
else {
ShaderKey shader_key(matpass.gpumat, geometry_type, pipeline_type);
- auto add_cb = [&]() -> DRWShadingGroup * {
- /* First time encountering this shader. Create a shading group. */
- return inst_.pipelines.material_add(blender_mat, matpass.gpumat, pipeline_type);
- };
- DRWShadingGroup *grp = shader_map_.lookup_or_add_cb(shader_key, add_cb);
-
- if (grp != nullptr) {
- /* Shading group for this shader already exists. Create a sub one for this material. */
- /* IMPORTANT: We always create a subgroup so that all subgroups are inserted after the
- * first "empty" shgroup. This avoids messing the order of subgroups when there is more
- * nested subgroup (i.e: hair drawing). */
- /* TODO(@fclem): Remove material resource binding from the first group creation. */
- matpass.shgrp = DRW_shgroup_create_sub(grp);
- DRW_shgroup_add_material_resources(matpass.shgrp, matpass.gpumat);
+ PassMain::Sub *shader_sub = shader_map_.lookup_or_add_cb(shader_key, [&]() {
+ /* First time encountering this shader. Create a sub that will contain materials using it. */
+ return inst_.pipelines.material_add(ob, blender_mat, matpass.gpumat, pipeline_type);
+ });
+
+ if (shader_sub != nullptr) {
+ /* Create a sub for this material as `shader_sub` is for sharing shader between materials. */
+ matpass.sub_pass = &shader_sub->sub(GPU_material_get_name(matpass.gpumat));
+ matpass.sub_pass->material_set(*inst_.manager, matpass.gpumat);
}
}
return matpass;
}
-Material &MaterialModule::material_sync(::Material *blender_mat,
+Material &MaterialModule::material_sync(Object *ob,
+ ::Material *blender_mat,
eMaterialGeometry geometry_type,
bool has_motion)
{
@@ -249,27 +241,32 @@ Material &MaterialModule::material_sync(::Material *blender_mat,
MaterialKey material_key(blender_mat, geometry_type, surface_pipe);
- /* TODO: allocate in blocks to avoid memory fragmentation. */
- auto add_cb = [&]() { return new Material(); };
- Material &mat = *material_map_.lookup_or_add_cb(material_key, add_cb);
-
- /* Forward pipeline needs to use one shgroup per object. */
- if (mat.init == false || (surface_pipe == MAT_PIPE_FORWARD)) {
- mat.init = true;
+ Material &mat = material_map_.lookup_or_add_cb(material_key, [&]() {
+ Material mat;
/* Order is important for transparent. */
- mat.prepass = material_pass_get(blender_mat, prepass_pipe, geometry_type);
- mat.shading = material_pass_get(blender_mat, surface_pipe, geometry_type);
+ mat.prepass = material_pass_get(ob, blender_mat, prepass_pipe, geometry_type);
+ mat.shading = material_pass_get(ob, blender_mat, surface_pipe, geometry_type);
if (blender_mat->blend_shadow == MA_BS_NONE) {
mat.shadow = MaterialPass();
}
else {
- mat.shadow = material_pass_get(blender_mat, MAT_PIPE_SHADOW, geometry_type);
+ mat.shadow = material_pass_get(ob, blender_mat, MAT_PIPE_SHADOW, geometry_type);
}
-
mat.is_alpha_blend_transparent = (blender_mat->blend_method == MA_BM_BLEND) &&
- GPU_material_flag_get(mat.prepass.gpumat,
+ GPU_material_flag_get(mat.shading.gpumat,
GPU_MATFLAG_TRANSPARENT);
+ return mat;
+ });
+
+ if (mat.is_alpha_blend_transparent) {
+ /* Transparent needs to use one sub pass per object to support reordering.
+ * NOTE: Pre-pass needs to be created first in order to be sorted first. */
+ mat.prepass.sub_pass = inst_.pipelines.forward.prepass_transparent_add(
+ ob, blender_mat, mat.shading.gpumat);
+ mat.shading.sub_pass = inst_.pipelines.forward.material_transparent_add(
+ ob, blender_mat, mat.shading.gpumat);
}
+
return mat;
}
@@ -297,7 +294,7 @@ MaterialArray &MaterialModule::material_array_get(Object *ob, bool has_motion)
for (auto i : IndexRange(materials_len)) {
::Material *blender_mat = material_from_slot(ob, i);
- Material &mat = material_sync(blender_mat, to_material_geometry(ob), has_motion);
+ Material &mat = material_sync(ob, blender_mat, to_material_geometry(ob), has_motion);
material_array_.materials.append(&mat);
material_array_.gpu_materials.append(mat.shading.gpumat);
}
@@ -310,7 +307,7 @@ Material &MaterialModule::material_get(Object *ob,
eMaterialGeometry geometry_type)
{
::Material *blender_mat = material_from_slot(ob, mat_nr);
- Material &mat = material_sync(blender_mat, geometry_type, has_motion);
+ Material &mat = material_sync(ob, blender_mat, geometry_type, has_motion);
return mat;
}
diff --git a/source/blender/draw/engines/eevee_next/eevee_material.hh b/source/blender/draw/engines/eevee_next/eevee_material.hh
index 23165a741b9..ad0c293926b 100644
--- a/source/blender/draw/engines/eevee_next/eevee_material.hh
+++ b/source/blender/draw/engines/eevee_next/eevee_material.hh
@@ -203,12 +203,11 @@ class DefaultSurfaceNodeTree {
* \{ */
struct MaterialPass {
- GPUMaterial *gpumat = nullptr;
- DRWShadingGroup *shgrp = nullptr;
+ GPUMaterial *gpumat;
+ PassMain::Sub *sub_pass;
};
struct Material {
- bool init = false;
bool is_alpha_blend_transparent;
MaterialPass shadow, shading, prepass;
};
@@ -228,8 +227,8 @@ class MaterialModule {
private:
Instance &inst_;
- Map<MaterialKey, Material *> material_map_;
- Map<ShaderKey, DRWShadingGroup *> shader_map_;
+ Map<MaterialKey, Material> material_map_;
+ Map<ShaderKey, PassMain::Sub *> shader_map_;
MaterialArray material_array_;
@@ -254,13 +253,15 @@ class MaterialModule {
Material &material_get(Object *ob, bool has_motion, int mat_nr, eMaterialGeometry geometry_type);
private:
- Material &material_sync(::Material *blender_mat,
+ Material &material_sync(Object *ob,
+ ::Material *blender_mat,
eMaterialGeometry geometry_type,
bool has_motion);
/** Return correct material or empty default material if slot is empty. */
::Material *material_from_slot(Object *ob, int slot);
- MaterialPass material_pass_get(::Material *blender_mat,
+ MaterialPass material_pass_get(Object *ob,
+ ::Material *blender_mat,
eMaterialPipeline pipeline_type,
eMaterialGeometry geometry_type);
};
diff --git a/source/blender/draw/engines/eevee_next/eevee_motion_blur.cc b/source/blender/draw/engines/eevee_next/eevee_motion_blur.cc
index 660eb9f1e22..f68abafa3d4 100644
--- a/source/blender/draw/engines/eevee_next/eevee_motion_blur.cc
+++ b/source/blender/draw/engines/eevee_next/eevee_motion_blur.cc
@@ -135,53 +135,49 @@ void MotionBlurModule::sync()
eGPUSamplerState no_filter = GPU_SAMPLER_DEFAULT;
RenderBuffers &render_buffers = inst_.render_buffers;
+ motion_blur_ps_.init();
+ inst_.velocity.bind_resources(&motion_blur_ps_);
+ inst_.sampling.bind_resources(&motion_blur_ps_);
{
/* Create max velocity tiles. */
- DRW_PASS_CREATE(tiles_flatten_ps_, DRW_STATE_NO_DRAW);
+ PassSimple::Sub &sub = motion_blur_ps_.sub("TilesFlatten");
eShaderType shader = (inst_.is_viewport()) ? MOTION_BLUR_TILE_FLATTEN_VIEWPORT :
MOTION_BLUR_TILE_FLATTEN_RENDER;
- GPUShader *sh = inst_.shaders.static_shader_get(shader);
- DRWShadingGroup *grp = DRW_shgroup_create(sh, tiles_flatten_ps_);
- inst_.velocity.bind_resources(grp);
- DRW_shgroup_uniform_block(grp, "motion_blur_buf", data_);
- DRW_shgroup_uniform_texture_ref(grp, "depth_tx", &render_buffers.depth_tx);
- DRW_shgroup_uniform_image_ref(grp, "velocity_img", &render_buffers.vector_tx);
- DRW_shgroup_uniform_image_ref(grp, "out_tiles_img", &tiles_tx_);
-
- DRW_shgroup_call_compute_ref(grp, dispatch_flatten_size_);
- DRW_shgroup_barrier(grp, GPU_BARRIER_SHADER_IMAGE_ACCESS | GPU_BARRIER_TEXTURE_FETCH);
+ sub.shader_set(inst_.shaders.static_shader_get(shader));
+ sub.bind_ubo("motion_blur_buf", data_);
+ sub.bind_texture("depth_tx", &render_buffers.depth_tx);
+ sub.bind_image("velocity_img", &render_buffers.vector_tx);
+ sub.bind_image("out_tiles_img", &tiles_tx_);
+ sub.dispatch(&dispatch_flatten_size_);
+ sub.barrier(GPU_BARRIER_SHADER_IMAGE_ACCESS | GPU_BARRIER_TEXTURE_FETCH);
}
{
/* Expand max velocity tiles by spreading them in their neighborhood. */
- DRW_PASS_CREATE(tiles_dilate_ps_, DRW_STATE_NO_DRAW);
- GPUShader *sh = inst_.shaders.static_shader_get(MOTION_BLUR_TILE_DILATE);
- DRWShadingGroup *grp = DRW_shgroup_create(sh, tiles_dilate_ps_);
- DRW_shgroup_storage_block(grp, "tile_indirection_buf", tile_indirection_buf_);
- DRW_shgroup_uniform_image_ref(grp, "in_tiles_img", &tiles_tx_);
-
- DRW_shgroup_call_compute_ref(grp, dispatch_dilate_size_);
- DRW_shgroup_barrier(grp, GPU_BARRIER_SHADER_STORAGE);
+ PassSimple::Sub &sub = motion_blur_ps_.sub("TilesDilate");
+ sub.shader_set(inst_.shaders.static_shader_get(MOTION_BLUR_TILE_DILATE));
+ sub.bind_ssbo("tile_indirection_buf", tile_indirection_buf_);
+ sub.bind_image("in_tiles_img", &tiles_tx_);
+ sub.dispatch(&dispatch_dilate_size_);
+ sub.barrier(GPU_BARRIER_SHADER_STORAGE);
}
{
/* Do the motion blur gather algorithm. */
- DRW_PASS_CREATE(gather_ps_, DRW_STATE_NO_DRAW);
- GPUShader *sh = inst_.shaders.static_shader_get(MOTION_BLUR_GATHER);
- DRWShadingGroup *grp = DRW_shgroup_create(sh, gather_ps_);
- inst_.sampling.bind_resources(grp);
- DRW_shgroup_uniform_block(grp, "motion_blur_buf", data_);
- DRW_shgroup_storage_block(grp, "tile_indirection_buf", tile_indirection_buf_);
- DRW_shgroup_uniform_texture_ref_ex(grp, "depth_tx", &render_buffers.depth_tx, no_filter);
- DRW_shgroup_uniform_texture_ref_ex(grp, "velocity_tx", &render_buffers.vector_tx, no_filter);
- DRW_shgroup_uniform_texture_ref_ex(grp, "in_color_tx", &input_color_tx_, no_filter);
- DRW_shgroup_uniform_image_ref(grp, "in_tiles_img", &tiles_tx_);
- DRW_shgroup_uniform_image_ref(grp, "out_color_img", &output_color_tx_);
-
- DRW_shgroup_call_compute_ref(grp, dispatch_gather_size_);
- DRW_shgroup_barrier(grp, GPU_BARRIER_TEXTURE_FETCH);
+ PassSimple::Sub &sub = motion_blur_ps_.sub("ConvolveGather");
+ sub.shader_set(inst_.shaders.static_shader_get(MOTION_BLUR_GATHER));
+ sub.bind_ubo("motion_blur_buf", data_);
+ sub.bind_ssbo("tile_indirection_buf", tile_indirection_buf_);
+ sub.bind_texture("depth_tx", &render_buffers.depth_tx, no_filter);
+ sub.bind_texture("velocity_tx", &render_buffers.vector_tx, no_filter);
+ sub.bind_texture("in_color_tx", &input_color_tx_, no_filter);
+ sub.bind_image("in_tiles_img", &tiles_tx_);
+ sub.bind_image("out_color_img", &output_color_tx_);
+
+ sub.dispatch(&dispatch_gather_size_);
+ sub.barrier(GPU_BARRIER_TEXTURE_FETCH);
}
}
-void MotionBlurModule::render(GPUTexture **input_tx, GPUTexture **output_tx)
+void MotionBlurModule::render(View &view, GPUTexture **input_tx, GPUTexture **output_tx)
{
if (!motion_blur_fx_enabled_) {
return;
@@ -239,9 +235,7 @@ void MotionBlurModule::render(GPUTexture **input_tx, GPUTexture **output_tx)
GPU_storagebuf_clear_to_zero(tile_indirection_buf_);
- DRW_draw_pass(tiles_flatten_ps_);
- DRW_draw_pass(tiles_dilate_ps_);
- DRW_draw_pass(gather_ps_);
+ inst_.manager->submit(motion_blur_ps_, view);
tiles_tx_.release();
@@ -259,4 +253,4 @@ void MotionBlurModule::render(GPUTexture **input_tx, GPUTexture **output_tx)
/** \} */
-} // namespace blender::eevee \ No newline at end of file
+} // namespace blender::eevee
diff --git a/source/blender/draw/engines/eevee_next/eevee_motion_blur.hh b/source/blender/draw/engines/eevee_next/eevee_motion_blur.hh
index 310e94a702b..056c2e323d5 100644
--- a/source/blender/draw/engines/eevee_next/eevee_motion_blur.hh
+++ b/source/blender/draw/engines/eevee_next/eevee_motion_blur.hh
@@ -95,9 +95,7 @@ class MotionBlurModule {
GPUTexture *input_color_tx_ = nullptr;
GPUTexture *output_color_tx_ = nullptr;
- DRWPass *tiles_flatten_ps_ = nullptr;
- DRWPass *tiles_dilate_ps_ = nullptr;
- DRWPass *gather_ps_ = nullptr;
+ PassSimple motion_blur_ps_ = {"MotionBlur"};
MotionBlurTileIndirectionBuf tile_indirection_buf_;
MotionBlurDataBuf data_;
@@ -121,7 +119,7 @@ class MotionBlurModule {
return motion_blur_fx_enabled_;
}
- void render(GPUTexture **input_tx, GPUTexture **output_tx);
+ void render(View &view, GPUTexture **input_tx, GPUTexture **output_tx);
private:
float shutter_time_to_scene_time(float time);
diff --git a/source/blender/draw/engines/eevee_next/eevee_pipeline.cc b/source/blender/draw/engines/eevee_next/eevee_pipeline.cc
index 9185ce7904a..33978518ffc 100644
--- a/source/blender/draw/engines/eevee_next/eevee_pipeline.cc
+++ b/source/blender/draw/engines/eevee_next/eevee_pipeline.cc
@@ -24,37 +24,36 @@ namespace blender::eevee {
void WorldPipeline::sync(GPUMaterial *gpumat)
{
+ Manager &manager = *inst_.manager;
RenderBuffers &rbufs = inst_.render_buffers;
- DRWState state = DRW_STATE_WRITE_COLOR;
- world_ps_ = DRW_pass_create("World", state);
+ ResourceHandle handle = manager.resource_handle(float4x4::identity().ptr());
- /* Push a matrix at the same location as the camera. */
- float4x4 camera_mat = float4x4::identity();
- // copy_v3_v3(camera_mat[3], inst_.camera.data_get().viewinv[3]);
-
- DRWShadingGroup *grp = DRW_shgroup_material_create(gpumat, world_ps_);
- DRW_shgroup_uniform_texture(grp, "utility_tx", inst_.pipelines.utility_tx);
- DRW_shgroup_call_obmat(grp, DRW_cache_fullscreen_quad_get(), camera_mat.ptr());
- DRW_shgroup_uniform_float_copy(grp, "world_opacity_fade", inst_.film.background_opacity_get());
+ world_ps_.init();
+ world_ps_.state_set(DRW_STATE_WRITE_COLOR);
+ world_ps_.material_set(manager, gpumat);
+ world_ps_.push_constant("world_opacity_fade", inst_.film.background_opacity_get());
+ world_ps_.bind_texture("utility_tx", inst_.pipelines.utility_tx);
/* AOVs. */
- DRW_shgroup_uniform_image_ref(grp, "aov_color_img", &rbufs.aov_color_tx);
- DRW_shgroup_uniform_image_ref(grp, "aov_value_img", &rbufs.aov_value_tx);
- DRW_shgroup_storage_block_ref(grp, "aov_buf", &inst_.film.aovs_info);
+ world_ps_.bind_image("aov_color_img", &rbufs.aov_color_tx);
+ world_ps_.bind_image("aov_value_img", &rbufs.aov_value_tx);
+ world_ps_.bind_ssbo("aov_buf", &inst_.film.aovs_info);
/* RenderPasses. Cleared by background (even if bad practice). */
- DRW_shgroup_uniform_image_ref(grp, "rp_normal_img", &rbufs.normal_tx);
- DRW_shgroup_uniform_image_ref(grp, "rp_diffuse_light_img", &rbufs.diffuse_light_tx);
- DRW_shgroup_uniform_image_ref(grp, "rp_diffuse_color_img", &rbufs.diffuse_color_tx);
- DRW_shgroup_uniform_image_ref(grp, "rp_specular_light_img", &rbufs.specular_light_tx);
- DRW_shgroup_uniform_image_ref(grp, "rp_specular_color_img", &rbufs.specular_color_tx);
- DRW_shgroup_uniform_image_ref(grp, "rp_emission_img", &rbufs.emission_tx);
+ world_ps_.bind_image("rp_normal_img", &rbufs.normal_tx);
+ world_ps_.bind_image("rp_light_img", &rbufs.light_tx);
+ world_ps_.bind_image("rp_diffuse_color_img", &rbufs.diffuse_color_tx);
+ world_ps_.bind_image("rp_specular_color_img", &rbufs.specular_color_tx);
+ world_ps_.bind_image("rp_emission_img", &rbufs.emission_tx);
+ world_ps_.bind_image("rp_cryptomatte_img", &rbufs.cryptomatte_tx);
+
+ world_ps_.draw(DRW_cache_fullscreen_quad_get(), handle);
/* To allow opaque pass rendering over it. */
- DRW_shgroup_barrier(grp, GPU_BARRIER_SHADER_IMAGE_ACCESS);
+ world_ps_.barrier(GPU_BARRIER_SHADER_IMAGE_ACCESS);
}
-void WorldPipeline::render()
+void WorldPipeline::render(View &view)
{
- DRW_draw_pass(world_ps_);
+ inst_.manager->submit(world_ps_, view);
}
/** \} */
@@ -67,216 +66,167 @@ void WorldPipeline::render()
void ForwardPipeline::sync()
{
+ camera_forward_ = inst_.camera.forward();
+
+ DRWState state_depth_only = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS;
+ DRWState state_depth_color = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS |
+ DRW_STATE_WRITE_COLOR;
{
- DRWState state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS;
- prepass_ps_ = DRW_pass_create("Forward.Opaque.Prepass", state);
- prepass_velocity_ps_ = DRW_pass_create("Forward.Opaque.Prepass.Velocity",
- state | DRW_STATE_WRITE_COLOR);
+ prepass_ps_.init();
- state |= DRW_STATE_CULL_BACK;
- prepass_culled_ps_ = DRW_pass_create("Forward.Opaque.Prepass.Culled", state);
- prepass_culled_velocity_ps_ = DRW_pass_create("Forward.Opaque.Prepass.Velocity",
- state | DRW_STATE_WRITE_COLOR);
+ {
+ /* Common resources. */
- DRW_pass_link(prepass_ps_, prepass_velocity_ps_);
- DRW_pass_link(prepass_velocity_ps_, prepass_culled_ps_);
- DRW_pass_link(prepass_culled_ps_, prepass_culled_velocity_ps_);
- }
- {
- DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL;
- opaque_ps_ = DRW_pass_create("Forward.Opaque", state);
+ /* Textures. */
+ prepass_ps_.bind_texture(RBUFS_UTILITY_TEX_SLOT, inst_.pipelines.utility_tx);
- state |= DRW_STATE_CULL_BACK;
- opaque_culled_ps_ = DRW_pass_create("Forward.Opaque.Culled", state);
+ inst_.velocity.bind_resources(&prepass_ps_);
+ inst_.sampling.bind_resources(&prepass_ps_);
+ }
+
+ prepass_double_sided_static_ps_ = &prepass_ps_.sub("DoubleSided.Static");
+ prepass_double_sided_static_ps_->state_set(state_depth_only);
+
+ prepass_single_sided_static_ps_ = &prepass_ps_.sub("SingleSided.Static");
+ prepass_single_sided_static_ps_->state_set(state_depth_only | DRW_STATE_CULL_BACK);
- DRW_pass_link(opaque_ps_, opaque_culled_ps_);
+ prepass_double_sided_moving_ps_ = &prepass_ps_.sub("DoubleSided.Moving");
+ prepass_double_sided_moving_ps_->state_set(state_depth_color);
+
+ prepass_single_sided_moving_ps_ = &prepass_ps_.sub("SingleSided.Moving");
+ prepass_single_sided_moving_ps_->state_set(state_depth_color | DRW_STATE_CULL_BACK);
}
{
- DRWState state = DRW_STATE_DEPTH_LESS_EQUAL;
- transparent_ps_ = DRW_pass_create("Forward.Transparent", state);
+ opaque_ps_.init();
+
+ {
+ /* Common resources. */
+
+ /* RenderPasses. */
+ opaque_ps_.bind_image(RBUFS_NORMAL_SLOT, &inst_.render_buffers.normal_tx);
+ opaque_ps_.bind_image(RBUFS_LIGHT_SLOT, &inst_.render_buffers.light_tx);
+ opaque_ps_.bind_image(RBUFS_DIFF_COLOR_SLOT, &inst_.render_buffers.diffuse_color_tx);
+ opaque_ps_.bind_image(RBUFS_SPEC_COLOR_SLOT, &inst_.render_buffers.specular_color_tx);
+ opaque_ps_.bind_image(RBUFS_EMISSION_SLOT, &inst_.render_buffers.emission_tx);
+ /* AOVs. */
+ opaque_ps_.bind_image(RBUFS_AOV_COLOR_SLOT, &inst_.render_buffers.aov_color_tx);
+ opaque_ps_.bind_image(RBUFS_AOV_VALUE_SLOT, &inst_.render_buffers.aov_value_tx);
+ /* Cryptomatte. */
+ opaque_ps_.bind_image(RBUFS_CRYPTOMATTE_SLOT, &inst_.render_buffers.cryptomatte_tx);
+ /* Storage Buf. */
+ opaque_ps_.bind_ssbo(RBUFS_AOV_BUF_SLOT, &inst_.film.aovs_info);
+ /* Textures. */
+ opaque_ps_.bind_texture(RBUFS_UTILITY_TEX_SLOT, inst_.pipelines.utility_tx);
+
+ inst_.lights.bind_resources(&opaque_ps_);
+ inst_.sampling.bind_resources(&opaque_ps_);
+ inst_.cryptomatte.bind_resources(&opaque_ps_);
+ }
+
+ opaque_single_sided_ps_ = &opaque_ps_.sub("SingleSided");
+ opaque_single_sided_ps_->state_set(DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL |
+ DRW_STATE_CULL_BACK);
+
+ opaque_double_sided_ps_ = &opaque_ps_.sub("DoubleSided");
+ opaque_double_sided_ps_->state_set(DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL);
}
-}
+ {
+ transparent_ps_.init();
+ /* Workaround limitation of PassSortable. Use dummy pass that will be sorted first in all
+ * circumstances. */
+ PassMain::Sub &sub = transparent_ps_.sub("ResourceBind", -FLT_MAX);
-DRWShadingGroup *ForwardPipeline::material_opaque_add(::Material *blender_mat, GPUMaterial *gpumat)
-{
- RenderBuffers &rbufs = inst_.render_buffers;
- DRWPass *pass = (blender_mat->blend_flag & MA_BL_CULL_BACKFACE) ? opaque_culled_ps_ : opaque_ps_;
- LightModule &lights = inst_.lights;
- Sampling &sampling = inst_.sampling;
- // LightProbeModule &lightprobes = inst_.lightprobes;
- // RaytracingModule &raytracing = inst_.raytracing;
- // eGPUSamplerState no_interp = GPU_SAMPLER_DEFAULT;
- DRWShadingGroup *grp = DRW_shgroup_material_create(gpumat, pass);
- lights.bind_resources(grp);
- sampling.bind_resources(grp);
- // DRW_shgroup_uniform_block(grp, "sampling_buf", inst_.sampling.ubo_get());
- // DRW_shgroup_uniform_block(grp, "grids_buf", lightprobes.grid_ubo_get());
- // DRW_shgroup_uniform_block(grp, "cubes_buf", lightprobes.cube_ubo_get());
- // DRW_shgroup_uniform_block(grp, "probes_buf", lightprobes.info_ubo_get());
- // DRW_shgroup_uniform_texture_ref(grp, "lightprobe_grid_tx", lightprobes.grid_tx_ref_get());
- // DRW_shgroup_uniform_texture_ref(grp, "lightprobe_cube_tx", lightprobes.cube_tx_ref_get());
- DRW_shgroup_uniform_texture(grp, "utility_tx", inst_.pipelines.utility_tx);
- /* AOVs. */
- DRW_shgroup_uniform_image_ref(grp, "aov_color_img", &rbufs.aov_color_tx);
- DRW_shgroup_uniform_image_ref(grp, "aov_value_img", &rbufs.aov_value_tx);
- DRW_shgroup_storage_block_ref(grp, "aov_buf", &inst_.film.aovs_info);
- /* RenderPasses. */
- DRW_shgroup_uniform_image_ref(grp, "rp_normal_img", &rbufs.normal_tx);
- DRW_shgroup_uniform_image_ref(grp, "rp_diffuse_light_img", &rbufs.diffuse_light_tx);
- DRW_shgroup_uniform_image_ref(grp, "rp_diffuse_color_img", &rbufs.diffuse_color_tx);
- DRW_shgroup_uniform_image_ref(grp, "rp_specular_light_img", &rbufs.specular_light_tx);
- DRW_shgroup_uniform_image_ref(grp, "rp_specular_color_img", &rbufs.specular_color_tx);
- DRW_shgroup_uniform_image_ref(grp, "rp_emission_img", &rbufs.emission_tx);
-
- /* TODO(fclem): Make this only needed if material uses it ... somehow. */
- // if (true) {
- // DRW_shgroup_uniform_texture_ref(
- // grp, "sss_transmittance_tx", inst_.subsurface.transmittance_ref_get());
- // }
- // if (raytracing.enabled()) {
- // DRW_shgroup_uniform_block(grp, "rt_diffuse_buf", raytracing.diffuse_data);
- // DRW_shgroup_uniform_block(grp, "rt_reflection_buf", raytracing.reflection_data);
- // DRW_shgroup_uniform_block(grp, "rt_refraction_buf", raytracing.refraction_data);
- // DRW_shgroup_uniform_texture_ref_ex(grp, "radiance_tx", &input_screen_radiance_tx_,
- // no_interp);
- // }
- // if (raytracing.enabled()) {
- // DRW_shgroup_uniform_block(grp, "hiz_buf", inst_.hiz.ubo_get());
- // DRW_shgroup_uniform_texture_ref(grp, "hiz_tx", inst_.hiz_front.texture_ref_get());
- // }
- return grp;
-}
+ /* Common resources. */
-DRWShadingGroup *ForwardPipeline::prepass_opaque_add(::Material *blender_mat,
- GPUMaterial *gpumat,
- bool has_motion)
-{
- DRWPass *pass = (blender_mat->blend_flag & MA_BL_CULL_BACKFACE) ?
- (has_motion ? prepass_culled_velocity_ps_ : prepass_culled_ps_) :
- (has_motion ? prepass_velocity_ps_ : prepass_ps_);
- DRWShadingGroup *grp = DRW_shgroup_material_create(gpumat, pass);
- if (has_motion) {
- inst_.velocity.bind_resources(grp);
+ /* Textures. */
+ sub.bind_texture(RBUFS_UTILITY_TEX_SLOT, inst_.pipelines.utility_tx);
+
+ inst_.lights.bind_resources(&sub);
+ inst_.sampling.bind_resources(&sub);
}
- return grp;
}
-DRWShadingGroup *ForwardPipeline::material_transparent_add(::Material *blender_mat,
- GPUMaterial *gpumat)
+PassMain::Sub *ForwardPipeline::prepass_opaque_add(::Material *blender_mat,
+ GPUMaterial *gpumat,
+ bool has_motion)
{
- RenderBuffers &rbufs = inst_.render_buffers;
- LightModule &lights = inst_.lights;
- Sampling &sampling = inst_.sampling;
- // LightProbeModule &lightprobes = inst_.lightprobes;
- // RaytracingModule &raytracing = inst_.raytracing;
- // eGPUSamplerState no_interp = GPU_SAMPLER_DEFAULT;
- DRWShadingGroup *grp = DRW_shgroup_material_create(gpumat, transparent_ps_);
- lights.bind_resources(grp);
- sampling.bind_resources(grp);
- // DRW_shgroup_uniform_block(grp, "sampling_buf", inst_.sampling.ubo_get());
- // DRW_shgroup_uniform_block(grp, "grids_buf", lightprobes.grid_ubo_get());
- // DRW_shgroup_uniform_block(grp, "cubes_buf", lightprobes.cube_ubo_get());
- // DRW_shgroup_uniform_block(grp, "probes_buf", lightprobes.info_ubo_get());
- // DRW_shgroup_uniform_texture_ref(grp, "lightprobe_grid_tx", lightprobes.grid_tx_ref_get());
- // DRW_shgroup_uniform_texture_ref(grp, "lightprobe_cube_tx", lightprobes.cube_tx_ref_get());
- DRW_shgroup_uniform_texture(grp, "utility_tx", inst_.pipelines.utility_tx);
- /* TODO(fclem): Make this only needed if material uses it ... somehow. */
- // if (true) {
- // DRW_shgroup_uniform_texture_ref(
- // grp, "sss_transmittance_tx", inst_.subsurface.transmittance_ref_get());
- // }
- // if (raytracing.enabled()) {
- // DRW_shgroup_uniform_block(grp, "rt_diffuse_buf", raytracing.diffuse_data);
- // DRW_shgroup_uniform_block(grp, "rt_reflection_buf", raytracing.reflection_data);
- // DRW_shgroup_uniform_block(grp, "rt_refraction_buf", raytracing.refraction_data);
- // DRW_shgroup_uniform_texture_ref_ex(
- // grp, "rt_radiance_tx", &input_screen_radiance_tx_, no_interp);
- // }
- // if (raytracing.enabled()) {
- // DRW_shgroup_uniform_block(grp, "hiz_buf", inst_.hiz.ubo_get());
- // DRW_shgroup_uniform_texture_ref(grp, "hiz_tx", inst_.hiz_front.texture_ref_get());
- // }
- {
- /* TODO(fclem): This is not needed. This is only to please the OpenGL debug Layer.
- * If we are to introduce transparency render-passes support, it would be through a separate
- * pass. */
- /* AOVs. */
- DRW_shgroup_uniform_image_ref(grp, "aov_color_img", &rbufs.aov_color_tx);
- DRW_shgroup_uniform_image_ref(grp, "aov_value_img", &rbufs.aov_value_tx);
- DRW_shgroup_storage_block_ref(grp, "aov_buf", &inst_.film.aovs_info);
- /* RenderPasses. */
- DRW_shgroup_uniform_image_ref(grp, "rp_normal_img", &rbufs.normal_tx);
- DRW_shgroup_uniform_image_ref(grp, "rp_diffuse_light_img", &rbufs.diffuse_light_tx);
- DRW_shgroup_uniform_image_ref(grp, "rp_diffuse_color_img", &rbufs.diffuse_color_tx);
- DRW_shgroup_uniform_image_ref(grp, "rp_specular_light_img", &rbufs.specular_light_tx);
- DRW_shgroup_uniform_image_ref(grp, "rp_specular_color_img", &rbufs.specular_color_tx);
- DRW_shgroup_uniform_image_ref(grp, "rp_emission_img", &rbufs.emission_tx);
- }
+ PassMain::Sub *pass = (blender_mat->blend_flag & MA_BL_CULL_BACKFACE) ?
+ (has_motion ? prepass_single_sided_moving_ps_ :
+ prepass_single_sided_static_ps_) :
+ (has_motion ? prepass_double_sided_moving_ps_ :
+ prepass_double_sided_static_ps_);
+ return &pass->sub(GPU_material_get_name(gpumat));
+}
- DRWState state_disable = DRW_STATE_WRITE_DEPTH;
- DRWState state_enable = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_CUSTOM;
- if (blender_mat->blend_flag & MA_BL_CULL_BACKFACE) {
- state_enable |= DRW_STATE_CULL_BACK;
- }
- DRW_shgroup_state_disable(grp, state_disable);
- DRW_shgroup_state_enable(grp, state_enable);
- return grp;
+PassMain::Sub *ForwardPipeline::material_opaque_add(::Material *blender_mat, GPUMaterial *gpumat)
+{
+ PassMain::Sub *pass = (blender_mat->blend_flag & MA_BL_CULL_BACKFACE) ? opaque_single_sided_ps_ :
+ opaque_double_sided_ps_;
+ return &pass->sub(GPU_material_get_name(gpumat));
}
-DRWShadingGroup *ForwardPipeline::prepass_transparent_add(::Material *blender_mat,
- GPUMaterial *gpumat)
+PassMain::Sub *ForwardPipeline::prepass_transparent_add(const Object *ob,
+ ::Material *blender_mat,
+ GPUMaterial *gpumat)
{
if ((blender_mat->blend_flag & MA_BL_HIDE_BACKFACE) == 0) {
return nullptr;
}
+ DRWState state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL;
+ if ((blender_mat->blend_flag & MA_BL_CULL_BACKFACE)) {
+ state |= DRW_STATE_CULL_BACK;
+ }
+ float sorting_value = math::dot(float3(ob->obmat[3]), camera_forward_);
+ PassMain::Sub *pass = &transparent_ps_.sub(GPU_material_get_name(gpumat), sorting_value);
+ pass->state_set(state);
+ pass->material_set(*inst_.manager, gpumat);
+ return pass;
+}
- DRWShadingGroup *grp = DRW_shgroup_material_create(gpumat, transparent_ps_);
-
- DRWState state_disable = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_CUSTOM;
- DRWState state_enable = DRW_STATE_WRITE_DEPTH;
- if (blender_mat->blend_flag & MA_BL_CULL_BACKFACE) {
- state_enable |= DRW_STATE_CULL_BACK;
+PassMain::Sub *ForwardPipeline::material_transparent_add(const Object *ob,
+ ::Material *blender_mat,
+ GPUMaterial *gpumat)
+{
+ DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_CUSTOM | DRW_STATE_DEPTH_LESS_EQUAL;
+ if ((blender_mat->blend_flag & MA_BL_CULL_BACKFACE)) {
+ state |= DRW_STATE_CULL_BACK;
}
- DRW_shgroup_state_disable(grp, state_disable);
- DRW_shgroup_state_enable(grp, state_enable);
- return grp;
+ float sorting_value = math::dot(float3(ob->obmat[3]), camera_forward_);
+ PassMain::Sub *pass = &transparent_ps_.sub(GPU_material_get_name(gpumat), sorting_value);
+ pass->state_set(state);
+ pass->material_set(*inst_.manager, gpumat);
+ return pass;
}
-void ForwardPipeline::render(const DRWView *view,
+void ForwardPipeline::render(View &view,
Framebuffer &prepass_fb,
Framebuffer &combined_fb,
- GPUTexture *depth_tx,
GPUTexture *UNUSED(combined_tx))
{
- UNUSED_VARS(view, depth_tx, prepass_fb, combined_fb);
- // HiZBuffer &hiz = inst_.hiz_front;
+ UNUSED_VARS(view);
- DRW_stats_group_start("ForwardOpaque");
+ DRW_stats_group_start("Forward.Opaque");
GPU_framebuffer_bind(prepass_fb);
- DRW_draw_pass(prepass_ps_);
+ inst_.manager->submit(prepass_ps_, view);
- // hiz.set_dirty();
+ // if (!DRW_pass_is_empty(prepass_ps_)) {
+ inst_.hiz_buffer.set_dirty();
+ // }
// if (inst_.raytracing.enabled()) {
// rt_buffer.radiance_copy(combined_tx);
- // hiz.update(depth_tx);
+ // inst_.hiz_buffer.update();
// }
// inst_.shadows.set_view(view, depth_tx);
GPU_framebuffer_bind(combined_fb);
- DRW_draw_pass(opaque_ps_);
+ inst_.manager->submit(opaque_ps_, view);
DRW_stats_group_end();
- DRW_stats_group_start("ForwardTransparent");
- /* TODO(fclem) This is suboptimal. We could sort during sync. */
- /* FIXME(fclem) This wont work for panoramic, where we need
- * to sort by distance to camera, not by z. */
- DRW_pass_sort_shgroup_z(transparent_ps_);
- DRW_draw_pass(transparent_ps_);
- DRW_stats_group_end();
+ inst_.manager->submit(transparent_ps_, view);
// if (inst_.raytracing.enabled()) {
// gbuffer.ray_radiance_tx.release();
diff --git a/source/blender/draw/engines/eevee_next/eevee_pipeline.hh b/source/blender/draw/engines/eevee_next/eevee_pipeline.hh
index 3bdc718767b..0614a963dec 100644
--- a/source/blender/draw/engines/eevee_next/eevee_pipeline.hh
+++ b/source/blender/draw/engines/eevee_next/eevee_pipeline.hh
@@ -13,6 +13,7 @@
#pragma once
#include "DRW_render.h"
+#include "draw_shader_shared.h"
/* TODO(fclem): Move it to GPU/DRAW. */
#include "../eevee/eevee_lut.h"
@@ -31,13 +32,13 @@ class WorldPipeline {
private:
Instance &inst_;
- DRWPass *world_ps_ = nullptr;
+ PassSimple world_ps_ = {"World.Background"};
public:
WorldPipeline(Instance &inst) : inst_(inst){};
void sync(GPUMaterial *gpumat);
- void render();
+ void render(View &view);
};
/** \} */
@@ -52,13 +53,18 @@ class ForwardPipeline {
private:
Instance &inst_;
- DRWPass *prepass_ps_ = nullptr;
- DRWPass *prepass_velocity_ps_ = nullptr;
- DRWPass *prepass_culled_ps_ = nullptr;
- DRWPass *prepass_culled_velocity_ps_ = nullptr;
- DRWPass *opaque_ps_ = nullptr;
- DRWPass *opaque_culled_ps_ = nullptr;
- DRWPass *transparent_ps_ = nullptr;
+ PassMain prepass_ps_ = {"Prepass"};
+ PassMain::Sub *prepass_single_sided_static_ps_ = nullptr;
+ PassMain::Sub *prepass_single_sided_moving_ps_ = nullptr;
+ PassMain::Sub *prepass_double_sided_static_ps_ = nullptr;
+ PassMain::Sub *prepass_double_sided_moving_ps_ = nullptr;
+
+ PassMain opaque_ps_ = {"Shading"};
+ PassMain::Sub *opaque_single_sided_ps_ = nullptr;
+ PassMain::Sub *opaque_double_sided_ps_ = nullptr;
+
+ PassSortable transparent_ps_ = {"Forward.Transparent"};
+ float3 camera_forward_;
// GPUTexture *input_screen_radiance_tx_ = nullptr;
@@ -67,31 +73,19 @@ class ForwardPipeline {
void sync();
- DRWShadingGroup *material_add(::Material *blender_mat, GPUMaterial *gpumat)
- {
- return (GPU_material_flag_get(gpumat, GPU_MATFLAG_TRANSPARENT)) ?
- material_transparent_add(blender_mat, gpumat) :
- material_opaque_add(blender_mat, gpumat);
- }
+ PassMain::Sub *prepass_opaque_add(::Material *blender_mat, GPUMaterial *gpumat, bool has_motion);
+ PassMain::Sub *material_opaque_add(::Material *blender_mat, GPUMaterial *gpumat);
- DRWShadingGroup *prepass_add(::Material *blender_mat, GPUMaterial *gpumat, bool has_motion)
- {
- return (GPU_material_flag_get(gpumat, GPU_MATFLAG_TRANSPARENT)) ?
- prepass_transparent_add(blender_mat, gpumat) :
- prepass_opaque_add(blender_mat, gpumat, has_motion);
- }
-
- DRWShadingGroup *material_opaque_add(::Material *blender_mat, GPUMaterial *gpumat);
- DRWShadingGroup *prepass_opaque_add(::Material *blender_mat,
- GPUMaterial *gpumat,
- bool has_motion);
- DRWShadingGroup *material_transparent_add(::Material *blender_mat, GPUMaterial *gpumat);
- DRWShadingGroup *prepass_transparent_add(::Material *blender_mat, GPUMaterial *gpumat);
+ PassMain::Sub *prepass_transparent_add(const Object *ob,
+ ::Material *blender_mat,
+ GPUMaterial *gpumat);
+ PassMain::Sub *material_transparent_add(const Object *ob,
+ ::Material *blender_mat,
+ GPUMaterial *gpumat);
- void render(const DRWView *view,
+ void render(View &view,
Framebuffer &prepass_fb,
Framebuffer &combined_fb,
- GPUTexture *depth_tx,
GPUTexture *combined_tx);
};
@@ -193,26 +187,36 @@ class PipelineModule {
// velocity.sync();
}
- DRWShadingGroup *material_add(::Material *blender_mat,
- GPUMaterial *gpumat,
- eMaterialPipeline pipeline_type)
+ PassMain::Sub *material_add(Object *ob,
+ ::Material *blender_mat,
+ GPUMaterial *gpumat,
+ eMaterialPipeline pipeline_type)
{
switch (pipeline_type) {
case MAT_PIPE_DEFERRED_PREPASS:
// return deferred.prepass_add(blender_mat, gpumat, false);
- break;
+ case MAT_PIPE_FORWARD_PREPASS:
+ if (GPU_material_flag_get(gpumat, GPU_MATFLAG_TRANSPARENT)) {
+ return forward.prepass_transparent_add(ob, blender_mat, gpumat);
+ }
+ return forward.prepass_opaque_add(blender_mat, gpumat, false);
+
case MAT_PIPE_DEFERRED_PREPASS_VELOCITY:
// return deferred.prepass_add(blender_mat, gpumat, true);
- break;
- case MAT_PIPE_FORWARD_PREPASS:
- return forward.prepass_add(blender_mat, gpumat, false);
case MAT_PIPE_FORWARD_PREPASS_VELOCITY:
- return forward.prepass_add(blender_mat, gpumat, true);
+ if (GPU_material_flag_get(gpumat, GPU_MATFLAG_TRANSPARENT)) {
+ return forward.prepass_transparent_add(ob, blender_mat, gpumat);
+ }
+ return forward.prepass_opaque_add(blender_mat, gpumat, true);
+
case MAT_PIPE_DEFERRED:
// return deferred.material_add(blender_mat, gpumat);
- break;
case MAT_PIPE_FORWARD:
- return forward.material_add(blender_mat, gpumat);
+ if (GPU_material_flag_get(gpumat, GPU_MATFLAG_TRANSPARENT)) {
+ return forward.material_transparent_add(ob, blender_mat, gpumat);
+ }
+ return forward.material_opaque_add(blender_mat, gpumat);
+
case MAT_PIPE_VOLUME:
/* TODO(fclem) volume pass. */
return nullptr;
diff --git a/source/blender/draw/engines/eevee_next/eevee_renderbuffers.cc b/source/blender/draw/engines/eevee_next/eevee_renderbuffers.cc
index b69fde7b26c..f5638cc5160 100644
--- a/source/blender/draw/engines/eevee_next/eevee_renderbuffers.cc
+++ b/source/blender/draw/engines/eevee_next/eevee_renderbuffers.cc
@@ -5,7 +5,7 @@
/** \file
* \ingroup eevee
*
- * A film is a fullscreen buffer (usually at output extent)
+ * A film is a full-screen buffer (usually at output extent)
* that will be able to accumulate sample in any distorted camera_type
* using a pixel filter.
*
@@ -26,9 +26,11 @@ namespace blender::eevee {
void RenderBuffers::acquire(int2 extent)
{
+ const eViewLayerEEVEEPassType enabled_passes = inst_.film.enabled_passes_get();
+
auto pass_extent = [&](eViewLayerEEVEEPassType pass_bit) -> int2 {
/* Use dummy texture for disabled passes. Allows correct bindings. */
- return (inst_.film.enabled_passes_get() & pass_bit) ? extent : int2(1);
+ return (enabled_passes & pass_bit) ? extent : int2(1);
};
eGPUTextureFormat color_format = GPU_RGBA16F;
@@ -38,17 +40,22 @@ void RenderBuffers::acquire(int2 extent)
depth_tx.acquire(extent, GPU_DEPTH24_STENCIL8);
combined_tx.acquire(extent, color_format);
- bool do_vector_render_pass = (inst_.film.enabled_passes_get() & EEVEE_RENDER_PASS_VECTOR) ||
+ bool do_vector_render_pass = (enabled_passes & EEVEE_RENDER_PASS_VECTOR) ||
(inst_.motion_blur.postfx_enabled() && !inst_.is_viewport());
+ uint32_t max_light_color_layer = max_ii(enabled_passes & EEVEE_RENDER_PASS_DIFFUSE_LIGHT ?
+ (int)RENDER_PASS_LAYER_DIFFUSE_LIGHT :
+ -1,
+ enabled_passes & EEVEE_RENDER_PASS_SPECULAR_LIGHT ?
+ (int)RENDER_PASS_LAYER_SPECULAR_LIGHT :
+ -1) +
+ 1;
/* Only RG16F when only doing only reprojection or motion blur. */
eGPUTextureFormat vector_format = do_vector_render_pass ? GPU_RGBA16F : GPU_RG16F;
/* TODO(fclem): Make vector pass allocation optional if no TAA or motion blur is needed. */
vector_tx.acquire(extent, vector_format);
normal_tx.acquire(pass_extent(EEVEE_RENDER_PASS_NORMAL), color_format);
- diffuse_light_tx.acquire(pass_extent(EEVEE_RENDER_PASS_DIFFUSE_LIGHT), color_format);
diffuse_color_tx.acquire(pass_extent(EEVEE_RENDER_PASS_DIFFUSE_COLOR), color_format);
- specular_light_tx.acquire(pass_extent(EEVEE_RENDER_PASS_SPECULAR_LIGHT), color_format);
specular_color_tx.acquire(pass_extent(EEVEE_RENDER_PASS_SPECULAR_COLOR), color_format);
volume_light_tx.acquire(pass_extent(EEVEE_RENDER_PASS_VOLUME_LIGHT), color_format);
emission_tx.acquire(pass_extent(EEVEE_RENDER_PASS_EMIT), color_format);
@@ -56,11 +63,29 @@ void RenderBuffers::acquire(int2 extent)
shadow_tx.acquire(pass_extent(EEVEE_RENDER_PASS_SHADOW), float_format);
ambient_occlusion_tx.acquire(pass_extent(EEVEE_RENDER_PASS_AO), float_format);
+ light_tx.ensure_2d_array(color_format,
+ max_light_color_layer > 0 ? extent : int2(1),
+ max_ii(1, max_light_color_layer));
+
const AOVsInfoData &aovs = inst_.film.aovs_info;
aov_color_tx.ensure_2d_array(
color_format, (aovs.color_len > 0) ? extent : int2(1), max_ii(1, aovs.color_len));
aov_value_tx.ensure_2d_array(
float_format, (aovs.value_len > 0) ? extent : int2(1), max_ii(1, aovs.value_len));
+
+ eGPUTextureFormat cryptomatte_format = GPU_R32F;
+ const int cryptomatte_layer_len = inst_.film.cryptomatte_layer_max_get();
+ if (cryptomatte_layer_len == 2) {
+ cryptomatte_format = GPU_RG32F;
+ }
+ else if (cryptomatte_layer_len == 3) {
+ cryptomatte_format = GPU_RGBA32F;
+ }
+ cryptomatte_tx.acquire(
+ pass_extent(static_cast<eViewLayerEEVEEPassType>(EEVEE_RENDER_PASS_CRYPTOMATTE_OBJECT |
+ EEVEE_RENDER_PASS_CRYPTOMATTE_ASSET |
+ EEVEE_RENDER_PASS_CRYPTOMATTE_MATERIAL)),
+ cryptomatte_format);
}
void RenderBuffers::release()
@@ -70,15 +95,14 @@ void RenderBuffers::release()
normal_tx.release();
vector_tx.release();
- diffuse_light_tx.release();
diffuse_color_tx.release();
- specular_light_tx.release();
specular_color_tx.release();
volume_light_tx.release();
emission_tx.release();
environment_tx.release();
shadow_tx.release();
ambient_occlusion_tx.release();
+ cryptomatte_tx.release();
}
} // namespace blender::eevee
diff --git a/source/blender/draw/engines/eevee_next/eevee_renderbuffers.hh b/source/blender/draw/engines/eevee_next/eevee_renderbuffers.hh
index 787f5604aa4..ae5d7fbae5c 100644
--- a/source/blender/draw/engines/eevee_next/eevee_renderbuffers.hh
+++ b/source/blender/draw/engines/eevee_next/eevee_renderbuffers.hh
@@ -28,17 +28,16 @@ class RenderBuffers {
// TextureFromPool mist_tx; /* Derived from depth_tx during accumulation. */
TextureFromPool normal_tx;
TextureFromPool vector_tx;
- TextureFromPool diffuse_light_tx;
TextureFromPool diffuse_color_tx;
- TextureFromPool specular_light_tx;
TextureFromPool specular_color_tx;
TextureFromPool volume_light_tx;
TextureFromPool emission_tx;
TextureFromPool environment_tx;
TextureFromPool shadow_tx;
TextureFromPool ambient_occlusion_tx;
- // TextureFromPool cryptomatte_tx; /* TODO */
+ TextureFromPool cryptomatte_tx;
/* TODO(fclem): Use texture from pool once they support texture array. */
+ Texture light_tx;
Texture aov_color_tx;
Texture aov_value_tx;
diff --git a/source/blender/draw/engines/eevee_next/eevee_sampling.hh b/source/blender/draw/engines/eevee_next/eevee_sampling.hh
index be87ee74886..c2bf23d20fc 100644
--- a/source/blender/draw/engines/eevee_next/eevee_sampling.hh
+++ b/source/blender/draw/engines/eevee_next/eevee_sampling.hh
@@ -87,6 +87,12 @@ class Sampling {
DRW_shgroup_storage_block_ref(grp, "sampling_buf", &data_);
}
+ template<typename T> void bind_resources(draw::detail::PassBase<T> *pass)
+ {
+ /* Storage Buf. */
+ pass->bind_ssbo(SAMPLING_BUF_SLOT, &data_);
+ }
+
/* Returns a pseudo random number in [0..1] range. Each dimension are de-correlated. */
float rng_get(eSamplingDimension dimension) const
{
diff --git a/source/blender/draw/engines/eevee_next/eevee_shader.cc b/source/blender/draw/engines/eevee_next/eevee_shader.cc
index a535d3407ac..05ff06e7435 100644
--- a/source/blender/draw/engines/eevee_next/eevee_shader.cc
+++ b/source/blender/draw/engines/eevee_next/eevee_shader.cc
@@ -9,6 +9,8 @@
* and static shader usage.
*/
+#include "GPU_capabilities.h"
+
#include "gpu_shader_create_info.hh"
#include "eevee_shader.hh"
@@ -82,6 +84,12 @@ const char *ShaderModule::static_shader_create_info_name_get(eShaderType shader_
return "eevee_film_frag";
case FILM_COMP:
return "eevee_film_comp";
+ case FILM_CRYPTOMATTE_POST:
+ return "eevee_film_cryptomatte_post";
+ case HIZ_DEBUG:
+ return "eevee_hiz_debug";
+ case HIZ_UPDATE:
+ return "eevee_hiz_update";
case MOTION_BLUR_GATHER:
return "eevee_motion_blur_gather";
case MOTION_BLUR_TILE_DILATE:
@@ -176,11 +184,41 @@ void ShaderModule::material_create_info_ammend(GPUMaterial *gpumat, GPUCodegenOu
GPUCodegenOutput &codegen = *codegen_;
ShaderCreateInfo &info = *reinterpret_cast<ShaderCreateInfo *>(codegen.create_info);
- info.auto_resource_location(true);
+ /* WORKAROUND: Replace by new ob info. */
+ int64_t ob_info_index = info.additional_infos_.first_index_of_try("draw_object_infos");
+ if (ob_info_index != -1) {
+ info.additional_infos_[ob_info_index] = "draw_object_infos_new";
+ }
+
+ /* WORKAROUND: Add new ob attr buffer. */
+ if (GPU_material_uniform_attributes(gpumat) != nullptr) {
+ info.additional_info("draw_object_attribute_new");
+ }
+
+ /* WORKAROUND: Avoid utility texture merge error. TODO: find a cleaner fix. */
+ for (auto &resource : info.batch_resources_) {
+ if (resource.bind_type == ShaderCreateInfo::Resource::BindType::SAMPLER) {
+ if (resource.slot == RBUFS_UTILITY_TEX_SLOT) {
+ resource.slot = GPU_max_textures_frag() - 1;
+ }
+ }
+ }
if (GPU_material_flag_get(gpumat, GPU_MATFLAG_TRANSPARENT)) {
info.define("MAT_TRANSPARENT");
+ /* Transparent material do not have any velocity specific pipeline. */
+ if (pipeline_type == MAT_PIPE_FORWARD_PREPASS_VELOCITY) {
+ pipeline_type = MAT_PIPE_FORWARD_PREPASS;
+ }
}
+
+ if (GPU_material_flag_get(gpumat, GPU_MATFLAG_TRANSPARENT) == false &&
+ pipeline_type == MAT_PIPE_FORWARD) {
+ /* Opaque forward do support AOVs and render pass. */
+ info.additional_info("eevee_aov_out");
+ info.additional_info("eevee_render_pass_out");
+ }
+
if (GPU_material_flag_get(gpumat, GPU_MATFLAG_BARYCENTRIC)) {
switch (geometry_type) {
case MAT_GEOM_MESH:
@@ -433,6 +471,8 @@ GPUMaterial *ShaderModule::material_shader_get(const char *name,
this);
GPU_material_status_set(gpumat, GPU_MAT_QUEUED);
GPU_material_compile(gpumat);
+ /* Queue deferred material optimization. */
+ DRW_shader_queue_optimize_material(gpumat);
return gpumat;
}
diff --git a/source/blender/draw/engines/eevee_next/eevee_shader.hh b/source/blender/draw/engines/eevee_next/eevee_shader.hh
index 5b43a1abf43..88538557c07 100644
--- a/source/blender/draw/engines/eevee_next/eevee_shader.hh
+++ b/source/blender/draw/engines/eevee_next/eevee_shader.hh
@@ -28,6 +28,7 @@ namespace blender::eevee {
enum eShaderType {
FILM_FRAG = 0,
FILM_COMP,
+ FILM_CRYPTOMATTE_POST,
DOF_BOKEH_LUT,
DOF_DOWNSAMPLE,
@@ -47,6 +48,9 @@ enum eShaderType {
DOF_TILES_DILATE_MINMAX,
DOF_TILES_FLATTEN,
+ HIZ_UPDATE,
+ HIZ_DEBUG,
+
LIGHT_CULLING_DEBUG,
LIGHT_CULLING_SELECT,
LIGHT_CULLING_SORT,
diff --git a/source/blender/draw/engines/eevee_next/eevee_shader_shared.hh b/source/blender/draw/engines/eevee_next/eevee_shader_shared.hh
index 885317fc673..8e96445d6b9 100644
--- a/source/blender/draw/engines/eevee_next/eevee_shader_shared.hh
+++ b/source/blender/draw/engines/eevee_next/eevee_shader_shared.hh
@@ -12,16 +12,16 @@
# include "BLI_memory_utils.hh"
# include "DRW_gpu_wrapper.hh"
+# include "draw_manager.hh"
+# include "draw_pass.hh"
+
# include "eevee_defines.hh"
# include "GPU_shader_shared.h"
namespace blender::eevee {
-using draw::Framebuffer;
-using draw::SwapChain;
-using draw::Texture;
-using draw::TextureFromPool;
+using namespace draw;
constexpr eGPUSamplerState no_filter = GPU_SAMPLER_DEFAULT;
constexpr eGPUSamplerState with_filter = GPU_SAMPLER_FILTER;
@@ -38,40 +38,44 @@ constexpr eGPUSamplerState with_filter = GPU_SAMPLER_FILTER;
enum eDebugMode : uint32_t {
DEBUG_NONE = 0u,
/**
- * Gradient showing light evaluation hotspots.
+ * Gradient showing light evaluation hot-spots.
*/
DEBUG_LIGHT_CULLING = 1u,
/**
- * Tilemaps to screen. Is also present in other modes.
+ * Show incorrectly downsample tiles in red.
+ */
+ DEBUG_HIZ_VALIDATION = 2u,
+ /**
+ * Tile-maps to screen. Is also present in other modes.
* - Black pixels, no pages allocated.
* - Green pixels, pages cached.
* - Red pixels, pages allocated.
*/
- DEBUG_SHADOW_TILEMAPS = 2u,
+ DEBUG_SHADOW_TILEMAPS = 10u,
/**
* Random color per pages. Validates page density allocation and sampling.
*/
- DEBUG_SHADOW_PAGES = 3u,
+ DEBUG_SHADOW_PAGES = 11u,
/**
- * Outputs random color per tilemap (or tilemap level). Validates tilemaps coverage.
- * Black means not covered by any tilemaps LOD of the shadow.
+ * Outputs random color per tile-map (or tile-map level). Validates tile-maps coverage.
+ * Black means not covered by any tile-maps LOD of the shadow.
*/
- DEBUG_SHADOW_LOD = 4u,
+ DEBUG_SHADOW_LOD = 12u,
/**
* Outputs white pixels for pages allocated and black pixels for unused pages.
* This needs DEBUG_SHADOW_PAGE_ALLOCATION_ENABLED defined in order to work.
*/
- DEBUG_SHADOW_PAGE_ALLOCATION = 5u,
+ DEBUG_SHADOW_PAGE_ALLOCATION = 13u,
/**
- * Outputs the tilemap atlas. Default tilemap is too big for the usual screen resolution.
+ * Outputs the tile-map atlas. Default tile-map is too big for the usual screen resolution.
* Try lowering SHADOW_TILEMAP_PER_ROW and SHADOW_MAX_TILEMAP before using this option.
*/
- DEBUG_SHADOW_TILE_ALLOCATION = 6u,
+ DEBUG_SHADOW_TILE_ALLOCATION = 14u,
/**
* Visualize linear depth stored in the atlas regions of the active light.
* This way, one can check if the rendering, the copying and the shadow sampling functions works.
*/
- DEBUG_SHADOW_SHADOW_DEPTH = 7u
+ DEBUG_SHADOW_SHADOW_DEPTH = 15u
};
/** \} */
@@ -190,6 +194,17 @@ BLI_STATIC_ASSERT_ALIGN(CameraData, 16)
#define FILM_PRECOMP_SAMPLE_MAX 16
+enum eFilmWeightLayerIndex : uint32_t {
+ FILM_WEIGHT_LAYER_ACCUMULATION = 0u,
+ FILM_WEIGHT_LAYER_DISTANCE = 1u,
+};
+
+enum ePassStorageType : uint32_t {
+ PASS_STORAGE_COLOR = 0u,
+ PASS_STORAGE_VALUE = 1u,
+ PASS_STORAGE_CRYPTOMATTE = 2u,
+};
+
struct FilmSample {
int2 texel;
float weight;
@@ -246,13 +261,19 @@ struct FilmData {
int combined_id;
/** Id of the render-pass to be displayed. -1 for combined. */
int display_id;
- /** True if the render-pass to be displayed is from the value accum buffer. */
- bool1 display_is_value;
+ /** Storage type of the render-pass to be displayed. */
+ ePassStorageType display_storage_type;
/** True if we bypass the accumulation and directly output the accumulation buffer. */
bool1 display_only;
/** Start of AOVs and number of aov. */
int aov_color_id, aov_color_len;
int aov_value_id, aov_value_len;
+ /** Start of cryptomatte per layer (-1 if pass is not enabled). */
+ int cryptomatte_object_id;
+ int cryptomatte_asset_id;
+ int cryptomatte_material_id;
+ /** Max number of samples stored per layer (is even number). */
+ int cryptomatte_samples_len;
/** Settings to render mist pass */
float mist_scale, mist_bias, mist_exponent;
/** Scene exposure used for better noise reduction. */
@@ -288,6 +309,17 @@ static inline float film_filter_weight(float filter_radius, float sample_distanc
/** \} */
/* -------------------------------------------------------------------- */
+/** \name Render passes
+ * \{ */
+
+enum eRenderPassLayerIndex : uint32_t {
+ RENDER_PASS_LAYER_DIFFUSE_LIGHT = 0u,
+ RENDER_PASS_LAYER_SPECULAR_LIGHT = 1u,
+};
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name Arbitrary Output Variables
* \{ */
@@ -613,6 +645,20 @@ BLI_STATIC_ASSERT_ALIGN(LightData, 16)
/** \} */
/* -------------------------------------------------------------------- */
+/** \name Hierarchical-Z Buffer
+ * \{ */
+
+struct HiZData {
+ /** Scale factor to remove HiZBuffer padding. */
+ float2 uv_scale;
+
+ float2 _pad0;
+};
+BLI_STATIC_ASSERT_ALIGN(HiZData, 16)
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name Ray-Tracing
* \{ */
@@ -699,22 +745,24 @@ float4 utility_tx_sample(sampler2DArray util_tx, float2 uv, float layer)
using AOVsInfoDataBuf = draw::StorageBuffer<AOVsInfoData>;
using CameraDataBuf = draw::UniformBuffer<CameraData>;
-using LightDataBuf = draw::StorageArrayBuffer<LightData, LIGHT_CHUNK>;
+using DepthOfFieldDataBuf = draw::UniformBuffer<DepthOfFieldData>;
+using DepthOfFieldScatterListBuf = draw::StorageArrayBuffer<ScatterRect, 16, true>;
+using DrawIndirectBuf = draw::StorageBuffer<DrawCommand, true>;
+using FilmDataBuf = draw::UniformBuffer<FilmData>;
+using HiZDataBuf = draw::UniformBuffer<HiZData>;
using LightCullingDataBuf = draw::StorageBuffer<LightCullingData>;
using LightCullingKeyBuf = draw::StorageArrayBuffer<uint, LIGHT_CHUNK, true>;
using LightCullingTileBuf = draw::StorageArrayBuffer<uint, LIGHT_CHUNK, true>;
using LightCullingZbinBuf = draw::StorageArrayBuffer<uint, CULLING_ZBIN_COUNT, true>;
using LightCullingZdistBuf = draw::StorageArrayBuffer<float, LIGHT_CHUNK, true>;
-using DepthOfFieldDataBuf = draw::UniformBuffer<DepthOfFieldData>;
-using DepthOfFieldScatterListBuf = draw::StorageArrayBuffer<ScatterRect, 16, true>;
-using DrawIndirectBuf = draw::StorageBuffer<DrawCommand, true>;
-using FilmDataBuf = draw::UniformBuffer<FilmData>;
+using LightDataBuf = draw::StorageArrayBuffer<LightData, LIGHT_CHUNK>;
using MotionBlurDataBuf = draw::UniformBuffer<MotionBlurData>;
using MotionBlurTileIndirectionBuf = draw::StorageBuffer<MotionBlurTileIndirection, true>;
using SamplingDataBuf = draw::StorageBuffer<SamplingData>;
using VelocityGeometryBuf = draw::StorageArrayBuffer<float4, 16, true>;
using VelocityIndexBuf = draw::StorageArrayBuffer<VelocityIndex, 16>;
using VelocityObjectBuf = draw::StorageArrayBuffer<float4x4, 16>;
+using CryptomatteObjectBuf = draw::StorageArrayBuffer<float2, 16>;
} // namespace blender::eevee
#endif
diff --git a/source/blender/draw/engines/eevee_next/eevee_sync.cc b/source/blender/draw/engines/eevee_next/eevee_sync.cc
index e2d4b0ac1c2..09ea7c9ec3d 100644
--- a/source/blender/draw/engines/eevee_next/eevee_sync.cc
+++ b/source/blender/draw/engines/eevee_next/eevee_sync.cc
@@ -74,25 +74,12 @@ WorldHandle &SyncModule::sync_world(::World *world)
/** \name Common
* \{ */
-static inline void shgroup_geometry_call(DRWShadingGroup *grp,
- Object *ob,
- GPUBatch *geom,
- int v_first = -1,
- int v_count = -1,
- bool use_instancing = false)
+static inline void geometry_call(PassMain::Sub *sub_pass,
+ GPUBatch *geom,
+ ResourceHandle resource_handle)
{
- if (grp == nullptr) {
- return;
- }
-
- if (v_first == -1) {
- DRW_shgroup_call(grp, geom, ob);
- }
- else if (use_instancing) {
- DRW_shgroup_call_instance_range(grp, ob, geom, v_first, v_count);
- }
- else {
- DRW_shgroup_call_range(grp, ob, geom, v_first, v_count);
+ if (sub_pass != nullptr) {
+ sub_pass->draw(geom, resource_handle);
}
}
@@ -102,9 +89,13 @@ static inline void shgroup_geometry_call(DRWShadingGroup *grp,
/** \name Mesh
* \{ */
-void SyncModule::sync_mesh(Object *ob, ObjectHandle &ob_handle)
+void SyncModule::sync_mesh(Object *ob,
+ ObjectHandle &ob_handle,
+ ResourceHandle res_handle,
+ const ObjectRef &ob_ref)
{
- bool has_motion = inst_.velocity.step_object_sync(ob, ob_handle.object_key, ob_handle.recalc);
+ bool has_motion = inst_.velocity.step_object_sync(
+ ob, ob_handle.object_key, res_handle, ob_handle.recalc);
MaterialArray &material_array = inst_.materials.material_array_get(ob, has_motion);
@@ -123,14 +114,20 @@ void SyncModule::sync_mesh(Object *ob, ObjectHandle &ob_handle)
continue;
}
Material *material = material_array.materials[i];
- shgroup_geometry_call(material->shading.shgrp, ob, geom);
- shgroup_geometry_call(material->prepass.shgrp, ob, geom);
- shgroup_geometry_call(material->shadow.shgrp, ob, geom);
+ geometry_call(material->shading.sub_pass, geom, res_handle);
+ geometry_call(material->prepass.sub_pass, geom, res_handle);
+ geometry_call(material->shadow.sub_pass, geom, res_handle);
- is_shadow_caster = is_shadow_caster || material->shadow.shgrp != nullptr;
+ is_shadow_caster = is_shadow_caster || material->shadow.sub_pass != nullptr;
is_alpha_blend = is_alpha_blend || material->is_alpha_blend_transparent;
+
+ GPUMaterial *gpu_material = material_array.gpu_materials[i];
+ ::Material *mat = GPU_material_get_material(gpu_material);
+ inst_.cryptomatte.sync_material(mat);
}
+ inst_.manager->extract_object_attributes(res_handle, ob_ref, material_array.gpu_materials);
+ inst_.cryptomatte.sync_object(ob, res_handle);
// shadows.sync_object(ob, ob_handle, is_shadow_caster, is_alpha_blend);
}
@@ -155,11 +152,13 @@ struct gpIterData {
int vcount = 0;
bool instancing = false;
- gpIterData(Instance &inst_, Object *ob_, ObjectHandle &ob_handle)
+ gpIterData(Instance &inst_, Object *ob_, ObjectHandle &ob_handle, ResourceHandle resource_handle)
: inst(inst_),
ob(ob_),
material_array(inst_.materials.material_array_get(
- ob_, inst_.velocity.step_object_sync(ob, ob_handle.object_key, ob_handle.recalc)))
+ ob_,
+ inst_.velocity.step_object_sync(
+ ob, ob_handle.object_key, resource_handle, ob_handle.recalc)))
{
cfra = DEG_get_ctime(inst.depsgraph);
};
@@ -167,26 +166,28 @@ struct gpIterData {
static void gpencil_drawcall_flush(gpIterData &iter)
{
+#if 0 /* Incompatible with new draw manager. */
if (iter.geom != nullptr) {
- shgroup_geometry_call(iter.material->shading.shgrp,
+ geometry_call(iter.material->shading.sub_pass,
iter.ob,
iter.geom,
iter.vfirst,
iter.vcount,
iter.instancing);
- shgroup_geometry_call(iter.material->prepass.shgrp,
+ geometry_call(iter.material->prepass.sub_pass,
iter.ob,
iter.geom,
iter.vfirst,
iter.vcount,
iter.instancing);
- shgroup_geometry_call(iter.material->shadow.shgrp,
+ geometry_call(iter.material->shadow.sub_pass,
iter.ob,
iter.geom,
iter.vfirst,
iter.vcount,
iter.instancing);
}
+#endif
iter.geom = nullptr;
iter.vfirst = -1;
iter.vcount = 0;
@@ -250,21 +251,22 @@ static void gpencil_stroke_sync(bGPDlayer *UNUSED(gpl),
}
}
-void SyncModule::sync_gpencil(Object *ob, ObjectHandle &ob_handle)
+void SyncModule::sync_gpencil(Object *ob, ObjectHandle &ob_handle, ResourceHandle res_handle)
{
/* TODO(fclem): Waiting for a user option to use the render engine instead of gpencil engine. */
if (true) {
inst_.gpencil_engine_enabled = true;
return;
}
+ UNUSED_VARS(res_handle);
- gpIterData iter(inst_, ob, ob_handle);
+ gpIterData iter(inst_, ob, ob_handle, res_handle);
BKE_gpencil_visible_stroke_iter((bGPdata *)ob->data, nullptr, gpencil_stroke_sync, &iter);
gpencil_drawcall_flush(iter);
- // bool is_caster = true; /* TODO material.shadow.shgrp. */
+ // bool is_caster = true; /* TODO material.shadow.sub_pass. */
// bool is_alpha_blend = true; /* TODO material.is_alpha_blend. */
// shadows.sync_object(ob, ob_handle, is_caster, is_alpha_blend);
}
@@ -280,19 +282,24 @@ static void shgroup_curves_call(MaterialPass &matpass,
ParticleSystem *part_sys = nullptr,
ModifierData *modifier_data = nullptr)
{
- if (matpass.shgrp == nullptr) {
+ UNUSED_VARS(ob, modifier_data);
+ if (matpass.sub_pass == nullptr) {
return;
}
if (part_sys != nullptr) {
- DRW_shgroup_hair_create_sub(ob, part_sys, modifier_data, matpass.shgrp, matpass.gpumat);
+ // DRW_shgroup_hair_create_sub(ob, part_sys, modifier_data, matpass.sub_pass, matpass.gpumat);
}
else {
- DRW_shgroup_curves_create_sub(ob, matpass.shgrp, matpass.gpumat);
+ // DRW_shgroup_curves_create_sub(ob, matpass.sub_pass, matpass.gpumat);
}
}
-void SyncModule::sync_curves(Object *ob, ObjectHandle &ob_handle, ModifierData *modifier_data)
+void SyncModule::sync_curves(Object *ob,
+ ObjectHandle &ob_handle,
+ ResourceHandle res_handle,
+ ModifierData *modifier_data)
{
+ UNUSED_VARS(res_handle);
int mat_nr = CURVES_MATERIAL_NR;
ParticleSystem *part_sys = nullptr;
@@ -317,10 +324,16 @@ void SyncModule::sync_curves(Object *ob, ObjectHandle &ob_handle, ModifierData *
shgroup_curves_call(material.prepass, ob, part_sys, modifier_data);
shgroup_curves_call(material.shadow, ob, part_sys, modifier_data);
+ inst_.cryptomatte.sync_object(ob, res_handle);
+ GPUMaterial *gpu_material =
+ inst_.materials.material_array_get(ob, has_motion).gpu_materials[mat_nr - 1];
+ ::Material *mat = GPU_material_get_material(gpu_material);
+ inst_.cryptomatte.sync_material(mat);
+
/* TODO(fclem) Hair velocity. */
// shading_passes.velocity.gpencil_add(ob, ob_handle);
- // bool is_caster = material.shadow.shgrp != nullptr;
+ // bool is_caster = material.shadow.sub_pass != nullptr;
// bool is_alpha_blend = material.is_alpha_blend_transparent;
// shadows.sync_object(ob, ob_handle, is_caster, is_alpha_blend);
}
diff --git a/source/blender/draw/engines/eevee_next/eevee_sync.hh b/source/blender/draw/engines/eevee_next/eevee_sync.hh
index bd8147a2882..ab883ce44c2 100644
--- a/source/blender/draw/engines/eevee_next/eevee_sync.hh
+++ b/source/blender/draw/engines/eevee_next/eevee_sync.hh
@@ -150,9 +150,15 @@ class SyncModule {
ObjectHandle &sync_object(Object *ob);
WorldHandle &sync_world(::World *world);
- void sync_mesh(Object *ob, ObjectHandle &ob_handle);
- void sync_gpencil(Object *ob, ObjectHandle &ob_handle);
- void sync_curves(Object *ob, ObjectHandle &ob_handle, ModifierData *modifier_data = nullptr);
+ void sync_mesh(Object *ob,
+ ObjectHandle &ob_handle,
+ ResourceHandle res_handle,
+ const ObjectRef &ob_ref);
+ void sync_gpencil(Object *ob, ObjectHandle &ob_handle, ResourceHandle res_handle);
+ void sync_curves(Object *ob,
+ ObjectHandle &ob_handle,
+ ResourceHandle res_handle,
+ ModifierData *modifier_data = nullptr);
};
/** \} */
diff --git a/source/blender/draw/engines/eevee_next/eevee_velocity.cc b/source/blender/draw/engines/eevee_next/eevee_velocity.cc
index 36734f0c28c..7af311a8ccc 100644
--- a/source/blender/draw/engines/eevee_next/eevee_velocity.cc
+++ b/source/blender/draw/engines/eevee_next/eevee_velocity.cc
@@ -43,6 +43,10 @@ void VelocityModule::init()
step_ = STEP_CURRENT;
/* Let the main sync loop handle the current step. */
}
+
+ /* For viewport, only previous motion is supported.
+ * Still bind previous step to avoid undefined behavior. */
+ next_step_ = inst_.is_viewport() ? STEP_PREVIOUS : STEP_NEXT;
}
static void step_object_sync_render(void *velocity,
@@ -51,7 +55,9 @@ static void step_object_sync_render(void *velocity,
Depsgraph *UNUSED(depsgraph))
{
ObjectKey object_key(ob);
- reinterpret_cast<VelocityModule *>(velocity)->step_object_sync(ob, object_key);
+ /* NOTE: Dummy resource handle since this will not be used for drawing. */
+ ResourceHandle resource_handle(0);
+ reinterpret_cast<VelocityModule *>(velocity)->step_object_sync(ob, object_key, resource_handle);
}
void VelocityModule::step_sync(eVelocityStep step, float time)
@@ -78,6 +84,7 @@ void VelocityModule::step_camera_sync()
bool VelocityModule::step_object_sync(Object *ob,
ObjectKey &object_key,
+ ResourceHandle resource_handle,
int /*IDRecalcFlag*/ recalc)
{
bool has_motion = object_has_velocity(ob) || (recalc & ID_RECALC_TRANSFORM);
@@ -89,8 +96,6 @@ bool VelocityModule::step_object_sync(Object *ob,
return false;
}
- uint32_t resource_id = DRW_object_resource_id_get(ob);
-
/* Object motion. */
/* FIXME(fclem) As we are using original objects pointers, there is a chance the previous
* object key matches a totally different object if the scene was changed by user or python
@@ -99,7 +104,7 @@ bool VelocityModule::step_object_sync(Object *ob,
* We live with that until we have a correct way of identifying new objects. */
VelocityObjectData &vel = velocity_map.lookup_or_add_default(object_key);
vel.obj.ofs[step_] = object_steps_usage[step_]++;
- vel.obj.resource_id = resource_id;
+ vel.obj.resource_id = resource_handle.resource_index();
vel.id = (ID *)ob->data;
object_steps[step_]->get_or_resize(vel.obj.ofs[step_]) = ob->obmat;
if (step_ == STEP_CURRENT) {
@@ -257,7 +262,7 @@ void VelocityModule::end_sync()
uint32_t max_resource_id_ = 0u;
for (Map<ObjectKey, VelocityObjectData>::Item item : velocity_map.items()) {
- if (item.value.obj.resource_id == (uint)-1) {
+ if (item.value.obj.resource_id == (uint32_t)-1) {
deleted_obj.append(item.key);
}
else {
@@ -273,11 +278,11 @@ void VelocityModule::end_sync()
inst_.sampling.reset();
}
- for (auto key : deleted_obj) {
+ for (auto &key : deleted_obj) {
velocity_map.remove(key);
}
- indirection_buf.resize(power_of_2_max_u(max_resource_id_ + 1));
+ indirection_buf.resize(ceil_to_multiple_u(max_resource_id_, 128));
/* Avoid uploading more data to the GPU as well as an extra level of
* indirection on the GPU by copying back offsets the to VelocityIndex. */
diff --git a/source/blender/draw/engines/eevee_next/eevee_velocity.hh b/source/blender/draw/engines/eevee_next/eevee_velocity.hh
index 01b8a5fb8c1..6f18b05d476 100644
--- a/source/blender/draw/engines/eevee_next/eevee_velocity.hh
+++ b/source/blender/draw/engines/eevee_next/eevee_velocity.hh
@@ -67,7 +67,10 @@ class VelocityModule {
private:
Instance &inst_;
+ /** Step being synced. */
eVelocityStep step_ = STEP_CURRENT;
+ /** Step referenced as next step. */
+ eVelocityStep next_step_ = STEP_NEXT;
public:
VelocityModule(Instance &inst) : inst_(inst)
@@ -102,7 +105,10 @@ class VelocityModule {
void step_sync(eVelocityStep step, float time);
/* Gather motion data. Returns true if the object **can** have motion. */
- bool step_object_sync(Object *ob, ObjectKey &object_key, int recalc = 0);
+ bool step_object_sync(Object *ob,
+ ObjectKey &object_key,
+ ResourceHandle resource_handle,
+ int recalc = 0);
/* Moves next frame data to previous frame data. Nullify next frame data. */
void step_swap();
@@ -112,6 +118,20 @@ class VelocityModule {
void bind_resources(DRWShadingGroup *grp);
+ template<typename T> void bind_resources(draw::detail::Pass<T> *pass)
+ {
+ /* Storage Buf. */
+ pass->bind_ssbo(VELOCITY_OBJ_PREV_BUF_SLOT, &(*object_steps[STEP_PREVIOUS]));
+ pass->bind_ssbo(VELOCITY_OBJ_NEXT_BUF_SLOT, &(*object_steps[next_step_]));
+ pass->bind_ssbo(VELOCITY_GEO_PREV_BUF_SLOT, &(*geometry_steps[STEP_PREVIOUS]));
+ pass->bind_ssbo(VELOCITY_GEO_NEXT_BUF_SLOT, &(*geometry_steps[next_step_]));
+ pass->bind_ssbo(VELOCITY_INDIRECTION_BUF_SLOT, &indirection_buf);
+ /* Uniform Buf. */
+ pass->bind_ubo(VELOCITY_CAMERA_PREV_BUF, &(*camera_steps[STEP_PREVIOUS]));
+ pass->bind_ubo(VELOCITY_CAMERA_CURR_BUF, &(*camera_steps[STEP_CURRENT]));
+ pass->bind_ubo(VELOCITY_CAMERA_NEXT_BUF, &(*camera_steps[next_step_]));
+ }
+
bool camera_has_motion() const;
bool camera_changed_projection() const;
diff --git a/source/blender/draw/engines/eevee_next/eevee_view.cc b/source/blender/draw/engines/eevee_next/eevee_view.cc
index b7154465a70..48951c2bae7 100644
--- a/source/blender/draw/engines/eevee_next/eevee_view.cc
+++ b/source/blender/draw/engines/eevee_next/eevee_view.cc
@@ -102,6 +102,8 @@ void ShadingView::render()
update_view();
+ inst_.hiz_buffer.set_dirty();
+
DRW_stats_group_start(name_);
DRW_view_set_active(render_view_);
@@ -116,10 +118,10 @@ void ShadingView::render()
GPU_framebuffer_bind(combined_fb_);
GPU_framebuffer_clear_color_depth(combined_fb_, clear_color, 1.0f);
- inst_.pipelines.world.render();
+ inst_.pipelines.world.render(render_view_new_);
/* TODO(fclem): Move it after the first prepass (and hiz update) once pipeline is stabilized. */
- inst_.lights.set_view(render_view_, extent_);
+ inst_.lights.set_view(render_view_new_, extent_);
// inst_.pipelines.deferred.render(
// render_view_, rt_buffer_opaque_, rt_buffer_refract_, depth_tx_, combined_tx_);
@@ -128,10 +130,10 @@ void ShadingView::render()
// inst_.lookdev.render_overlay(view_fb_);
- inst_.pipelines.forward.render(
- render_view_, prepass_fb_, combined_fb_, rbufs.depth_tx, rbufs.combined_tx);
+ inst_.pipelines.forward.render(render_view_new_, prepass_fb_, combined_fb_, rbufs.combined_tx);
- inst_.lights.debug_draw(combined_fb_);
+ inst_.lights.debug_draw(render_view_new_, combined_fb_);
+ inst_.hiz_buffer.debug_draw(render_view_new_, combined_fb_);
GPUTexture *combined_final_tx = render_postfx(rbufs.combined_tx);
@@ -155,8 +157,8 @@ GPUTexture *ShadingView::render_postfx(GPUTexture *input_tx)
GPUTexture *output_tx = postfx_tx_;
/* Swapping is done internally. Actual output is set to the next input. */
- inst_.depth_of_field.render(&input_tx, &output_tx, dof_buffer_);
- inst_.motion_blur.render(&input_tx, &output_tx);
+ inst_.depth_of_field.render(render_view_new_, &input_tx, &output_tx, dof_buffer_);
+ inst_.motion_blur.render(render_view_new_, &input_tx, &output_tx);
return input_tx;
}
@@ -184,6 +186,8 @@ void ShadingView::update_view()
* out of the blurring radius. To fix this, use custom enlarged culling matrix. */
inst_.depth_of_field.jitter_apply(winmat, viewmat);
DRW_view_update_sub(render_view_, viewmat.ptr(), winmat.ptr());
+
+ render_view_new_.sync(viewmat, winmat);
}
/** \} */
diff --git a/source/blender/draw/engines/eevee_next/eevee_view.hh b/source/blender/draw/engines/eevee_next/eevee_view.hh
index 65f27aba795..74e513357cd 100644
--- a/source/blender/draw/engines/eevee_next/eevee_view.hh
+++ b/source/blender/draw/engines/eevee_next/eevee_view.hh
@@ -57,6 +57,7 @@ class ShadingView {
DRWView *sub_view_ = nullptr;
/** Same as sub_view_ but has Depth Of Field jitter applied. */
DRWView *render_view_ = nullptr;
+ View render_view_new_;
/** Render size of the view. Can change between scene sample eval. */
int2 extent_ = {-1, -1};
@@ -65,7 +66,7 @@ class ShadingView {
public:
ShadingView(Instance &inst, const char *name, const float (*face_matrix)[4])
- : inst_(inst), name_(name), face_matrix_(face_matrix){};
+ : inst_(inst), name_(name), face_matrix_(face_matrix), render_view_new_(name){};
~ShadingView(){};
diff --git a/source/blender/draw/engines/eevee_next/eevee_world.cc b/source/blender/draw/engines/eevee_next/eevee_world.cc
index 56cb0f127db..313c0bda42e 100644
--- a/source/blender/draw/engines/eevee_next/eevee_world.cc
+++ b/source/blender/draw/engines/eevee_next/eevee_world.cc
@@ -42,10 +42,10 @@ DefaultWorldNodeTree::~DefaultWorldNodeTree()
MEM_SAFE_FREE(ntree_);
}
-/* Configure a default nodetree with the given world. */
+/* Configure a default node-tree with the given world. */
bNodeTree *DefaultWorldNodeTree::nodetree_get(::World *wo)
{
- /* WARNING: This function is not threadsafe. Which is not a problem for the moment. */
+ /* WARNING: This function is not thread-safe. Which is not a problem for the moment. */
copy_v3_fl3(color_socket_->value, wo->horr, wo->horg, wo->horb);
return ntree_;
}
diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_cryptomatte_lib.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_cryptomatte_lib.glsl
new file mode 100644
index 00000000000..e874a6b56ea
--- /dev/null
+++ b/source/blender/draw/engines/eevee_next/shaders/eevee_cryptomatte_lib.glsl
@@ -0,0 +1,70 @@
+/** Storing/merging and sorting cryptomatte samples. */
+
+bool cryptomatte_can_merge_sample(vec2 dst, vec2 src)
+{
+ if (dst == vec2(0.0, 0.0)) {
+ return true;
+ }
+ if (dst.x == src.x) {
+ return true;
+ }
+ return false;
+}
+
+vec2 cryptomatte_merge_sample(vec2 dst, vec2 src)
+{
+ return vec2(src.x, dst.y + src.y);
+}
+
+vec4 cryptomatte_false_color(float hash)
+{
+ uint m3hash = floatBitsToUint(hash);
+ return vec4(hash,
+ float(m3hash << 8) / float(0xFFFFFFFFu),
+ float(m3hash << 16) / float(0xFFFFFFFFu),
+ 1.0);
+}
+
+void cryptomatte_clear_samples(FilmSample dst)
+{
+ int layer_len = imageSize(cryptomatte_img).z;
+ for (int i = 0; i < layer_len; i++) {
+ imageStore(cryptomatte_img, ivec3(dst.texel, i), vec4(0.0));
+ }
+}
+
+void cryptomatte_store_film_sample(FilmSample dst,
+ int cryptomatte_layer_id,
+ vec2 crypto_sample,
+ out vec4 out_color)
+{
+ if (crypto_sample.y == 0.0) {
+ return;
+ }
+ for (int i = 0; i < film_buf.cryptomatte_samples_len / 2; i++) {
+ ivec3 img_co = ivec3(dst.texel, cryptomatte_layer_id + i);
+ vec4 sample_pair = imageLoad(cryptomatte_img, img_co);
+ if (cryptomatte_can_merge_sample(sample_pair.xy, crypto_sample)) {
+ sample_pair.xy = cryptomatte_merge_sample(sample_pair.xy, crypto_sample);
+ /* In viewport only one layer is active. */
+ /* TODO(jbakker): we are displaying the first sample, but we should display the highest
+ * weighted one. */
+ if (cryptomatte_layer_id + i == 0) {
+ out_color = cryptomatte_false_color(sample_pair.x);
+ }
+ }
+ else if (cryptomatte_can_merge_sample(sample_pair.zw, crypto_sample)) {
+ sample_pair.zw = cryptomatte_merge_sample(sample_pair.zw, crypto_sample);
+ }
+ else if (i == film_buf.cryptomatte_samples_len / 2 - 1) {
+ /* TODO(jbakker): New hash detected, but there is no space left to store it. Currently we
+ * will ignore this sample, but ideally we could replace a sample with a lowest weight. */
+ continue;
+ }
+ else {
+ continue;
+ }
+ imageStore(cryptomatte_img, img_co, sample_pair);
+ break;
+ }
+}
diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_depth_of_field_accumulator_lib.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_depth_of_field_accumulator_lib.glsl
index 57f229feedb..99a47c541e9 100644
--- a/source/blender/draw/engines/eevee_next/shaders/eevee_depth_of_field_accumulator_lib.glsl
+++ b/source/blender/draw/engines/eevee_next/shaders/eevee_depth_of_field_accumulator_lib.glsl
@@ -665,7 +665,7 @@ void dof_slight_focus_gather(sampler2D depth_tx,
dof_gather_accumulate_resolve(total_sample_count, bg_accum, bg_col, bg_weight, unused_occlusion);
dof_gather_accumulate_resolve(total_sample_count, fg_accum, fg_col, fg_weight, unused_occlusion);
- /* Fix weighting issues on perfectly focus to slight focus transitionning areas. */
+ /* Fix weighting issues on perfectly focus to slight focus transitioning areas. */
if (abs(center_data.coc) < 0.5) {
bg_col = center_data.color;
bg_weight = 1.0;
diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_depth_of_field_filter_comp.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_depth_of_field_filter_comp.glsl
index c5c0e210109..49c93ca63cd 100644
--- a/source/blender/draw/engines/eevee_next/shaders/eevee_depth_of_field_filter_comp.glsl
+++ b/source/blender/draw/engines/eevee_next/shaders/eevee_depth_of_field_filter_comp.glsl
@@ -134,8 +134,8 @@ void main()
{
/**
* NOTE: We can **NOT** optimize by discarding some tiles as the result is sampled using bilinear
- * filtering in the resolve pass. Not outputing to a tile means that border texels have undefined
- * value and tile border will be noticeable in the final image.
+ * filtering in the resolve pass. Not outputting to a tile means that border texels have
+ * undefined value and tile border will be noticeable in the final image.
*/
cache_init();
diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_depth_of_field_gather_comp.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_depth_of_field_gather_comp.glsl
index e9905cd8aaf..cf8dd7a36e6 100644
--- a/source/blender/draw/engines/eevee_next/shaders/eevee_depth_of_field_gather_comp.glsl
+++ b/source/blender/draw/engines/eevee_next/shaders/eevee_depth_of_field_gather_comp.glsl
@@ -2,8 +2,8 @@
/**
* Gather pass: Convolve foreground and background parts in separate passes.
*
- * Using the min&max CoC tile buffer, we select the best apropriate method to blur the scene color.
- * A fast gather path is taken if there is not many CoC variation inside the tile.
+ * Using the min&max CoC tile buffer, we select the best appropriate method to blur the scene
+ *color. A fast gather path is taken if there is not many CoC variation inside the tile.
*
* We sample using an octaweb sampling pattern. We randomize the kernel center and each ring
* rotation to ensure maximum coverage.
diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_depth_of_field_hole_fill_comp.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_depth_of_field_hole_fill_comp.glsl
index 2b664520bba..5cdabbc2d4b 100644
--- a/source/blender/draw/engines/eevee_next/shaders/eevee_depth_of_field_hole_fill_comp.glsl
+++ b/source/blender/draw/engines/eevee_next/shaders/eevee_depth_of_field_hole_fill_comp.glsl
@@ -2,8 +2,8 @@
/**
* Holefill pass: Gather background parts where foreground is present.
*
- * Using the min&max CoC tile buffer, we select the best apropriate method to blur the scene color.
- * A fast gather path is taken if there is not many CoC variation inside the tile.
+ * Using the min&max CoC tile buffer, we select the best appropriate method to blur the scene
+ *color. A fast gather path is taken if there is not many CoC variation inside the tile.
*
* We sample using an octaweb sampling pattern. We randomize the kernel center and each ring
* rotation to ensure maximum coverage.
diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_depth_of_field_reduce_comp.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_depth_of_field_reduce_comp.glsl
index c757e8304ac..a6426cd06e4 100644
--- a/source/blender/draw/engines/eevee_next/shaders/eevee_depth_of_field_reduce_comp.glsl
+++ b/source/blender/draw/engines/eevee_next/shaders/eevee_depth_of_field_reduce_comp.glsl
@@ -8,7 +8,7 @@
* Inputs:
* - Output of setup pass (halfres) and reduce downsample pass (quarter res).
* Outputs:
- * - Halfres padded to avoid mipmap mis-alignment (so possibly not matching input size).
+ * - Halfres padded to avoid mipmap misalignment (so possibly not matching input size).
* - Gather input color (whole mip chain), Scatter rect list, Signed CoC (whole mip chain).
**/
@@ -98,7 +98,7 @@ void main()
do_scatter[LOCAL_INDEX] *= dof_scatter_screen_border_rejection(coc_cache[LOCAL_INDEX], texel);
/* Only scatter if neighborhood is different enough. */
do_scatter[LOCAL_INDEX] *= dof_scatter_neighborhood_rejection(color_cache[LOCAL_INDEX].rgb);
- /* For debuging. */
+ /* For debugging. */
if (no_scatter_pass) {
do_scatter[LOCAL_INDEX] = 0.0;
}
@@ -133,9 +133,9 @@ void main()
/* Issue a sprite for each field if any CoC matches. */
if (any(lessThan(do_scatter4 * sign(coc4), vec4(0.0)))) {
/* Same value for all threads. Not an issue if we don't sync access to it. */
- scatter_fg_indirect_buf.v_count = 4u;
+ scatter_fg_indirect_buf.vertex_len = 4u;
/* Issue 1 strip instance per sprite. */
- uint rect_id = atomicAdd(scatter_fg_indirect_buf.i_count, 1u);
+ uint rect_id = atomicAdd(scatter_fg_indirect_buf.instance_len, 1u);
if (rect_id < dof_buf.scatter_max_rect) {
vec4 coc4_fg = max(vec4(0.0), -coc4);
@@ -166,9 +166,9 @@ void main()
}
if (any(greaterThan(do_scatter4 * sign(coc4), vec4(0.0)))) {
/* Same value for all threads. Not an issue if we don't sync access to it. */
- scatter_bg_indirect_buf.v_count = 4u;
+ scatter_bg_indirect_buf.vertex_len = 4u;
/* Issue 1 strip instance per sprite. */
- uint rect_id = atomicAdd(scatter_bg_indirect_buf.i_count, 1u);
+ uint rect_id = atomicAdd(scatter_bg_indirect_buf.instance_len, 1u);
if (rect_id < dof_buf.scatter_max_rect) {
vec4 coc4_bg = max(vec4(0.0), coc4);
vec4 bg_weights = dof_layer_weight(coc4_bg) * dof_sample_weight(coc4_bg) * do_scatter4;
diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_depth_of_field_resolve_comp.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_depth_of_field_resolve_comp.glsl
index d21f6d69541..5123eb0c238 100644
--- a/source/blender/draw/engines/eevee_next/shaders/eevee_depth_of_field_resolve_comp.glsl
+++ b/source/blender/draw/engines/eevee_next/shaders/eevee_depth_of_field_resolve_comp.glsl
@@ -36,7 +36,7 @@ float dof_slight_focus_coc_tile_get(vec2 frag_coord)
}
/* Use atomic reduce operation. */
atomicMax(shared_max_slight_focus_abs_coc, floatBitsToUint(local_abs_max));
- /* "Broadcast" result accross all threads. */
+ /* "Broadcast" result across all threads. */
barrier();
return uintBitsToFloat(shared_max_slight_focus_abs_coc);
@@ -44,7 +44,7 @@ float dof_slight_focus_coc_tile_get(vec2 frag_coord)
vec3 dof_neighborhood_clamp(vec2 frag_coord, vec3 color, float center_coc, float weight)
{
- /* Stabilize color by clamping with the stable half res neighboorhood. */
+ /* Stabilize color by clamping with the stable half res neighborhood. */
vec3 neighbor_min, neighbor_max;
const vec2 corners[4] = vec2[4](vec2(-1, -1), vec2(1, -1), vec2(-1, 1), vec2(1, 1));
for (int i = 0; i < 4; i++) {
@@ -165,7 +165,7 @@ void main()
out_color = out_color * (1.0 - layer_weight) + layer_color;
}
- /* Fix float precision issue in alpha compositing. */
+ /* Fix float precision issue in alpha compositing. */
if (out_color.a > 0.99) {
out_color.a = 1.0;
}
diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_depth_of_field_stabilize_comp.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_depth_of_field_stabilize_comp.glsl
index b22af0e88f0..46a25b84840 100644
--- a/source/blender/draw/engines/eevee_next/shaders/eevee_depth_of_field_stabilize_comp.glsl
+++ b/source/blender/draw/engines/eevee_next/shaders/eevee_depth_of_field_stabilize_comp.glsl
@@ -83,7 +83,7 @@ void dof_cache_init()
barrier();
}
-/* Note: Sample color space is already in YCoCg space. */
+/* NOTE: Sample color space is already in YCoCg space. */
DofSample dof_fetch_input_sample(ivec2 offset)
{
ivec2 coord = offset + 1 + ivec2(gl_LocalInvocationID.xy);
@@ -211,7 +211,7 @@ vec2 dof_pixel_history_motion_vector(ivec2 texel_sample)
return vector.xy * vec2(textureSize(color_tx, 0));
}
-/* Load color using a special filter to avoid loosing detail.
+/* Load color using a special filter to avoid losing detail.
* \a texel is sample position with subpixel accuracy. */
DofSample dof_sample_history(vec2 input_texel)
{
@@ -285,17 +285,17 @@ float dof_history_blend_factor(
/* 5% of incoming color by default. */
float blend = 0.05;
- /* Blend less history if the pixel has substential velocity. */
+ /* Blend less history if the pixel has substantial velocity. */
/* NOTE(fclem): velocity threshold multiplied by 2 because of half resolution. */
blend = mix(blend, 0.20, saturate(velocity * 0.02 * 2.0));
/**
* "High Quality Temporal Supersampling" by Brian Karis at Siggraph 2014 (Slide 43)
- * Bias towards history if incomming pixel is near clamping. Reduces flicker.
+ * Bias towards history if incoming pixel is near clamping. Reduces flicker.
*/
float distance_to_luma_clip = min_v2(vec2(luma_history - luma_min, luma_max - luma_history));
/* Divide by bbox size to get a factor. 2 factor to compensate the line above. */
distance_to_luma_clip *= 2.0 * safe_rcp(luma_max - luma_min);
- /* Linearly blend when history gets bellow to 25% of the bbox size. */
+ /* Linearly blend when history gets below to 25% of the bbox size. */
blend *= saturate(distance_to_luma_clip * 4.0 + 0.1);
/* Progressively discard history until history CoC is twice as big as the filtered CoC.
* Note we use absolute diff here because we are not comparing neighbors and thus do not risk to
@@ -335,7 +335,7 @@ void main()
DofSample dst = dof_sample_history(history_texel);
- /* Get local color bounding box of source neighboorhood. */
+ /* Get local color bounding box of source neighborhood. */
DofNeighborhoodMinMax bbox = dof_neighbor_boundbox();
float blend = dof_history_blend_factor(velocity, history_texel, bbox, src, dst);
diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_film_cryptomatte_post_comp.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_film_cryptomatte_post_comp.glsl
new file mode 100644
index 00000000000..120edd9c35e
--- /dev/null
+++ b/source/blender/draw/engines/eevee_next/shaders/eevee_film_cryptomatte_post_comp.glsl
@@ -0,0 +1,77 @@
+#pragma BLENDER_REQUIRE(common_math_lib.glsl)
+
+#define CRYPTOMATTE_LEVELS_MAX 16
+
+void cryptomatte_load_samples(ivec2 texel, int layer, out vec2 samples[CRYPTOMATTE_LEVELS_MAX])
+{
+ int pass_len = divide_ceil(cryptomatte_samples_per_layer, 2);
+ int layer_id = layer * pass_len;
+
+ /* Read all samples from the cryptomatte layer. */
+ for (int p = 0; p < pass_len; p++) {
+ vec4 pass_sample = imageLoad(cryptomatte_img, ivec3(texel, p + layer_id));
+ samples[p * 2] = pass_sample.xy;
+ samples[p * 2 + 1] = pass_sample.zw;
+ }
+ for (int i = pass_len * 2; i < CRYPTOMATTE_LEVELS_MAX; i++) {
+ samples[i] = vec2(0.0);
+ }
+}
+
+void cryptomatte_sort_samples(inout vec2 samples[CRYPTOMATTE_LEVELS_MAX])
+{
+ /* Sort samples. Lame implementation, can be replaced with a more efficient algorithm. */
+ for (int i = 0; i < cryptomatte_samples_per_layer - 1 && samples[i].y != 0.0; i++) {
+ int highest_index = i;
+ float highest_weight = samples[i].y;
+ for (int j = i + 1; j < cryptomatte_samples_per_layer && samples[j].y != 0.0; j++) {
+ if (samples[j].y > highest_weight) {
+ highest_index = j;
+ highest_weight = samples[j].y;
+ }
+ };
+
+ if (highest_index != i) {
+ vec2 tmp = samples[i];
+ samples[i] = samples[highest_index];
+ samples[highest_index] = tmp;
+ }
+ }
+}
+void cryptomatte_normalize_weight(float total_weight, inout vec2 samples[CRYPTOMATTE_LEVELS_MAX])
+{
+ for (int i = 0; i < CRYPTOMATTE_LEVELS_MAX; i++) {
+ samples[i].y /= total_weight;
+ }
+}
+
+void cryptomatte_store_samples(ivec2 texel, int layer, in vec2 samples[CRYPTOMATTE_LEVELS_MAX])
+{
+ int pass_len = divide_ceil(cryptomatte_samples_per_layer, 2);
+ int layer_id = layer * pass_len;
+
+ /* Store samples back to the cryptomatte layer. */
+ for (int p = 0; p < pass_len; p++) {
+ vec4 pass_sample;
+ pass_sample.xy = samples[p * 2];
+ pass_sample.zw = samples[p * 2 + 1];
+ imageStore(cryptomatte_img, ivec3(texel, p + layer_id), pass_sample);
+ }
+}
+
+void main()
+{
+ ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
+ for (int layer = 0; layer < cryptomatte_layer_len; layer++) {
+ vec2 samples[CRYPTOMATTE_LEVELS_MAX];
+ cryptomatte_load_samples(texel, layer, samples);
+ cryptomatte_sort_samples(samples);
+ /* Repeat texture coordinates as the weight can be optimized to a small portion of the film. */
+ float weight = imageLoad(
+ weight_img,
+ ivec3(texel % imageSize(weight_img).xy, FILM_WEIGHT_LAYER_ACCUMULATION))
+ .x;
+ cryptomatte_normalize_weight(weight, samples);
+ cryptomatte_store_samples(texel, layer, samples);
+ }
+}
diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_film_frag.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_film_frag.glsl
index 26040234fd0..e2aaf9128a5 100644
--- a/source/blender/draw/engines/eevee_next/shaders/eevee_film_frag.glsl
+++ b/source/blender/draw/engines/eevee_next/shaders/eevee_film_frag.glsl
@@ -13,13 +13,17 @@ void main()
if (film_buf.display_id == -1) {
out_color = texelFetch(in_combined_tx, texel_film, 0);
}
- else if (film_buf.display_is_value) {
+ else if (film_buf.display_storage_type == PASS_STORAGE_VALUE) {
out_color.rgb = imageLoad(value_accum_img, ivec3(texel_film, film_buf.display_id)).rrr;
out_color.a = 1.0;
}
- else {
+ else if (film_buf.display_storage_type == PASS_STORAGE_COLOR) {
out_color = imageLoad(color_accum_img, ivec3(texel_film, film_buf.display_id));
}
+ else /* PASS_STORAGE_CRYPTOMATTE */ {
+ out_color = cryptomatte_false_color(
+ imageLoad(cryptomatte_img, ivec3(texel_film, film_buf.display_id)).r);
+ }
}
else {
film_process_data(texel_film, out_color, out_depth);
diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_film_lib.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_film_lib.glsl
index bf6293d5561..21b9a83abb9 100644
--- a/source/blender/draw/engines/eevee_next/shaders/eevee_film_lib.glsl
+++ b/source/blender/draw/engines/eevee_next/shaders/eevee_film_lib.glsl
@@ -8,6 +8,7 @@
#pragma BLENDER_REQUIRE(eevee_camera_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_velocity_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_colorspace_lib.glsl)
+#pragma BLENDER_REQUIRE(eevee_cryptomatte_lib.glsl)
/* Return scene linear Z depth from the camera or radial depth for panoramic cameras. */
float film_depth_convert_to_scene(float depth)
@@ -105,12 +106,18 @@ void film_sample_accum(FilmSample samp, int pass_id, sampler2D tex, inout float
accum += texelFetch(tex, samp.texel, 0).x * samp.weight;
}
-void film_sample_accum(FilmSample samp, int pass_id, sampler2DArray tex, inout vec4 accum)
+void film_sample_accum(
+ FilmSample samp, int pass_id, uint layer, sampler2DArray tex, inout vec4 accum)
{
if (pass_id == -1) {
return;
}
- accum += texelFetch(tex, ivec3(samp.texel, pass_id), 0) * samp.weight;
+ accum += texelFetch(tex, ivec3(samp.texel, layer), 0) * samp.weight;
+}
+
+void film_sample_accum(FilmSample samp, int pass_id, sampler2DArray tex, inout vec4 accum)
+{
+ film_sample_accum(samp, pass_id, pass_id, tex, accum);
}
void film_sample_accum(FilmSample samp, int pass_id, sampler2DArray tex, inout float accum)
@@ -152,15 +159,51 @@ void film_sample_accum_combined(FilmSample samp, inout vec4 accum, inout float w
weight_accum += weight;
}
+void film_sample_cryptomatte_accum(FilmSample samp,
+ int layer,
+ sampler2D tex,
+ inout vec2 crypto_samples[4])
+{
+ float hash = texelFetch(tex, samp.texel, 0)[layer];
+ /* Find existing entry. */
+ for (int i = 0; i < 4; i++) {
+ if (crypto_samples[i].x == hash) {
+ crypto_samples[i].y += samp.weight;
+ return;
+ }
+ }
+ /* Overwrite entry with less weight. */
+ for (int i = 0; i < 4; i++) {
+ if (crypto_samples[i].y < samp.weight) {
+ crypto_samples[i] = vec2(hash, samp.weight);
+ return;
+ }
+ }
+}
+
+void film_cryptomatte_layer_accum_and_store(
+ FilmSample dst, ivec2 texel_film, int pass_id, int layer_component, inout vec4 out_color)
+{
+ if (pass_id == -1) {
+ return;
+ }
+ /* x = hash, y = accumed weight. Only keep track of 4 highest weighted samples. */
+ vec2 crypto_samples[4] = vec2[4](vec2(0.0), vec2(0.0), vec2(0.0), vec2(0.0));
+ for (int i = 0; i < film_buf.samples_len; i++) {
+ FilmSample src = film_sample_get(i, texel_film);
+ film_sample_cryptomatte_accum(src, layer_component, cryptomatte_tx, crypto_samples);
+ }
+ for (int i = 0; i < 4; i++) {
+ cryptomatte_store_film_sample(dst, pass_id, crypto_samples[i], out_color);
+ }
+}
+
/** \} */
/* -------------------------------------------------------------------- */
/** \name Load/Store Data
* \{ */
-#define WEIGHT_lAYER_ACCUMULATION 0
-#define WEIGHT_lAYER_DISTANCE 1
-
/* Returns the distance used to store nearest interpolation data. */
float film_distance_load(ivec2 texel)
{
@@ -170,7 +213,7 @@ float film_distance_load(ivec2 texel)
if (!film_buf.use_history || film_buf.use_reprojection) {
return 1.0e16;
}
- return imageLoad(in_weight_img, ivec3(texel, WEIGHT_lAYER_DISTANCE)).x;
+ return imageLoad(in_weight_img, ivec3(texel, FILM_WEIGHT_LAYER_DISTANCE)).x;
}
float film_weight_load(ivec2 texel)
@@ -181,7 +224,7 @@ float film_weight_load(ivec2 texel)
if (!film_buf.use_history || film_buf.use_reprojection) {
return 0.0;
}
- return imageLoad(in_weight_img, ivec3(texel, WEIGHT_lAYER_ACCUMULATION)).x;
+ return imageLoad(in_weight_img, ivec3(texel, FILM_WEIGHT_LAYER_ACCUMULATION)).x;
}
/* Returns motion in pixel space to retrieve the pixel history. */
@@ -544,12 +587,12 @@ void film_store_depth(ivec2 texel_film, float value, out float out_depth)
void film_store_distance(ivec2 texel, float value)
{
- imageStore(out_weight_img, ivec3(texel, WEIGHT_lAYER_DISTANCE), vec4(value));
+ imageStore(out_weight_img, ivec3(texel, FILM_WEIGHT_LAYER_DISTANCE), vec4(value));
}
void film_store_weight(ivec2 texel, float value)
{
- imageStore(out_weight_img, ivec3(texel, WEIGHT_lAYER_ACCUMULATION), vec4(value));
+ imageStore(out_weight_img, ivec3(texel, FILM_WEIGHT_LAYER_ACCUMULATION), vec4(value));
}
float film_display_depth_ammend(ivec2 texel, float depth)
@@ -632,8 +675,16 @@ void film_process_data(ivec2 texel_film, out vec4 out_color, out float out_depth
for (int i = 0; i < film_buf.samples_len; i++) {
FilmSample src = film_sample_get(i, texel_film);
- film_sample_accum(src, film_buf.diffuse_light_id, diffuse_light_tx, diffuse_light_accum);
- film_sample_accum(src, film_buf.specular_light_id, specular_light_tx, specular_light_accum);
+ film_sample_accum(src,
+ film_buf.diffuse_light_id,
+ RENDER_PASS_LAYER_DIFFUSE_LIGHT,
+ light_tx,
+ diffuse_light_accum);
+ film_sample_accum(src,
+ film_buf.specular_light_id,
+ RENDER_PASS_LAYER_SPECULAR_LIGHT,
+ light_tx,
+ specular_light_accum);
film_sample_accum(src, film_buf.volume_light_id, volume_light_tx, volume_light_accum);
film_sample_accum(src, film_buf.emission_id, emission_tx, emission_accum);
}
@@ -687,4 +738,18 @@ void film_process_data(ivec2 texel_film, out vec4 out_color, out float out_depth
}
film_store_value(dst, film_buf.aov_value_id + aov, aov_accum, out_color);
}
+
+ if (film_buf.cryptomatte_samples_len != 0) {
+ /* Cryptomatte passes cannot be cleared by a weighted store like other passes. */
+ if (!film_buf.use_history || film_buf.use_reprojection) {
+ cryptomatte_clear_samples(dst);
+ }
+
+ film_cryptomatte_layer_accum_and_store(
+ dst, texel_film, film_buf.cryptomatte_object_id, 0, out_color);
+ film_cryptomatte_layer_accum_and_store(
+ dst, texel_film, film_buf.cryptomatte_asset_id, 1, out_color);
+ film_cryptomatte_layer_accum_and_store(
+ dst, texel_film, film_buf.cryptomatte_material_id, 2, out_color);
+ }
}
diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_hiz_debug_frag.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_hiz_debug_frag.glsl
new file mode 100644
index 00000000000..e93d0f472fa
--- /dev/null
+++ b/source/blender/draw/engines/eevee_next/shaders/eevee_hiz_debug_frag.glsl
@@ -0,0 +1,24 @@
+
+/**
+ * Debug hiz down sampling pass.
+ * Output red if above any max pixels, blue otherwise.
+ */
+
+void main()
+{
+ ivec2 texel = ivec2(gl_FragCoord.xy);
+
+ float depth0 = texelFetch(hiz_tx, texel, 0).r;
+
+ vec4 color = vec4(0.1, 0.1, 1.0, 1.0);
+ for (int i = 1; i < HIZ_MIP_COUNT; i++) {
+ ivec2 lvl_texel = texel / ivec2(uvec2(1) << uint(i));
+ lvl_texel = min(lvl_texel, textureSize(hiz_tx, i) - 1);
+ if (texelFetch(hiz_tx, lvl_texel, i).r < depth0) {
+ color = vec4(1.0, 0.1, 0.1, 1.0);
+ break;
+ }
+ }
+ out_debug_color_add = vec4(color.rgb, 0.0) * 0.2;
+ out_debug_color_mul = color;
+}
diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_hiz_update_comp.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_hiz_update_comp.glsl
new file mode 100644
index 00000000000..597bc73e2ad
--- /dev/null
+++ b/source/blender/draw/engines/eevee_next/shaders/eevee_hiz_update_comp.glsl
@@ -0,0 +1,121 @@
+
+/**
+ * Shader that down-sample depth buffer, creating a Hierarchical-Z buffer.
+ * Saves max value of each 2x2 texel in the mipmap above the one we are
+ * rendering to. Adapted from
+ * http://rastergrid.com/blog/2010/10/hierarchical-z-map-based-occlusion-culling/
+ *
+ * Major simplification has been made since we pad the buffer to always be
+ * bigger than input to avoid mipmapping misalignement.
+ *
+ * Start by copying the base level by quad loading the depth.
+ * Then each thread compute it's local depth for level 1.
+ * After that we use shared variables to do inter thread comunication and
+ * downsample to max level.
+ */
+
+#pragma BLENDER_REQUIRE(common_math_lib.glsl)
+
+shared float local_depths[gl_WorkGroupSize.y][gl_WorkGroupSize.x];
+
+/* Load values from the previous lod level. */
+vec4 load_local_depths(ivec2 pixel)
+{
+ pixel *= 2;
+ return vec4(local_depths[pixel.y + 1][pixel.x + 0],
+ local_depths[pixel.y + 1][pixel.x + 1],
+ local_depths[pixel.y + 0][pixel.x + 1],
+ local_depths[pixel.y + 0][pixel.x + 0]);
+}
+
+void store_local_depth(ivec2 pixel, float depth)
+{
+ local_depths[pixel.y][pixel.x] = depth;
+}
+
+void main()
+{
+ ivec2 local_px = ivec2(gl_LocalInvocationID.xy);
+ /* Bottom left corner of the kernel. */
+ ivec2 kernel_origin = ivec2(gl_WorkGroupSize.xy * gl_WorkGroupID.xy);
+
+ /* Copy level 0. */
+ ivec2 src_px = ivec2(kernel_origin + local_px) * 2;
+ vec2 samp_co = (vec2(src_px) + 0.5) / vec2(textureSize(depth_tx, 0));
+ vec4 samp = textureGather(depth_tx, samp_co);
+
+ if (update_mip_0) {
+ imageStore(out_mip_0, src_px + ivec2(0, 1), samp.xxxx);
+ imageStore(out_mip_0, src_px + ivec2(1, 1), samp.yyyy);
+ imageStore(out_mip_0, src_px + ivec2(1, 0), samp.zzzz);
+ imageStore(out_mip_0, src_px + ivec2(0, 0), samp.wwww);
+ }
+
+ /* Level 1. (No load) */
+ float max_depth = max_v4(samp);
+ ivec2 dst_px = ivec2(kernel_origin + local_px);
+ imageStore(out_mip_1, dst_px, vec4(max_depth));
+ store_local_depth(local_px, max_depth);
+
+ /* Level 2-5. */
+ bool active_thread;
+ int mask_shift = 1;
+
+#define downsample_level(out_mip__, lod_) \
+ active_thread = all(lessThan(local_px, gl_WorkGroupSize.xy >> uint(mask_shift))); \
+ barrier(); /* Wait for previous writes to finish. */ \
+ if (active_thread) { \
+ max_depth = max_v4(load_local_depths(local_px)); \
+ dst_px = ivec2((kernel_origin >> mask_shift) + local_px); \
+ imageStore(out_mip__, dst_px, vec4(max_depth)); \
+ } \
+ barrier(); /* Wait for previous reads to finish. */ \
+ if (active_thread) { \
+ store_local_depth(local_px, max_depth); \
+ } \
+ mask_shift++;
+
+ downsample_level(out_mip_2, 2);
+ downsample_level(out_mip_3, 3);
+ downsample_level(out_mip_4, 4);
+ downsample_level(out_mip_5, 5);
+
+ /* Since we pad the destination texture, the mip size is equal to the dispatch size. */
+ uint tile_count = uint(imageSize(out_mip_5).x * imageSize(out_mip_5).y);
+ /* Let the last tile handle the remaining LOD. */
+ bool last_tile = atomicAdd(finished_tile_counter, 1u) + 1u < tile_count;
+ if (last_tile == false) {
+ return;
+ }
+ finished_tile_counter = 0u;
+
+ ivec2 iter = divide_ceil(imageSize(out_mip_5), ivec2(gl_WorkGroupSize * 2u));
+ ivec2 image_border = imageSize(out_mip_5) - 1;
+ for (int y = 0; y < iter.y; y++) {
+ for (int x = 0; x < iter.x; x++) {
+ /* Load result of the other work groups. */
+ kernel_origin = ivec2(gl_WorkGroupSize) * ivec2(x, y);
+ src_px = ivec2(kernel_origin + local_px) * 2;
+ vec4 samp;
+ samp.x = imageLoad(out_mip_5, min(src_px + ivec2(0, 1), image_border)).x;
+ samp.y = imageLoad(out_mip_5, min(src_px + ivec2(1, 1), image_border)).x;
+ samp.z = imageLoad(out_mip_5, min(src_px + ivec2(1, 0), image_border)).x;
+ samp.w = imageLoad(out_mip_5, min(src_px + ivec2(0, 0), image_border)).x;
+ /* Level 6. */
+ float max_depth = max_v4(samp);
+ ivec2 dst_px = ivec2(kernel_origin + local_px);
+ imageStore(out_mip_6, dst_px, vec4(max_depth));
+ store_local_depth(local_px, max_depth);
+
+ mask_shift = 1;
+
+ /* Level 7. */
+ downsample_level(out_mip_7, 7);
+
+ /* Limited by OpenGL maximum of 8 image slot. */
+ // downsample_level(out_mip_8, 8);
+ // downsample_level(out_mip_9, 9);
+ // downsample_level(out_mip_10, 10);
+ }
+ }
+}
diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_light_culling_debug_frag.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_light_culling_debug_frag.glsl
index 321c99f7952..eefc024d0b8 100644
--- a/source/blender/draw/engines/eevee_next/shaders/eevee_light_culling_debug_frag.glsl
+++ b/source/blender/draw/engines/eevee_next/shaders/eevee_light_culling_debug_frag.glsl
@@ -14,7 +14,7 @@ void main()
{
ivec2 texel = ivec2(gl_FragCoord.xy);
- float depth = texelFetch(depth_tx, texel, 0).r;
+ float depth = texelFetch(hiz_tx, texel, 0).r;
float vP_z = get_view_z_from_depth(depth);
vec3 P = get_world_space_from_depth(uvcoordsvar.xy, depth);
@@ -36,17 +36,19 @@ void main()
vec3 L;
float dist;
light_vector_get(light, P, L, dist);
- if (light_attenuation(light_buf[l_idx], L, dist) > 0.0) {
+ if (light_attenuation(light, L, dist) > 0.0) {
light_nocull |= 1u << l_idx;
}
}
LIGHT_FOREACH_END
+ vec4 color = vec4(heatmap_gradient(light_count / 4.0), 1.0);
+
if ((light_cull & light_nocull) != light_nocull) {
/* ERROR. Some lights were culled incorrectly. */
- out_debug_color = vec4(0.0, 1.0, 0.0, 1.0);
- }
- else {
- out_debug_color = vec4(heatmap_gradient(light_count / 4.0), 1.0);
+ color = vec4(0.0, 1.0, 0.0, 1.0);
}
-} \ No newline at end of file
+
+ out_debug_color_add = vec4(color.rgb, 0.0) * 0.2;
+ out_debug_color_mul = color;
+}
diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_light_culling_sort_comp.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_light_culling_sort_comp.glsl
index daf2016cd35..e98b170cd4c 100644
--- a/source/blender/draw/engines/eevee_next/shaders/eevee_light_culling_sort_comp.glsl
+++ b/source/blender/draw/engines/eevee_next/shaders/eevee_light_culling_sort_comp.glsl
@@ -25,7 +25,7 @@ void main()
int prefix_sum = 0;
/* Iterate over the whole key buffer. */
- uint iter = divide_ceil_u(light_cull_buf.visible_count, gl_WorkGroupSize.x);
+ uint iter = divide_ceil(light_cull_buf.visible_count, gl_WorkGroupSize.x);
for (uint i = 0u; i < iter; i++) {
uint index = gl_WorkGroupSize.x * i + gl_LocalInvocationID.x;
/* NOTE: This will load duplicated values, but they will be discarded. */
diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_light_culling_zbin_comp.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_light_culling_zbin_comp.glsl
index d96f191fb77..ae20153f26c 100644
--- a/source/blender/draw/engines/eevee_next/shaders/eevee_light_culling_zbin_comp.glsl
+++ b/source/blender/draw/engines/eevee_next/shaders/eevee_light_culling_zbin_comp.glsl
@@ -25,7 +25,7 @@ void main()
}
barrier();
- uint light_iter = divide_ceil_u(light_cull_buf.visible_count, gl_WorkGroupSize.x);
+ uint light_iter = divide_ceil(light_cull_buf.visible_count, gl_WorkGroupSize.x);
for (uint i = 0u; i < light_iter; i++) {
uint index = i * gl_WorkGroupSize.x + gl_LocalInvocationID.x;
if (index >= light_cull_buf.visible_count) {
diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_motion_blur_dilate_comp.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_motion_blur_dilate_comp.glsl
index 99186ab6f67..07139ea6a09 100644
--- a/source/blender/draw/engines/eevee_next/shaders/eevee_motion_blur_dilate_comp.glsl
+++ b/source/blender/draw/engines/eevee_next/shaders/eevee_motion_blur_dilate_comp.glsl
@@ -2,7 +2,6 @@
/**
* Dilate motion vector tiles until we covered maximum velocity.
* Outputs the largest intersecting motion vector in the neighborhood.
- *
*/
#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl)
@@ -20,7 +19,7 @@ MotionRect compute_motion_rect(ivec2 tile, vec2 motion)
#if DEBUG_BYPASS_DILATION
return MotionRect(tile, ivec2(1));
#endif
- /* Ceil to number of tile touched.*/
+ /* Ceil to number of tile touched. */
ivec2 point1 = tile + ivec2(sign(motion) * ceil(abs(motion) / float(MOTION_BLUR_TILE_SIZE)));
ivec2 point2 = tile;
diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_nodetree_lib.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_nodetree_lib.glsl
index 13ad387289d..dd047709afd 100644
--- a/source/blender/draw/engines/eevee_next/shaders/eevee_nodetree_lib.glsl
+++ b/source/blender/draw/engines/eevee_next/shaders/eevee_nodetree_lib.glsl
@@ -409,3 +409,31 @@ vec4 attr_load_color_post(vec4 attr)
#endif
/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Uniform Attributes
+ *
+ * TODO(@fclem): These implementation details should concern the DRWManager and not be a fix on
+ * the engine side. But as of now, the engines are responsible for loading the attributes.
+ *
+ * \{ */
+
+vec4 attr_load_uniform(vec4 attr, const uint attr_hash)
+{
+#if defined(OBATTR_LIB)
+ uint index = floatBitsToUint(ObjectAttributeStart);
+ for (uint i = 0; i < floatBitsToUint(ObjectAttributeLen); i++, index++) {
+ if (drw_attrs[index].hash_code == attr_hash) {
+ return vec4(drw_attrs[index].data_x,
+ drw_attrs[index].data_y,
+ drw_attrs[index].data_z,
+ drw_attrs[index].data_w);
+ }
+ }
+ return vec4(0.0);
+#else
+ return attr;
+#endif
+}
+
+/** \} */
diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_surf_depth_frag.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_surf_depth_frag.glsl
index bd32215ddc2..183aac1e546 100644
--- a/source/blender/draw/engines/eevee_next/shaders/eevee_surf_depth_frag.glsl
+++ b/source/blender/draw/engines/eevee_next/shaders/eevee_surf_depth_frag.glsl
@@ -6,6 +6,7 @@
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
#pragma BLENDER_REQUIRE(common_math_lib.glsl)
#pragma BLENDER_REQUIRE(common_hair_lib.glsl)
+#pragma BLENDER_REQUIRE(eevee_sampling_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_nodetree_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_surf_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_velocity_lib.glsl)
@@ -73,8 +74,7 @@ void main()
nodetree_surface();
- // float noise_offset = sampling_rng_1D_get(SAMPLING_TRANSPARENCY);
- float noise_offset = 0.5;
+ float noise_offset = sampling_rng_1D_get(SAMPLING_TRANSPARENCY);
float random_threshold = hashed_alpha_threshold(1.0, noise_offset, g_data.P);
float transparency = avg(g_transmittance);
diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_surf_forward_frag.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_surf_forward_frag.glsl
index 26d2c066937..ab29067763d 100644
--- a/source/blender/draw/engines/eevee_next/shaders/eevee_surf_forward_frag.glsl
+++ b/source/blender/draw/engines/eevee_next/shaders/eevee_surf_forward_frag.glsl
@@ -97,13 +97,20 @@ void main()
out_normal += g_refraction_data.N * g_refraction_data.weight;
out_normal = safe_normalize(out_normal);
+#ifdef MAT_RENDER_PASS_SUPPORT
ivec2 out_texel = ivec2(gl_FragCoord.xy);
imageStore(rp_normal_img, out_texel, vec4(out_normal, 1.0));
- imageStore(rp_diffuse_light_img, out_texel, vec4(diffuse_light, 1.0));
+ imageStore(
+ rp_light_img, ivec3(out_texel, RENDER_PASS_LAYER_DIFFUSE_LIGHT), vec4(diffuse_light, 1.0));
+ imageStore(
+ rp_light_img, ivec3(out_texel, RENDER_PASS_LAYER_SPECULAR_LIGHT), vec4(specular_light, 1.0));
imageStore(rp_diffuse_color_img, out_texel, vec4(g_diffuse_data.color, 1.0));
- imageStore(rp_specular_light_img, out_texel, vec4(specular_light, 1.0));
imageStore(rp_specular_color_img, out_texel, vec4(specular_color, 1.0));
imageStore(rp_emission_img, out_texel, vec4(g_emission, 1.0));
+ imageStore(rp_cryptomatte_img,
+ out_texel,
+ vec4(cryptomatte_object_buf[resource_id], node_tree.crypto_hash, 0.0));
+#endif
out_radiance.rgb *= 1.0 - g_holdout;
diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_surf_lib.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_surf_lib.glsl
index 30b48edaa78..6c1fc818f41 100644
--- a/source/blender/draw/engines/eevee_next/shaders/eevee_surf_lib.glsl
+++ b/source/blender/draw/engines/eevee_next/shaders/eevee_surf_lib.glsl
@@ -40,7 +40,7 @@ void init_globals_curves()
/* Shade as a cylinder. */
float cos_theta = interp.curves_time_width / interp.curves_thickness;
float sin_theta = sqrt(max(0.0, 1.0 - cos_theta * cos_theta));
- g_data.N = normalize(interp.N * sin_theta + interp.curves_binormal * cos_theta);
+ g_data.N = g_data.Ni = normalize(interp.N * sin_theta + interp.curves_binormal * cos_theta);
/* Costly, but follows cycles per pixel tangent space (not following curve shape). */
vec3 V = cameraVec(g_data.P);
@@ -60,13 +60,14 @@ void init_globals_curves()
void init_globals_gpencil()
{
/* Undo backface flip as the gpencil normal is already pointing towards the camera. */
- g_data.N = interp.N;
+ g_data.N = g_data.Ni = interp.N;
}
void init_globals()
{
/* Default values. */
g_data.P = interp.P;
+ g_data.Ni = interp.N;
g_data.N = safe_normalize(interp.N);
g_data.Ng = g_data.N;
g_data.is_strand = false;
@@ -81,6 +82,7 @@ void init_globals()
#ifdef GPU_FRAGMENT_SHADER
g_data.N = (FrontFacing) ? g_data.N : -g_data.N;
+ g_data.Ni = (FrontFacing) ? g_data.Ni : -g_data.Ni;
g_data.Ng = safe_normalize(cross(dFdx(g_data.P), dFdy(g_data.P)));
#endif
diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_surf_world_frag.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_surf_world_frag.glsl
index ed75282a550..442c2579c84 100644
--- a/source/blender/draw/engines/eevee_next/shaders/eevee_surf_world_frag.glsl
+++ b/source/blender/draw/engines/eevee_next/shaders/eevee_surf_world_frag.glsl
@@ -26,11 +26,14 @@ void main()
ivec2 out_texel = ivec2(gl_FragCoord.xy);
imageStore(rp_normal_img, out_texel, vec4(0.0, 0.0, 0.0, 1.0));
- imageStore(rp_diffuse_light_img, out_texel, vec4(0.0, 0.0, 0.0, 1.0));
+ imageStore(
+ rp_light_img, ivec3(out_texel, RENDER_PASS_LAYER_DIFFUSE_LIGHT), vec4(0.0, 0.0, 0.0, 1.0));
+ imageStore(
+ rp_light_img, ivec3(out_texel, RENDER_PASS_LAYER_SPECULAR_LIGHT), vec4(0.0, 0.0, 0.0, 1.0));
imageStore(rp_diffuse_color_img, out_texel, vec4(0.0, 0.0, 0.0, 1.0));
- imageStore(rp_specular_light_img, out_texel, vec4(0.0, 0.0, 0.0, 1.0));
imageStore(rp_specular_color_img, out_texel, vec4(0.0, 0.0, 0.0, 1.0));
imageStore(rp_emission_img, out_texel, vec4(0.0, 0.0, 0.0, 1.0));
+ imageStore(rp_cryptomatte_img, out_texel, vec4(0.0));
out_background.rgb = safe_color(g_emission) * (1.0 - g_holdout);
out_background.a = saturate(avg(g_transmittance)) * g_holdout;
diff --git a/source/blender/draw/engines/eevee_next/shaders/infos/eevee_depth_of_field_info.hh b/source/blender/draw/engines/eevee_next/shaders/infos/eevee_depth_of_field_info.hh
index b398a6cc4e7..b689a7f53a2 100644
--- a/source/blender/draw/engines/eevee_next/shaders/infos/eevee_depth_of_field_info.hh
+++ b/source/blender/draw/engines/eevee_next/shaders/infos/eevee_depth_of_field_info.hh
@@ -11,7 +11,7 @@ GPU_SHADER_CREATE_INFO(eevee_depth_of_field_bokeh_lut)
.do_static_compilation(true)
.local_group_size(DOF_BOKEH_LUT_SIZE, DOF_BOKEH_LUT_SIZE)
.additional_info("eevee_shared", "draw_view")
- .uniform_buf(1, "DepthOfFieldData", "dof_buf")
+ .uniform_buf(6, "DepthOfFieldData", "dof_buf")
.image(0, GPU_RG16F, Qualifier::WRITE, ImageType::FLOAT_2D, "out_gather_lut_img")
.image(1, GPU_R16F, Qualifier::WRITE, ImageType::FLOAT_2D, "out_scatter_lut_img")
.image(2, GPU_R16F, Qualifier::WRITE, ImageType::FLOAT_2D, "out_resolve_lut_img")
@@ -21,7 +21,7 @@ GPU_SHADER_CREATE_INFO(eevee_depth_of_field_setup)
.do_static_compilation(true)
.local_group_size(DOF_DEFAULT_GROUP_SIZE, DOF_DEFAULT_GROUP_SIZE)
.additional_info("eevee_shared", "draw_view")
- .uniform_buf(1, "DepthOfFieldData", "dof_buf")
+ .uniform_buf(6, "DepthOfFieldData", "dof_buf")
.sampler(0, ImageType::FLOAT_2D, "color_tx")
.sampler(1, ImageType::DEPTH_2D, "depth_tx")
.image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "out_color_img")
@@ -32,7 +32,7 @@ GPU_SHADER_CREATE_INFO(eevee_depth_of_field_stabilize)
.do_static_compilation(true)
.local_group_size(DOF_STABILIZE_GROUP_SIZE, DOF_STABILIZE_GROUP_SIZE)
.additional_info("eevee_shared", "draw_view", "eevee_velocity_camera")
- .uniform_buf(4, "DepthOfFieldData", "dof_buf")
+ .uniform_buf(6, "DepthOfFieldData", "dof_buf")
.sampler(0, ImageType::FLOAT_2D, "coc_tx")
.sampler(1, ImageType::FLOAT_2D, "color_tx")
.sampler(2, ImageType::FLOAT_2D, "velocity_tx")
@@ -57,7 +57,7 @@ GPU_SHADER_CREATE_INFO(eevee_depth_of_field_reduce)
.do_static_compilation(true)
.local_group_size(DOF_REDUCE_GROUP_SIZE, DOF_REDUCE_GROUP_SIZE)
.additional_info("eevee_shared", "draw_view")
- .uniform_buf(1, "DepthOfFieldData", "dof_buf")
+ .uniform_buf(6, "DepthOfFieldData", "dof_buf")
.sampler(0, ImageType::FLOAT_2D, "downsample_tx")
.storage_buf(0, Qualifier::WRITE, "ScatterRect", "scatter_fg_list_buf[]")
.storage_buf(1, Qualifier::WRITE, "ScatterRect", "scatter_bg_list_buf[]")
@@ -154,7 +154,7 @@ GPU_SHADER_CREATE_INFO(eevee_depth_of_field_gather_common)
"draw_view",
"eevee_depth_of_field_tiles_common",
"eevee_sampling_data")
- .uniform_buf(2, "DepthOfFieldData", "dof_buf")
+ .uniform_buf(6, "DepthOfFieldData", "dof_buf")
.local_group_size(DOF_GATHER_GROUP_SIZE, DOF_GATHER_GROUP_SIZE)
.sampler(0, ImageType::FLOAT_2D, "color_tx")
.sampler(1, ImageType::FLOAT_2D, "color_bilinear_tx")
@@ -229,7 +229,7 @@ GPU_SHADER_CREATE_INFO(eevee_depth_of_field_resolve)
"draw_view",
"eevee_depth_of_field_tiles_common",
"eevee_sampling_data")
- .uniform_buf(2, "DepthOfFieldData", "dof_buf")
+ .uniform_buf(6, "DepthOfFieldData", "dof_buf")
.sampler(0, ImageType::DEPTH_2D, "depth_tx")
.sampler(1, ImageType::FLOAT_2D, "color_tx")
.sampler(2, ImageType::FLOAT_2D, "color_bg_tx")
diff --git a/source/blender/draw/engines/eevee_next/shaders/infos/eevee_film_info.hh b/source/blender/draw/engines/eevee_next/shaders/infos/eevee_film_info.hh
index a5baaca51f9..4541f14d96c 100644
--- a/source/blender/draw/engines/eevee_next/shaders/infos/eevee_film_info.hh
+++ b/source/blender/draw/engines/eevee_next/shaders/infos/eevee_film_info.hh
@@ -4,25 +4,24 @@
#include "gpu_shader_create_info.hh"
GPU_SHADER_CREATE_INFO(eevee_film)
- .uniform_buf(4, "FilmData", "film_buf")
+ .uniform_buf(6, "FilmData", "film_buf")
.sampler(0, ImageType::DEPTH_2D, "depth_tx")
.sampler(1, ImageType::FLOAT_2D, "combined_tx")
.sampler(2, ImageType::FLOAT_2D, "normal_tx")
.sampler(3, ImageType::FLOAT_2D, "vector_tx")
- .sampler(4, ImageType::FLOAT_2D, "diffuse_light_tx")
+ .sampler(4, ImageType::FLOAT_2D_ARRAY, "light_tx")
.sampler(5, ImageType::FLOAT_2D, "diffuse_color_tx")
- .sampler(6, ImageType::FLOAT_2D, "specular_light_tx")
- .sampler(7, ImageType::FLOAT_2D, "specular_color_tx")
- .sampler(8, ImageType::FLOAT_2D, "volume_light_tx")
- .sampler(9, ImageType::FLOAT_2D, "emission_tx")
- .sampler(10, ImageType::FLOAT_2D, "environment_tx")
- .sampler(11, ImageType::FLOAT_2D, "shadow_tx")
- .sampler(12, ImageType::FLOAT_2D, "ambient_occlusion_tx")
- .sampler(13, ImageType::FLOAT_2D_ARRAY, "aov_color_tx")
- .sampler(14, ImageType::FLOAT_2D_ARRAY, "aov_value_tx")
+ .sampler(6, ImageType::FLOAT_2D, "specular_color_tx")
+ .sampler(7, ImageType::FLOAT_2D, "volume_light_tx")
+ .sampler(8, ImageType::FLOAT_2D, "emission_tx")
+ .sampler(9, ImageType::FLOAT_2D, "environment_tx")
+ .sampler(10, ImageType::FLOAT_2D, "shadow_tx")
+ .sampler(11, ImageType::FLOAT_2D, "ambient_occlusion_tx")
+ .sampler(12, ImageType::FLOAT_2D_ARRAY, "aov_color_tx")
+ .sampler(13, ImageType::FLOAT_2D_ARRAY, "aov_value_tx")
/* Color History for TAA needs to be sampler to leverage bilinear sampling. */
- .sampler(15, ImageType::FLOAT_2D, "in_combined_tx")
- // .sampler(15, ImageType::FLOAT_2D, "cryptomatte_tx") /* TODO */
+ .sampler(14, ImageType::FLOAT_2D, "in_combined_tx")
+ .sampler(15, ImageType::FLOAT_2D, "cryptomatte_tx")
.image(0, GPU_R32F, Qualifier::READ, ImageType::FLOAT_2D_ARRAY, "in_weight_img")
.image(1, GPU_R32F, Qualifier::WRITE, ImageType::FLOAT_2D_ARRAY, "out_weight_img")
/* Color History for TAA needs to be sampler to leverage bilinear sampling. */
@@ -31,6 +30,7 @@ GPU_SHADER_CREATE_INFO(eevee_film)
.image(4, GPU_R32F, Qualifier::READ_WRITE, ImageType::FLOAT_2D, "depth_img")
.image(5, GPU_RGBA16F, Qualifier::READ_WRITE, ImageType::FLOAT_2D_ARRAY, "color_accum_img")
.image(6, GPU_R16F, Qualifier::READ_WRITE, ImageType::FLOAT_2D_ARRAY, "value_accum_img")
+ .image(7, GPU_RGBA32F, Qualifier::READ_WRITE, ImageType::FLOAT_2D_ARRAY, "cryptomatte_img")
.additional_info("eevee_shared")
.additional_info("eevee_velocity_camera")
.additional_info("draw_view");
@@ -46,3 +46,13 @@ GPU_SHADER_CREATE_INFO(eevee_film_comp)
.local_group_size(FILM_GROUP_SIZE, FILM_GROUP_SIZE)
.compute_source("eevee_film_comp.glsl")
.additional_info("eevee_film");
+
+GPU_SHADER_CREATE_INFO(eevee_film_cryptomatte_post)
+ .do_static_compilation(true)
+ .image(0, GPU_RGBA32F, Qualifier::READ_WRITE, ImageType::FLOAT_2D_ARRAY, "cryptomatte_img")
+ .image(1, GPU_R32F, Qualifier::READ, ImageType::FLOAT_2D_ARRAY, "weight_img")
+ .push_constant(Type::INT, "cryptomatte_layer_len")
+ .push_constant(Type::INT, "cryptomatte_samples_per_layer")
+ .local_group_size(FILM_GROUP_SIZE, FILM_GROUP_SIZE)
+ .compute_source("eevee_film_cryptomatte_post_comp.glsl")
+ .additional_info("eevee_shared");
diff --git a/source/blender/draw/engines/eevee_next/shaders/infos/eevee_hiz_info.hh b/source/blender/draw/engines/eevee_next/shaders/infos/eevee_hiz_info.hh
new file mode 100644
index 00000000000..5e32631a8f8
--- /dev/null
+++ b/source/blender/draw/engines/eevee_next/shaders/infos/eevee_hiz_info.hh
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "eevee_defines.hh"
+#include "gpu_shader_create_info.hh"
+
+GPU_SHADER_CREATE_INFO(eevee_hiz_data)
+ .sampler(15, ImageType::FLOAT_2D, "hiz_tx")
+ .uniform_buf(5, "HiZData", "hiz_buf");
+
+GPU_SHADER_CREATE_INFO(eevee_hiz_update)
+ .do_static_compilation(true)
+ .local_group_size(FILM_GROUP_SIZE, FILM_GROUP_SIZE)
+ .storage_buf(0, Qualifier::READ_WRITE, "uint", "finished_tile_counter")
+ .sampler(0, ImageType::DEPTH_2D, "depth_tx")
+ .image(0, GPU_R32F, Qualifier::WRITE, ImageType::FLOAT_2D, "out_mip_0")
+ .image(1, GPU_R32F, Qualifier::WRITE, ImageType::FLOAT_2D, "out_mip_1")
+ .image(2, GPU_R32F, Qualifier::WRITE, ImageType::FLOAT_2D, "out_mip_2")
+ .image(3, GPU_R32F, Qualifier::WRITE, ImageType::FLOAT_2D, "out_mip_3")
+ .image(4, GPU_R32F, Qualifier::WRITE, ImageType::FLOAT_2D, "out_mip_4")
+ .image(5, GPU_R32F, Qualifier::READ_WRITE, ImageType::FLOAT_2D, "out_mip_5")
+ .image(6, GPU_R32F, Qualifier::WRITE, ImageType::FLOAT_2D, "out_mip_6")
+ .image(7, GPU_R32F, Qualifier::WRITE, ImageType::FLOAT_2D, "out_mip_7")
+ .push_constant(Type::BOOL, "update_mip_0")
+ .compute_source("eevee_hiz_update_comp.glsl");
+
+GPU_SHADER_CREATE_INFO(eevee_hiz_debug)
+ .do_static_compilation(true)
+ .fragment_out(0, Type::VEC4, "out_debug_color_add", DualBlend::SRC_0)
+ .fragment_out(0, Type::VEC4, "out_debug_color_mul", DualBlend::SRC_1)
+ .fragment_source("eevee_hiz_debug_frag.glsl")
+ .additional_info("eevee_shared", "eevee_hiz_data", "draw_fullscreen");
diff --git a/source/blender/draw/engines/eevee_next/shaders/infos/eevee_light_culling_info.hh b/source/blender/draw/engines/eevee_next/shaders/infos/eevee_light_culling_info.hh
index 56fda25ed13..41602426a1d 100644
--- a/source/blender/draw/engines/eevee_next/shaders/infos/eevee_light_culling_info.hh
+++ b/source/blender/draw/engines/eevee_next/shaders/infos/eevee_light_culling_info.hh
@@ -8,10 +8,10 @@
* \{ */
GPU_SHADER_CREATE_INFO(eevee_light_data)
- .storage_buf(0, Qualifier::READ, "LightCullingData", "light_cull_buf")
- .storage_buf(1, Qualifier::READ, "LightData", "light_buf[]")
- .storage_buf(2, Qualifier::READ, "uint", "light_zbin_buf[]")
- .storage_buf(3, Qualifier::READ, "uint", "light_tile_buf[]");
+ .storage_buf(LIGHT_CULL_BUF_SLOT, Qualifier::READ, "LightCullingData", "light_cull_buf")
+ .storage_buf(LIGHT_BUF_SLOT, Qualifier::READ, "LightData", "light_buf[]")
+ .storage_buf(LIGHT_ZBIN_BUF_SLOT, Qualifier::READ, "uint", "light_zbin_buf[]")
+ .storage_buf(LIGHT_TILE_BUF_SLOT, Qualifier::READ, "uint", "light_tile_buf[]");
/** \} */
@@ -67,10 +67,10 @@ GPU_SHADER_CREATE_INFO(eevee_light_culling_tile)
GPU_SHADER_CREATE_INFO(eevee_light_culling_debug)
.do_static_compilation(true)
- .sampler(0, ImageType::DEPTH_2D, "depth_tx")
- .fragment_out(0, Type::VEC4, "out_debug_color")
- .additional_info("eevee_shared", "draw_view")
+ .fragment_out(0, Type::VEC4, "out_debug_color_add", DualBlend::SRC_0)
+ .fragment_out(0, Type::VEC4, "out_debug_color_mul", DualBlend::SRC_1)
.fragment_source("eevee_light_culling_debug_frag.glsl")
- .additional_info("draw_fullscreen", "eevee_light_data");
+ .additional_info(
+ "eevee_shared", "draw_view", "draw_fullscreen", "eevee_light_data", "eevee_hiz_data");
/** \} */
diff --git a/source/blender/draw/engines/eevee_next/shaders/infos/eevee_material_info.hh b/source/blender/draw/engines/eevee_next/shaders/infos/eevee_material_info.hh
index 6929dec1150..78d52d4b90e 100644
--- a/source/blender/draw/engines/eevee_next/shaders/infos/eevee_material_info.hh
+++ b/source/blender/draw/engines/eevee_next/shaders/infos/eevee_material_info.hh
@@ -1,5 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
+#include "eevee_defines.hh"
#include "gpu_shader_create_info.hh"
/* -------------------------------------------------------------------- */
@@ -14,9 +15,10 @@ GPU_SHADER_CREATE_INFO(eevee_shared)
GPU_SHADER_CREATE_INFO(eevee_sampling_data)
.define("EEVEE_SAMPLING_DATA")
.additional_info("eevee_shared")
- .storage_buf(14, Qualifier::READ, "SamplingData", "sampling_buf");
+ .storage_buf(6, Qualifier::READ, "SamplingData", "sampling_buf");
-GPU_SHADER_CREATE_INFO(eevee_utility_texture).sampler(8, ImageType::FLOAT_2D_ARRAY, "utility_tx");
+GPU_SHADER_CREATE_INFO(eevee_utility_texture)
+ .sampler(RBUFS_UTILITY_TEX_SLOT, ImageType::FLOAT_2D_ARRAY, "utility_tx");
/** \} */
@@ -30,7 +32,7 @@ GPU_SHADER_CREATE_INFO(eevee_geom_mesh)
.vertex_in(0, Type::VEC3, "pos")
.vertex_in(1, Type::VEC3, "nor")
.vertex_source("eevee_geom_mesh_vert.glsl")
- .additional_info("draw_mesh", "draw_resource_id_varying", "draw_resource_handle");
+ .additional_info("draw_modelmat_new", "draw_resource_id_varying", "draw_view");
GPU_SHADER_CREATE_INFO(eevee_geom_gpencil)
.additional_info("eevee_shared")
@@ -52,7 +54,7 @@ GPU_SHADER_CREATE_INFO(eevee_geom_world)
.define("MAT_GEOM_WORLD")
.builtins(BuiltinBits::VERTEX_ID)
.vertex_source("eevee_geom_world_vert.glsl")
- .additional_info("draw_modelmat", "draw_resource_id_varying", "draw_resource_handle");
+ .additional_info("draw_modelmat_new", "draw_resource_id_varying", "draw_view");
/** \} */
@@ -78,9 +80,21 @@ GPU_SHADER_INTERFACE_INFO(eevee_surf_iface, "interp")
GPU_SHADER_CREATE_INFO(eevee_aov_out)
.define("MAT_AOV_SUPPORT")
- .image_array_out(6, Qualifier::WRITE, GPU_RGBA16F, "aov_color_img")
- .image_array_out(7, Qualifier::WRITE, GPU_R16F, "aov_value_img")
- .storage_buf(7, Qualifier::READ, "AOVsInfoData", "aov_buf");
+ .image_array_out(RBUFS_AOV_COLOR_SLOT, Qualifier::WRITE, GPU_RGBA16F, "aov_color_img")
+ .image_array_out(RBUFS_AOV_VALUE_SLOT, Qualifier::WRITE, GPU_R16F, "aov_value_img")
+ .storage_buf(RBUFS_AOV_BUF_SLOT, Qualifier::READ, "AOVsInfoData", "aov_buf");
+
+GPU_SHADER_CREATE_INFO(eevee_render_pass_out)
+ .define("MAT_RENDER_PASS_SUPPORT")
+ .image_out(RBUFS_NORMAL_SLOT, Qualifier::READ_WRITE, GPU_RGBA16F, "rp_normal_img")
+ .image_array_out(RBUFS_LIGHT_SLOT, Qualifier::READ_WRITE, GPU_RGBA16F, "rp_light_img")
+ .image_out(RBUFS_DIFF_COLOR_SLOT, Qualifier::READ_WRITE, GPU_RGBA16F, "rp_diffuse_color_img")
+ .image_out(RBUFS_SPEC_COLOR_SLOT, Qualifier::READ_WRITE, GPU_RGBA16F, "rp_specular_color_img")
+ .image_out(RBUFS_EMISSION_SLOT, Qualifier::READ_WRITE, GPU_RGBA16F, "rp_emission_img");
+
+GPU_SHADER_CREATE_INFO(eevee_cryptomatte_out)
+ .storage_buf(7, Qualifier::READ, "vec2", "cryptomatte_object_buf[]", Frequency::PASS)
+ .image_out(7, Qualifier::WRITE, GPU_RGBA32F, "rp_cryptomatte_img");
GPU_SHADER_CREATE_INFO(eevee_surf_deferred)
.vertex_out(eevee_surf_iface)
@@ -104,7 +118,6 @@ GPU_SHADER_CREATE_INFO(eevee_surf_deferred)
;
GPU_SHADER_CREATE_INFO(eevee_surf_forward)
- .auto_resource_location(true)
.vertex_out(eevee_surf_iface)
/* Early fragment test is needed for render passes support for forward surfaces. */
/* NOTE: This removes the possibility of using gl_FragDepth. */
@@ -112,43 +125,33 @@ GPU_SHADER_CREATE_INFO(eevee_surf_forward)
.fragment_out(0, Type::VEC4, "out_radiance", DualBlend::SRC_0)
.fragment_out(0, Type::VEC4, "out_transmittance", DualBlend::SRC_1)
.fragment_source("eevee_surf_forward_frag.glsl")
- .image_out(0, Qualifier::READ_WRITE, GPU_RGBA16F, "rp_normal_img")
- .image_out(1, Qualifier::READ_WRITE, GPU_RGBA16F, "rp_diffuse_light_img")
- .image_out(2, Qualifier::READ_WRITE, GPU_RGBA16F, "rp_diffuse_color_img")
- .image_out(3, Qualifier::READ_WRITE, GPU_RGBA16F, "rp_specular_light_img")
- .image_out(4, Qualifier::READ_WRITE, GPU_RGBA16F, "rp_specular_color_img")
- .image_out(5, Qualifier::READ_WRITE, GPU_RGBA16F, "rp_emission_img")
- .additional_info("eevee_aov_out",
+ .additional_info("eevee_cryptomatte_out",
"eevee_light_data",
"eevee_utility_texture",
"eevee_sampling_data"
- // "eevee_lightprobe_data",
+ // "eevee_lightprobe_data",
+ // "eevee_shadow_data"
/* Optionally added depending on the material. */
// "eevee_raytrace_data",
// "eevee_transmittance_data",
- // "eevee_shadow_data"
+ // "eevee_aov_out",
+ // "eevee_render_pass_out",
);
GPU_SHADER_CREATE_INFO(eevee_surf_depth)
.vertex_out(eevee_surf_iface)
.fragment_source("eevee_surf_depth_frag.glsl")
- // .additional_info("eevee_sampling_data", "eevee_utility_texture")
- ;
+ .additional_info("eevee_sampling_data", "eevee_utility_texture");
GPU_SHADER_CREATE_INFO(eevee_surf_world)
.vertex_out(eevee_surf_iface)
- .image_out(0, Qualifier::READ_WRITE, GPU_RGBA16F, "rp_normal_img")
- .image_out(1, Qualifier::READ_WRITE, GPU_RGBA16F, "rp_diffuse_light_img")
- .image_out(2, Qualifier::READ_WRITE, GPU_RGBA16F, "rp_diffuse_color_img")
- .image_out(3, Qualifier::READ_WRITE, GPU_RGBA16F, "rp_specular_light_img")
- .image_out(4, Qualifier::READ_WRITE, GPU_RGBA16F, "rp_specular_color_img")
- .image_out(5, Qualifier::READ_WRITE, GPU_RGBA16F, "rp_emission_img")
.push_constant(Type::FLOAT, "world_opacity_fade")
.fragment_out(0, Type::VEC4, "out_background")
.fragment_source("eevee_surf_world_frag.glsl")
- .additional_info("eevee_aov_out"
- //"eevee_utility_texture"
- );
+ .additional_info("eevee_aov_out",
+ "eevee_cryptomatte_out",
+ "eevee_render_pass_out",
+ "eevee_utility_texture");
#undef image_out
#undef image_array_out
@@ -190,10 +193,7 @@ GPU_SHADER_CREATE_INFO(eevee_volume_deferred)
GPU_SHADER_CREATE_INFO(eevee_material_stub).define("EEVEE_MATERIAL_STUBS");
# define EEVEE_MAT_FINAL_VARIATION(name, ...) \
- GPU_SHADER_CREATE_INFO(name) \
- .additional_info(__VA_ARGS__) \
- .auto_resource_location(true) \
- .do_static_compilation(true);
+ GPU_SHADER_CREATE_INFO(name).additional_info(__VA_ARGS__).do_static_compilation(true);
# define EEVEE_MAT_GEOM_VARIATIONS(prefix, ...) \
EEVEE_MAT_FINAL_VARIATION(prefix##_world, "eevee_geom_world", __VA_ARGS__) \
diff --git a/source/blender/draw/engines/eevee_next/shaders/infos/eevee_motion_blur_info.hh b/source/blender/draw/engines/eevee_next/shaders/infos/eevee_motion_blur_info.hh
index d6ff34b0ed2..ec302ec6770 100644
--- a/source/blender/draw/engines/eevee_next/shaders/infos/eevee_motion_blur_info.hh
+++ b/source/blender/draw/engines/eevee_next/shaders/infos/eevee_motion_blur_info.hh
@@ -6,7 +6,7 @@
GPU_SHADER_CREATE_INFO(eevee_motion_blur_tiles_flatten)
.local_group_size(MOTION_BLUR_GROUP_SIZE, MOTION_BLUR_GROUP_SIZE)
.additional_info("eevee_shared", "draw_view", "eevee_velocity_camera")
- .uniform_buf(4, "MotionBlurData", "motion_blur_buf")
+ .uniform_buf(6, "MotionBlurData", "motion_blur_buf")
.sampler(0, ImageType::DEPTH_2D, "depth_tx")
.image(1, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "out_tiles_img")
.compute_source("eevee_motion_blur_flatten_comp.glsl");
@@ -35,7 +35,7 @@ GPU_SHADER_CREATE_INFO(eevee_motion_blur_gather)
.do_static_compilation(true)
.local_group_size(MOTION_BLUR_GROUP_SIZE, MOTION_BLUR_GROUP_SIZE)
.additional_info("eevee_shared", "draw_view", "eevee_sampling_data")
- .uniform_buf(4, "MotionBlurData", "motion_blur_buf")
+ .uniform_buf(6, "MotionBlurData", "motion_blur_buf")
.sampler(0, ImageType::DEPTH_2D, "depth_tx")
.sampler(1, ImageType::FLOAT_2D, "velocity_tx")
.sampler(2, ImageType::FLOAT_2D, "in_color_tx")
diff --git a/source/blender/draw/engines/eevee_next/shaders/infos/eevee_velocity_info.hh b/source/blender/draw/engines/eevee_next/shaders/infos/eevee_velocity_info.hh
index 6e8e8fb020a..0a1c2721c61 100644
--- a/source/blender/draw/engines/eevee_next/shaders/infos/eevee_velocity_info.hh
+++ b/source/blender/draw/engines/eevee_next/shaders/infos/eevee_velocity_info.hh
@@ -1,5 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
+#include "eevee_defines.hh"
#include "gpu_shader_create_info.hh"
/* -------------------------------------------------------------------- */
@@ -17,19 +18,20 @@ GPU_SHADER_INTERFACE_INFO(eevee_velocity_surface_iface, "motion")
GPU_SHADER_CREATE_INFO(eevee_velocity_camera)
.define("VELOCITY_CAMERA")
- .uniform_buf(1, "CameraData", "camera_prev")
- .uniform_buf(2, "CameraData", "camera_curr")
- .uniform_buf(3, "CameraData", "camera_next");
+ .uniform_buf(VELOCITY_CAMERA_PREV_BUF, "CameraData", "camera_prev")
+ .uniform_buf(VELOCITY_CAMERA_CURR_BUF, "CameraData", "camera_curr")
+ .uniform_buf(VELOCITY_CAMERA_NEXT_BUF, "CameraData", "camera_next");
GPU_SHADER_CREATE_INFO(eevee_velocity_geom)
.define("MAT_VELOCITY")
- .auto_resource_location(true)
- .storage_buf(4, Qualifier::READ, "mat4", "velocity_obj_prev_buf[]", Frequency::PASS)
- .storage_buf(5, Qualifier::READ, "mat4", "velocity_obj_next_buf[]", Frequency::PASS)
- .storage_buf(6, Qualifier::READ, "vec4", "velocity_geo_prev_buf[]", Frequency::PASS)
- .storage_buf(7, Qualifier::READ, "vec4", "velocity_geo_next_buf[]", Frequency::PASS)
- .storage_buf(
- 7, Qualifier::READ, "VelocityIndex", "velocity_indirection_buf[]", Frequency::PASS)
+ .storage_buf(VELOCITY_OBJ_PREV_BUF_SLOT, Qualifier::READ, "mat4", "velocity_obj_prev_buf[]")
+ .storage_buf(VELOCITY_OBJ_NEXT_BUF_SLOT, Qualifier::READ, "mat4", "velocity_obj_next_buf[]")
+ .storage_buf(VELOCITY_GEO_PREV_BUF_SLOT, Qualifier::READ, "vec4", "velocity_geo_prev_buf[]")
+ .storage_buf(VELOCITY_GEO_NEXT_BUF_SLOT, Qualifier::READ, "vec4", "velocity_geo_next_buf[]")
+ .storage_buf(VELOCITY_INDIRECTION_BUF_SLOT,
+ Qualifier::READ,
+ "VelocityIndex",
+ "velocity_indirection_buf[]")
.vertex_out(eevee_velocity_surface_iface)
.fragment_out(0, Type::VEC4, "out_velocity")
.additional_info("eevee_velocity_camera");
diff --git a/source/blender/draw/engines/external/external_engine.c b/source/blender/draw/engines/external/external_engine.c
index b9c09e2bc4f..3f047d8de68 100644
--- a/source/blender/draw/engines/external/external_engine.c
+++ b/source/blender/draw/engines/external/external_engine.c
@@ -236,7 +236,11 @@ static void external_draw_scene_do_v3d(void *vedata)
RegionView3D *rv3d = draw_ctx->rv3d;
ARegion *region = draw_ctx->region;
- DRW_state_reset_ex(DRW_STATE_DEFAULT & ~DRW_STATE_DEPTH_LESS_EQUAL);
+ DRW_state_reset_ex(DRW_STATE_WRITE_COLOR);
+
+ /* The external engine can use the OpenGL rendering API directly, so make sure the state is
+ * already applied. */
+ GPU_apply_state();
/* Create render engine. */
if (!rv3d->render_engine) {
@@ -332,6 +336,12 @@ static void external_draw_scene_do_image(void *UNUSED(vedata))
BLI_assert(re != NULL);
BLI_assert(engine != NULL);
+ DRW_state_reset_ex(DRW_STATE_WRITE_COLOR);
+
+ /* The external engine can use the OpenGL rendering API directly, so make sure the state is
+ * already applied. */
+ GPU_apply_state();
+
const DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
/* Clear the depth buffer to the value used by the background overlay so that the overlay is not
diff --git a/source/blender/draw/engines/gpencil/gpencil_draw_data.c b/source/blender/draw/engines/gpencil/gpencil_draw_data.c
index 65ddb80ad55..e54ac99a888 100644
--- a/source/blender/draw/engines/gpencil/gpencil_draw_data.c
+++ b/source/blender/draw/engines/gpencil/gpencil_draw_data.c
@@ -460,7 +460,7 @@ GPENCIL_ViewLayerData *GPENCIL_view_layer_data_ensure(void)
GPENCIL_ViewLayerData **vldata = (GPENCIL_ViewLayerData **)DRW_view_layer_engine_data_ensure(
&draw_engine_gpencil_type, gpencil_view_layer_data_free);
- /* NOTE(&fclem): Putting this stuff in viewlayer means it is shared by all viewports.
+ /* NOTE(@fclem): Putting this stuff in view-layer means it is shared by all viewports.
* For now it is ok, but in the future, it could become a problem if we implement
* the caching system. */
if (*vldata == NULL) {
diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.c b/source/blender/draw/engines/gpencil/gpencil_engine.c
index 4f520e61936..42c396a0d43 100644
--- a/source/blender/draw/engines/gpencil/gpencil_engine.c
+++ b/source/blender/draw/engines/gpencil/gpencil_engine.c
@@ -799,7 +799,7 @@ static void gpencil_draw_mask(GPENCIL_Data *vedata, GPENCIL_tObject *ob, GPENCIL
}
GPENCIL_tLayer *mask_layer = gpencil_layer_cache_get(ob, i);
- /* When filtering by viewlayer, the mask could be null and must be ignored. */
+ /* When filtering by view-layer, the mask could be null and must be ignored. */
if (mask_layer == NULL) {
continue;
}
diff --git a/source/blender/draw/engines/gpencil/shaders/infos/gpencil_info.hh b/source/blender/draw/engines/gpencil/shaders/infos/gpencil_info.hh
index 1db98d13c4a..ee22362e0d4 100644
--- a/source/blender/draw/engines/gpencil/shaders/infos/gpencil_info.hh
+++ b/source/blender/draw/engines/gpencil/shaders/infos/gpencil_info.hh
@@ -47,7 +47,7 @@ GPU_SHADER_CREATE_INFO(gpencil_geometry)
/** \} */
/* -------------------------------------------------------------------- */
-/** \name Fullscreen shaders
+/** \name Full-Screen Shaders
* \{ */
GPU_SHADER_CREATE_INFO(gpencil_layer_blend)
diff --git a/source/blender/draw/engines/overlay/overlay_antialiasing.c b/source/blender/draw/engines/overlay/overlay_antialiasing.cc
index 780915b7fc4..2242ad8b609 100644
--- a/source/blender/draw/engines/overlay/overlay_antialiasing.c
+++ b/source/blender/draw/engines/overlay/overlay_antialiasing.cc
@@ -34,8 +34,8 @@
* - Works without geometry shader.
* - Can inflate line thickness.
* - Coverage is very close to perfect and can even be filtered (Blackman-Harris, gaussian).
- * - Wires can "bleed" / overlap non-line objects since the filter is in screenspace.
- * - Only uses one additional lightweight fullscreen buffer (compared to MSAA/SMAA).
+ * - Wires can "bleed" / overlap non-line objects since the filter is in screen-space.
+ * - Only uses one additional lightweight full-screen buffer (compared to MSAA/SMAA).
* - No convergence time (compared to TAA).
*/
@@ -43,7 +43,7 @@
#include "ED_screen.h"
-#include "overlay_private.h"
+#include "overlay_private.hh"
void OVERLAY_antialiasing_init(OVERLAY_Data *vedata)
{
@@ -55,7 +55,8 @@ void OVERLAY_antialiasing_init(OVERLAY_Data *vedata)
/* Small texture which will have very small impact on render-time. */
if (txl->dummy_depth_tx == NULL) {
const float pixel[1] = {1.0f};
- txl->dummy_depth_tx = DRW_texture_create_2d(1, 1, GPU_DEPTH_COMPONENT24, 0, pixel);
+ txl->dummy_depth_tx = DRW_texture_create_2d(
+ 1, 1, GPU_DEPTH_COMPONENT24, DRWTextureFlag(0), pixel);
}
if (!DRW_state_is_fbo()) {
@@ -72,7 +73,7 @@ void OVERLAY_antialiasing_init(OVERLAY_Data *vedata)
if (pd->antialiasing.enabled) {
DRW_texture_ensure_fullscreen_2d(&txl->overlay_color_tx, GPU_SRGB8_A8, DRW_TEX_FILTER);
- DRW_texture_ensure_fullscreen_2d(&txl->overlay_line_tx, GPU_RGBA8, 0);
+ DRW_texture_ensure_fullscreen_2d(&txl->overlay_line_tx, GPU_RGBA8, DRWTextureFlag(0));
color_tex = txl->overlay_color_tx;
line_tex = txl->overlay_line_tx;
@@ -177,7 +178,7 @@ void OVERLAY_antialiasing_cache_finish(OVERLAY_Data *vedata)
const bool do_wireframe = pd->antialiasing.do_depth_copy ||
pd->antialiasing.do_depth_infront_copy;
if (pd->xray_enabled || do_wireframe) {
- DRW_texture_ensure_fullscreen_2d(&txl->temp_depth_tx, GPU_DEPTH24_STENCIL8, 0);
+ DRW_texture_ensure_fullscreen_2d(&txl->temp_depth_tx, GPU_DEPTH24_STENCIL8, DRWTextureFlag(0));
}
}
diff --git a/source/blender/draw/engines/overlay/overlay_armature.c b/source/blender/draw/engines/overlay/overlay_armature.cc
index df5ee6a18c0..494fd3739d7 100644
--- a/source/blender/draw/engines/overlay/overlay_armature.c
+++ b/source/blender/draw/engines/overlay/overlay_armature.cc
@@ -37,7 +37,7 @@
#include "draw_common.h"
#include "draw_manager_text.h"
-#include "overlay_private.h"
+#include "overlay_private.hh"
#include "draw_cache_impl.h"
@@ -100,7 +100,7 @@ bool OVERLAY_armature_is_pose_mode(Object *ob, const DRWContextState *draw_ctx)
}
/* Armature parent is also handled by pose mode engine. */
- if ((active_ob != NULL) && (draw_ctx->object_mode & OB_MODE_ALL_WEIGHT_PAINT)) {
+ if ((active_ob != nullptr) && (draw_ctx->object_mode & OB_MODE_ALL_WEIGHT_PAINT)) {
if (ob == draw_ctx->object_pose) {
return true;
}
@@ -123,7 +123,7 @@ void OVERLAY_armature_cache_init(OVERLAY_Data *vedata)
pd->armature.do_pose_xray = (pd->overlay.flag & V3D_OVERLAY_BONE_SELECT) != 0;
pd->armature.do_pose_fade_geom = pd->armature.do_pose_xray &&
((draw_ctx->object_mode & OB_MODE_WEIGHT_PAINT) == 0) &&
- draw_ctx->object_pose != NULL;
+ draw_ctx->object_pose != nullptr;
const float wire_alpha = pd->overlay.bone_wire_alpha;
const bool use_wire_alpha = (wire_alpha < 1.0f);
@@ -139,16 +139,18 @@ void OVERLAY_armature_cache_init(OVERLAY_Data *vedata)
DRWShadingGroup *grp;
pd->armature_bone_select_act_grp = grp = DRW_shgroup_create(sh, psl->armature_bone_select_ps);
- DRW_shgroup_uniform_vec4_copy(grp, "color", (float[4]){0.0f, 0.0f, 0.0f, alpha});
+ float4 color = {0.0f, 0.0f, 0.0f, alpha};
+ DRW_shgroup_uniform_vec4_copy(grp, "ucolor", color);
pd->armature_bone_select_grp = grp = DRW_shgroup_create(sh, psl->armature_bone_select_ps);
- DRW_shgroup_uniform_vec4_copy(grp, "color", (float[4]){0.0f, 0.0f, 0.0f, pow(alpha, 4)});
+ color = {0.0f, 0.0f, 0.0f, powf(alpha, 4)};
+ DRW_shgroup_uniform_vec4_copy(grp, "ucolor", color);
}
for (int i = 0; i < 2; i++) {
struct GPUShader *sh;
struct GPUVertFormat *format;
- DRWShadingGroup *grp = NULL;
+ DRWShadingGroup *grp = nullptr;
OVERLAY_InstanceFormats *formats = OVERLAY_shader_instance_formats_get();
OVERLAY_ArmatureCallBuffers *cb = &pd->armature_call_buffers[i];
@@ -157,7 +159,8 @@ void OVERLAY_armature_cache_init(OVERLAY_Data *vedata)
cb->transp.custom_shapes_ghash = BLI_ghash_ptr_new(__func__);
DRWPass **p_armature_ps = &psl->armature_ps[i];
- DRWState infront_state = (DRW_state_is_select() && (i == 1)) ? DRW_STATE_IN_FRONT_SELECT : 0;
+ DRWState infront_state = (DRW_state_is_select() && (i == 1)) ? DRW_STATE_IN_FRONT_SELECT :
+ DRWState(0);
state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_WRITE_DEPTH;
DRW_PASS_CREATE(*p_armature_ps, state | pd->clipping_state | infront_state);
DRWPass *armature_ps = *p_armature_ps;
@@ -612,15 +615,16 @@ static void drw_shgroup_bone_envelope(ArmatureDrawContext *ctx,
/* Custom (geometry) */
-extern void drw_batch_cache_validate(Object *custom);
-extern void drw_batch_cache_generate_requested_delayed(Object *custom);
+extern "C" void drw_batch_cache_validate(Object *custom);
+extern "C" void drw_batch_cache_generate_requested_delayed(Object *custom);
BLI_INLINE DRWCallBuffer *custom_bone_instance_shgroup(ArmatureDrawContext *ctx,
DRWShadingGroup *grp,
struct GPUBatch *custom_geom)
{
- DRWCallBuffer *buf = BLI_ghash_lookup(ctx->custom_shapes_ghash, custom_geom);
- if (buf == NULL) {
+ DRWCallBuffer *buf = static_cast<DRWCallBuffer *>(
+ BLI_ghash_lookup(ctx->custom_shapes_ghash, custom_geom));
+ if (buf == nullptr) {
OVERLAY_InstanceFormats *formats = OVERLAY_shader_instance_formats_get();
buf = DRW_shgroup_call_buffer_instance(grp, formats->instance_bone, custom_geom);
BLI_ghash_insert(ctx->custom_shapes_ghash, custom_geom, buf);
@@ -641,7 +645,7 @@ static void drw_shgroup_bone_custom_solid_mesh(ArmatureDrawContext *ctx,
DRW_mesh_batch_cache_validate(custom, mesh);
struct GPUBatch *surf = DRW_mesh_batch_cache_get_surface(mesh);
- struct GPUBatch *edges = DRW_mesh_batch_cache_get_edge_detection(mesh, NULL);
+ struct GPUBatch *edges = DRW_mesh_batch_cache_get_edge_detection(mesh, nullptr);
struct GPUBatch *ledges = DRW_mesh_batch_cache_get_loose_edges(mesh);
BoneInstanceData inst_data;
DRWCallBuffer *buf;
@@ -710,7 +714,7 @@ static void drw_shgroup_custom_bone_curve(ArmatureDrawContext *ctx,
/* This only handles curves without any surface. The other curve types should have been converted
* to meshes and rendered in the mesh drawing function. */
- struct GPUBatch *ledges = NULL;
+ struct GPUBatch *ledges = nullptr;
if (custom->type == OB_FONT) {
ledges = DRW_cache_text_edge_wire_get(custom);
}
@@ -744,14 +748,15 @@ static void drw_shgroup_bone_custom_solid(ArmatureDrawContext *ctx,
* other data type, but supporting all evaluated geometry components would require a much
* larger refactor of this area. */
Mesh *mesh = BKE_object_get_evaluated_mesh_no_subsurf(custom);
- if (mesh != NULL) {
+ if (mesh != nullptr) {
drw_shgroup_bone_custom_solid_mesh(
ctx, mesh, bone_mat, bone_color, hint_color, outline_color, custom);
return;
}
if (ELEM(custom->type, OB_CURVES_LEGACY, OB_FONT, OB_SURF)) {
- drw_shgroup_custom_bone_curve(ctx, custom->data, bone_mat, outline_color, custom);
+ drw_shgroup_custom_bone_curve(
+ ctx, static_cast<Curve *>(custom->data), bone_mat, outline_color, custom);
}
}
@@ -762,13 +767,14 @@ static void drw_shgroup_bone_custom_wire(ArmatureDrawContext *ctx,
{
/* See comments in #drw_shgroup_bone_custom_solid. */
Mesh *mesh = BKE_object_get_evaluated_mesh_no_subsurf(custom);
- if (mesh != NULL) {
+ if (mesh != nullptr) {
drw_shgroup_bone_custom_mesh_wire(ctx, mesh, bone_mat, color, custom);
return;
}
if (ELEM(custom->type, OB_CURVES_LEGACY, OB_FONT, OB_SURF)) {
- drw_shgroup_custom_bone_curve(ctx, custom->data, bone_mat, color, custom);
+ drw_shgroup_custom_bone_curve(
+ ctx, static_cast<Curve *>(custom->data), bone_mat, color, custom);
}
}
@@ -890,14 +896,14 @@ enum {
/* This function sets the color-set for coloring a certain bone */
static void set_pchan_colorset(ArmatureDrawContext *ctx, Object *ob, bPoseChannel *pchan)
{
- bPose *pose = (ob) ? ob->pose : NULL;
- bArmature *arm = (ob) ? ob->data : NULL;
- bActionGroup *grp = NULL;
+ bPose *pose = (ob) ? ob->pose : nullptr;
+ bArmature *arm = (ob) ? static_cast<bArmature *>(ob->data) : nullptr;
+ bActionGroup *grp = nullptr;
short color_index = 0;
/* sanity check */
- if (ELEM(NULL, ob, arm, pose, pchan)) {
- ctx->bcolor = NULL;
+ if (ELEM(nullptr, ob, arm, pose, pchan)) {
+ ctx->bcolor = nullptr;
return;
}
@@ -914,7 +920,7 @@ static void set_pchan_colorset(ArmatureDrawContext *ctx, Object *ob, bPoseChanne
}
}
- /* bcolor is a pointer to the color set to use. If NULL, then the default
+ /* bcolor is a pointer to the color set to use. If nullptr, then the default
* color set (based on the theme colors for 3d-view) is used.
*/
if (color_index > 0) {
@@ -922,11 +928,11 @@ static void set_pchan_colorset(ArmatureDrawContext *ctx, Object *ob, bPoseChanne
ctx->bcolor = &btheme->tarm[(color_index - 1)];
}
else if (color_index == -1) {
- /* use the group's own custom color set (grp is always != NULL here) */
+ /* use the group's own custom color set (grp is always != nullptr here) */
ctx->bcolor = &grp->cs;
}
else {
- ctx->bcolor = NULL;
+ ctx->bcolor = nullptr;
}
}
@@ -1008,7 +1014,7 @@ static bool set_pchan_color(const ArmatureDrawContext *ctx,
return true;
}
case PCHAN_COLOR_CONSTS: {
- if ((bcolor == NULL) || (bcolor->flag & TH_WIRECOLOR_CONSTCOLS)) {
+ if ((bcolor == nullptr) || (bcolor->flag & TH_WIRECOLOR_CONSTCOLS)) {
if (constflag & PCHAN_HAS_TARGET) {
copy_v4_v4(fcolor, G_draw.block.color_bone_pose_target);
}
@@ -1192,15 +1198,15 @@ static const float *get_bone_hint_color(const ArmatureDrawContext *ctx,
static void pchan_draw_data_init(bPoseChannel *pchan)
{
- if (pchan->draw_data != NULL) {
+ if (pchan->draw_data != nullptr) {
if (pchan->draw_data->bbone_matrix_len != pchan->bone->segments) {
MEM_SAFE_FREE(pchan->draw_data);
}
}
- if (pchan->draw_data == NULL) {
- pchan->draw_data = MEM_mallocN(
- sizeof(*pchan->draw_data) + sizeof(Mat4) * pchan->bone->segments, __func__);
+ if (pchan->draw_data == nullptr) {
+ pchan->draw_data = static_cast<bPoseChannelDrawData *>(
+ MEM_mallocN(sizeof(*pchan->draw_data) + sizeof(Mat4) * pchan->bone->segments, __func__));
pchan->draw_data->bbone_matrix_len = pchan->bone->segments;
}
}
@@ -1243,11 +1249,11 @@ static void edbo_compute_bbone_child(bArmature *arm)
{
EditBone *eBone;
- for (eBone = arm->edbo->first; eBone; eBone = eBone->next) {
- eBone->bbone_child = NULL;
+ for (eBone = static_cast<EditBone *>(arm->edbo->first); eBone; eBone = eBone->next) {
+ eBone->bbone_child = nullptr;
}
- for (eBone = arm->edbo->first; eBone; eBone = eBone->next) {
+ for (eBone = static_cast<EditBone *>(arm->edbo->first); eBone; eBone = eBone->next) {
if (eBone->parent && (eBone->flag & BONE_CONNECTED)) {
eBone->parent->bbone_child = eBone;
}
@@ -1274,7 +1280,7 @@ static void ebone_spline_preview(EditBone *ebone, const float result_array[MAX_B
prev = ebone->parent;
}
else {
- prev = NULL;
+ prev = nullptr;
}
}
else {
@@ -1398,7 +1404,8 @@ static void draw_bone_update_disp_matrix_bbone(EditBone *eBone, bPoseChannel *pc
bbone_segments = eBone->segments;
}
- size_to_mat4(s, (const float[3]){xwidth, length / bbone_segments, zwidth});
+ const float3 size_vec = {xwidth, length / bbone_segments, zwidth};
+ size_to_mat4(s, size_vec);
/* Compute BBones segment matrices... */
/* Note that we need this even for one-segment bones, because box drawing need specific weirdo
@@ -1471,8 +1478,8 @@ static void draw_axes(ArmatureDrawContext *ctx,
{
float final_col[4];
const float *col = (ctx->const_color) ? ctx->const_color :
- (BONE_FLAG(eBone, pchan) & BONE_SELECTED) ? G_draw.block.color_text_hi :
- G_draw.block.color_text;
+ (BONE_FLAG(eBone, pchan) & BONE_SELECTED) ? &G_draw.block.color_text_hi.x :
+ &G_draw.block.color_text.x;
copy_v4_v4(final_col, col);
/* Mix with axes color. */
final_col[3] = (ctx->const_color) ? 1.0 : (BONE_FLAG(eBone, pchan) & BONE_SELECTED) ? 0.1 : 0.65;
@@ -1483,7 +1490,8 @@ static void draw_axes(ArmatureDrawContext *ctx,
float axis_mat[4][4];
float length = pchan->bone->length;
copy_m4_m4(axis_mat, pchan->custom_tx ? pchan->custom_tx->pose_mat : pchan->pose_mat);
- rescale_m4(axis_mat, (float[3]){length, length, length});
+ const float3 length_vec = {length, length, length};
+ rescale_m4(axis_mat, length_vec);
translate_m4(axis_mat, 0.0, arm->axes_position - 1.0, 0.0);
drw_shgroup_bone_axes(ctx, axis_mat, final_col);
@@ -1509,8 +1517,8 @@ static void draw_points(ArmatureDrawContext *ctx,
copy_v4_v4(col_solid_root, G_draw.block.color_bone_solid);
copy_v4_v4(col_solid_tail, G_draw.block.color_bone_solid);
- copy_v4_v4(col_wire_root, (ctx->const_color) ? ctx->const_color : G_draw.block.color_vertex);
- copy_v4_v4(col_wire_tail, (ctx->const_color) ? ctx->const_color : G_draw.block.color_vertex);
+ copy_v4_v4(col_wire_root, (ctx->const_color) ? ctx->const_color : &G_draw.block.color_vertex.x);
+ copy_v4_v4(col_wire_tail, (ctx->const_color) ? ctx->const_color : &G_draw.block.color_vertex.x);
const bool is_envelope_draw = (arm->drawtype == ARM_ENVELOPE);
const float envelope_ignore = -1.0f;
@@ -1704,7 +1712,7 @@ static void draw_bone_line(ArmatureDrawContext *ctx,
const float *col_head = no_display;
const float *col_tail = col_bone;
- if (ctx->const_color != NULL) {
+ if (ctx->const_color != nullptr) {
col_wire = no_display; /* actually shrink the display. */
col_bone = col_head = col_tail = ctx->const_color;
}
@@ -1724,7 +1732,7 @@ static void draw_bone_line(ArmatureDrawContext *ctx,
(pchan->bone->parent && (boneflag & BONE_CONNECTED)))) {
if (eBone) {
- col_head = (eBone->flag & BONE_ROOTSEL) ? G_draw.block.color_vertex_select : col_bone;
+ col_head = (eBone->flag & BONE_ROOTSEL) ? &G_draw.block.color_vertex_select.x : col_bone;
}
else {
col_head = col_bone;
@@ -1773,7 +1781,7 @@ static void draw_bone_wire(ArmatureDrawContext *ctx,
if (pchan) {
Mat4 *bbones_mat = (Mat4 *)pchan->draw_data->bbone_matrix;
- BLI_assert(bbones_mat != NULL);
+ BLI_assert(bbones_mat != nullptr);
for (int i = pchan->bone->segments; i--; bbones_mat++) {
drw_shgroup_bone_wire(ctx, bbones_mat->mat, col_wire);
@@ -1813,7 +1821,7 @@ static void draw_bone_box(ArmatureDrawContext *ctx,
if (pchan) {
Mat4 *bbones_mat = (Mat4 *)pchan->draw_data->bbone_matrix;
- BLI_assert(bbones_mat != NULL);
+ BLI_assert(bbones_mat != nullptr);
for (int i = pchan->bone->segments; i--; bbones_mat++) {
drw_shgroup_bone_box(ctx, bbones_mat->mat, col_solid, col_hint, col_wire);
@@ -1874,7 +1882,7 @@ static void draw_bone_degrees_of_freedom(ArmatureDrawContext *ctx, bPoseChannel
float xminmax[2], zminmax[2];
float color[4];
- if (ctx->dof_sphere == NULL) {
+ if (ctx->dof_sphere == nullptr) {
return;
}
@@ -1938,9 +1946,9 @@ static void pchan_draw_ik_lines(ArmatureDrawContext *ctx,
{
bConstraint *con;
bPoseChannel *parchan;
- float *line_start = NULL, *line_end = NULL;
+ float *line_start = nullptr, *line_end = nullptr;
- for (con = pchan->constraints.first; con; con = con->next) {
+ for (con = static_cast<bConstraint *>(pchan->constraints.first); con; con = con->next) {
if (con->enforce == 0.0f) {
continue;
}
@@ -2163,7 +2171,7 @@ static bool pchan_culling_test_envelope(const DRWView *view,
const Object *ob,
const bPoseChannel *pchan)
{
- const bArmature *arm = ob->data;
+ const bArmature *arm = static_cast<bArmature *>(ob->data);
BLI_assert(arm->drawtype == ARM_ENVELOPE);
UNUSED_VARS_NDEBUG(arm);
BoundSphere bsphere;
@@ -2177,7 +2185,7 @@ static bool pchan_culling_test_bbone(const DRWView *view,
const Object *ob,
const bPoseChannel *pchan)
{
- const bArmature *arm = ob->data;
+ const bArmature *arm = static_cast<bArmature *>(ob->data);
BLI_assert(arm->drawtype == ARM_B_BONE);
UNUSED_VARS_NDEBUG(arm);
const float ob_scale = mat4_to_size_max_axis(ob->obmat);
@@ -2224,11 +2232,12 @@ static void draw_armature_edit(ArmatureDrawContext *ctx)
* however the active bone isn't updated. Long term solution is an 'EditArmature' struct.
* for now we can draw from the original armature. See: T66773. */
// bArmature *arm = ob->data;
- bArmature *arm = ob_orig->data;
+ bArmature *arm = static_cast<bArmature *>(ob_orig->data);
edbo_compute_bbone_child(arm);
- for (eBone = arm->edbo->first, index = ob_orig->runtime.select_id; eBone;
+ for (eBone = static_cast<EditBone *>(arm->edbo->first), index = ob_orig->runtime.select_id;
+ eBone;
eBone = eBone->next, index += 0x10000) {
if (eBone->layer & arm->layer) {
if ((eBone->flag & BONE_HIDDEN_A) == 0) {
@@ -2249,37 +2258,37 @@ static void draw_armature_edit(ArmatureDrawContext *ctx)
boneflag &= ~BONE_DRAW_LOCKED_WEIGHT;
if (!is_select) {
- draw_bone_relations(ctx, eBone, NULL, arm, boneflag, constflag);
+ draw_bone_relations(ctx, eBone, nullptr, arm, boneflag, constflag);
}
if (arm->drawtype == ARM_ENVELOPE) {
- draw_bone_update_disp_matrix_default(eBone, NULL);
- draw_bone_envelope(ctx, eBone, NULL, arm, boneflag, constflag, select_id);
+ draw_bone_update_disp_matrix_default(eBone, nullptr);
+ draw_bone_envelope(ctx, eBone, nullptr, arm, boneflag, constflag, select_id);
}
else if (arm->drawtype == ARM_LINE) {
- draw_bone_update_disp_matrix_default(eBone, NULL);
- draw_bone_line(ctx, eBone, NULL, arm, boneflag, constflag, select_id);
+ draw_bone_update_disp_matrix_default(eBone, nullptr);
+ draw_bone_line(ctx, eBone, nullptr, arm, boneflag, constflag, select_id);
}
else if (arm->drawtype == ARM_WIRE) {
- draw_bone_update_disp_matrix_bbone(eBone, NULL);
- draw_bone_wire(ctx, eBone, NULL, arm, boneflag, constflag, select_id);
+ draw_bone_update_disp_matrix_bbone(eBone, nullptr);
+ draw_bone_wire(ctx, eBone, nullptr, arm, boneflag, constflag, select_id);
}
else if (arm->drawtype == ARM_B_BONE) {
- draw_bone_update_disp_matrix_bbone(eBone, NULL);
- draw_bone_box(ctx, eBone, NULL, arm, boneflag, constflag, select_id);
+ draw_bone_update_disp_matrix_bbone(eBone, nullptr);
+ draw_bone_box(ctx, eBone, nullptr, arm, boneflag, constflag, select_id);
}
else {
- draw_bone_update_disp_matrix_default(eBone, NULL);
- draw_bone_octahedral(ctx, eBone, NULL, arm, boneflag, constflag, select_id);
+ draw_bone_update_disp_matrix_default(eBone, nullptr);
+ draw_bone_octahedral(ctx, eBone, nullptr, arm, boneflag, constflag, select_id);
}
if (!is_select) {
if (show_text && (arm->flag & ARM_DRAWNAMES)) {
- draw_bone_name(ctx, eBone, NULL, arm, boneflag);
+ draw_bone_name(ctx, eBone, nullptr, arm, boneflag);
}
if (arm->flag & ARM_DRAWAXES) {
- draw_axes(ctx, eBone, NULL, arm);
+ draw_axes(ctx, eBone, nullptr, arm);
}
}
}
@@ -2292,13 +2301,13 @@ static void draw_armature_pose(ArmatureDrawContext *ctx)
Object *ob = ctx->ob;
const DRWContextState *draw_ctx = DRW_context_state_get();
const Scene *scene = draw_ctx->scene;
- bArmature *arm = ob->data;
+ bArmature *arm = static_cast<bArmature *>(ob->data);
bPoseChannel *pchan;
int index = -1;
const bool show_text = DRW_state_show_text();
bool draw_locked_weights = false;
- /* We can't safely draw non-updated pose, might contain NULL bone pointers... */
+ /* We can't safely draw non-updated pose, might contain nullptr bone pointers... */
if (ob->pose->flag & POSE_RECALC) {
return;
}
@@ -2323,7 +2332,7 @@ static void draw_armature_pose(ArmatureDrawContext *ctx)
/* Allow selection when in weight-paint mode
* (selection code ensures this won't become active). */
((draw_ctx->object_mode & OB_MODE_ALL_WEIGHT_PAINT) &&
- (draw_ctx->object_pose != NULL))))) &&
+ (draw_ctx->object_pose != nullptr))))) &&
DRW_state_is_select();
if (is_pose_select) {
@@ -2334,10 +2343,11 @@ static void draw_armature_pose(ArmatureDrawContext *ctx)
/* In weight paint mode retrieve the vertex group lock status. */
if ((draw_ctx->object_mode & OB_MODE_ALL_WEIGHT_PAINT) && (draw_ctx->object_pose == ob) &&
- (draw_ctx->obact != NULL)) {
+ (draw_ctx->obact != nullptr)) {
draw_locked_weights = true;
- for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
+ for (pchan = static_cast<bPoseChannel *>(ob->pose->chanbase.first); pchan;
+ pchan = pchan->next) {
pchan->bone->flag &= ~BONE_DRAW_LOCKED_WEIGHT;
}
@@ -2355,9 +2365,10 @@ static void draw_armature_pose(ArmatureDrawContext *ctx)
}
}
- const DRWView *view = is_pose_select ? DRW_view_default_get() : NULL;
+ const DRWView *view = is_pose_select ? DRW_view_default_get() : nullptr;
- for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next, index += 0x10000) {
+ for (pchan = static_cast<bPoseChannel *>(ob->pose->chanbase.first); pchan;
+ pchan = pchan->next, index += 0x10000) {
Bone *bone = pchan->bone;
const bool bone_visible = (bone->flag & (BONE_HIDDEN_P | BONE_HIDDEN_PG)) == 0;
@@ -2392,43 +2403,43 @@ static void draw_armature_pose(ArmatureDrawContext *ctx)
}
if (!is_pose_select) {
- draw_bone_relations(ctx, NULL, pchan, arm, boneflag, constflag);
+ draw_bone_relations(ctx, nullptr, pchan, arm, boneflag, constflag);
}
if ((pchan->custom) && !(arm->flag & ARM_NO_CUSTOM)) {
draw_bone_update_disp_matrix_custom(pchan);
if (!is_pose_select || pchan_culling_test_custom(view, ob, pchan)) {
- draw_bone_custom_shape(ctx, NULL, pchan, arm, boneflag, constflag, select_id);
+ draw_bone_custom_shape(ctx, nullptr, pchan, arm, boneflag, constflag, select_id);
}
}
else if (arm->drawtype == ARM_ENVELOPE) {
- draw_bone_update_disp_matrix_default(NULL, pchan);
+ draw_bone_update_disp_matrix_default(nullptr, pchan);
if (!is_pose_select || pchan_culling_test_envelope(view, ob, pchan)) {
- draw_bone_envelope(ctx, NULL, pchan, arm, boneflag, constflag, select_id);
+ draw_bone_envelope(ctx, nullptr, pchan, arm, boneflag, constflag, select_id);
}
}
else if (arm->drawtype == ARM_LINE) {
- draw_bone_update_disp_matrix_default(NULL, pchan);
+ draw_bone_update_disp_matrix_default(nullptr, pchan);
if (!is_pose_select || pchan_culling_test_line(view, ob, pchan)) {
- draw_bone_line(ctx, NULL, pchan, arm, boneflag, constflag, select_id);
+ draw_bone_line(ctx, nullptr, pchan, arm, boneflag, constflag, select_id);
}
}
else if (arm->drawtype == ARM_WIRE) {
- draw_bone_update_disp_matrix_bbone(NULL, pchan);
+ draw_bone_update_disp_matrix_bbone(nullptr, pchan);
if (!is_pose_select || pchan_culling_test_wire(view, ob, pchan)) {
- draw_bone_wire(ctx, NULL, pchan, arm, boneflag, constflag, select_id);
+ draw_bone_wire(ctx, nullptr, pchan, arm, boneflag, constflag, select_id);
}
}
else if (arm->drawtype == ARM_B_BONE) {
- draw_bone_update_disp_matrix_bbone(NULL, pchan);
+ draw_bone_update_disp_matrix_bbone(nullptr, pchan);
if (!is_pose_select || pchan_culling_test_bbone(view, ob, pchan)) {
- draw_bone_box(ctx, NULL, pchan, arm, boneflag, constflag, select_id);
+ draw_bone_box(ctx, nullptr, pchan, arm, boneflag, constflag, select_id);
}
}
else {
- draw_bone_update_disp_matrix_default(NULL, pchan);
+ draw_bone_update_disp_matrix_default(nullptr, pchan);
if (!is_pose_select || pchan_culling_test_octohedral(view, ob, pchan)) {
- draw_bone_octahedral(ctx, NULL, pchan, arm, boneflag, constflag, select_id);
+ draw_bone_octahedral(ctx, nullptr, pchan, arm, boneflag, constflag, select_id);
}
}
@@ -2439,11 +2450,11 @@ static void draw_armature_pose(ArmatureDrawContext *ctx)
}
if (show_text && (arm->flag & ARM_DRAWNAMES)) {
- draw_bone_name(ctx, NULL, pchan, arm, boneflag);
+ draw_bone_name(ctx, nullptr, pchan, arm, boneflag);
}
if (arm->flag & ARM_DRAWAXES) {
- draw_axes(ctx, NULL, pchan, arm);
+ draw_axes(ctx, nullptr, pchan, arm);
}
}
}
@@ -2467,7 +2478,7 @@ static void armature_context_setup(ArmatureDrawContext *ctx,
const bool draw_as_wire = (ob->dt < OB_SOLID);
const bool is_filled = (!pd->armature.transparent && !draw_as_wire) || !is_object_mode;
const bool is_transparent = pd->armature.transparent || (draw_as_wire && !is_object_mode);
- bArmature *arm = ob->data;
+ bArmature *arm = static_cast<bArmature *>(ob->data);
OVERLAY_ArmatureCallBuffers *cbo = &pd->armature_call_buffers[is_xray];
OVERLAY_ArmatureCallBuffersInner *cb = is_transparent ? &cbo->transp : &cbo->solid;
@@ -2476,8 +2487,8 @@ static void armature_context_setup(ArmatureDrawContext *ctx,
switch (arm->drawtype) {
case ARM_ENVELOPE:
ctx->envelope_outline = cb->envelope_outline;
- ctx->envelope_solid = (is_filled) ? cb->envelope_fill : NULL;
- ctx->envelope_distance = (do_envelope_dist) ? cb->envelope_distance : NULL;
+ ctx->envelope_solid = (is_filled) ? cb->envelope_fill : nullptr;
+ ctx->envelope_distance = (do_envelope_dist) ? cb->envelope_distance : nullptr;
break;
case ARM_LINE:
ctx->stick = cb->stick;
@@ -2487,20 +2498,20 @@ static void armature_context_setup(ArmatureDrawContext *ctx,
break;
case ARM_B_BONE:
ctx->outline = cb->box_outline;
- ctx->solid = (is_filled) ? cb->box_fill : NULL;
+ ctx->solid = (is_filled) ? cb->box_fill : nullptr;
break;
case ARM_OCTA:
ctx->outline = cb->octa_outline;
- ctx->solid = (is_filled) ? cb->octa_fill : NULL;
+ ctx->solid = (is_filled) ? cb->octa_fill : nullptr;
break;
}
ctx->ob = ob;
ctx->extras = &pd->extra_call_buffers[is_xray];
ctx->dof_lines = cb->dof_lines;
ctx->dof_sphere = cb->dof_sphere;
- ctx->point_solid = (is_filled) ? cb->point_fill : NULL;
+ ctx->point_solid = (is_filled) ? cb->point_fill : nullptr;
ctx->point_outline = cb->point_outline;
- ctx->custom_solid = (is_filled) ? cb->custom_fill : NULL;
+ ctx->custom_solid = (is_filled) ? cb->custom_fill : nullptr;
ctx->custom_outline = cb->custom_outline;
ctx->custom_wire = cb->custom_wire;
ctx->custom_shapes_ghash = cb->custom_shapes_ghash;
@@ -2518,7 +2529,7 @@ void OVERLAY_edit_armature_cache_populate(OVERLAY_Data *vedata, Object *ob)
{
OVERLAY_PrivateData *pd = vedata->stl->pd;
ArmatureDrawContext arm_ctx;
- armature_context_setup(&arm_ctx, pd, ob, true, true, false, NULL);
+ armature_context_setup(&arm_ctx, pd, ob, true, true, false, nullptr);
draw_armature_edit(&arm_ctx);
}
@@ -2526,7 +2537,7 @@ void OVERLAY_pose_armature_cache_populate(OVERLAY_Data *vedata, Object *ob)
{
OVERLAY_PrivateData *pd = vedata->stl->pd;
ArmatureDrawContext arm_ctx;
- armature_context_setup(&arm_ctx, pd, ob, true, false, true, NULL);
+ armature_context_setup(&arm_ctx, pd, ob, true, false, true, nullptr);
draw_armature_pose(&arm_ctx);
}
@@ -2586,8 +2597,8 @@ void OVERLAY_armature_cache_finish(OVERLAY_Data *vedata)
for (int i = 0; i < 2; i++) {
if (pd->armature_call_buffers[i].solid.custom_shapes_ghash) {
/* TODO(fclem): Do not free it for each frame but reuse it. Avoiding alloc cost. */
- BLI_ghash_free(pd->armature_call_buffers[i].solid.custom_shapes_ghash, NULL, NULL);
- BLI_ghash_free(pd->armature_call_buffers[i].transp.custom_shapes_ghash, NULL, NULL);
+ BLI_ghash_free(pd->armature_call_buffers[i].solid.custom_shapes_ghash, nullptr, nullptr);
+ BLI_ghash_free(pd->armature_call_buffers[i].transp.custom_shapes_ghash, nullptr, nullptr);
}
}
}
@@ -2604,7 +2615,7 @@ void OVERLAY_armature_in_front_draw(OVERLAY_Data *vedata)
{
OVERLAY_PassList *psl = vedata->psl;
- if (psl->armature_bone_select_ps == NULL || DRW_state_is_select()) {
+ if (psl->armature_bone_select_ps == nullptr || DRW_state_is_select()) {
DRW_draw_pass(psl->armature_transp_ps[1]);
DRW_draw_pass(psl->armature_ps[1]);
}
@@ -2615,7 +2626,7 @@ void OVERLAY_pose_draw(OVERLAY_Data *vedata)
OVERLAY_PassList *psl = vedata->psl;
OVERLAY_FramebufferList *fbl = vedata->fbl;
- if (psl->armature_bone_select_ps != NULL) {
+ if (psl->armature_bone_select_ps != nullptr) {
if (DRW_state_is_fbo()) {
GPU_framebuffer_bind(fbl->overlay_default_fb);
}
diff --git a/source/blender/draw/engines/overlay/overlay_background.c b/source/blender/draw/engines/overlay/overlay_background.cc
index 32bcd04e05b..2442efc033e 100644
--- a/source/blender/draw/engines/overlay/overlay_background.c
+++ b/source/blender/draw/engines/overlay/overlay_background.cc
@@ -10,7 +10,7 @@
#include "UI_resources.h"
#include "draw_manager_text.h"
-#include "overlay_private.h"
+#include "overlay_private.hh"
void OVERLAY_background_cache_init(OVERLAY_Data *vedata)
{
@@ -20,7 +20,7 @@ void OVERLAY_background_cache_init(OVERLAY_Data *vedata)
const DRWContextState *draw_ctx = DRW_context_state_get();
const Scene *scene = draw_ctx->scene;
const RegionView3D *rv3d = draw_ctx->rv3d;
- const BoundBox *bb = rv3d ? rv3d->clipbb : NULL;
+ const BoundBox *bb = rv3d ? rv3d->clipbb : nullptr;
const View3D *v3d = draw_ctx->v3d;
bool draw_clipping_bounds = (pd->clipping_state != 0);
@@ -80,7 +80,7 @@ void OVERLAY_background_cache_init(OVERLAY_Data *vedata)
DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth);
DRW_shgroup_uniform_vec4_copy(grp, "colorOverride", color_override);
DRW_shgroup_uniform_int_copy(grp, "bgType", background_type);
- DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
+ DRW_shgroup_call_procedural_triangles(grp, nullptr, 1);
}
if (draw_clipping_bounds) {
@@ -89,14 +89,14 @@ void OVERLAY_background_cache_init(OVERLAY_Data *vedata)
GPUShader *sh = OVERLAY_shader_clipbound();
DRWShadingGroup *grp = DRW_shgroup_create(sh, psl->clipping_frustum_ps);
- DRW_shgroup_uniform_vec4_copy(grp, "color", G_draw.block.color_clipping_border);
+ DRW_shgroup_uniform_vec4_copy(grp, "ucolor", G_draw.block.color_clipping_border);
DRW_shgroup_uniform_vec3(grp, "boundbox", &bb->vec[0][0], 8);
struct GPUBatch *cube = DRW_cache_cube_get();
- DRW_shgroup_call(grp, cube, NULL);
+ DRW_shgroup_call(grp, cube, nullptr);
}
else {
- psl->clipping_frustum_ps = NULL;
+ psl->clipping_frustum_ps = nullptr;
}
}
diff --git a/source/blender/draw/engines/overlay/overlay_edit_curve.c b/source/blender/draw/engines/overlay/overlay_edit_curve.cc
index 09e3c3410c3..b84eb9b3a43 100644
--- a/source/blender/draw/engines/overlay/overlay_edit_curve.c
+++ b/source/blender/draw/engines/overlay/overlay_edit_curve.cc
@@ -9,7 +9,7 @@
#include "DNA_curve_types.h"
-#include "overlay_private.h"
+#include "overlay_private.hh"
void OVERLAY_edit_curve_cache_init(OVERLAY_Data *vedata)
{
@@ -65,7 +65,7 @@ void OVERLAY_edit_curve_cache_populate(OVERLAY_Data *vedata, Object *ob)
bool draw_normals = (pd->overlay.edit_flag & V3D_OVERLAY_EDIT_CU_NORMALS) != 0;
bool do_xray = (ob->dtx & OB_DRAW_IN_FRONT) != 0;
- Curve *cu = ob->data;
+ Curve *cu = static_cast<Curve *>(ob->data);
struct GPUBatch *geom;
geom = DRW_cache_curve_edge_wire_get(ob);
diff --git a/source/blender/draw/engines/overlay/overlay_edit_curves.cc b/source/blender/draw/engines/overlay/overlay_edit_curves.cc
index 02e40ea0304..dab44c655a5 100644
--- a/source/blender/draw/engines/overlay/overlay_edit_curves.cc
+++ b/source/blender/draw/engines/overlay/overlay_edit_curves.cc
@@ -11,7 +11,7 @@
#include "draw_cache_impl.h"
-#include "overlay_private.h"
+#include "overlay_private.hh"
void OVERLAY_edit_curves_init(OVERLAY_Data *vedata)
{
diff --git a/source/blender/draw/engines/overlay/overlay_edit_mesh.c b/source/blender/draw/engines/overlay/overlay_edit_mesh.cc
index 4d65cbc04ff..4509fd53ed8 100644
--- a/source/blender/draw/engines/overlay/overlay_edit_mesh.c
+++ b/source/blender/draw/engines/overlay/overlay_edit_mesh.cc
@@ -18,7 +18,7 @@
#include "draw_cache_impl.h"
#include "draw_manager_text.h"
-#include "overlay_private.h"
+#include "overlay_private.hh"
#define OVERLAY_EDIT_TEXT \
(V3D_OVERLAY_EDIT_EDGE_LEN | V3D_OVERLAY_EDIT_FACE_AREA | V3D_OVERLAY_EDIT_FACE_ANG | \
@@ -45,9 +45,9 @@ void OVERLAY_edit_mesh_cache_init(OVERLAY_Data *vedata)
OVERLAY_PassList *psl = vedata->psl;
OVERLAY_PrivateData *pd = vedata->stl->pd;
OVERLAY_ShadingData *shdata = &pd->shdata;
- DRWShadingGroup *grp = NULL;
- GPUShader *sh = NULL;
- DRWState state = 0;
+ DRWShadingGroup *grp = nullptr;
+ GPUShader *sh = nullptr;
+ DRWState state = DRWState(0);
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
@@ -109,7 +109,7 @@ void OVERLAY_edit_mesh_cache_init(OVERLAY_Data *vedata)
{
/* Normals */
state = DRW_STATE_WRITE_DEPTH | DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL |
- (pd->edit_mesh.do_zbufclip ? DRW_STATE_BLEND_ALPHA : 0);
+ (pd->edit_mesh.do_zbufclip ? DRW_STATE_BLEND_ALPHA : DRWState(0));
DRW_PASS_CREATE(psl->edit_mesh_normals_ps, state | pd->clipping_state);
sh = OVERLAY_shader_edit_mesh_normal();
@@ -204,7 +204,7 @@ void OVERLAY_edit_mesh_cache_init(OVERLAY_Data *vedata)
DRW_shgroup_state_enable(grp, DRW_STATE_WRITE_DEPTH);
}
else {
- pd->edit_mesh_facedots_grp[i] = NULL;
+ pd->edit_mesh_facedots_grp[i] = nullptr;
}
}
}
@@ -234,24 +234,24 @@ static void overlay_edit_mesh_add_ob_to_pass(OVERLAY_PrivateData *pd, Object *ob
pd->edit_mesh_faces_grp[in_front];
skin_roots_shgrp = pd->edit_mesh_skin_roots_grp[in_front];
- geom_edges = DRW_mesh_batch_cache_get_edit_edges(ob->data);
- geom_tris = DRW_mesh_batch_cache_get_edit_triangles(ob->data);
+ geom_edges = DRW_mesh_batch_cache_get_edit_edges(me);
+ geom_tris = DRW_mesh_batch_cache_get_edit_triangles(me);
DRW_shgroup_call_no_cull(edge_shgrp, geom_edges, ob);
DRW_shgroup_call_no_cull(face_shgrp, geom_tris, ob);
if (pd->edit_mesh.select_vert) {
- geom_verts = DRW_mesh_batch_cache_get_edit_vertices(ob->data);
+ geom_verts = DRW_mesh_batch_cache_get_edit_vertices(me);
DRW_shgroup_call_no_cull(vert_shgrp, geom_verts, ob);
if (has_skin_roots) {
circle = DRW_cache_circle_get();
- skin_roots = DRW_mesh_batch_cache_get_edit_skin_roots(ob->data);
+ skin_roots = DRW_mesh_batch_cache_get_edit_skin_roots(me);
DRW_shgroup_call_instances_with_attrs(skin_roots_shgrp, ob, circle, skin_roots);
}
}
if (fdot_shgrp) {
- geom_fcenter = DRW_mesh_batch_cache_get_edit_facedots(ob->data);
+ geom_fcenter = DRW_mesh_batch_cache_get_edit_facedots(me);
DRW_shgroup_call_no_cull(fdot_shgrp, geom_fcenter, ob);
}
}
@@ -259,7 +259,7 @@ static void overlay_edit_mesh_add_ob_to_pass(OVERLAY_PrivateData *pd, Object *ob
void OVERLAY_edit_mesh_cache_populate(OVERLAY_Data *vedata, Object *ob)
{
OVERLAY_PrivateData *pd = vedata->stl->pd;
- struct GPUBatch *geom = NULL;
+ struct GPUBatch *geom = nullptr;
bool draw_as_solid = (ob->dt > OB_WIRE);
bool do_in_front = (ob->dtx & OB_DRAW_IN_FRONT) != 0;
@@ -283,16 +283,17 @@ void OVERLAY_edit_mesh_cache_populate(OVERLAY_Data *vedata, Object *ob)
if (vnormals_do || lnormals_do || fnormals_do) {
struct GPUBatch *normal_geom = DRW_cache_normal_arrow_get();
+ Mesh *me = static_cast<Mesh *>(ob->data);
if (vnormals_do) {
- geom = DRW_mesh_batch_cache_get_edit_vnors(ob->data);
+ geom = DRW_mesh_batch_cache_get_edit_vnors(me);
DRW_shgroup_call_instances_with_attrs(pd->edit_mesh_normals_grp, ob, normal_geom, geom);
}
if (lnormals_do) {
- geom = DRW_mesh_batch_cache_get_edit_lnors(ob->data);
+ geom = DRW_mesh_batch_cache_get_edit_lnors(me);
DRW_shgroup_call_instances_with_attrs(pd->edit_mesh_normals_grp, ob, normal_geom, geom);
}
if (fnormals_do) {
- geom = DRW_mesh_batch_cache_get_edit_facedots(ob->data);
+ geom = DRW_mesh_batch_cache_get_edit_facedots(me);
DRW_shgroup_call_instances_with_attrs(pd->edit_mesh_normals_grp, ob, normal_geom, geom);
}
}
@@ -351,7 +352,7 @@ void OVERLAY_edit_mesh_draw(OVERLAY_Data *vedata)
DRW_view_set_active(pd->view_edit_faces_cage);
DRW_draw_pass(psl->edit_mesh_faces_cage_ps[NOT_IN_FRONT]);
- DRW_view_set_active(NULL);
+ DRW_view_set_active(nullptr);
GPU_framebuffer_bind(fbl->overlay_in_front_fb);
GPU_framebuffer_clear_depth(fbl->overlay_in_front_fb, 1.0f);
@@ -372,7 +373,7 @@ void OVERLAY_edit_mesh_draw(OVERLAY_Data *vedata)
}
if (!DRW_pass_is_empty(psl->edit_mesh_depth_ps[IN_FRONT])) {
- DRW_view_set_active(NULL);
+ DRW_view_set_active(nullptr);
DRW_draw_pass(psl->edit_mesh_depth_ps[IN_FRONT]);
}
diff --git a/source/blender/draw/engines/overlay/overlay_edit_text.c b/source/blender/draw/engines/overlay/overlay_edit_text.cc
index dfef5b3c241..ebadaa530e4 100644
--- a/source/blender/draw/engines/overlay/overlay_edit_text.c
+++ b/source/blender/draw/engines/overlay/overlay_edit_text.cc
@@ -7,11 +7,13 @@
#include "DRW_render.h"
+#include "UI_resources.h"
+
#include "BKE_vfont.h"
#include "DNA_curve_types.h"
-#include "overlay_private.h"
+#include "overlay_private.hh"
void OVERLAY_edit_text_cache_init(OVERLAY_Data *vedata)
{
@@ -35,20 +37,27 @@ void OVERLAY_edit_text_cache_init(OVERLAY_Data *vedata)
sh = OVERLAY_shader_uniform_color();
pd->edit_text_wire_grp[i] = grp = DRW_shgroup_create(sh, psl->edit_text_wire_ps[i]);
- DRW_shgroup_uniform_vec4_copy(grp, "color", G_draw.block.color_wire);
+ DRW_shgroup_uniform_vec4_copy(grp, "ucolor", G_draw.block.color_wire);
}
{
+ /* Cursor (text caret). */
state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ALPHA;
- DRW_PASS_CREATE(psl->edit_text_overlay_ps, state | pd->clipping_state);
-
+ DRW_PASS_CREATE(psl->edit_text_cursor_ps, state | pd->clipping_state);
sh = OVERLAY_shader_uniform_color();
- pd->edit_text_overlay_grp = grp = DRW_shgroup_create(sh, psl->edit_text_overlay_ps);
+ pd->edit_text_cursor_grp = grp = DRW_shgroup_create(sh, psl->edit_text_cursor_ps);
+ DRW_shgroup_uniform_vec4(grp, "ucolor", pd->edit_text.cursor_color, 1);
- DRW_shgroup_uniform_vec4(grp, "color", pd->edit_text.overlay_color, 1);
+ /* Selection boxes. */
+ state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ALPHA;
+ DRW_PASS_CREATE(psl->edit_text_selection_ps, state | pd->clipping_state);
+ sh = OVERLAY_shader_uniform_color();
+ pd->edit_text_selection_grp = grp = DRW_shgroup_create(sh, psl->edit_text_selection_ps);
+ DRW_shgroup_uniform_vec4(grp, "ucolor", pd->edit_text.selection_color, 1);
- state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_MUL | DRW_STATE_DEPTH_GREATER_EQUAL |
+ /* Highlight text within selection boxes. */
+ state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ALPHA | DRW_STATE_DEPTH_GREATER_EQUAL |
pd->clipping_state;
- DRW_PASS_INSTANCE_CREATE(psl->edit_text_darken_ps, psl->edit_text_overlay_ps, state);
+ DRW_PASS_INSTANCE_CREATE(psl->edit_text_highlight_ps, psl->edit_text_selection_ps, state);
}
{
/* Create view which will render everything (hopefully) behind the text geometry. */
@@ -74,7 +83,7 @@ static void v2_quad_corners_to_mat4(const float corners[4][2], float r_mat[4][4]
static void edit_text_cache_populate_select(OVERLAY_Data *vedata, Object *ob)
{
OVERLAY_PrivateData *pd = vedata->stl->pd;
- const Curve *cu = ob->data;
+ const Curve *cu = static_cast<Curve *>(ob->data);
EditFont *ef = cu->editfont;
float final_mat[4][4], box[4][2];
struct GPUBatch *geom = DRW_cache_quad_get();
@@ -112,14 +121,14 @@ static void edit_text_cache_populate_select(OVERLAY_Data *vedata, Object *ob)
v2_quad_corners_to_mat4(box, final_mat);
mul_m4_m4m4(final_mat, ob->obmat, final_mat);
- DRW_shgroup_call_obmat(pd->edit_text_overlay_grp, geom, final_mat);
+ DRW_shgroup_call_obmat(pd->edit_text_selection_grp, geom, final_mat);
}
}
static void edit_text_cache_populate_cursor(OVERLAY_Data *vedata, Object *ob)
{
OVERLAY_PrivateData *pd = vedata->stl->pd;
- const Curve *cu = ob->data;
+ const Curve *cu = static_cast<Curve *>(ob->data);
EditFont *edit_font = cu->editfont;
float(*cursor)[2] = edit_font->textcurs;
float mat[4][4];
@@ -128,13 +137,13 @@ static void edit_text_cache_populate_cursor(OVERLAY_Data *vedata, Object *ob)
mul_m4_m4m4(mat, ob->obmat, mat);
struct GPUBatch *geom = DRW_cache_quad_get();
- DRW_shgroup_call_obmat(pd->edit_text_overlay_grp, geom, mat);
+ DRW_shgroup_call_obmat(pd->edit_text_cursor_grp, geom, mat);
}
static void edit_text_cache_populate_boxes(OVERLAY_Data *vedata, Object *ob)
{
OVERLAY_ExtraCallBuffers *cb = OVERLAY_extra_call_buffer_get(vedata, ob);
- const Curve *cu = ob->data;
+ const Curve *cu = static_cast<Curve *>(ob->data);
for (int i = 0; i < cu->totbox; i++) {
TextBox *tb = &cu->tb[i];
@@ -193,11 +202,18 @@ void OVERLAY_edit_text_draw(OVERLAY_Data *vedata)
DRW_view_set_active(pd->view_edit_text);
- /* Alpha blended. */
- copy_v4_fl4(pd->edit_text.overlay_color, 0.8f, 0.8f, 0.8f, 0.5f);
- DRW_draw_pass(psl->edit_text_overlay_ps);
+ /* Selection Boxes. */
+ UI_GetThemeColor4fv(TH_WIDGET_TEXT_SELECTION, pd->edit_text.selection_color);
+ srgb_to_linearrgb_v4(pd->edit_text.selection_color, pd->edit_text.selection_color);
+ DRW_draw_pass(psl->edit_text_selection_ps);
+
+ /* Highlight text within selection boxes. */
+ UI_GetThemeColor4fv(TH_WIDGET_TEXT_HIGHLIGHT, pd->edit_text.selection_color);
+ srgb_to_linearrgb_v4(pd->edit_text.selection_color, pd->edit_text.selection_color);
+ DRW_draw_pass(psl->edit_text_highlight_ps);
- /* Multiply previous result where depth test fail. */
- copy_v4_fl4(pd->edit_text.overlay_color, 0.0f, 0.0f, 0.0f, 1.0f);
- DRW_draw_pass(psl->edit_text_darken_ps);
+ /* Cursor (text caret). */
+ UI_GetThemeColor4fv(TH_WIDGET_TEXT_CURSOR, pd->edit_text.cursor_color);
+ srgb_to_linearrgb_v4(pd->edit_text.cursor_color, pd->edit_text.cursor_color);
+ DRW_draw_pass(psl->edit_text_cursor_ps);
}
diff --git a/source/blender/draw/engines/overlay/overlay_edit_uv.c b/source/blender/draw/engines/overlay/overlay_edit_uv.cc
index 4cfe9fcea4e..7425c577897 100644
--- a/source/blender/draw/engines/overlay/overlay_edit_uv.c
+++ b/source/blender/draw/engines/overlay/overlay_edit_uv.cc
@@ -31,7 +31,7 @@
#include "UI_interface.h"
#include "UI_resources.h"
-#include "overlay_private.h"
+#include "overlay_private.hh"
/* Forward declarations. */
static void overlay_edit_uv_cache_populate(OVERLAY_Data *vedata, Object *ob);
@@ -70,7 +70,7 @@ static GPUTexture *edit_uv_mask_texture(
{
const int height = (float)height_ * (aspy / aspx);
MaskRasterHandle *handle;
- float *buffer = MEM_mallocN(sizeof(float) * height * width, __func__);
+ float *buffer = static_cast<float *>(MEM_mallocN(sizeof(float) * height * width, __func__));
/* Initialize rasterization handle. */
handle = BKE_maskrasterize_handle_new();
@@ -102,10 +102,12 @@ void OVERLAY_edit_uv_init(OVERLAY_Data *vedata)
Image *image = sima->image;
/* By design no image is an image type. This so editor shows UV's by default. */
- const bool is_image_type =
- (image == NULL) || ELEM(image->type, IMA_TYPE_IMAGE, IMA_TYPE_MULTILAYER, IMA_TYPE_UV_TEST);
+ const bool is_image_type = (image == nullptr) || ELEM(image->type,
+ IMA_TYPE_IMAGE,
+ IMA_TYPE_MULTILAYER,
+ IMA_TYPE_UV_TEST);
const bool is_uv_editor = sima->mode == SI_MODE_UV;
- const bool has_edit_object = (draw_ctx->object_edit) != NULL;
+ const bool has_edit_object = (draw_ctx->object_edit) != nullptr;
const bool is_paint_mode = sima->mode == SI_MODE_PAINT;
const bool is_view_mode = sima->mode == SI_MODE_VIEW;
const bool is_mask_mode = sima->mode == SI_MODE_MASK;
@@ -141,12 +143,13 @@ void OVERLAY_edit_uv_init(OVERLAY_Data *vedata)
((draw_ctx->object_mode & (OB_MODE_TEXTURE_PAINT)) != 0)) ||
(do_uv_overlay && (show_modified_uvs)));
- pd->edit_uv.do_mask_overlay = show_overlays && is_mask_mode && (sima->mask_info.mask != NULL) &&
+ pd->edit_uv.do_mask_overlay = show_overlays && is_mask_mode &&
+ (sima->mask_info.mask != nullptr) &&
((sima->mask_info.draw_flag & MASK_DRAWFLAG_OVERLAY) != 0);
- pd->edit_uv.mask_overlay_mode = sima->mask_info.overlay_mode;
+ pd->edit_uv.mask_overlay_mode = eMaskOverlayMode(sima->mask_info.overlay_mode);
pd->edit_uv.mask = sima->mask_info.mask ? (Mask *)DEG_get_evaluated_id(
draw_ctx->depsgraph, &sima->mask_info.mask->id) :
- NULL;
+ nullptr;
pd->edit_uv.do_uv_stretching_overlay = show_overlays && do_uvstretching_overlay;
pd->edit_uv.uv_opacity = sima->uv_opacity;
@@ -157,10 +160,9 @@ void OVERLAY_edit_uv_init(OVERLAY_Data *vedata)
pd->edit_uv.do_smooth_wire = ((U.gpu_flag & USER_GPU_FLAG_OVERLAY_SMOOTH_WIRE) != 0);
pd->edit_uv.do_stencil_overlay = show_overlays && do_stencil_overlay;
- pd->edit_uv.draw_type = sima->dt_uvstretch;
+ pd->edit_uv.draw_type = eSpaceImage_UVDT_Stretch(sima->dt_uvstretch);
BLI_listbase_clear(&pd->edit_uv.totals);
pd->edit_uv.total_area_ratio = 0.0f;
- pd->edit_uv.total_area_ratio_inv = 0.0f;
/* During engine initialization phase the `sima` isn't locked and
* we are able to retrieve the needed data.
@@ -280,8 +282,6 @@ void OVERLAY_edit_uv_cache_init(OVERLAY_Data *vedata)
DRW_shgroup_uniform_block(pd->edit_uv_stretching_grp, "globalsBlock", G_draw.block_ubo);
DRW_shgroup_uniform_float(
pd->edit_uv_stretching_grp, "totalAreaRatio", &pd->edit_uv.total_area_ratio, 1);
- DRW_shgroup_uniform_float(
- pd->edit_uv_stretching_grp, "totalAreaRatioInv", &pd->edit_uv.total_area_ratio_inv, 1);
}
}
@@ -301,8 +301,9 @@ void OVERLAY_edit_uv_cache_init(OVERLAY_Data *vedata)
srgb_to_linearrgb_v4(selected_color, selected_color);
DRWShadingGroup *grp = DRW_shgroup_create(sh, psl->edit_uv_tiled_image_borders_ps);
- DRW_shgroup_uniform_vec4_copy(grp, "color", theme_color);
- DRW_shgroup_uniform_vec3_copy(grp, "offset", (float[3]){0.0f, 0.0f, 0.0f});
+ DRW_shgroup_uniform_vec4_copy(grp, "ucolor", theme_color);
+ const float3 offset = {0.0f, 0.0f, 0.0f};
+ DRW_shgroup_uniform_vec3_copy(grp, "offset", offset);
LISTBASE_FOREACH (ImageTile *, tile, &image->tiles) {
const int tile_x = ((tile->tile_number - 1001) % 10);
@@ -314,7 +315,8 @@ void OVERLAY_edit_uv_cache_init(OVERLAY_Data *vedata)
/* Only mark active border when overlays are enabled. */
if (pd->edit_uv.do_tiled_image_overlay) {
/* Active tile border */
- ImageTile *active_tile = BLI_findlink(&image->tiles, image->active_tile_index);
+ ImageTile *active_tile = static_cast<ImageTile *>(
+ BLI_findlink(&image->tiles, image->active_tile_index));
if (active_tile) {
obmat[3][0] = (float)((active_tile->tile_number - 1001) % 10);
obmat[3][1] = (float)((active_tile->tile_number - 1001) / 10);
@@ -333,8 +335,9 @@ void OVERLAY_edit_uv_cache_init(OVERLAY_Data *vedata)
char text[16];
LISTBASE_FOREACH (ImageTile *, tile, &image->tiles) {
BLI_snprintf(text, 5, "%d", tile->tile_number);
- float tile_location[3] = {
- ((tile->tile_number - 1001) % 10), ((tile->tile_number - 1001) / 10), 0.0f};
+ float tile_location[3] = {static_cast<float>((tile->tile_number - 1001) % 10),
+ static_cast<float>((tile->tile_number - 1001) / 10),
+ 0.0f};
DRW_text_cache_add(
dt, tile_location, text, strlen(text), 10, 10, DRW_TEXT_CACHE_GLOBALSPACE, color);
}
@@ -343,11 +346,12 @@ void OVERLAY_edit_uv_cache_init(OVERLAY_Data *vedata)
if (pd->edit_uv.do_stencil_overlay) {
const Brush *brush = BKE_paint_brush(&ts->imapaint.paint);
Image *stencil_image = brush->clone.image;
- ImBuf *stencil_ibuf = BKE_image_acquire_ibuf(stencil_image, NULL, &pd->edit_uv.stencil_lock);
+ ImBuf *stencil_ibuf = BKE_image_acquire_ibuf(
+ stencil_image, nullptr, &pd->edit_uv.stencil_lock);
- if (stencil_ibuf == NULL) {
- pd->edit_uv.stencil_ibuf = NULL;
- pd->edit_uv.stencil_image = NULL;
+ if (stencil_ibuf == nullptr) {
+ pd->edit_uv.stencil_ibuf = nullptr;
+ pd->edit_uv.stencil_image = nullptr;
}
else {
DRW_PASS_CREATE(psl->edit_uv_stencil_ps,
@@ -358,16 +362,18 @@ void OVERLAY_edit_uv_cache_init(OVERLAY_Data *vedata)
DRWShadingGroup *grp = DRW_shgroup_create(sh, psl->edit_uv_stencil_ps);
pd->edit_uv.stencil_ibuf = stencil_ibuf;
pd->edit_uv.stencil_image = stencil_image;
- GPUTexture *stencil_texture = BKE_image_get_gpu_texture(stencil_image, NULL, stencil_ibuf);
+ GPUTexture *stencil_texture = BKE_image_get_gpu_texture(
+ stencil_image, nullptr, stencil_ibuf);
DRW_shgroup_uniform_texture(grp, "imgTexture", stencil_texture);
DRW_shgroup_uniform_bool_copy(grp, "imgPremultiplied", true);
DRW_shgroup_uniform_bool_copy(grp, "imgAlphaBlend", true);
- DRW_shgroup_uniform_vec4_copy(
- grp, "color", (float[4]){1.0f, 1.0f, 1.0f, brush->clone.alpha});
+ const float4 color = {1.0f, 1.0f, 1.0f, brush->clone.alpha};
+ DRW_shgroup_uniform_vec4_copy(grp, "color", color);
float size_image[2];
- BKE_image_get_size_fl(image, NULL, size_image);
- float size_stencil_image[2] = {stencil_ibuf->x, stencil_ibuf->y};
+ BKE_image_get_size_fl(image, nullptr, size_image);
+ float size_stencil_image[2] = {static_cast<float>(stencil_ibuf->x),
+ static_cast<float>(stencil_ibuf->y)};
float obmat[4][4];
unit_m4(obmat);
@@ -380,8 +386,8 @@ void OVERLAY_edit_uv_cache_init(OVERLAY_Data *vedata)
}
}
else {
- pd->edit_uv.stencil_ibuf = NULL;
- pd->edit_uv.stencil_image = NULL;
+ pd->edit_uv.stencil_ibuf = nullptr;
+ pd->edit_uv.stencil_image = nullptr;
}
if (pd->edit_uv.do_mask_overlay) {
@@ -400,8 +406,9 @@ void OVERLAY_edit_uv_cache_init(OVERLAY_Data *vedata)
pd->edit_uv.image_aspect[1]);
pd->edit_uv.mask_texture = mask_texture;
DRW_shgroup_uniform_texture(grp, "imgTexture", mask_texture);
- DRW_shgroup_uniform_vec4_copy(grp, "color", (float[4]){1.0f, 1.0f, 1.0f, 1.0f});
- DRW_shgroup_call_obmat(grp, geom, NULL);
+ const float4 color = {1.0f, 1.0f, 1.0f, 1.0f};
+ DRW_shgroup_uniform_vec4_copy(grp, "color", color);
+ DRW_shgroup_call_obmat(grp, geom, nullptr);
}
/* HACK: When editing objects that share the same mesh we should only draw the
@@ -411,7 +418,7 @@ void OVERLAY_edit_uv_cache_init(OVERLAY_Data *vedata)
draw_ctx->obact->type == OB_MESH) {
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_mode_unique_data(
- draw_ctx->view_layer, NULL, &objects_len, draw_ctx->object_mode);
+ draw_ctx->scene, draw_ctx->view_layer, nullptr, &objects_len, draw_ctx->object_mode);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *object_eval = DEG_get_evaluated_object(draw_ctx->depsgraph, objects[ob_index]);
DRW_mesh_batch_cache_validate(object_eval, (Mesh *)object_eval->data);
@@ -443,26 +450,26 @@ static void overlay_edit_uv_cache_populate(OVERLAY_Data *vedata, Object *ob)
if (has_active_edit_uvmap) {
if (pd->edit_uv.do_uv_overlay) {
- geom = DRW_mesh_batch_cache_get_edituv_edges(ob, ob->data);
+ geom = DRW_mesh_batch_cache_get_edituv_edges(ob, me);
if (geom) {
- DRW_shgroup_call_obmat(pd->edit_uv_edges_grp, geom, NULL);
+ DRW_shgroup_call_obmat(pd->edit_uv_edges_grp, geom, nullptr);
}
if (pd->edit_uv.do_verts) {
- geom = DRW_mesh_batch_cache_get_edituv_verts(ob, ob->data);
+ geom = DRW_mesh_batch_cache_get_edituv_verts(ob, me);
if (geom) {
- DRW_shgroup_call_obmat(pd->edit_uv_verts_grp, geom, NULL);
+ DRW_shgroup_call_obmat(pd->edit_uv_verts_grp, geom, nullptr);
}
}
if (pd->edit_uv.do_faces) {
- geom = DRW_mesh_batch_cache_get_edituv_faces(ob, ob->data);
+ geom = DRW_mesh_batch_cache_get_edituv_faces(ob, me);
if (geom) {
- DRW_shgroup_call_obmat(pd->edit_uv_faces_grp, geom, NULL);
+ DRW_shgroup_call_obmat(pd->edit_uv_faces_grp, geom, nullptr);
}
}
if (pd->edit_uv.do_face_dots) {
- geom = DRW_mesh_batch_cache_get_edituv_facedots(ob, ob->data);
+ geom = DRW_mesh_batch_cache_get_edituv_facedots(ob, me);
if (geom) {
- DRW_shgroup_call_obmat(pd->edit_uv_face_dots_grp, geom, NULL);
+ DRW_shgroup_call_obmat(pd->edit_uv_face_dots_grp, geom, nullptr);
}
}
}
@@ -472,23 +479,23 @@ static void overlay_edit_uv_cache_populate(OVERLAY_Data *vedata, Object *ob)
geom = DRW_mesh_batch_cache_get_edituv_faces_stretch_angle(ob, me);
}
else /* SI_UVDT_STRETCH_AREA */ {
- OVERLAY_StretchingAreaTotals *totals = MEM_mallocN(sizeof(OVERLAY_StretchingAreaTotals),
- __func__);
+ OVERLAY_StretchingAreaTotals *totals = static_cast<OVERLAY_StretchingAreaTotals *>(
+ MEM_mallocN(sizeof(OVERLAY_StretchingAreaTotals), __func__));
BLI_addtail(&pd->edit_uv.totals, totals);
geom = DRW_mesh_batch_cache_get_edituv_faces_stretch_area(
ob, me, &totals->total_area, &totals->total_area_uv);
}
if (geom) {
- DRW_shgroup_call_obmat(pd->edit_uv_stretching_grp, geom, NULL);
+ DRW_shgroup_call_obmat(pd->edit_uv_stretching_grp, geom, nullptr);
}
}
}
if (draw_shadows && (has_active_object_uvmap || has_active_edit_uvmap)) {
if (pd->edit_uv.do_uv_shadow_overlay) {
- geom = DRW_mesh_batch_cache_get_uv_edges(ob, ob->data);
+ geom = DRW_mesh_batch_cache_get_uv_edges(ob, me);
if (geom) {
- DRW_shgroup_call_obmat(pd->edit_uv_shadow_edges_grp, geom, NULL);
+ DRW_shgroup_call_obmat(pd->edit_uv_shadow_edges_grp, geom, nullptr);
}
}
}
@@ -510,7 +517,6 @@ static void edit_uv_stretching_update_ratios(OVERLAY_Data *vedata)
if (total_area > FLT_EPSILON && total_area_uv > FLT_EPSILON) {
pd->edit_uv.total_area_ratio = total_area / total_area_uv;
- pd->edit_uv.total_area_ratio_inv = total_area_uv / total_area;
}
}
BLI_freelistN(&pd->edit_uv.totals);
@@ -534,8 +540,8 @@ static void OVERLAY_edit_uv_draw_finish(OVERLAY_Data *vedata)
if (pd->edit_uv.stencil_ibuf) {
BKE_image_release_ibuf(
pd->edit_uv.stencil_image, pd->edit_uv.stencil_ibuf, pd->edit_uv.stencil_lock);
- pd->edit_uv.stencil_image = NULL;
- pd->edit_uv.stencil_ibuf = NULL;
+ pd->edit_uv.stencil_image = nullptr;
+ pd->edit_uv.stencil_ibuf = nullptr;
}
DRW_TEXTURE_FREE_SAFE(pd->edit_uv.mask_texture);
@@ -554,7 +560,7 @@ void OVERLAY_edit_uv_draw(OVERLAY_Data *vedata)
/* Combined overlay renders in the default framebuffer and modifies the image in SRS.
* The alpha overlay renders in the overlay framebuffer. */
const bool is_combined_overlay = pd->edit_uv.mask_overlay_mode == MASK_OVERLAY_COMBINED;
- GPUFrameBuffer *previous_framebuffer = NULL;
+ GPUFrameBuffer *previous_framebuffer = nullptr;
if (is_combined_overlay) {
DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
previous_framebuffer = GPU_framebuffer_active_get();
diff --git a/source/blender/draw/engines/overlay/overlay_engine.c b/source/blender/draw/engines/overlay/overlay_engine.cc
index 5edd68bffff..bb9f2e3a8ce 100644
--- a/source/blender/draw/engines/overlay/overlay_engine.c
+++ b/source/blender/draw/engines/overlay/overlay_engine.cc
@@ -22,7 +22,7 @@
#include "DNA_space_types.h"
#include "overlay_engine.h"
-#include "overlay_private.h"
+#include "overlay_private.hh"
/* -------------------------------------------------------------------- */
/** \name Engine Callbacks
@@ -30,7 +30,7 @@
static void OVERLAY_engine_init(void *vedata)
{
- OVERLAY_Data *data = vedata;
+ OVERLAY_Data *data = static_cast<OVERLAY_Data *>(vedata);
OVERLAY_StorageList *stl = data->stl;
const DRWContextState *draw_ctx = DRW_context_state_get();
const RegionView3D *rv3d = draw_ctx->rv3d;
@@ -40,28 +40,29 @@ static void OVERLAY_engine_init(void *vedata)
if (!stl->pd) {
/* Allocate transient pointers. */
- stl->pd = MEM_callocN(sizeof(*stl->pd), __func__);
+ stl->pd = static_cast<OVERLAY_PrivateData *>(MEM_callocN(sizeof(*stl->pd), __func__));
}
/* Allocate instance. */
- if (data->instance == NULL) {
- data->instance = MEM_callocN(sizeof(*data->instance), __func__);
+ if (data->instance == nullptr) {
+ data->instance = static_cast<OVERLAY_Instance *>(
+ MEM_callocN(sizeof(*data->instance), __func__));
}
OVERLAY_PrivateData *pd = stl->pd;
- pd->space_type = v3d != NULL ? SPACE_VIEW3D : draw_ctx->space_data->spacetype;
+ pd->space_type = v3d != nullptr ? (int)SPACE_VIEW3D : draw_ctx->space_data->spacetype;
if (pd->space_type == SPACE_IMAGE) {
const SpaceImage *sima = (SpaceImage *)draw_ctx->space_data;
pd->hide_overlays = (sima->overlay.flag & SI_OVERLAY_SHOW_OVERLAYS) == 0;
- pd->clipping_state = 0;
+ pd->clipping_state = DRWState(0);
OVERLAY_grid_init(data);
OVERLAY_edit_uv_init(data);
return;
}
if (pd->space_type == SPACE_NODE) {
pd->hide_overlays = true;
- pd->clipping_state = 0;
+ pd->clipping_state = DRWState(0);
return;
}
@@ -101,98 +102,99 @@ static void OVERLAY_engine_init(void *vedata)
pd->use_in_front = (v3d->shading.type <= OB_SOLID) ||
BKE_scene_uses_blender_workbench(draw_ctx->scene);
pd->wireframe_mode = (v3d->shading.type == OB_WIRE);
- pd->clipping_state = RV3D_CLIPPING_ENABLED(v3d, rv3d) ? DRW_STATE_CLIP_PLANES : 0;
+ pd->clipping_state = RV3D_CLIPPING_ENABLED(v3d, rv3d) ? DRW_STATE_CLIP_PLANES : DRWState(0);
pd->xray_opacity = XRAY_ALPHA(v3d);
pd->xray_enabled = XRAY_ACTIVE(v3d);
pd->xray_enabled_and_not_wire = pd->xray_enabled && v3d->shading.type > OB_WIRE;
pd->clear_in_front = (v3d->shading.type != OB_SOLID);
pd->cfra = DEG_get_ctime(draw_ctx->depsgraph);
- OVERLAY_antialiasing_init(vedata);
+ OVERLAY_antialiasing_init(data);
switch (stl->pd->ctx_mode) {
case CTX_MODE_EDIT_MESH:
- OVERLAY_edit_mesh_init(vedata);
+ OVERLAY_edit_mesh_init(data);
break;
case CTX_MODE_EDIT_CURVES:
- OVERLAY_edit_curves_init(vedata);
+ OVERLAY_edit_curves_init(data);
break;
default:
/* Nothing to do. */
break;
}
- OVERLAY_facing_init(vedata);
- OVERLAY_grid_init(vedata);
- OVERLAY_image_init(vedata);
- OVERLAY_outline_init(vedata);
- OVERLAY_wireframe_init(vedata);
- OVERLAY_paint_init(vedata);
+ OVERLAY_facing_init(data);
+ OVERLAY_grid_init(data);
+ OVERLAY_image_init(data);
+ OVERLAY_outline_init(data);
+ OVERLAY_wireframe_init(data);
+ OVERLAY_paint_init(data);
}
static void OVERLAY_cache_init(void *vedata)
{
- OVERLAY_Data *data = vedata;
+ OVERLAY_Data *data = static_cast<OVERLAY_Data *>(vedata);
OVERLAY_StorageList *stl = data->stl;
OVERLAY_PrivateData *pd = stl->pd;
if (pd->space_type == SPACE_IMAGE) {
- OVERLAY_background_cache_init(vedata);
- OVERLAY_grid_cache_init(vedata);
- OVERLAY_edit_uv_cache_init(vedata);
+ OVERLAY_background_cache_init(data);
+ OVERLAY_grid_cache_init(data);
+ OVERLAY_edit_uv_cache_init(data);
return;
}
if (pd->space_type == SPACE_NODE) {
- OVERLAY_background_cache_init(vedata);
+ OVERLAY_background_cache_init(data);
return;
}
switch (pd->ctx_mode) {
- case CTX_MODE_EDIT_MESH:
- OVERLAY_edit_mesh_cache_init(vedata);
+ case CTX_MODE_EDIT_MESH: {
+ OVERLAY_edit_mesh_cache_init(data);
/* `pd->edit_mesh.flag` is valid after calling `OVERLAY_edit_mesh_cache_init`. */
const bool draw_edit_weights = (pd->edit_mesh.flag & V3D_OVERLAY_EDIT_WEIGHT);
if (draw_edit_weights) {
- OVERLAY_paint_cache_init(vedata);
+ OVERLAY_paint_cache_init(data);
}
break;
+ }
case CTX_MODE_EDIT_SURFACE:
case CTX_MODE_EDIT_CURVE:
- OVERLAY_edit_curve_cache_init(vedata);
+ OVERLAY_edit_curve_cache_init(data);
break;
case CTX_MODE_EDIT_TEXT:
- OVERLAY_edit_text_cache_init(vedata);
+ OVERLAY_edit_text_cache_init(data);
break;
case CTX_MODE_EDIT_ARMATURE:
break;
case CTX_MODE_EDIT_METABALL:
break;
case CTX_MODE_EDIT_LATTICE:
- OVERLAY_edit_lattice_cache_init(vedata);
+ OVERLAY_edit_lattice_cache_init(data);
break;
case CTX_MODE_PARTICLE:
- OVERLAY_edit_particle_cache_init(vedata);
+ OVERLAY_edit_particle_cache_init(data);
break;
case CTX_MODE_POSE:
case CTX_MODE_PAINT_WEIGHT:
case CTX_MODE_PAINT_VERTEX:
case CTX_MODE_PAINT_TEXTURE:
- OVERLAY_paint_cache_init(vedata);
+ OVERLAY_paint_cache_init(data);
break;
case CTX_MODE_SCULPT:
- OVERLAY_sculpt_cache_init(vedata);
+ OVERLAY_sculpt_cache_init(data);
break;
case CTX_MODE_EDIT_GPENCIL:
case CTX_MODE_PAINT_GPENCIL:
case CTX_MODE_SCULPT_GPENCIL:
case CTX_MODE_VERTEX_GPENCIL:
case CTX_MODE_WEIGHT_GPENCIL:
- OVERLAY_edit_gpencil_cache_init(vedata);
+ OVERLAY_edit_gpencil_cache_init(data);
break;
case CTX_MODE_EDIT_CURVES:
- OVERLAY_edit_curves_cache_init(vedata);
+ OVERLAY_edit_curves_cache_init(data);
break;
case CTX_MODE_SCULPT_CURVES:
- OVERLAY_sculpt_curves_cache_init(vedata);
+ OVERLAY_sculpt_curves_cache_init(data);
break;
case CTX_MODE_OBJECT:
break;
@@ -200,22 +202,22 @@ static void OVERLAY_cache_init(void *vedata)
BLI_assert_msg(0, "Draw mode invalid");
break;
}
- OVERLAY_antialiasing_cache_init(vedata);
- OVERLAY_armature_cache_init(vedata);
- OVERLAY_background_cache_init(vedata);
- OVERLAY_fade_cache_init(vedata);
- OVERLAY_mode_transfer_cache_init(vedata);
- OVERLAY_extra_cache_init(vedata);
- OVERLAY_facing_cache_init(vedata);
- OVERLAY_gpencil_cache_init(vedata);
- OVERLAY_grid_cache_init(vedata);
- OVERLAY_image_cache_init(vedata);
- OVERLAY_metaball_cache_init(vedata);
- OVERLAY_motion_path_cache_init(vedata);
- OVERLAY_outline_cache_init(vedata);
- OVERLAY_particle_cache_init(vedata);
- OVERLAY_wireframe_cache_init(vedata);
- OVERLAY_volume_cache_init(vedata);
+ OVERLAY_antialiasing_cache_init(data);
+ OVERLAY_armature_cache_init(data);
+ OVERLAY_background_cache_init(data);
+ OVERLAY_fade_cache_init(data);
+ OVERLAY_mode_transfer_cache_init(data);
+ OVERLAY_extra_cache_init(data);
+ OVERLAY_facing_cache_init(data);
+ OVERLAY_gpencil_cache_init(data);
+ OVERLAY_grid_cache_init(data);
+ OVERLAY_image_cache_init(data);
+ OVERLAY_metaball_cache_init(data);
+ OVERLAY_motion_path_cache_init(data);
+ OVERLAY_outline_cache_init(data);
+ OVERLAY_particle_cache_init(data);
+ OVERLAY_wireframe_cache_init(data);
+ OVERLAY_volume_cache_init(data);
}
BLI_INLINE OVERLAY_DupliData *OVERLAY_duplidata_get(Object *ob, void *vedata, bool *do_init)
@@ -223,12 +225,13 @@ BLI_INLINE OVERLAY_DupliData *OVERLAY_duplidata_get(Object *ob, void *vedata, bo
OVERLAY_DupliData **dupli_data = (OVERLAY_DupliData **)DRW_duplidata_get(vedata);
*do_init = false;
if (!ELEM(ob->type, OB_MESH, OB_SURF, OB_LATTICE, OB_CURVES_LEGACY, OB_FONT)) {
- return NULL;
+ return nullptr;
}
if (dupli_data) {
- if (*dupli_data == NULL) {
- *dupli_data = MEM_callocN(sizeof(OVERLAY_DupliData), __func__);
+ if (*dupli_data == nullptr) {
+ *dupli_data = static_cast<OVERLAY_DupliData *>(
+ MEM_callocN(sizeof(OVERLAY_DupliData), __func__));
*do_init = true;
}
else if ((*dupli_data)->base_flag != ob->base_flag) {
@@ -237,7 +240,7 @@ BLI_INLINE OVERLAY_DupliData *OVERLAY_duplidata_get(Object *ob, void *vedata, bo
}
return *dupli_data;
}
- return NULL;
+ return nullptr;
}
static bool overlay_object_is_edit_mode(const OVERLAY_PrivateData *pd, const Object *ob)
@@ -289,7 +292,7 @@ static bool overlay_should_fade_object(Object *ob, Object *active_object)
static void OVERLAY_cache_populate(void *vedata, Object *ob)
{
- OVERLAY_Data *data = vedata;
+ OVERLAY_Data *data = static_cast<OVERLAY_Data *>(vedata);
OVERLAY_PrivateData *pd = data->stl->pd;
if (pd->space_type == SPACE_IMAGE) {
@@ -312,7 +315,7 @@ static void OVERLAY_cache_populate(void *vedata, Object *ob)
(draw_ctx->object_mode & OB_MODE_ALL_PAINT);
const bool in_sculpt_curve_mode = (ob == draw_ctx->obact) &&
(draw_ctx->object_mode & OB_MODE_SCULPT_CURVES);
- const bool in_sculpt_mode = (ob == draw_ctx->obact) && (ob->sculpt != NULL) &&
+ const bool in_sculpt_mode = (ob == draw_ctx->obact) && (ob->sculpt != nullptr) &&
(ob->sculpt->mode_type == OB_MODE_SCULPT);
const bool in_curves_sculpt_mode = (ob == draw_ctx->obact) &&
(ob->mode == OB_MODE_SCULPT_CURVES);
@@ -320,7 +323,6 @@ static void OVERLAY_cache_populate(void *vedata, Object *ob)
OB_MESH,
OB_CURVES_LEGACY,
OB_SURF,
- OB_MBALL,
OB_FONT,
OB_GPENCIL,
OB_CURVES,
@@ -354,108 +356,108 @@ static void OVERLAY_cache_populate(void *vedata, Object *ob)
OVERLAY_DupliData *dupli = OVERLAY_duplidata_get(ob, vedata, &do_init);
if (draw_fade) {
- OVERLAY_fade_cache_populate(vedata, ob);
+ OVERLAY_fade_cache_populate(data, ob);
}
if (draw_facing) {
- OVERLAY_facing_cache_populate(vedata, ob);
+ OVERLAY_facing_cache_populate(data, ob);
}
if (draw_mode_transfer) {
- OVERLAY_mode_transfer_cache_populate(vedata, ob);
+ OVERLAY_mode_transfer_cache_populate(data, ob);
}
if (draw_wires) {
- OVERLAY_wireframe_cache_populate(vedata, ob, dupli, do_init);
+ OVERLAY_wireframe_cache_populate(data, ob, dupli, do_init);
}
if (draw_outlines) {
- OVERLAY_outline_cache_populate(vedata, ob, dupli, do_init);
+ OVERLAY_outline_cache_populate(data, ob, dupli, do_init);
}
if (draw_bone_selection) {
- OVERLAY_pose_cache_populate(vedata, ob);
+ OVERLAY_pose_cache_populate(data, ob);
}
if (ob->type == OB_VOLUME) {
- OVERLAY_volume_cache_populate(vedata, ob);
+ OVERLAY_volume_cache_populate(data, ob);
}
if (in_edit_mode && !pd->hide_overlays) {
switch (ob->type) {
case OB_MESH:
- OVERLAY_edit_mesh_cache_populate(vedata, ob);
+ OVERLAY_edit_mesh_cache_populate(data, ob);
if (draw_edit_weights) {
- OVERLAY_paint_weight_cache_populate(vedata, ob);
+ OVERLAY_paint_weight_cache_populate(data, ob);
}
break;
case OB_ARMATURE:
if (draw_bones) {
- OVERLAY_edit_armature_cache_populate(vedata, ob);
+ OVERLAY_edit_armature_cache_populate(data, ob);
}
break;
case OB_CURVES_LEGACY:
- OVERLAY_edit_curve_cache_populate(vedata, ob);
+ OVERLAY_edit_curve_cache_populate(data, ob);
break;
case OB_SURF:
- OVERLAY_edit_surf_cache_populate(vedata, ob);
+ OVERLAY_edit_surf_cache_populate(data, ob);
break;
case OB_LATTICE:
- OVERLAY_edit_lattice_cache_populate(vedata, ob);
+ OVERLAY_edit_lattice_cache_populate(data, ob);
break;
case OB_MBALL:
- OVERLAY_edit_metaball_cache_populate(vedata, ob);
+ OVERLAY_edit_metaball_cache_populate(data, ob);
break;
case OB_FONT:
- OVERLAY_edit_text_cache_populate(vedata, ob);
+ OVERLAY_edit_text_cache_populate(data, ob);
break;
case OB_CURVES:
- OVERLAY_edit_curves_cache_populate(vedata, ob);
+ OVERLAY_edit_curves_cache_populate(data, ob);
break;
}
}
else if (in_pose_mode && draw_bones) {
- OVERLAY_pose_armature_cache_populate(vedata, ob);
+ OVERLAY_pose_armature_cache_populate(data, ob);
}
else if (in_paint_mode && !pd->hide_overlays) {
switch (draw_ctx->object_mode) {
case OB_MODE_VERTEX_PAINT:
- OVERLAY_paint_vertex_cache_populate(vedata, ob);
+ OVERLAY_paint_vertex_cache_populate(data, ob);
break;
case OB_MODE_WEIGHT_PAINT:
- OVERLAY_paint_weight_cache_populate(vedata, ob);
+ OVERLAY_paint_weight_cache_populate(data, ob);
break;
case OB_MODE_TEXTURE_PAINT:
- OVERLAY_paint_texture_cache_populate(vedata, ob);
+ OVERLAY_paint_texture_cache_populate(data, ob);
break;
default:
break;
}
}
else if (in_particle_edit_mode) {
- OVERLAY_edit_particle_cache_populate(vedata, ob);
+ OVERLAY_edit_particle_cache_populate(data, ob);
}
if (in_sculpt_mode) {
- OVERLAY_sculpt_cache_populate(vedata, ob);
+ OVERLAY_sculpt_cache_populate(data, ob);
}
else if (in_curves_sculpt_mode) {
- OVERLAY_sculpt_curves_cache_populate(vedata, ob);
+ OVERLAY_sculpt_curves_cache_populate(data, ob);
}
if (draw_motion_paths) {
- OVERLAY_motion_path_cache_populate(vedata, ob);
+ OVERLAY_motion_path_cache_populate(data, ob);
}
if (!pd->hide_overlays) {
switch (ob->type) {
case OB_ARMATURE:
if (draw_bones && (is_select || (!in_edit_mode && !in_pose_mode))) {
- OVERLAY_armature_cache_populate(vedata, ob);
+ OVERLAY_armature_cache_populate(data, ob);
}
break;
case OB_MBALL:
if (!in_edit_mode) {
- OVERLAY_metaball_cache_populate(vedata, ob);
+ OVERLAY_metaball_cache_populate(data, ob);
}
break;
case OB_GPENCIL:
- OVERLAY_gpencil_cache_populate(vedata, ob);
+ OVERLAY_gpencil_cache_populate(data, ob);
break;
}
}
@@ -463,25 +465,25 @@ static void OVERLAY_cache_populate(void *vedata, Object *ob)
if (draw_extras) {
switch (ob->type) {
case OB_EMPTY:
- OVERLAY_empty_cache_populate(vedata, ob);
+ OVERLAY_empty_cache_populate(data, ob);
break;
case OB_LAMP:
- OVERLAY_light_cache_populate(vedata, ob);
+ OVERLAY_light_cache_populate(data, ob);
break;
case OB_CAMERA:
- OVERLAY_camera_cache_populate(vedata, ob);
+ OVERLAY_camera_cache_populate(data, ob);
break;
case OB_SPEAKER:
- OVERLAY_speaker_cache_populate(vedata, ob);
+ OVERLAY_speaker_cache_populate(data, ob);
break;
case OB_LIGHTPROBE:
- OVERLAY_lightprobe_cache_populate(vedata, ob);
+ OVERLAY_lightprobe_cache_populate(data, ob);
break;
case OB_LATTICE: {
/* Unlike the other types above, lattices actually have a bounding box defined, so hide the
* lattice wires if only the bounding-box is requested. */
if (ob->dt > OB_BOUNDBOX) {
- OVERLAY_lattice_cache_populate(vedata, ob);
+ OVERLAY_lattice_cache_populate(data, ob);
}
break;
}
@@ -489,12 +491,12 @@ static void OVERLAY_cache_populate(void *vedata, Object *ob)
}
if (!BLI_listbase_is_empty(&ob->particlesystem)) {
- OVERLAY_particle_cache_populate(vedata, ob);
+ OVERLAY_particle_cache_populate(data, ob);
}
/* Relationship, object center, bounding-box... etc. */
if (!pd->hide_overlays) {
- OVERLAY_extra_cache_populate(vedata, ob);
+ OVERLAY_extra_cache_populate(data, ob);
}
if (dupli) {
@@ -504,11 +506,11 @@ static void OVERLAY_cache_populate(void *vedata, Object *ob)
static void OVERLAY_cache_finish(void *vedata)
{
- OVERLAY_Data *data = vedata;
+ OVERLAY_Data *data = static_cast<OVERLAY_Data *>(vedata);
OVERLAY_PrivateData *pd = data->stl->pd;
if (ELEM(pd->space_type, SPACE_IMAGE)) {
- OVERLAY_edit_uv_cache_finish(vedata);
+ OVERLAY_edit_uv_cache_finish(data);
return;
}
if (ELEM(pd->space_type, SPACE_NODE)) {
@@ -521,29 +523,30 @@ static void OVERLAY_cache_finish(void *vedata)
DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
- DRW_texture_ensure_fullscreen_2d(&dtxl->depth_in_front, GPU_DEPTH24_STENCIL8, 0);
+ DRW_texture_ensure_fullscreen_2d(
+ &dtxl->depth_in_front, GPU_DEPTH24_STENCIL8, DRWTextureFlag(0));
GPU_framebuffer_ensure_config(
&dfbl->in_front_fb,
{GPU_ATTACHMENT_TEXTURE(dtxl->depth_in_front), GPU_ATTACHMENT_TEXTURE(dtxl->color)});
}
- OVERLAY_mode_transfer_cache_finish(vedata);
- OVERLAY_antialiasing_cache_finish(vedata);
- OVERLAY_armature_cache_finish(vedata);
- OVERLAY_image_cache_finish(vedata);
+ OVERLAY_mode_transfer_cache_finish(data);
+ OVERLAY_antialiasing_cache_finish(data);
+ OVERLAY_armature_cache_finish(data);
+ OVERLAY_image_cache_finish(data);
}
static void OVERLAY_draw_scene(void *vedata)
{
- OVERLAY_Data *data = vedata;
+ OVERLAY_Data *data = static_cast<OVERLAY_Data *>(vedata);
OVERLAY_PrivateData *pd = data->stl->pd;
OVERLAY_FramebufferList *fbl = data->fbl;
DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
/* Needs to be done first as it modifies the scene color and depth buffer. */
if (pd->space_type == SPACE_VIEW3D) {
- OVERLAY_image_scene_background_draw(vedata);
+ OVERLAY_image_scene_background_draw(data);
}
if (DRW_state_is_fbo()) {
@@ -570,45 +573,45 @@ static void OVERLAY_draw_scene(void *vedata)
return;
}
- OVERLAY_image_background_draw(vedata);
- OVERLAY_background_draw(vedata);
+ OVERLAY_image_background_draw(data);
+ OVERLAY_background_draw(data);
- OVERLAY_antialiasing_start(vedata);
+ OVERLAY_antialiasing_start(data);
- DRW_view_set_active(NULL);
+ DRW_view_set_active(nullptr);
if (DRW_state_is_fbo()) {
GPU_framebuffer_bind(fbl->overlay_color_only_fb);
}
- OVERLAY_outline_draw(vedata);
- OVERLAY_xray_depth_copy(vedata);
+ OVERLAY_outline_draw(data);
+ OVERLAY_xray_depth_copy(data);
if (DRW_state_is_fbo()) {
GPU_framebuffer_bind(fbl->overlay_default_fb);
}
- OVERLAY_image_draw(vedata);
- OVERLAY_fade_draw(vedata);
- OVERLAY_facing_draw(vedata);
- OVERLAY_mode_transfer_draw(vedata);
- OVERLAY_extra_blend_draw(vedata);
- OVERLAY_volume_draw(vedata);
+ OVERLAY_image_draw(data);
+ OVERLAY_fade_draw(data);
+ OVERLAY_facing_draw(data);
+ OVERLAY_mode_transfer_draw(data);
+ OVERLAY_extra_blend_draw(data);
+ OVERLAY_volume_draw(data);
/* These overlays are drawn here to avoid artifacts with wire-frame opacity. */
switch (pd->ctx_mode) {
case CTX_MODE_SCULPT:
- OVERLAY_sculpt_draw(vedata);
+ OVERLAY_sculpt_draw(data);
break;
case CTX_MODE_SCULPT_CURVES:
- OVERLAY_sculpt_curves_draw(vedata);
+ OVERLAY_sculpt_curves_draw(data);
break;
case CTX_MODE_EDIT_MESH:
case CTX_MODE_POSE:
case CTX_MODE_PAINT_WEIGHT:
case CTX_MODE_PAINT_VERTEX:
case CTX_MODE_PAINT_TEXTURE:
- OVERLAY_paint_draw(vedata);
+ OVERLAY_paint_draw(data);
break;
default:
break;
@@ -618,46 +621,46 @@ static void OVERLAY_draw_scene(void *vedata)
GPU_framebuffer_bind(fbl->overlay_line_fb);
}
- OVERLAY_wireframe_draw(vedata);
- OVERLAY_armature_draw(vedata);
- OVERLAY_particle_draw(vedata);
- OVERLAY_metaball_draw(vedata);
- OVERLAY_gpencil_draw(vedata);
- OVERLAY_extra_draw(vedata);
+ OVERLAY_wireframe_draw(data);
+ OVERLAY_armature_draw(data);
+ OVERLAY_particle_draw(data);
+ OVERLAY_metaball_draw(data);
+ OVERLAY_gpencil_draw(data);
+ OVERLAY_extra_draw(data);
if (DRW_state_is_fbo()) {
GPU_framebuffer_bind(fbl->overlay_color_only_fb);
}
- OVERLAY_xray_fade_draw(vedata);
- OVERLAY_grid_draw(vedata);
+ OVERLAY_xray_fade_draw(data);
+ OVERLAY_grid_draw(data);
- OVERLAY_xray_depth_infront_copy(vedata);
+ OVERLAY_xray_depth_infront_copy(data);
if (DRW_state_is_fbo()) {
GPU_framebuffer_bind(fbl->overlay_in_front_fb);
}
- OVERLAY_fade_infront_draw(vedata);
- OVERLAY_facing_infront_draw(vedata);
- OVERLAY_mode_transfer_infront_draw(vedata);
+ OVERLAY_fade_infront_draw(data);
+ OVERLAY_facing_infront_draw(data);
+ OVERLAY_mode_transfer_infront_draw(data);
if (DRW_state_is_fbo()) {
GPU_framebuffer_bind(fbl->overlay_line_in_front_fb);
}
- OVERLAY_wireframe_in_front_draw(vedata);
- OVERLAY_armature_in_front_draw(vedata);
- OVERLAY_extra_in_front_draw(vedata);
- OVERLAY_metaball_in_front_draw(vedata);
+ OVERLAY_wireframe_in_front_draw(data);
+ OVERLAY_armature_in_front_draw(data);
+ OVERLAY_extra_in_front_draw(data);
+ OVERLAY_metaball_in_front_draw(data);
if (DRW_state_is_fbo()) {
GPU_framebuffer_bind(fbl->overlay_color_only_fb);
}
- OVERLAY_image_in_front_draw(vedata);
- OVERLAY_motion_path_draw(vedata);
- OVERLAY_extra_centers_draw(vedata);
+ OVERLAY_image_in_front_draw(data);
+ OVERLAY_motion_path_draw(data);
+ OVERLAY_extra_centers_draw(data);
if (DRW_state_is_select() || DRW_state_is_depth()) {
/* Edit modes have their own selection code. */
@@ -668,41 +671,41 @@ static void OVERLAY_draw_scene(void *vedata)
switch (pd->ctx_mode) {
case CTX_MODE_EDIT_MESH:
- OVERLAY_edit_mesh_draw(vedata);
+ OVERLAY_edit_mesh_draw(data);
break;
case CTX_MODE_EDIT_SURFACE:
case CTX_MODE_EDIT_CURVE:
- OVERLAY_edit_curve_draw(vedata);
+ OVERLAY_edit_curve_draw(data);
break;
case CTX_MODE_EDIT_TEXT:
- OVERLAY_edit_text_draw(vedata);
+ OVERLAY_edit_text_draw(data);
break;
case CTX_MODE_EDIT_LATTICE:
- OVERLAY_edit_lattice_draw(vedata);
+ OVERLAY_edit_lattice_draw(data);
break;
case CTX_MODE_POSE:
- OVERLAY_pose_draw(vedata);
+ OVERLAY_pose_draw(data);
break;
case CTX_MODE_PARTICLE:
- OVERLAY_edit_particle_draw(vedata);
+ OVERLAY_edit_particle_draw(data);
break;
case CTX_MODE_EDIT_GPENCIL:
case CTX_MODE_PAINT_GPENCIL:
case CTX_MODE_SCULPT_GPENCIL:
case CTX_MODE_VERTEX_GPENCIL:
case CTX_MODE_WEIGHT_GPENCIL:
- OVERLAY_edit_gpencil_draw(vedata);
+ OVERLAY_edit_gpencil_draw(data);
break;
case CTX_MODE_SCULPT_CURVES:
break;
case CTX_MODE_EDIT_CURVES:
- OVERLAY_edit_curves_draw(vedata);
+ OVERLAY_edit_curves_draw(data);
break;
default:
break;
}
- OVERLAY_antialiasing_end(vedata);
+ OVERLAY_antialiasing_end(data);
}
static void OVERLAY_engine_free(void)
@@ -726,8 +729,8 @@ static void OVERLAY_instance_free(void *instance_)
static const DrawEngineDataSize overlay_data_size = DRW_VIEWPORT_DATA_SIZE(OVERLAY_Data);
DrawEngineType draw_engine_overlay_type = {
- NULL,
- NULL,
+ nullptr,
+ nullptr,
N_("Overlay"),
&overlay_data_size,
&OVERLAY_engine_init,
@@ -737,10 +740,10 @@ DrawEngineType draw_engine_overlay_type = {
&OVERLAY_cache_populate,
&OVERLAY_cache_finish,
&OVERLAY_draw_scene,
- NULL,
- NULL,
- NULL,
- NULL,
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr,
};
/** \} */
diff --git a/source/blender/draw/engines/overlay/overlay_engine.h b/source/blender/draw/engines/overlay/overlay_engine.h
index 18ab7f1456e..a33ea17dc1e 100644
--- a/source/blender/draw/engines/overlay/overlay_engine.h
+++ b/source/blender/draw/engines/overlay/overlay_engine.h
@@ -7,4 +7,12 @@
#pragma once
+#ifdef __cplusplus
+extern "C" {
+#endif
+
extern DrawEngineType draw_engine_overlay_type;
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/draw/engines/overlay/overlay_extra.c b/source/blender/draw/engines/overlay/overlay_extra.cc
index 4354777986c..f0665f7e90f 100644
--- a/source/blender/draw/engines/overlay/overlay_extra.c
+++ b/source/blender/draw/engines/overlay/overlay_extra.cc
@@ -38,7 +38,7 @@
#include "ED_view3d.h"
-#include "overlay_private.h"
+#include "overlay_private.hh"
#include "draw_common.h"
#include "draw_manager_text.h"
@@ -79,7 +79,8 @@ void OVERLAY_extra_cache_init(OVERLAY_Data *vedata)
OVERLAY_ExtraCallBuffers *cb = &pd->extra_call_buffers[i];
DRWPass **p_extra_ps = &psl->extra_ps[i];
- DRWState infront_state = (DRW_state_is_select() && (i == 1)) ? DRW_STATE_IN_FRONT_SELECT : 0;
+ DRWState infront_state = (DRW_state_is_select() && (i == 1)) ? DRW_STATE_IN_FRONT_SELECT :
+ DRWState(0);
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL;
DRW_PASS_CREATE(*p_extra_ps, state | pd->clipping_state | infront_state);
@@ -194,23 +195,23 @@ void OVERLAY_extra_cache_init(OVERLAY_Data *vedata)
DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
grp_sub = DRW_shgroup_create_sub(grp);
- DRW_shgroup_uniform_vec4_copy(grp_sub, "color", G_draw.block.color_active);
+ DRW_shgroup_uniform_vec4_copy(grp_sub, "ucolor", G_draw.block.color_active);
cb->center_active = BUF_POINT(grp_sub, format);
grp_sub = DRW_shgroup_create_sub(grp);
- DRW_shgroup_uniform_vec4_copy(grp_sub, "color", G_draw.block.color_select);
+ DRW_shgroup_uniform_vec4_copy(grp_sub, "ucolor", G_draw.block.color_select);
cb->center_selected = BUF_POINT(grp_sub, format);
grp_sub = DRW_shgroup_create_sub(grp);
- DRW_shgroup_uniform_vec4_copy(grp_sub, "color", G_draw.block.color_deselect);
+ DRW_shgroup_uniform_vec4_copy(grp_sub, "ucolor", G_draw.block.color_deselect);
cb->center_deselected = BUF_POINT(grp_sub, format);
grp_sub = DRW_shgroup_create_sub(grp);
- DRW_shgroup_uniform_vec4_copy(grp_sub, "color", G_draw.block.color_library_select);
+ DRW_shgroup_uniform_vec4_copy(grp_sub, "ucolor", G_draw.block.color_library_select);
cb->center_selected_lib = BUF_POINT(grp_sub, format);
grp_sub = DRW_shgroup_create_sub(grp);
- DRW_shgroup_uniform_vec4_copy(grp_sub, "color", G_draw.block.color_library);
+ DRW_shgroup_uniform_vec4_copy(grp_sub, "ucolor", G_draw.block.color_library);
cb->center_deselected_lib = BUF_POINT(grp_sub, format);
}
}
@@ -352,7 +353,7 @@ static void OVERLAY_bounds(OVERLAY_ExtraCallBuffers *cb,
const BoundBox *bb = BKE_object_boundbox_get(ob);
BoundBox bb_local;
- if (bb == NULL) {
+ if (bb == nullptr) {
const float min[3] = {-1.0f, -1.0f, -1.0f}, max[3] = {1.0f, 1.0f, 1.0f};
BKE_boundbox_init_from_minmax(&bb_local, min, max);
bb = &bb_local;
@@ -443,17 +444,17 @@ static void OVERLAY_collision(OVERLAY_ExtraCallBuffers *cb, Object *ob, const fl
static void OVERLAY_texture_space(OVERLAY_ExtraCallBuffers *cb, Object *ob, const float *color)
{
- if (ob->data == NULL) {
+ if (ob->data == nullptr) {
return;
}
- ID *ob_data = ob->data;
- float *texcoloc = NULL;
- float *texcosize = NULL;
+ ID *ob_data = static_cast<ID *>(ob->data);
+ float *texcoloc = nullptr;
+ float *texcosize = nullptr;
switch (GS(ob_data->name)) {
case ID_ME:
- BKE_mesh_texspace_get_reference((Mesh *)ob_data, NULL, &texcoloc, &texcosize);
+ BKE_mesh_texspace_get_reference((Mesh *)ob_data, nullptr, &texcoloc, &texcosize);
break;
case ID_CU_LEGACY: {
Curve *cu = (Curve *)ob_data;
@@ -480,7 +481,7 @@ static void OVERLAY_texture_space(OVERLAY_ExtraCallBuffers *cb, Object *ob, cons
float mat[4][4];
- if (texcoloc != NULL && texcosize != NULL) {
+ if (texcoloc != nullptr && texcosize != nullptr) {
size_to_mat4(mat, texcosize);
copy_v3_v3(mat[3], texcoloc);
}
@@ -495,10 +496,10 @@ static void OVERLAY_texture_space(OVERLAY_ExtraCallBuffers *cb, Object *ob, cons
static void OVERLAY_forcefield(OVERLAY_ExtraCallBuffers *cb, Object *ob, ViewLayer *view_layer)
{
- int theme_id = DRW_object_wire_theme_get(ob, view_layer, NULL);
+ int theme_id = DRW_object_wire_theme_get(ob, view_layer, nullptr);
float *color = DRW_color_background_blend_get(theme_id);
PartDeflect *pd = ob->pd;
- Curve *cu = (ob->type == OB_CURVES_LEGACY) ? ob->data : NULL;
+ Curve *cu = (ob->type == OB_CURVES_LEGACY) ? static_cast<Curve *>(ob->data) : nullptr;
union {
float mat[4][4];
@@ -529,12 +530,12 @@ static void OVERLAY_forcefield(OVERLAY_ExtraCallBuffers *cb, Object *ob, ViewLay
if (cu && (cu->flag & CU_PATH) && ob->runtime.curve_cache->anim_path_accum_length) {
instdata.size_x = instdata.size_y = instdata.size_z = pd->f_strength;
float pos[4];
- BKE_where_on_path(ob, 0.0f, pos, NULL, NULL, NULL, NULL);
+ BKE_where_on_path(ob, 0.0f, pos, nullptr, nullptr, nullptr, nullptr);
copy_v3_v3(instdata.pos, ob->obmat[3]);
translate_m4(instdata.mat, pos[0], pos[1], pos[2]);
DRW_buffer_add_entry(cb->field_curve, color, &instdata);
- BKE_where_on_path(ob, 1.0f, pos, NULL, NULL, NULL, NULL);
+ BKE_where_on_path(ob, 1.0f, pos, nullptr, nullptr, nullptr, nullptr);
copy_v3_v3(instdata.pos, ob->obmat[3]);
translate_m4(instdata.mat, pos[0], pos[1], pos[2]);
DRW_buffer_add_entry(cb->field_sphere_limit, color, &instdata);
@@ -600,7 +601,7 @@ void OVERLAY_light_cache_populate(OVERLAY_Data *vedata, Object *ob)
const DRWContextState *draw_ctx = DRW_context_state_get();
ViewLayer *view_layer = draw_ctx->view_layer;
- Light *la = ob->data;
+ Light *la = static_cast<Light *>(ob->data);
float *color_p;
DRW_object_wire_theme_get(ob, view_layer, &color_p);
/* Remove the alpha. */
@@ -644,7 +645,8 @@ void OVERLAY_light_cache_populate(OVERLAY_Data *vedata, Object *ob)
else if (la->type == LA_SPOT) {
/* Previous implementation was using the clipend distance as cone size.
* We cannot do this anymore so we use a fixed size of 10. (see T72871) */
- rescale_m4(instdata.mat, (float[3]){10.0f, 10.0f, 10.0f});
+ const float3 scale_vec = {10.0f, 10.0f, 10.0f};
+ rescale_m4(instdata.mat, scale_vec);
/* For cycles and eevee the spot attenuation is
* y = (1/(1 + x^2) - a)/((1 - a) b)
* We solve the case where spot attenuation y = 1 and y = 0
@@ -756,7 +758,7 @@ void OVERLAY_lightprobe_cache_populate(OVERLAY_Data *vedata, Object *ob)
uint cell_count = prb->grid_resolution_x * prb->grid_resolution_y * prb->grid_resolution_z;
DRWShadingGroup *grp = DRW_shgroup_create_sub(vedata->stl->pd->extra_grid_grp);
DRW_shgroup_uniform_mat4_copy(grp, "gridModelMatrix", instdata.mat);
- DRW_shgroup_call_procedural_points(grp, NULL, cell_count);
+ DRW_shgroup_call_procedural_points(grp, nullptr, cell_count);
}
break;
case LIGHTPROBE_TYPE_PLANAR:
@@ -849,7 +851,7 @@ static void camera_view3d_reconstruction(
const bool is_select = DRW_state_is_select();
MovieClip *clip = BKE_object_movieclip_get(scene, ob, false);
- if (clip == NULL) {
+ if (clip == nullptr) {
return;
}
@@ -985,7 +987,7 @@ static float camera_offaxis_shiftx_get(Scene *scene,
const OVERLAY_CameraInstanceData *instdata,
bool right_eye)
{
- Camera *cam = ob->data;
+ Camera *cam = static_cast<Camera *>(ob->data);
if (cam->stereo.convergence_mode == CAM_S3D_OFFAXIS) {
const char *viewnames[2] = {STEREO_LEFT_NAME, STEREO_RIGHT_NAME};
const float shiftx = BKE_camera_multiview_shift_x(&scene->r, ob, viewnames[right_eye]);
@@ -1007,7 +1009,7 @@ static void camera_stereoscopy_extra(OVERLAY_ExtraCallBuffers *cb,
const OVERLAY_CameraInstanceData *instdata)
{
OVERLAY_CameraInstanceData stereodata = *instdata;
- Camera *cam = ob->data;
+ Camera *cam = static_cast<Camera *>(ob->data);
const bool is_select = DRW_state_is_select();
const char *viewnames[2] = {STEREO_LEFT_NAME, STEREO_RIGHT_NAME};
@@ -1111,7 +1113,7 @@ void OVERLAY_camera_cache_populate(OVERLAY_Data *vedata, Object *ob)
Scene *scene = draw_ctx->scene;
RegionView3D *rv3d = draw_ctx->rv3d;
- Camera *cam = ob->data;
+ Camera *cam = static_cast<Camera *>(ob->data);
Object *camera_object = DEG_get_evaluated_object(draw_ctx->depsgraph, v3d->camera);
const bool is_select = DRW_state_is_select();
const bool is_active = (ob == camera_object);
@@ -1257,7 +1259,7 @@ static void OVERLAY_relationship_lines(OVERLAY_ExtraCallBuffers *cb,
}
/* Drawing the hook lines. */
- for (ModifierData *md = ob->modifiers.first; md; md = md->next) {
+ for (ModifierData *md = static_cast<ModifierData *>(ob->modifiers.first); md; md = md->next) {
if (md->type == eModifierType_Hook) {
HookModifierData *hmd = (HookModifierData *)md;
float center[3];
@@ -1286,14 +1288,14 @@ static void OVERLAY_relationship_lines(OVERLAY_ExtraCallBuffers *cb,
bConstraintOb *cob;
ListBase *list = &ob->constraints;
- cob = BKE_constraints_make_evalob(depsgraph, scene, ob, NULL, CONSTRAINT_OBTYPE_OBJECT);
+ cob = BKE_constraints_make_evalob(depsgraph, scene, ob, nullptr, CONSTRAINT_OBTYPE_OBJECT);
- for (curcon = list->first; curcon; curcon = curcon->next) {
+ for (curcon = static_cast<bConstraint *>(list->first); curcon; curcon = curcon->next) {
if (ELEM(curcon->type, CONSTRAINT_TYPE_FOLLOWTRACK, CONSTRAINT_TYPE_OBJECTSOLVER)) {
/* special case for object solver and follow track constraints because they don't fill
* constraint targets properly (design limitation -- scene is needed for their target
* but it can't be accessed from get_targets callback) */
- Object *camob = NULL;
+ Object *camob = nullptr;
if (curcon->type == CONSTRAINT_TYPE_FOLLOWTRACK) {
bFollowTrackConstraint *data = (bFollowTrackConstraint *)curcon->data;
@@ -1310,14 +1312,14 @@ static void OVERLAY_relationship_lines(OVERLAY_ExtraCallBuffers *cb,
}
else {
const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(curcon);
- ListBase targets = {NULL, NULL};
+ ListBase targets = {nullptr, nullptr};
if ((curcon->ui_expand_flag & (1 << 0)) && BKE_constraint_targets_get(curcon, &targets)) {
bConstraintTarget *ct;
BKE_constraint_custom_object_space_init(cob, curcon);
- for (ct = targets.first; ct; ct = ct->next) {
+ for (ct = static_cast<bConstraintTarget *>(targets.first); ct; ct = ct->next) {
/* calculate target's matrix */
if (ct->flag & CONSTRAINT_TAR_CUSTOM_SPACE) {
copy_m4_m4(ct->matrix, cob->space_obj_world_matrix);
@@ -1335,7 +1337,7 @@ static void OVERLAY_relationship_lines(OVERLAY_ExtraCallBuffers *cb,
}
}
}
- /* NOTE: Don't use BKE_constraints_clear_evalob here as that will reset ob->constinv. */
+ /* NOTE: Don't use #BKE_constraints_clear_evalob here as that will reset `ob->constinv`. */
MEM_freeN(cob);
}
}
@@ -1394,7 +1396,7 @@ static void OVERLAY_volume_extra(OVERLAY_ExtraCallBuffers *cb,
if (fds->axis_slice_method == AXIS_SLICE_SINGLE) {
float viewinv[4][4];
- DRW_view_viewmat_get(NULL, viewinv, true);
+ DRW_view_viewmat_get(nullptr, viewinv, true);
const int axis = (fds->slice_axis == SLICE_AXIS_AUTO) ? axis_dominant_v3_single(viewinv[2]) :
fds->slice_axis - 1;
@@ -1485,11 +1487,12 @@ static void OVERLAY_volume_extra(OVERLAY_ExtraCallBuffers *cb,
static void OVERLAY_object_center(OVERLAY_ExtraCallBuffers *cb,
Object *ob,
OVERLAY_PrivateData *pd,
+ const Scene *scene,
ViewLayer *view_layer)
{
const bool is_library = ID_REAL_USERS(&ob->id) > 1 || ID_IS_LINKED(ob);
-
- if (ob == OBACT(view_layer)) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ if (ob == BKE_view_layer_active_object_get(view_layer)) {
DRW_buffer_add_entry(cb->center_active, ob->obmat[3]);
}
else if (ob->base_flag & BASE_SELECTED) {
@@ -1526,7 +1529,7 @@ void OVERLAY_extra_cache_populate(OVERLAY_Data *vedata, Object *ob)
const DRWContextState *draw_ctx = DRW_context_state_get();
ViewLayer *view_layer = draw_ctx->view_layer;
Scene *scene = draw_ctx->scene;
- ModifierData *md = NULL;
+ ModifierData *md = nullptr;
const bool is_select_mode = DRW_state_is_select();
const bool is_paint_mode = (draw_ctx->object_mode &
@@ -1550,7 +1553,7 @@ void OVERLAY_extra_cache_populate(OVERLAY_Data *vedata, Object *ob)
const bool draw_volume = !from_dupli &&
(md = BKE_modifiers_findby_type(ob, eModifierType_Fluid)) &&
(BKE_modifier_is_enabled(scene, md, eModifierMode_Realtime)) &&
- (((FluidModifierData *)md)->domain != NULL) &&
+ (((FluidModifierData *)md)->domain != nullptr) &&
(scene->r.cfra >=
(((FluidModifierData *)md)->domain->cache_frame_start)) &&
(scene->r.cfra <= (((FluidModifierData *)md)->domain->cache_frame_end));
@@ -1573,7 +1576,7 @@ void OVERLAY_extra_cache_populate(OVERLAY_Data *vedata, Object *ob)
/* don't show object extras in set's */
if (!from_dupli) {
if (draw_obcenters) {
- OVERLAY_object_center(cb, ob, pd, view_layer);
+ OVERLAY_object_center(cb, ob, pd, scene, view_layer);
}
if (draw_relations) {
OVERLAY_relationship_lines(cb, draw_ctx->depsgraph, draw_ctx->scene, ob);
@@ -1584,7 +1587,7 @@ void OVERLAY_extra_cache_populate(OVERLAY_Data *vedata, Object *ob)
if (draw_texspace) {
OVERLAY_texture_space(cb, ob, color);
}
- if (ob->rigidbody_object != NULL) {
+ if (ob->rigidbody_object != nullptr) {
OVERLAY_collision(cb, ob, color);
}
if (ob->dtx & OB_AXIS) {
diff --git a/source/blender/draw/engines/overlay/overlay_facing.c b/source/blender/draw/engines/overlay/overlay_facing.cc
index bf06600eb33..9a501c8f1bb 100644
--- a/source/blender/draw/engines/overlay/overlay_facing.c
+++ b/source/blender/draw/engines/overlay/overlay_facing.cc
@@ -8,7 +8,7 @@
#include "BKE_paint.h"
#include "DRW_render.h"
-#include "overlay_private.h"
+#include "overlay_private.hh"
void OVERLAY_facing_init(OVERLAY_Data *UNUSED(vedata))
{
diff --git a/source/blender/draw/engines/overlay/overlay_fade.c b/source/blender/draw/engines/overlay/overlay_fade.cc
index 056e02a04e1..ee5540d91eb 100644
--- a/source/blender/draw/engines/overlay/overlay_fade.c
+++ b/source/blender/draw/engines/overlay/overlay_fade.cc
@@ -10,7 +10,7 @@
#include "ED_view3d.h"
-#include "overlay_private.h"
+#include "overlay_private.hh"
void OVERLAY_fade_init(OVERLAY_Data *UNUSED(vedata))
{
@@ -36,7 +36,7 @@ void OVERLAY_fade_cache_init(OVERLAY_Data *vedata)
if (draw_ctx->v3d->shading.background_type == V3D_SHADING_BACKGROUND_THEME) {
srgb_to_linearrgb_v4(color, color);
}
- DRW_shgroup_uniform_vec4_copy(pd->fade_grp[i], "color", color);
+ DRW_shgroup_uniform_vec4_copy(pd->fade_grp[i], "ucolor", color);
}
if (!pd->use_in_front) {
diff --git a/source/blender/draw/engines/overlay/overlay_gpencil.c b/source/blender/draw/engines/overlay/overlay_gpencil.cc
index 9531b0dd983..f72bf81bf57 100644
--- a/source/blender/draw/engines/overlay/overlay_gpencil.c
+++ b/source/blender/draw/engines/overlay/overlay_gpencil.cc
@@ -17,7 +17,7 @@
#include "ED_view3d.h"
-#include "overlay_private.h"
+#include "overlay_private.hh"
#include "draw_common.h"
#include "draw_manager_text.h"
@@ -30,22 +30,22 @@ void OVERLAY_edit_gpencil_cache_init(OVERLAY_Data *vedata)
DRWShadingGroup *grp;
/* Default: Display nothing. */
- pd->edit_gpencil_points_grp = NULL;
- pd->edit_gpencil_wires_grp = NULL;
- psl->edit_gpencil_ps = NULL;
+ pd->edit_gpencil_points_grp = nullptr;
+ pd->edit_gpencil_wires_grp = nullptr;
+ psl->edit_gpencil_ps = nullptr;
- pd->edit_gpencil_curve_handle_grp = NULL;
- pd->edit_gpencil_curve_points_grp = NULL;
- psl->edit_gpencil_curve_ps = NULL;
+ pd->edit_gpencil_curve_handle_grp = nullptr;
+ pd->edit_gpencil_curve_points_grp = nullptr;
+ psl->edit_gpencil_curve_ps = nullptr;
const DRWContextState *draw_ctx = DRW_context_state_get();
View3D *v3d = draw_ctx->v3d;
Object *ob = draw_ctx->obact;
- bGPdata *gpd = ob ? (bGPdata *)ob->data : NULL;
+ bGPdata *gpd = ob ? (bGPdata *)ob->data : nullptr;
Scene *scene = draw_ctx->scene;
ToolSettings *ts = scene->toolsettings;
- if (gpd == NULL || ob->type != OB_GPENCIL) {
+ if (gpd == nullptr || ob->type != OB_GPENCIL) {
return;
}
@@ -169,14 +169,14 @@ void OVERLAY_edit_gpencil_cache_init(OVERLAY_Data *vedata)
sh = OVERLAY_shader_edit_gpencil_guide_point();
grp = DRW_shgroup_create(sh, psl->edit_gpencil_gizmos_ps);
- if (gpd->runtime.cp_points != NULL) {
+ if (gpd->runtime.cp_points != nullptr) {
for (int i = 0; i < gpd->runtime.tot_cp_points; i++) {
bGPDcontrolpoint *cp = &gpd->runtime.cp_points[i];
grp = DRW_shgroup_create_sub(grp);
DRW_shgroup_uniform_vec3_copy(grp, "pPosition", &cp->x);
DRW_shgroup_uniform_float_copy(grp, "pSize", cp->size * 0.8f * G_draw.block.size_pixel);
DRW_shgroup_uniform_vec4_copy(grp, "pColor", cp->color);
- DRW_shgroup_call_procedural_points(grp, NULL, 1);
+ DRW_shgroup_call_procedural_points(grp, nullptr, 1);
}
}
@@ -187,7 +187,7 @@ void OVERLAY_edit_gpencil_cache_init(OVERLAY_Data *vedata)
DRW_shgroup_uniform_vec3_copy(grp, "pPosition", ts->gp_sculpt.guide.location);
}
else if (ts->gp_sculpt.guide.reference_point == GP_GUIDE_REF_OBJECT &&
- ts->gp_sculpt.guide.reference_object != NULL) {
+ ts->gp_sculpt.guide.reference_object != nullptr) {
UI_GetThemeColor4fv(TH_GIZMO_SECONDARY, color);
DRW_shgroup_uniform_vec3_copy(grp, "pPosition", ts->gp_sculpt.guide.reference_object->loc);
}
@@ -197,7 +197,7 @@ void OVERLAY_edit_gpencil_cache_init(OVERLAY_Data *vedata)
}
DRW_shgroup_uniform_vec4_copy(grp, "pColor", color);
DRW_shgroup_uniform_float_copy(grp, "pSize", 8.0f * G_draw.block.size_pixel);
- DRW_shgroup_call_procedural_points(grp, NULL, 1);
+ DRW_shgroup_call_procedural_points(grp, nullptr, 1);
}
}
}
@@ -210,12 +210,12 @@ void OVERLAY_gpencil_cache_init(OVERLAY_Data *vedata)
DRWShadingGroup *grp;
/* Default: Display nothing. */
- psl->gpencil_canvas_ps = NULL;
+ psl->gpencil_canvas_ps = nullptr;
const DRWContextState *draw_ctx = DRW_context_state_get();
View3D *v3d = draw_ctx->v3d;
Object *ob = draw_ctx->obact;
- bGPdata *gpd = ob ? (bGPdata *)ob->data : NULL;
+ bGPdata *gpd = ob ? (bGPdata *)ob->data : nullptr;
Scene *scene = draw_ctx->scene;
ToolSettings *ts = scene->toolsettings;
const View3DCursor *cursor = &scene->cursor;
@@ -223,7 +223,7 @@ void OVERLAY_gpencil_cache_init(OVERLAY_Data *vedata)
pd->edit_curve.show_handles = v3d->overlay.handle_display != CURVE_HANDLE_NONE;
pd->edit_curve.handle_display = v3d->overlay.handle_display;
- if (gpd == NULL || ob->type != OB_GPENCIL) {
+ if (gpd == nullptr || ob->type != OB_GPENCIL) {
return;
}
@@ -234,7 +234,7 @@ void OVERLAY_gpencil_cache_init(OVERLAY_Data *vedata)
const bool grid_xray = (v3d->gp_flag & V3D_GP_SHOW_GRID_XRAY);
if (show_grid && show_overlays) {
- const char *grid_unit = NULL;
+ const char *grid_unit = nullptr;
float mat[4][4];
float col_grid[4];
float size[2];
@@ -247,7 +247,7 @@ void OVERLAY_gpencil_cache_init(OVERLAY_Data *vedata)
/* Rotate and scale except align to cursor. */
bGPDlayer *gpl = BKE_gpencil_layer_active_get(gpd);
- if (gpl != NULL) {
+ if (gpl != nullptr) {
if (ts->gp_sculpt.lock_axis != GP_LOCKAXIS_CURSOR) {
float matrot[3][3];
copy_m3_m4(matrot, gpl->layer_mat);
@@ -267,12 +267,14 @@ void OVERLAY_gpencil_cache_init(OVERLAY_Data *vedata)
case GP_LOCKAXIS_Z:
/* Default. */
break;
- case GP_LOCKAXIS_CURSOR:
- loc_eul_size_to_mat4(mat, cursor->location, cursor->rotation_euler, (float[3]){1, 1, 1});
+ case GP_LOCKAXIS_CURSOR: {
+ const float3 size_vec = {1.0f, 1.0f, 1.0f};
+ loc_eul_size_to_mat4(mat, cursor->location, cursor->rotation_euler, size_vec);
break;
+ }
case GP_LOCKAXIS_VIEW:
/* view aligned */
- DRW_view_viewmat_get(NULL, viewinv, true);
+ DRW_view_viewmat_get(nullptr, viewinv, true);
copy_v3_v3(mat[0], viewinv[0]);
copy_v3_v3(mat[1], viewinv[1]);
break;
@@ -289,10 +291,11 @@ void OVERLAY_gpencil_cache_init(OVERLAY_Data *vedata)
translate_m4(mat, gpd->grid.offset[0], gpd->grid.offset[1], 0.0f);
mul_v2_v2fl(size, gpd->grid.scale, 2.0f * ED_scene_grid_scale(scene, &grid_unit));
- rescale_m4(mat, (float[3]){size[0], size[1], 0.0f});
+ const float3 scale_vec = {size[0], size[1], 0.0f};
+ rescale_m4(mat, scale_vec);
/* Apply layer loc transform, except cursor mode. */
- if ((gpl != NULL) && (ts->gpencil_v3d_align & GP_PROJECT_CURSOR) == 0) {
+ if ((gpl != nullptr) && (ts->gpencil_v3d_align & GP_PROJECT_CURSOR) == 0) {
add_v3_v3(mat[3], gpl->layer_mat[3]);
}
@@ -312,7 +315,7 @@ void OVERLAY_gpencil_cache_init(OVERLAY_Data *vedata)
DRW_shgroup_uniform_vec3_copy(grp, "yAxis", mat[1]);
DRW_shgroup_uniform_vec3_copy(grp, "origin", mat[3]);
DRW_shgroup_uniform_int_copy(grp, "halfLineCount", line_count / 2);
- DRW_shgroup_call_procedural_lines(grp, NULL, line_count);
+ DRW_shgroup_call_procedural_lines(grp, nullptr, line_count);
}
}
@@ -368,12 +371,12 @@ static void overlay_gpencil_draw_stroke_color_name(bGPDlayer *UNUSED(gpl),
{
Object *ob = (Object *)thunk;
Material *ma = BKE_object_material_get_eval(ob, gps->mat_nr + 1);
- if (ma == NULL) {
+ if (ma == nullptr) {
return;
}
MaterialGPencilStyle *gp_style = ma->gp_style;
/* skip stroke if it doesn't have any valid data */
- if ((gps->points == NULL) || (gps->totpoints < 1) || (gp_style == NULL)) {
+ if ((gps->points == nullptr) || (gps->totpoints < 1) || (gp_style == nullptr)) {
return;
}
/* check if the color is visible */
@@ -389,7 +392,7 @@ static void overlay_gpencil_draw_stroke_color_name(bGPDlayer *UNUSED(gpl),
const DRWContextState *draw_ctx = DRW_context_state_get();
ViewLayer *view_layer = draw_ctx->view_layer;
- int theme_id = DRW_object_wire_theme_get(ob, view_layer, NULL);
+ int theme_id = DRW_object_wire_theme_get(ob, view_layer, nullptr);
uchar color[4];
UI_GetThemeColor4ubv(theme_id, color);
@@ -417,7 +420,7 @@ static void OVERLAY_gpencil_color_names(Object *ob)
int cfra = DEG_get_ctime(draw_ctx->depsgraph);
BKE_gpencil_visible_stroke_advanced_iter(
- NULL, ob, NULL, overlay_gpencil_draw_stroke_color_name, ob, false, cfra);
+ nullptr, ob, nullptr, overlay_gpencil_draw_stroke_color_name, ob, false, cfra);
}
void OVERLAY_gpencil_cache_populate(OVERLAY_Data *vedata, Object *ob)
@@ -426,7 +429,7 @@ void OVERLAY_gpencil_cache_populate(OVERLAY_Data *vedata, Object *ob)
View3D *v3d = draw_ctx->v3d;
bGPdata *gpd = (bGPdata *)ob->data;
- if (gpd == NULL) {
+ if (gpd == nullptr) {
return;
}
diff --git a/source/blender/draw/engines/overlay/overlay_grid.c b/source/blender/draw/engines/overlay/overlay_grid.cc
index e424f49455b..d1958205a10 100644
--- a/source/blender/draw/engines/overlay/overlay_grid.c
+++ b/source/blender/draw/engines/overlay/overlay_grid.cc
@@ -17,7 +17,7 @@
#include "UI_resources.h"
-#include "overlay_private.h"
+#include "overlay_private.hh"
BLI_STATIC_ASSERT(SI_GRID_STEPS_LEN == OVERLAY_GRID_STEPS_LEN, "")
@@ -31,10 +31,12 @@ void OVERLAY_grid_init(OVERLAY_Data *vedata)
float *zplane_axes = pd->grid.zplane_axes;
float grid_steps[SI_GRID_STEPS_LEN] = {
0.001f, 0.01f, 0.1f, 1.0f, 10.0f, 100.0f, 1000.0f, 10000.0f};
- OVERLAY_GridBits grid_flag = 0, zneg_flag = 0, zpos_flag = 0;
+ float grid_steps_y[SI_GRID_STEPS_LEN] = {0.0f}; /* When zero, use value from grid_steps. */
+ OVERLAY_GridBits grid_flag = OVERLAY_GridBits(0), zneg_flag = OVERLAY_GridBits(0),
+ zpos_flag = OVERLAY_GridBits(0);
grid->line_size = max_ff(0.0f, U.pixelsize - 1.0f) * 0.5f;
/* Default, nothing is drawn. */
- pd->grid.grid_flag = pd->grid.zneg_flag = pd->grid.zpos_flag = 0;
+ pd->grid.grid_flag = pd->grid.zneg_flag = pd->grid.zpos_flag = OVERLAY_GridBits(0);
if (pd->space_type == SPACE_IMAGE) {
SpaceImage *sima = (SpaceImage *)draw_ctx->space_data;
@@ -49,6 +51,9 @@ void OVERLAY_grid_init(OVERLAY_Data *vedata)
true;
if (background_enabled) {
grid_flag = GRID_BACK | PLANE_IMAGE;
+ if (sima->flag & SI_GRID_OVER_IMAGE) {
+ grid_flag = PLANE_IMAGE;
+ }
}
const bool draw_grid = is_uv_edit || !ED_space_image_has_buffer(sima);
@@ -67,7 +72,7 @@ void OVERLAY_grid_init(OVERLAY_Data *vedata)
}
grid->zoom_factor = ED_space_image_zoom_level(v2d, SI_GRID_STEPS_LEN);
- ED_space_image_grid_steps(sima, grid_steps, SI_GRID_STEPS_LEN);
+ ED_space_image_grid_steps(sima, grid_steps, grid_steps_y, SI_GRID_STEPS_LEN);
}
else {
/* SPACE_VIEW3D */
@@ -88,10 +93,10 @@ void OVERLAY_grid_init(OVERLAY_Data *vedata)
float viewinv[4][4], wininv[4][4];
float viewmat[4][4], winmat[4][4];
- DRW_view_winmat_get(NULL, winmat, false);
- DRW_view_winmat_get(NULL, wininv, true);
- DRW_view_viewmat_get(NULL, viewmat, false);
- DRW_view_viewmat_get(NULL, viewinv, true);
+ DRW_view_winmat_get(nullptr, winmat, false);
+ DRW_view_winmat_get(nullptr, wininv, true);
+ DRW_view_viewmat_get(nullptr, viewmat, false);
+ DRW_view_viewmat_get(nullptr, viewinv, true);
/* If perspective view or non-axis aligned view. */
if (winmat[3][3] == 0.0f || rv3d->view == RV3D_VIEW_USER) {
@@ -196,6 +201,7 @@ void OVERLAY_grid_init(OVERLAY_Data *vedata)
/* Convert to UBO alignment. */
for (int i = 0; i < SI_GRID_STEPS_LEN; i++) {
grid->steps[i][0] = grid_steps[i];
+ grid->steps[i][1] = (grid_steps_y[i] != 0.0f) ? grid_steps_y[i] : grid_steps[i];
}
pd->grid.grid_flag = grid_flag;
pd->grid.zneg_flag = zneg_flag;
@@ -211,13 +217,13 @@ void OVERLAY_grid_cache_init(OVERLAY_Data *ved)
OVERLAY_PassList *psl = ved->psl;
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
- psl->grid_ps = NULL;
+ psl->grid_ps = nullptr;
if ((pd->grid.grid_flag == 0 && pd->grid.zpos_flag == 0) || !DRW_state_is_fbo()) {
return;
}
- if (ved->instance->grid_ubo == NULL) {
+ if (ved->instance->grid_ubo == nullptr) {
ved->instance->grid_ubo = GPU_uniformbuf_create(sizeof(OVERLAY_GridData));
}
GPU_uniformbuf_update(ved->instance->grid_ubo, &pd->grid_data);
@@ -257,21 +263,21 @@ void OVERLAY_grid_cache_init(OVERLAY_Data *ved)
DRW_shgroup_uniform_int_copy(grp, "grid_flag", pd->grid.zneg_flag);
DRW_shgroup_uniform_vec3_copy(grp, "plane_axes", pd->grid.zplane_axes);
if (pd->grid.zneg_flag & SHOW_AXIS_Z) {
- DRW_shgroup_call(grp, geom, NULL);
+ DRW_shgroup_call(grp, geom, nullptr);
}
grp = DRW_shgroup_create_sub(grp);
DRW_shgroup_uniform_int_copy(grp, "grid_flag", pd->grid.grid_flag);
DRW_shgroup_uniform_vec3_copy(grp, "plane_axes", pd->grid.grid_axes);
if (pd->grid.grid_flag) {
- DRW_shgroup_call(grp, geom, NULL);
+ DRW_shgroup_call(grp, geom, nullptr);
}
grp = DRW_shgroup_create_sub(grp);
DRW_shgroup_uniform_int_copy(grp, "grid_flag", pd->grid.zpos_flag);
DRW_shgroup_uniform_vec3_copy(grp, "plane_axes", pd->grid.zplane_axes);
if (pd->grid.zpos_flag & SHOW_AXIS_Z) {
- DRW_shgroup_call(grp, geom, NULL);
+ DRW_shgroup_call(grp, geom, nullptr);
}
}
@@ -284,7 +290,7 @@ void OVERLAY_grid_cache_init(OVERLAY_Data *ved)
/* add wire border */
GPUShader *sh = OVERLAY_shader_grid_image();
DRWShadingGroup *grp = DRW_shgroup_create(sh, psl->grid_ps);
- DRW_shgroup_uniform_vec4_copy(grp, "color", theme_color);
+ DRW_shgroup_uniform_vec4_copy(grp, "ucolor", theme_color);
unit_m4(mat);
for (int x = 0; x < grid->size[0]; x++) {
mat[3][0] = x;
diff --git a/source/blender/draw/engines/overlay/overlay_image.c b/source/blender/draw/engines/overlay/overlay_image.cc
index 3e9c05bb59f..47587319098 100644
--- a/source/blender/draw/engines/overlay/overlay_image.c
+++ b/source/blender/draw/engines/overlay/overlay_image.cc
@@ -23,7 +23,7 @@
#include "IMB_imbuf_types.h"
-#include "overlay_private.h"
+#include "overlay_private.hh"
void OVERLAY_image_init(OVERLAY_Data *vedata)
{
@@ -99,10 +99,10 @@ static eStereoViews camera_background_images_stereo_eye(const Scene *scene, cons
}
if (v3d->stereo3d_camera != STEREO_3D_ID) {
/* show only left or right camera */
- return v3d->stereo3d_camera;
+ return eStereoViews(v3d->stereo3d_camera);
}
- return v3d->multiview_eye;
+ return eStereoViews(v3d->multiview_eye);
}
static void camera_background_images_stereo_setup(const Scene *scene,
@@ -130,8 +130,8 @@ static struct GPUTexture *image_camera_background_texture_get(CameraBGImage *bgp
void *lock;
Image *image = bgpic->ima;
ImageUser *iuser = &bgpic->iuser;
- MovieClip *clip = NULL;
- GPUTexture *tex = NULL;
+ MovieClip *clip = nullptr;
+ GPUTexture *tex = nullptr;
Scene *scene = draw_ctx->scene;
float aspect_x, aspect_y;
int width, height;
@@ -140,9 +140,9 @@ static struct GPUTexture *image_camera_background_texture_get(CameraBGImage *bgp
*r_use_view_transform = false;
switch (bgpic->source) {
- case CAM_BGIMG_SOURCE_IMAGE:
- if (image == NULL) {
- return NULL;
+ case CAM_BGIMG_SOURCE_IMAGE: {
+ if (image == nullptr) {
+ return nullptr;
}
*r_use_alpha_premult = (image->alpha_mode == IMA_ALPHA_PREMUL);
*r_use_view_transform = (image->flag & IMA_VIEW_AS_RENDER) != 0;
@@ -150,33 +150,34 @@ static struct GPUTexture *image_camera_background_texture_get(CameraBGImage *bgp
BKE_image_user_frame_calc(image, iuser, ctime);
if (image->source == IMA_SRC_SEQUENCE && !(iuser->flag & IMA_USER_FRAME_IN_RANGE)) {
/* Frame is out of range, don't show. */
- return NULL;
+ return nullptr;
}
camera_background_images_stereo_setup(scene, draw_ctx->v3d, image, iuser);
iuser->scene = draw_ctx->scene;
ImBuf *ibuf = BKE_image_acquire_ibuf(image, iuser, &lock);
- if (ibuf == NULL) {
+ if (ibuf == nullptr) {
BKE_image_release_ibuf(image, ibuf, lock);
- iuser->scene = NULL;
- return NULL;
+ iuser->scene = nullptr;
+ return nullptr;
}
width = ibuf->x;
height = ibuf->y;
tex = BKE_image_get_gpu_texture(image, iuser, ibuf);
BKE_image_release_ibuf(image, ibuf, lock);
- iuser->scene = NULL;
+ iuser->scene = nullptr;
- if (tex == NULL) {
- return NULL;
+ if (tex == nullptr) {
+ return nullptr;
}
aspect_x = bgpic->ima->aspx;
aspect_y = bgpic->ima->aspy;
break;
+ }
- case CAM_BGIMG_SOURCE_MOVIE:
+ case CAM_BGIMG_SOURCE_MOVIE: {
if (bgpic->flag & CAM_BGIMG_FLAG_CAMERACLIP) {
if (scene->camera) {
clip = BKE_object_movieclip_get(scene, scene->camera, true);
@@ -186,14 +187,14 @@ static struct GPUTexture *image_camera_background_texture_get(CameraBGImage *bgp
clip = bgpic->clip;
}
- if (clip == NULL) {
- return NULL;
+ if (clip == nullptr) {
+ return nullptr;
}
BKE_movieclip_user_set_frame(&bgpic->cuser, ctime);
tex = BKE_movieclip_get_gpu_texture(clip, &bgpic->cuser);
- if (tex == NULL) {
- return NULL;
+ if (tex == nullptr) {
+ return nullptr;
}
aspect_x = clip->aspx;
@@ -205,10 +206,11 @@ static struct GPUTexture *image_camera_background_texture_get(CameraBGImage *bgp
/* Save for freeing. */
BLI_addtail(&pd->bg_movie_clips, BLI_genericNodeN(clip));
break;
+ }
default:
/* Unsupported type. */
- return NULL;
+ return nullptr;
}
*r_aspect = (width * aspect_x) / (height * aspect_y);
@@ -219,7 +221,7 @@ static void OVERLAY_image_free_movieclips_textures(OVERLAY_Data *data)
{
/* Free Movie clip textures after rendering */
LinkData *link;
- while ((link = BLI_pophead(&data->stl->pd->bg_movie_clips))) {
+ while ((link = static_cast<LinkData *>(BLI_pophead(&data->stl->pd->bg_movie_clips)))) {
MovieClip *clip = (MovieClip *)link->data;
BKE_movieclip_free_gputexture(clip);
MEM_freeN(link);
@@ -299,7 +301,7 @@ void OVERLAY_image_camera_cache_populate(OVERLAY_Data *vedata, Object *ob)
const DRWContextState *draw_ctx = DRW_context_state_get();
const View3D *v3d = draw_ctx->v3d;
const Scene *scene = draw_ctx->scene;
- Camera *cam = ob->data;
+ Camera *cam = static_cast<Camera *>(ob->data);
const bool show_frame = BKE_object_empty_image_frame_is_visible_in_view3d(ob, draw_ctx->rv3d);
@@ -333,7 +335,7 @@ void OVERLAY_image_camera_cache_populate(OVERLAY_Data *vedata, Object *ob)
/* Alpha is clamped just below 1.0 to fix background images to interfere with foreground
* images. Without this a background image with 1.0 will be rendered on top of a transparent
* foreground image due to the different blending modes they use. */
- const float color_premult_alpha[4] = {1.0f, 1.0f, 1.0f, MIN2(bgpic->alpha, 0.999999)};
+ const float color_premult_alpha[4] = {1.0f, 1.0f, 1.0f, std::min(bgpic->alpha, 0.999999f)};
DRWPass *pass = is_foreground ? (use_view_transform ? psl->image_foreground_scene_ps :
psl->image_foreground_ps) :
@@ -347,7 +349,7 @@ void OVERLAY_image_camera_cache_populate(OVERLAY_Data *vedata, Object *ob)
DRW_shgroup_uniform_bool_copy(grp, "imgAlphaBlend", true);
DRW_shgroup_uniform_bool_copy(grp, "isCameraBackground", true);
DRW_shgroup_uniform_bool_copy(grp, "depthSet", true);
- DRW_shgroup_uniform_vec4_copy(grp, "color", color_premult_alpha);
+ DRW_shgroup_uniform_vec4_copy(grp, "ucolor", color_premult_alpha);
DRW_shgroup_call_obmat(grp, DRW_cache_quad_get(), mat);
}
}
@@ -358,8 +360,8 @@ void OVERLAY_image_empty_cache_populate(OVERLAY_Data *vedata, Object *ob)
OVERLAY_PassList *psl = vedata->psl;
const DRWContextState *draw_ctx = DRW_context_state_get();
const RegionView3D *rv3d = draw_ctx->rv3d;
- GPUTexture *tex = NULL;
- Image *ima = ob->data;
+ GPUTexture *tex = nullptr;
+ Image *ima = static_cast<Image *>(ob->data);
float mat[4][4];
const bool show_frame = BKE_object_empty_image_frame_is_visible_in_view3d(ob, rv3d);
@@ -375,10 +377,10 @@ void OVERLAY_image_empty_cache_populate(OVERLAY_Data *vedata, Object *ob)
/* Calling 'BKE_image_get_size' may free the texture. Get the size from 'tex' instead,
* see: T59347 */
int size[2] = {0};
- if (ima != NULL) {
+ if (ima != nullptr) {
ImageUser iuser = *ob->iuser;
camera_background_images_stereo_setup(draw_ctx->scene, draw_ctx->v3d, ima, &iuser);
- tex = BKE_image_get_gpu_texture(ima, &iuser, NULL);
+ tex = BKE_image_get_gpu_texture(ima, &iuser, nullptr);
if (tex) {
size[0] = GPU_texture_orig_width(tex);
size[1] = GPU_texture_orig_height(tex);
@@ -388,7 +390,7 @@ void OVERLAY_image_empty_cache_populate(OVERLAY_Data *vedata, Object *ob)
CLAMP_MIN(size[1], 1);
float image_aspect[2];
- overlay_image_calc_aspect(ob->data, size, image_aspect);
+ overlay_image_calc_aspect(ima, size, image_aspect);
copy_m4_m4(mat, ob->obmat);
mul_v3_fl(mat[0], image_aspect[0] * 0.5f * ob->empty_drawsize);
@@ -399,7 +401,7 @@ void OVERLAY_image_empty_cache_populate(OVERLAY_Data *vedata, Object *ob)
/* Use the actual depth if we are doing depth tests to determine the distance to the object */
char depth_mode = DRW_state_is_depth() ? OB_EMPTY_IMAGE_DEPTH_DEFAULT : ob->empty_image_depth;
- DRWPass *pass = NULL;
+ DRWPass *pass = nullptr;
if ((ob->dtx & OB_DRAW_IN_FRONT) != 0) {
/* Object In Front overrides image empty depth mode. */
pass = psl->image_empties_front_ps;
@@ -433,7 +435,7 @@ void OVERLAY_image_empty_cache_populate(OVERLAY_Data *vedata, Object *ob)
DRW_shgroup_uniform_bool_copy(grp, "imgAlphaBlend", use_alpha_blend);
DRW_shgroup_uniform_bool_copy(grp, "isCameraBackground", false);
DRW_shgroup_uniform_bool_copy(grp, "depthSet", depth_mode != OB_EMPTY_IMAGE_DEPTH_DEFAULT);
- DRW_shgroup_uniform_vec4_copy(grp, "color", ob->color);
+ DRW_shgroup_uniform_vec4_copy(grp, "ucolor", ob->color);
DRW_shgroup_call_obmat(grp, DRW_cache_quad_get(), mat);
}
}
@@ -479,7 +481,7 @@ void OVERLAY_image_draw(OVERLAY_Data *vedata)
DRW_draw_pass(psl->image_empties_ps);
DRW_draw_pass(psl->image_empties_blend_ps);
- DRW_view_set_active(NULL);
+ DRW_view_set_active(nullptr);
}
void OVERLAY_image_in_front_draw(OVERLAY_Data *vedata)
@@ -492,7 +494,7 @@ void OVERLAY_image_in_front_draw(OVERLAY_Data *vedata)
DRW_draw_pass(psl->image_empties_front_ps);
DRW_draw_pass(psl->image_foreground_ps);
- DRW_view_set_active(NULL);
+ DRW_view_set_active(nullptr);
OVERLAY_image_free_movieclips_textures(vedata);
}
diff --git a/source/blender/draw/engines/overlay/overlay_lattice.c b/source/blender/draw/engines/overlay/overlay_lattice.cc
index 2035a9a9d3b..7b59aa78c89 100644
--- a/source/blender/draw/engines/overlay/overlay_lattice.c
+++ b/source/blender/draw/engines/overlay/overlay_lattice.cc
@@ -7,7 +7,7 @@
#include "DRW_render.h"
-#include "overlay_private.h"
+#include "overlay_private.hh"
void OVERLAY_edit_lattice_cache_init(OVERLAY_Data *vedata)
{
diff --git a/source/blender/draw/engines/overlay/overlay_metaball.c b/source/blender/draw/engines/overlay/overlay_metaball.cc
index f024f5dfac8..38de273028b 100644
--- a/source/blender/draw/engines/overlay/overlay_metaball.c
+++ b/source/blender/draw/engines/overlay/overlay_metaball.cc
@@ -15,7 +15,7 @@
#include "ED_mball.h"
-#include "overlay_private.h"
+#include "overlay_private.hh"
void OVERLAY_metaball_cache_init(OVERLAY_Data *vedata)
{
@@ -27,7 +27,8 @@ void OVERLAY_metaball_cache_init(OVERLAY_Data *vedata)
#define BUF_INSTANCE DRW_shgroup_call_buffer_instance
for (int i = 0; i < 2; i++) {
- DRWState infront_state = (DRW_state_is_select() && (i == 1)) ? DRW_STATE_IN_FRONT_SELECT : 0;
+ DRWState infront_state = (DRW_state_is_select() && (i == 1)) ? DRW_STATE_IN_FRONT_SELECT :
+ DRWState(0);
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL;
DRW_PASS_CREATE(psl->metaball_ps[i], state | pd->clipping_state | infront_state);
@@ -57,7 +58,7 @@ void OVERLAY_edit_metaball_cache_populate(OVERLAY_Data *vedata, Object *ob)
const bool do_in_front = (ob->dtx & OB_DRAW_IN_FRONT) != 0;
const bool is_select = DRW_state_is_select();
OVERLAY_PrivateData *pd = vedata->stl->pd;
- MetaBall *mb = ob->data;
+ MetaBall *mb = static_cast<MetaBall *>(ob->data);
const float *color;
const float *col_radius = G_draw.block.color_mball_radius;
@@ -103,7 +104,7 @@ void OVERLAY_metaball_cache_populate(OVERLAY_Data *vedata, Object *ob)
{
const bool do_in_front = (ob->dtx & OB_DRAW_IN_FRONT) != 0;
OVERLAY_PrivateData *pd = vedata->stl->pd;
- MetaBall *mb = ob->data;
+ MetaBall *mb = static_cast<MetaBall *>(ob->data);
const DRWContextState *draw_ctx = DRW_context_state_get();
float *color;
diff --git a/source/blender/draw/engines/overlay/overlay_mode_transfer.c b/source/blender/draw/engines/overlay/overlay_mode_transfer.cc
index e7b2008dee0..b312a12a07b 100644
--- a/source/blender/draw/engines/overlay/overlay_mode_transfer.c
+++ b/source/blender/draw/engines/overlay/overlay_mode_transfer.cc
@@ -13,7 +13,7 @@
#include "PIL_time.h"
#include "UI_resources.h"
-#include "overlay_private.h"
+#include "overlay_private.hh"
void OVERLAY_mode_transfer_cache_init(OVERLAY_Data *vedata)
{
@@ -100,7 +100,7 @@ void OVERLAY_mode_transfer_cache_populate(OVERLAY_Data *vedata, Object *ob)
UI_GetThemeColor3fv(TH_VERTEX_SELECT, color);
color[3] = mode_transfer_alpha_for_animation_time_get(animation_time);
srgb_to_linearrgb_v4(color, color);
- DRW_shgroup_uniform_vec4_copy(mode_transfer_grp[i], "color", color);
+ DRW_shgroup_uniform_vec4_copy(mode_transfer_grp[i], "ucolor", color);
}
if (!pd->use_in_front) {
diff --git a/source/blender/draw/engines/overlay/overlay_motion_path.c b/source/blender/draw/engines/overlay/overlay_motion_path.cc
index 58825923f37..00b2a8665fd 100644
--- a/source/blender/draw/engines/overlay/overlay_motion_path.c
+++ b/source/blender/draw/engines/overlay/overlay_motion_path.cc
@@ -20,7 +20,7 @@
#include "draw_manager_text.h"
-#include "overlay_private.h"
+#include "overlay_private.hh"
void OVERLAY_motion_path_cache_init(OVERLAY_Data *vedata)
{
@@ -63,7 +63,7 @@ static GPUVertBuf *mpath_vbo_get(bMotionPath *mpath)
static GPUBatch *mpath_batch_line_get(bMotionPath *mpath)
{
if (!mpath->batch_line) {
- mpath->batch_line = GPU_batch_create(GPU_PRIM_LINE_STRIP, mpath_vbo_get(mpath), NULL);
+ mpath->batch_line = GPU_batch_create(GPU_PRIM_LINE_STRIP, mpath_vbo_get(mpath), nullptr);
}
return mpath->batch_line;
}
@@ -71,7 +71,7 @@ static GPUBatch *mpath_batch_line_get(bMotionPath *mpath)
static GPUBatch *mpath_batch_points_get(bMotionPath *mpath)
{
if (!mpath->batch_points) {
- mpath->batch_points = GPU_batch_create(GPU_PRIM_POINTS, mpath_vbo_get(mpath), NULL);
+ mpath->batch_points = GPU_batch_create(GPU_PRIM_POINTS, mpath_vbo_get(mpath), nullptr);
}
return mpath->batch_points;
}
@@ -143,7 +143,7 @@ static void motion_path_cache(OVERLAY_Data *vedata,
DRW_shgroup_uniform_bool_copy(grp, "selected", selected);
DRW_shgroup_uniform_vec3_copy(grp, "customColor", color);
/* Only draw the required range. */
- DRW_shgroup_call_range(grp, NULL, mpath_batch_line_get(mpath), start_index, len);
+ DRW_shgroup_call_range(grp, nullptr, mpath_batch_line_get(mpath), start_index, len);
}
/* Draw points. */
@@ -155,7 +155,7 @@ static void motion_path_cache(OVERLAY_Data *vedata,
DRW_shgroup_uniform_bool_copy(grp, "showKeyFrames", show_keyframes);
DRW_shgroup_uniform_vec3_copy(grp, "customColor", color);
/* Only draw the required range. */
- DRW_shgroup_call_range(grp, NULL, mpath_batch_points_get(mpath), start_index, len);
+ DRW_shgroup_call_range(grp, nullptr, mpath_batch_points_get(mpath), start_index, len);
}
/* Draw frame numbers at each frame-step value. */
@@ -208,7 +208,7 @@ void OVERLAY_motion_path_cache_populate(OVERLAY_Data *vedata, Object *ob)
}
if (ob->mpath) {
- motion_path_cache(vedata, ob, NULL, &ob->avs, ob->mpath);
+ motion_path_cache(vedata, ob, nullptr, &ob->avs, ob->mpath);
}
}
diff --git a/source/blender/draw/engines/overlay/overlay_outline.c b/source/blender/draw/engines/overlay/overlay_outline.cc
index f2e2acc98a9..e308775dc6e 100644
--- a/source/blender/draw/engines/overlay/overlay_outline.c
+++ b/source/blender/draw/engines/overlay/overlay_outline.cc
@@ -16,14 +16,14 @@
#include "UI_resources.h"
-#include "overlay_private.h"
+#include "overlay_private.hh"
/* Returns the normal plane in NDC space. */
static void gpencil_depth_plane(Object *ob, float r_plane[4])
{
/* TODO: put that into private data. */
float viewinv[4][4];
- DRW_view_viewmat_get(NULL, viewinv, true);
+ DRW_view_viewmat_get(nullptr, viewinv, true);
float *camera_z_axis = viewinv[2];
float *camera_pos = viewinv[3];
@@ -47,7 +47,7 @@ static void gpencil_depth_plane(Object *ob, float r_plane[4])
/* BBox center in world space. */
copy_v3_v3(center, mat[3]);
/* View Vector. */
- if (DRW_view_is_persp_get(NULL)) {
+ if (DRW_view_is_persp_get(nullptr)) {
/* BBox center to camera vector. */
sub_v3_v3v3(r_plane, camera_pos, mat[3]);
}
@@ -78,8 +78,8 @@ void OVERLAY_outline_init(OVERLAY_Data *vedata)
if (DRW_state_is_fbo()) {
/* TODO: only alloc if needed. */
- DRW_texture_ensure_fullscreen_2d(&txl->temp_depth_tx, GPU_DEPTH24_STENCIL8, 0);
- DRW_texture_ensure_fullscreen_2d(&txl->outlines_id_tx, GPU_R16UI, 0);
+ DRW_texture_ensure_fullscreen_2d(&txl->temp_depth_tx, GPU_DEPTH24_STENCIL8, DRWTextureFlag(0));
+ DRW_texture_ensure_fullscreen_2d(&txl->outlines_id_tx, GPU_R16UI, DRWTextureFlag(0));
GPU_framebuffer_ensure_config(
&fbl->outlines_prepass_fb,
@@ -109,7 +109,7 @@ void OVERLAY_outline_cache_init(OVERLAY_Data *vedata)
OVERLAY_TextureList *txl = vedata->txl;
OVERLAY_PrivateData *pd = vedata->stl->pd;
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
- DRWShadingGroup *grp = NULL;
+ DRWShadingGroup *grp = nullptr;
const float outline_width = UI_GetThemeValuef(TH_OUTLINE_WIDTH);
const bool do_expand = (U.pixelsize > 1.0) || (outline_width > 2.0f);
@@ -161,7 +161,7 @@ void OVERLAY_outline_cache_init(OVERLAY_Data *vedata)
DRW_shgroup_uniform_texture_ref(grp, "sceneDepth", &dtxl->depth);
DRW_shgroup_uniform_texture_ref(grp, "outlineDepth", &txl->temp_depth_tx);
DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
- DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
+ DRW_shgroup_call_procedural_triangles(grp, nullptr, 1);
}
}
@@ -240,18 +240,17 @@ static void OVERLAY_outline_gpencil(OVERLAY_PrivateData *pd, Object *ob)
return;
}
- iterData iter = {
- .ob = ob,
- .stroke_grp = pd->outlines_gpencil_grp,
- .fill_grp = DRW_shgroup_create_sub(pd->outlines_gpencil_grp),
- .cfra = pd->cfra,
- };
+ iterData iter{};
+ iter.ob = ob;
+ iter.stroke_grp = pd->outlines_gpencil_grp;
+ iter.fill_grp = DRW_shgroup_create_sub(pd->outlines_gpencil_grp);
+ iter.cfra = pd->cfra;
if (gpd->draw_mode == GP_DRAWMODE_2D) {
gpencil_depth_plane(ob, iter.plane);
}
- BKE_gpencil_visible_stroke_advanced_iter(NULL,
+ BKE_gpencil_visible_stroke_advanced_iter(nullptr,
ob,
gpencil_layer_cache_populate,
gpencil_stroke_cache_populate,
@@ -263,7 +262,7 @@ static void OVERLAY_outline_gpencil(OVERLAY_PrivateData *pd, Object *ob)
static void OVERLAY_outline_volume(OVERLAY_PrivateData *pd, Object *ob)
{
struct GPUBatch *geom = DRW_cache_volume_selection_surface_get(ob);
- if (geom == NULL) {
+ if (geom == nullptr) {
return;
}
@@ -274,7 +273,7 @@ static void OVERLAY_outline_volume(OVERLAY_PrivateData *pd, Object *ob)
static void OVERLAY_outline_curves(OVERLAY_PrivateData *pd, Object *ob)
{
DRWShadingGroup *shgroup = pd->outlines_curves_grp;
- DRW_shgroup_curves_create_sub(ob, shgroup, NULL);
+ DRW_shgroup_curves_create_sub(ob, shgroup, nullptr);
}
void OVERLAY_outline_cache_populate(OVERLAY_Data *vedata,
@@ -285,7 +284,7 @@ void OVERLAY_outline_cache_populate(OVERLAY_Data *vedata,
OVERLAY_PrivateData *pd = vedata->stl->pd;
const DRWContextState *draw_ctx = DRW_context_state_get();
struct GPUBatch *geom;
- DRWShadingGroup *shgroup = NULL;
+ DRWShadingGroup *shgroup = nullptr;
const bool draw_outline = ob->dt > OB_BOUNDBOX;
/* Early exit: outlines of bounding boxes are not drawn. */
@@ -326,7 +325,7 @@ void OVERLAY_outline_cache_populate(OVERLAY_Data *vedata,
DRW_object_axis_orthogonal_to_view(ob, flat_axis));
if (pd->xray_enabled_and_not_wire || is_flat_object_viewed_from_side) {
- geom = DRW_cache_object_edge_detection_get(ob, NULL);
+ geom = DRW_cache_object_edge_detection_get(ob, nullptr);
}
else {
geom = DRW_cache_object_surface_get(ob);
@@ -359,7 +358,7 @@ void OVERLAY_outline_draw(OVERLAY_Data *vedata)
OVERLAY_PassList *psl = vedata->psl;
const float clearcol[4] = {0.0f, 0.0f, 0.0f, 0.0f};
- bool do_outlines = psl->outlines_prepass_ps != NULL &&
+ bool do_outlines = psl->outlines_prepass_ps != nullptr &&
!DRW_pass_is_empty(psl->outlines_prepass_ps);
if (DRW_state_is_fbo() && do_outlines) {
diff --git a/source/blender/draw/engines/overlay/overlay_paint.c b/source/blender/draw/engines/overlay/overlay_paint.cc
index c730c702a8d..b8f087a1460 100644
--- a/source/blender/draw/engines/overlay/overlay_paint.c
+++ b/source/blender/draw/engines/overlay/overlay_paint.cc
@@ -13,7 +13,7 @@
#include "DEG_depsgraph_query.h"
-#include "overlay_private.h"
+#include "overlay_private.hh"
/* Check if the given object is rendered (partially) transparent */
static bool paint_object_is_rendered_transparent(View3D *v3d, Object *ob)
@@ -31,7 +31,7 @@ static bool paint_object_is_rendered_transparent(View3D *v3d, Object *ob)
}
if (ob && ob->type == OB_MESH && ob->data &&
v3d->shading.color_type == V3D_SHADING_MATERIAL_COLOR) {
- Mesh *me = ob->data;
+ Mesh *me = static_cast<Mesh *>(ob->data);
for (int i = 0; i < me->totcol; i++) {
Material *mat = BKE_object_material_get_eval(ob, i + 1);
if (mat && mat->a < 1.0f) {
@@ -74,8 +74,8 @@ void OVERLAY_paint_cache_init(OVERLAY_Data *vedata)
const bool draw_contours = !is_edit_mode &&
(pd->overlay.wpaint_flag & V3D_OVERLAY_WPAINT_CONTOURS) != 0;
float opacity = 0.0f;
- pd->paint_depth_grp = NULL;
- psl->paint_depth_ps = NULL;
+ pd->paint_depth_grp = nullptr;
+ psl->paint_depth_ps = nullptr;
switch (pd->ctx_mode) {
case CTX_MODE_POSE:
@@ -130,14 +130,14 @@ void OVERLAY_paint_cache_init(OVERLAY_Data *vedata)
case CTX_MODE_PAINT_TEXTURE: {
const ImagePaintSettings *imapaint = &draw_ctx->scene->toolsettings->imapaint;
const bool mask_enabled = imapaint->flag & IMAGEPAINT_PROJECT_LAYER_STENCIL &&
- imapaint->stencil != NULL;
+ imapaint->stencil != nullptr;
opacity = mask_enabled ? pd->overlay.texture_paint_mode_opacity : 0.0f;
if (opacity > 0.0f) {
state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL | DRW_STATE_BLEND_ALPHA;
DRW_PASS_CREATE(psl->paint_color_ps, state | pd->clipping_state);
- GPUTexture *tex = BKE_image_get_gpu_texture(imapaint->stencil, NULL, NULL);
+ GPUTexture *tex = BKE_image_get_gpu_texture(imapaint->stencil, nullptr, nullptr);
const bool mask_premult = (imapaint->stencil->alpha_mode == IMA_ALPHA_PREMUL);
const bool mask_inverted = (imapaint->flag & IMAGEPAINT_PROJECT_LAYER_STENCIL_INV) != 0;
@@ -158,8 +158,8 @@ void OVERLAY_paint_cache_init(OVERLAY_Data *vedata)
}
if (opacity <= 0.0f) {
- psl->paint_color_ps = NULL;
- pd->paint_surf_grp = NULL;
+ psl->paint_color_ps = nullptr;
+ pd->paint_surf_grp = nullptr;
}
{
@@ -167,7 +167,8 @@ void OVERLAY_paint_cache_init(OVERLAY_Data *vedata)
DRW_PASS_CREATE(psl->paint_overlay_ps, state | pd->clipping_state);
sh = OVERLAY_shader_paint_face();
pd->paint_face_grp = grp = DRW_shgroup_create(sh, psl->paint_overlay_ps);
- DRW_shgroup_uniform_vec4_copy(grp, "color", (float[4]){1.0f, 1.0f, 1.0f, 0.2f});
+ const float4 color = {1.0f, 1.0f, 1.0f, 0.2f};
+ DRW_shgroup_uniform_vec4_copy(grp, "ucolor", color);
DRW_shgroup_state_enable(grp, DRW_STATE_BLEND_ALPHA);
sh = OVERLAY_shader_paint_wire();
@@ -190,9 +191,9 @@ void OVERLAY_paint_cache_init(OVERLAY_Data *vedata)
void OVERLAY_paint_texture_cache_populate(OVERLAY_Data *vedata, Object *ob)
{
OVERLAY_PrivateData *pd = vedata->stl->pd;
- struct GPUBatch *geom = NULL;
+ struct GPUBatch *geom = nullptr;
- const Mesh *me_orig = DEG_get_original_object(ob)->data;
+ const Mesh *me_orig = static_cast<Mesh *>(DEG_get_original_object(ob)->data);
const bool use_face_sel = (me_orig->editflag & ME_EDIT_PAINT_FACE_SEL) != 0;
if (pd->paint_surf_grp) {
@@ -209,9 +210,9 @@ void OVERLAY_paint_texture_cache_populate(OVERLAY_Data *vedata, Object *ob)
void OVERLAY_paint_vertex_cache_populate(OVERLAY_Data *vedata, Object *ob)
{
OVERLAY_PrivateData *pd = vedata->stl->pd;
- struct GPUBatch *geom = NULL;
+ struct GPUBatch *geom = nullptr;
- const Mesh *me_orig = DEG_get_original_object(ob)->data;
+ const Mesh *me_orig = static_cast<Mesh *>(DEG_get_original_object(ob)->data);
const bool is_edit_mode = (pd->ctx_mode == CTX_MODE_EDIT_MESH);
const bool use_wire = !is_edit_mode && (pd->overlay.paint_flag & V3D_OVERLAY_PAINT_WIRE);
const bool use_face_sel = !is_edit_mode && (me_orig->editflag & ME_EDIT_PAINT_FACE_SEL);
diff --git a/source/blender/draw/engines/overlay/overlay_particle.c b/source/blender/draw/engines/overlay/overlay_particle.cc
index b985bfb24bf..6f77a777ba0 100644
--- a/source/blender/draw/engines/overlay/overlay_particle.c
+++ b/source/blender/draw/engines/overlay/overlay_particle.cc
@@ -15,7 +15,7 @@
#include "ED_particle.h"
-#include "overlay_private.h"
+#include "overlay_private.hh"
/* -------------------------------------------------------------------- */
/** \name Edit Particles
@@ -64,7 +64,7 @@ void OVERLAY_edit_particle_cache_populate(OVERLAY_Data *vedata, Object *ob)
*/
Object *ob_orig = DEG_get_original_object(ob);
PTCacheEdit *edit = PE_create_current(draw_ctx->depsgraph, scene_orig, ob_orig);
- if (edit == NULL) {
+ if (edit == nullptr) {
/* Happens when trying to edit particles in EMITTER mode without
* having them cached.
*/
@@ -73,14 +73,14 @@ void OVERLAY_edit_particle_cache_populate(OVERLAY_Data *vedata, Object *ob)
/* NOTE: We need to pass evaluated particle system, which we need
* to find first.
*/
- ParticleSystem *psys = ob->particlesystem.first;
+ ParticleSystem *psys = static_cast<ParticleSystem *>(ob->particlesystem.first);
LISTBASE_FOREACH (ParticleSystem *, psys_orig, &ob_orig->particlesystem) {
if (PE_get_current_from_psys(psys_orig) == edit) {
break;
}
psys = psys->next;
}
- if (psys == NULL) {
+ if (psys == nullptr) {
printf("Error getting evaluated particle system for edit.\n");
return;
}
@@ -88,17 +88,17 @@ void OVERLAY_edit_particle_cache_populate(OVERLAY_Data *vedata, Object *ob)
struct GPUBatch *geom;
{
geom = DRW_cache_particles_get_edit_strands(ob, psys, edit, pd->edit_particle.use_weight);
- DRW_shgroup_call(pd->edit_particle_strand_grp, geom, NULL);
+ DRW_shgroup_call(pd->edit_particle_strand_grp, geom, nullptr);
}
if (pd->edit_particle.select_mode == SCE_SELECT_POINT) {
geom = DRW_cache_particles_get_edit_inner_points(ob, psys, edit);
- DRW_shgroup_call(pd->edit_particle_point_grp, geom, NULL);
+ DRW_shgroup_call(pd->edit_particle_point_grp, geom, nullptr);
}
if (ELEM(pd->edit_particle.select_mode, SCE_SELECT_POINT, SCE_SELECT_END)) {
geom = DRW_cache_particles_get_edit_tip_points(ob, psys, edit);
- DRW_shgroup_call(pd->edit_particle_point_grp, geom, NULL);
+ DRW_shgroup_call(pd->edit_particle_point_grp, geom, nullptr);
}
}
@@ -165,7 +165,7 @@ void OVERLAY_particle_cache_populate(OVERLAY_Data *vedata, Object *ob)
if (!ELEM(draw_as, PART_DRAW_NOT, PART_DRAW_OB, PART_DRAW_GR)) {
struct GPUBatch *geom = DRW_cache_particles_get_dots(ob, psys);
- struct GPUBatch *shape = NULL;
+ struct GPUBatch *shape = nullptr;
DRWShadingGroup *grp;
/* TODO(fclem): Here would be a good place for preemptive culling. */
@@ -173,7 +173,7 @@ void OVERLAY_particle_cache_populate(OVERLAY_Data *vedata, Object *ob)
/* NOTE(fclem): Is color even useful in our modern context? */
Material *ma = BKE_object_material_get_eval(ob, part->omat);
float color[4] = {0.6f, 0.6f, 0.6f, part->draw_size};
- if (ma != NULL) {
+ if (ma != nullptr) {
copy_v3_v3(color, &ma->r);
}
@@ -182,7 +182,7 @@ void OVERLAY_particle_cache_populate(OVERLAY_Data *vedata, Object *ob)
case PART_DRAW_DOT:
grp = DRW_shgroup_create_sub(pd->particle_dots_grp);
DRW_shgroup_uniform_vec4_copy(grp, "color", color);
- DRW_shgroup_call(grp, geom, NULL);
+ DRW_shgroup_call(grp, geom, nullptr);
break;
case PART_DRAW_AXIS:
case PART_DRAW_CIRC:
@@ -190,7 +190,7 @@ void OVERLAY_particle_cache_populate(OVERLAY_Data *vedata, Object *ob)
grp = DRW_shgroup_create_sub(pd->particle_shapes_grp);
DRW_shgroup_uniform_vec4_copy(grp, "color", color);
shape = DRW_cache_particles_get_prim(draw_as);
- DRW_shgroup_call_instances_with_attrs(grp, NULL, shape, geom);
+ DRW_shgroup_call_instances_with_attrs(grp, nullptr, shape, geom);
break;
}
}
diff --git a/source/blender/draw/engines/overlay/overlay_private.h b/source/blender/draw/engines/overlay/overlay_private.hh
index 7d216ca54cf..0a783c44029 100644
--- a/source/blender/draw/engines/overlay/overlay_private.h
+++ b/source/blender/draw/engines/overlay/overlay_private.hh
@@ -78,8 +78,9 @@ typedef struct OVERLAY_PassList {
DRWPass *edit_mesh_analysis_ps;
DRWPass *edit_mesh_normals_ps;
DRWPass *edit_particle_ps;
- DRWPass *edit_text_overlay_ps;
- DRWPass *edit_text_darken_ps;
+ DRWPass *edit_text_cursor_ps;
+ DRWPass *edit_text_selection_ps;
+ DRWPass *edit_text_highlight_ps;
DRWPass *edit_text_wire_ps[2];
DRWPass *edit_uv_edges_ps;
DRWPass *edit_uv_verts_ps;
@@ -252,7 +253,8 @@ typedef struct OVERLAY_PrivateData {
DRWShadingGroup *edit_mesh_analysis_grp;
DRWShadingGroup *edit_particle_strand_grp;
DRWShadingGroup *edit_particle_point_grp;
- DRWShadingGroup *edit_text_overlay_grp;
+ DRWShadingGroup *edit_text_cursor_grp;
+ DRWShadingGroup *edit_text_selection_grp;
DRWShadingGroup *edit_text_wire_grp[2];
DRWShadingGroup *edit_uv_verts_grp;
DRWShadingGroup *edit_uv_edges_grp;
@@ -338,7 +340,8 @@ typedef struct OVERLAY_PrivateData {
int handle_display;
} edit_curve;
struct {
- float overlay_color[4];
+ float cursor_color[4];
+ float selection_color[4];
} edit_text;
struct {
bool do_zbufclip;
@@ -384,7 +387,6 @@ typedef struct OVERLAY_PrivateData {
eSpaceImage_UVDT_Stretch draw_type;
ListBase totals;
float total_area_ratio;
- float total_area_ratio_inv;
/* stencil overlay */
struct Image *stencil_image;
diff --git a/source/blender/draw/engines/overlay/overlay_sculpt.c b/source/blender/draw/engines/overlay/overlay_sculpt.cc
index 4a6477b3f6c..ddad1f06537 100644
--- a/source/blender/draw/engines/overlay/overlay_sculpt.c
+++ b/source/blender/draw/engines/overlay/overlay_sculpt.cc
@@ -8,7 +8,7 @@
#include "DRW_render.h"
#include "draw_cache_impl.h"
-#include "overlay_private.h"
+#include "overlay_private.hh"
#include "BKE_paint.h"
#include "BKE_pbvh.h"
@@ -56,7 +56,7 @@ void OVERLAY_sculpt_cache_populate(OVERLAY_Data *vedata, Object *ob)
DRW_shgroup_call_sculpt(pd->sculpt_mask_grp, ob, false, true);
}
else {
- sculpt_overlays = DRW_mesh_batch_cache_get_sculpt_overlays(ob->data);
+ sculpt_overlays = DRW_mesh_batch_cache_get_sculpt_overlays(static_cast<Mesh *>(ob->data));
if (sculpt_overlays) {
DRW_shgroup_call(pd->sculpt_mask_grp, sculpt_overlays, ob);
}
diff --git a/source/blender/draw/engines/overlay/overlay_sculpt_curves.cc b/source/blender/draw/engines/overlay/overlay_sculpt_curves.cc
index b8021124f27..1bba2a366a5 100644
--- a/source/blender/draw/engines/overlay/overlay_sculpt_curves.cc
+++ b/source/blender/draw/engines/overlay/overlay_sculpt_curves.cc
@@ -8,7 +8,7 @@
#include "DRW_render.h"
#include "draw_cache_impl.h"
-#include "overlay_private.h"
+#include "overlay_private.hh"
#include "BKE_curves.hh"
diff --git a/source/blender/draw/engines/overlay/overlay_shader.c b/source/blender/draw/engines/overlay/overlay_shader.cc
index 2373363ab9d..b0a6926a57f 100644
--- a/source/blender/draw/engines/overlay/overlay_shader.c
+++ b/source/blender/draw/engines/overlay/overlay_shader.cc
@@ -11,7 +11,7 @@
#include "UI_resources.h"
-#include "overlay_private.h"
+#include "overlay_private.hh"
typedef struct OVERLAY_Shaders {
GPUShader *antialiasing;
@@ -106,7 +106,7 @@ typedef struct OVERLAY_Shaders {
static struct {
OVERLAY_Shaders sh_data[GPU_SHADER_CFG_LEN];
-} e_data = {{{NULL}}};
+} e_data = {{{nullptr}}};
GPUShader *OVERLAY_shader_antialiasing(void)
{
@@ -162,7 +162,7 @@ GPUShader *OVERLAY_shader_edit_mesh_edge(bool use_flat_interp)
const DRWContextState *draw_ctx = DRW_context_state_get();
OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg];
GPUShader **sh = use_flat_interp ? &sh_data->edit_mesh_edge_flat : &sh_data->edit_mesh_edge;
- if (*sh == NULL) {
+ if (*sh == nullptr) {
*sh = GPU_shader_create_from_info_name(
draw_ctx->sh_cfg ?
(use_flat_interp ? "overlay_edit_mesh_edge_flat_clipped" :
@@ -486,7 +486,7 @@ GPUShader *OVERLAY_shader_extra_wire(bool use_object, bool is_select)
OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg];
GPUShader **sh = (is_select) ? &sh_data->extra_wire_select : &sh_data->extra_wire[use_object];
if (!*sh) {
- const char *info_name = NULL;
+ const char *info_name = nullptr;
if (draw_ctx->sh_cfg) {
if (is_select) {
info_name = "overlay_extra_wire_select_clipped";
@@ -996,7 +996,7 @@ GPUShader *OVERLAY_shader_edit_uv_tiled_image_borders_get(void)
/** \} */
-static OVERLAY_InstanceFormats g_formats = {NULL};
+static OVERLAY_InstanceFormats g_formats = {nullptr};
OVERLAY_InstanceFormats *OVERLAY_shader_instance_formats_get(void)
{
diff --git a/source/blender/draw/engines/overlay/overlay_shader_shared.h b/source/blender/draw/engines/overlay/overlay_shader_shared.h
index 339b6f02e1a..739e5be6c2f 100644
--- a/source/blender/draw/engines/overlay/overlay_shader_shared.h
+++ b/source/blender/draw/engines/overlay/overlay_shader_shared.h
@@ -38,6 +38,9 @@ enum OVERLAY_GridBits {
PLANE_IMAGE = (1u << 11u),
CUSTOM_GRID = (1u << 12u),
};
+#ifndef GPU_SHADER
+ENUM_OPERATORS(OVERLAY_GridBits, CUSTOM_GRID)
+#endif
/* Match: #SI_GRID_STEPS_LEN */
#define OVERLAY_GRID_STEPS_LEN 8
diff --git a/source/blender/draw/engines/overlay/overlay_volume.c b/source/blender/draw/engines/overlay/overlay_volume.cc
index ee0d80734ab..daf76c394b3 100644
--- a/source/blender/draw/engines/overlay/overlay_volume.c
+++ b/source/blender/draw/engines/overlay/overlay_volume.cc
@@ -9,7 +9,7 @@
#include "DRW_render.h"
#include "GPU_shader.h"
-#include "overlay_private.h"
+#include "overlay_private.hh"
void OVERLAY_volume_cache_init(OVERLAY_Data *vedata)
{
@@ -25,8 +25,8 @@ void OVERLAY_volume_cache_init(OVERLAY_Data *vedata)
pd->volume_selection_surface_grp = grp;
}
else {
- psl->volume_ps = NULL;
- pd->volume_selection_surface_grp = NULL;
+ psl->volume_ps = nullptr;
+ pd->volume_selection_surface_grp = nullptr;
}
}
@@ -37,7 +37,7 @@ void OVERLAY_volume_cache_populate(OVERLAY_Data *vedata, Object *ob)
if (is_select) {
struct GPUBatch *geom = DRW_cache_volume_selection_surface_get(ob);
- if (geom != NULL) {
+ if (geom != nullptr) {
DRW_shgroup_call(pd->volume_selection_surface_grp, geom, ob);
}
}
diff --git a/source/blender/draw/engines/overlay/overlay_wireframe.c b/source/blender/draw/engines/overlay/overlay_wireframe.cc
index a5628559cfd..edaa96651b2 100644
--- a/source/blender/draw/engines/overlay/overlay_wireframe.c
+++ b/source/blender/draw/engines/overlay/overlay_wireframe.cc
@@ -27,7 +27,7 @@
#include "ED_view3d.h"
-#include "overlay_private.h"
+#include "overlay_private.hh"
void OVERLAY_wireframe_init(OVERLAY_Data *vedata)
{
@@ -43,7 +43,7 @@ void OVERLAY_wireframe_cache_init(OVERLAY_Data *vedata)
OVERLAY_TextureList *txl = vedata->txl;
OVERLAY_PrivateData *pd = vedata->stl->pd;
const DRWContextState *draw_ctx = DRW_context_state_get();
- DRWShadingGroup *grp = NULL;
+ DRWShadingGroup *grp = nullptr;
View3DShading *shading = &draw_ctx->v3d->shading;
@@ -112,7 +112,7 @@ void OVERLAY_wireframe_cache_init(OVERLAY_Data *vedata)
pd->wires_hair_grp[1][use_coloring] = pd->wires_hair_grp[0][use_coloring];
}
pd->wires_sculpt_grp[1] = pd->wires_sculpt_grp[0];
- psl->wireframe_xray_ps = NULL;
+ psl->wireframe_xray_ps = nullptr;
}
}
@@ -125,11 +125,11 @@ static void wireframe_hair_cache_populate(OVERLAY_Data *vedata, Object *ob, Part
DupliObject *dupli_object = DRW_object_get_dupli(ob);
float dupli_mat[4][4];
- if ((dupli_parent != NULL) && (dupli_object != NULL)) {
+ if ((dupli_parent != nullptr) && (dupli_object != nullptr)) {
if (dupli_object->type & OB_DUPLICOLLECTION) {
unit_m4(dupli_mat);
Collection *collection = dupli_parent->instance_collection;
- if (collection != NULL) {
+ if (collection != nullptr) {
sub_v3_v3(dupli_mat[3], collection->instance_offset);
}
mul_m4_m4m4(dupli_mat, dupli_parent->obmat, dupli_mat);
@@ -144,7 +144,7 @@ static void wireframe_hair_cache_populate(OVERLAY_Data *vedata, Object *ob, Part
unit_m4(dupli_mat);
}
- struct GPUBatch *hairs = DRW_cache_particles_get_hair(ob, psys, NULL);
+ struct GPUBatch *hairs = DRW_cache_particles_get_hair(ob, psys, nullptr);
const bool use_coloring = true;
DRWShadingGroup *shgrp = DRW_shgroup_create_sub(pd->wires_hair_grp[is_xray][use_coloring]);
@@ -167,7 +167,7 @@ void OVERLAY_wireframe_cache_populate(OVERLAY_Data *vedata,
bool is_mesh_verts_only = false;
if (is_mesh) {
/* TODO: Should be its own function. */
- Mesh *me = ob->data;
+ Mesh *me = static_cast<Mesh *>(ob->data);
if (is_edit_mode) {
BLI_assert(me->edit_mesh);
Mesh *editmesh_eval_final = BKE_object_get_editmesh_eval_final(ob);
@@ -184,7 +184,9 @@ void OVERLAY_wireframe_cache_populate(OVERLAY_Data *vedata,
(ob->dtx & OB_DRAWWIRE) || (ob->dt == OB_WIRE));
if (use_wire && pd->wireframe_mode && ob->particlesystem.first) {
- for (ParticleSystem *psys = ob->particlesystem.first; psys != NULL; psys = psys->next) {
+ for (ParticleSystem *psys = static_cast<ParticleSystem *>(ob->particlesystem.first);
+ psys != nullptr;
+ psys = psys->next) {
if (!DRW_object_is_visible_psys_in_active_context(ob, psys)) {
continue;
}
@@ -201,7 +203,7 @@ void OVERLAY_wireframe_cache_populate(OVERLAY_Data *vedata,
float *color;
DRW_object_wire_theme_get(ob, draw_ctx->view_layer, &color);
- struct GPUBatch *geom = NULL;
+ struct GPUBatch *geom = nullptr;
switch (ob->type) {
case OB_CURVES_LEGACY:
geom = DRW_cache_curve_edge_wire_get(ob);
@@ -251,7 +253,7 @@ void OVERLAY_wireframe_cache_populate(OVERLAY_Data *vedata,
bool draw_as_points = true;
if (ob->type == OB_VOLUME) {
/* Volume object as points exception. */
- Volume *volume = ob->data;
+ Volume *volume = static_cast<Volume *>(ob->data);
draw_as_points = volume->display.wireframe_type == VOLUME_WIREFRAME_POINTS;
}
@@ -268,12 +270,12 @@ void OVERLAY_wireframe_cache_populate(OVERLAY_Data *vedata,
}
}
- DRWShadingGroup *shgrp = NULL;
- struct GPUBatch *geom = NULL;
+ DRWShadingGroup *shgrp = nullptr;
+ struct GPUBatch *geom = nullptr;
/* Don't do that in edit Mesh mode, unless there is a modifier preview. */
if (use_wire && (!is_mesh || (!is_edit_mode || has_edit_mesh_cage))) {
- const bool is_sculpt_mode = ((ob->mode & OB_MODE_SCULPT) != 0) && (ob->sculpt != NULL);
+ const bool is_sculpt_mode = ((ob->mode & OB_MODE_SCULPT) != 0) && (ob->sculpt != nullptr);
const bool use_sculpt_pbvh = BKE_sculptsession_use_pbvh_draw(ob, draw_ctx->v3d) &&
!DRW_state_is_image_render();
const bool is_instance = (ob->base_flag & BASE_FROM_DUPLI);
@@ -343,7 +345,7 @@ void OVERLAY_wireframe_draw(OVERLAY_Data *data)
DRW_view_set_active(pd->view_wires);
DRW_draw_pass(psl->wireframe_ps);
- DRW_view_set_active(NULL);
+ DRW_view_set_active(nullptr);
}
void OVERLAY_wireframe_in_front_draw(OVERLAY_Data *data)
@@ -355,6 +357,6 @@ void OVERLAY_wireframe_in_front_draw(OVERLAY_Data *data)
DRW_view_set_active(pd->view_wires);
DRW_draw_pass(psl->wireframe_xray_ps);
- DRW_view_set_active(NULL);
+ DRW_view_set_active(nullptr);
}
}
diff --git a/source/blender/draw/engines/overlay/shaders/infos/overlay_armature_info.hh b/source/blender/draw/engines/overlay/shaders/infos/overlay_armature_info.hh
index 9f2acceed97..0ab653ba29f 100644
--- a/source/blender/draw/engines/overlay/shaders/infos/overlay_armature_info.hh
+++ b/source/blender/draw/engines/overlay/shaders/infos/overlay_armature_info.hh
@@ -69,6 +69,11 @@ GPU_SHADER_INTERFACE_INFO(overlay_armature_shape_outline_iface, "geom_in")
.smooth(Type::VEC4, "vColSize")
.flat(Type::INT, "inverted");
+GPU_SHADER_INTERFACE_INFO(overlay_armature_shape_outline_no_geom_iface, "")
+ .flat(Type::VEC4, "finalColor")
+ .flat(Type::VEC2, "edgeStart")
+ .no_perspective(Type::VEC2, "edgePos");
+
GPU_SHADER_CREATE_INFO(overlay_armature_shape_outline)
.do_static_compilation(true)
.vertex_in(0, Type::VEC3, "pos")
@@ -84,10 +89,26 @@ GPU_SHADER_CREATE_INFO(overlay_armature_shape_outline)
.fragment_source("overlay_armature_wire_frag.glsl")
.additional_info("overlay_frag_output", "overlay_armature_common", "draw_globals");
+GPU_SHADER_CREATE_INFO(overlay_armature_shape_outline_no_geom)
+ .do_static_compilation(true)
+ .vertex_in(0, Type::VEC3, "pos")
+ .vertex_in(1, Type::VEC3, "snor")
+ /* Per instance. */
+ .vertex_in(2, Type::VEC4, "color")
+ .vertex_in(3, Type::MAT4, "inst_obmat")
+ .vertex_out(overlay_armature_shape_outline_no_geom_iface)
+ .vertex_source("overlay_armature_shape_outline_vert_no_geom.glsl")
+ .fragment_source("overlay_armature_wire_frag.glsl")
+ .additional_info("overlay_frag_output", "overlay_armature_common", "draw_globals");
+
GPU_SHADER_CREATE_INFO(overlay_armature_shape_outline_clipped)
.do_static_compilation(true)
.additional_info("overlay_armature_shape_outline", "drw_clipped");
+GPU_SHADER_CREATE_INFO(overlay_armature_shape_outline_clipped_no_geom)
+ .do_static_compilation(true)
+ .additional_info("overlay_armature_shape_outline_no_geom", "drw_clipped");
+
GPU_SHADER_INTERFACE_INFO(overlay_armature_shape_solid_iface, "")
.smooth(Type::VEC4, "finalColor")
.flat(Type::INT, "inverted");
diff --git a/source/blender/draw/engines/overlay/shaders/infos/overlay_background_info.hh b/source/blender/draw/engines/overlay/shaders/infos/overlay_background_info.hh
index 88a012c35c9..8bc15400248 100644
--- a/source/blender/draw/engines/overlay/shaders/infos/overlay_background_info.hh
+++ b/source/blender/draw/engines/overlay/shaders/infos/overlay_background_info.hh
@@ -15,7 +15,7 @@ GPU_SHADER_CREATE_INFO(overlay_background)
GPU_SHADER_CREATE_INFO(overlay_clipbound)
.do_static_compilation(true)
- .push_constant(Type::VEC4, "color")
+ .push_constant(Type::VEC4, "ucolor")
.push_constant(Type::VEC3, "boundbox", 8)
.vertex_source("overlay_clipbound_vert.glsl")
.fragment_out(0, Type::VEC4, "fragColor")
diff --git a/source/blender/draw/engines/overlay/shaders/infos/overlay_edit_mode_info.hh b/source/blender/draw/engines/overlay/shaders/infos/overlay_edit_mode_info.hh
index 58f96110887..e2cc0a54153 100644
--- a/source/blender/draw/engines/overlay/shaders/infos/overlay_edit_mode_info.hh
+++ b/source/blender/draw/engines/overlay/shaders/infos/overlay_edit_mode_info.hh
@@ -22,6 +22,17 @@ GPU_SHADER_CREATE_INFO(overlay_edit_mesh_common)
.vertex_source("overlay_edit_mesh_vert.glsl")
.additional_info("draw_modelmat", "draw_globals");
+GPU_SHADER_CREATE_INFO(overlay_edit_mesh_common_no_geom)
+ .define("blender_srgb_to_framebuffer_space(a)", "a")
+ .sampler(0, ImageType::DEPTH_2D, "depthTex")
+ .fragment_out(0, Type::VEC4, "fragColor")
+ .push_constant(Type::BOOL, "selectFaces")
+ .push_constant(Type::BOOL, "selectEdges")
+ .push_constant(Type::FLOAT, "alpha")
+ .push_constant(Type::IVEC4, "dataMask")
+ .vertex_source("overlay_edit_mesh_vert_no_geom.glsl")
+ .additional_info("draw_modelmat", "draw_globals");
+
GPU_SHADER_INTERFACE_INFO(overlay_edit_mesh_vert_iface, "")
.smooth(Type::VEC4, "finalColor")
.smooth(Type::FLOAT, "vertexCrease");
@@ -61,11 +72,28 @@ GPU_SHADER_CREATE_INFO(overlay_edit_mesh_edge)
.fragment_source("overlay_edit_mesh_frag.glsl")
.additional_info("overlay_edit_mesh_common");
+/* The Non-Geometry shader variant passes directly to fragment. */
+GPU_SHADER_CREATE_INFO(overlay_edit_mesh_edge_no_geom)
+ .do_static_compilation(true)
+ .define("EDGE")
+ .vertex_in(0, Type::VEC3, "pos")
+ .vertex_in(1, Type::UCHAR4, "data")
+ .vertex_in(2, Type::VEC3_101010I2, "vnor")
+ .push_constant(Type::BOOL, "do_smooth_wire")
+ .vertex_out(overlay_edit_mesh_edge_geom_iface)
+ .fragment_source("overlay_edit_mesh_frag.glsl")
+ .additional_info("overlay_edit_mesh_common_no_geom");
+
GPU_SHADER_CREATE_INFO(overlay_edit_mesh_edge_flat)
.do_static_compilation(true)
.define("FLAT")
.additional_info("overlay_edit_mesh_edge");
+GPU_SHADER_CREATE_INFO(overlay_edit_mesh_edge_flat_no_geom)
+ .do_static_compilation(true)
+ .define("FLAT")
+ .additional_info("overlay_edit_mesh_edge_no_geom");
+
GPU_SHADER_CREATE_INFO(overlay_edit_mesh_face)
.do_static_compilation(true)
.define("FACE")
@@ -136,10 +164,18 @@ GPU_SHADER_CREATE_INFO(overlay_edit_mesh_edge_clipped)
.do_static_compilation(true)
.additional_info("overlay_edit_mesh_edge", "drw_clipped");
+GPU_SHADER_CREATE_INFO(overlay_edit_mesh_edge_clipped_no_geom)
+ .do_static_compilation(true)
+ .additional_info("overlay_edit_mesh_edge_no_geom", "drw_clipped");
+
GPU_SHADER_CREATE_INFO(overlay_edit_mesh_edge_flat_clipped)
.do_static_compilation(true)
.additional_info("overlay_edit_mesh_edge_flat", "drw_clipped");
+GPU_SHADER_CREATE_INFO(overlay_edit_mesh_edge_flat_clipped_no_geom)
+ .do_static_compilation(true)
+ .additional_info("overlay_edit_mesh_edge_flat_no_geom", "drw_clipped");
+
GPU_SHADER_CREATE_INFO(overlay_edit_mesh_face_clipped)
.do_static_compilation(true)
.additional_info("overlay_edit_mesh_face", "drw_clipped");
@@ -242,7 +278,7 @@ GPU_SHADER_CREATE_INFO(overlay_edit_uv_verts)
GPU_SHADER_CREATE_INFO(overlay_edit_uv_tiled_image_borders)
.do_static_compilation(true)
.vertex_in(0, Type::VEC3, "pos")
- .push_constant(Type::VEC4, "color")
+ .push_constant(Type::VEC4, "ucolor")
.fragment_out(0, Type::VEC4, "fragColor")
.vertex_source("overlay_edit_uv_tiled_image_borders_vert.glsl")
.fragment_source("overlay_uniform_color_frag.glsl")
@@ -258,7 +294,7 @@ GPU_SHADER_CREATE_INFO(overlay_edit_uv_stencil_image)
.sampler(0, ImageType::FLOAT_2D, "imgTexture")
.push_constant(Type::BOOL, "imgPremultiplied")
.push_constant(Type::BOOL, "imgAlphaBlend")
- .push_constant(Type::VEC4, "color")
+ .push_constant(Type::VEC4, "ucolor")
.fragment_out(0, Type::VEC4, "fragColor")
.fragment_source("overlay_image_frag.glsl")
.additional_info("draw_mesh");
@@ -293,7 +329,6 @@ GPU_SHADER_CREATE_INFO(overlay_edit_uv_stretching_area)
.do_static_compilation(true)
.vertex_in(1, Type::FLOAT, "ratio")
.push_constant(Type::FLOAT, "totalAreaRatio")
- .push_constant(Type::FLOAT, "totalAreaRatioInv")
.additional_info("overlay_edit_uv_stretching");
GPU_SHADER_CREATE_INFO(overlay_edit_uv_stretching_angle)
@@ -327,10 +362,29 @@ GPU_SHADER_CREATE_INFO(overlay_edit_curve_handle)
.fragment_source("overlay_varying_color.glsl")
.additional_info("draw_mesh", "draw_globals");
+GPU_SHADER_CREATE_INFO(overlay_edit_curve_handle_no_geom)
+ .do_static_compilation(true)
+ .typedef_source("overlay_shader_shared.h")
+ /* NOTE: Color already in Linear space. Which is what we want. */
+ .define("srgbTarget", "false")
+ .vertex_in(0, Type::VEC3, "pos")
+ .vertex_in(1, Type::INT, "data")
+ .vertex_out(overlay_edit_curve_handle_iface)
+ .push_constant(Type::BOOL, "showCurveHandles")
+ .push_constant(Type::INT, "curveHandleDisplay")
+ .fragment_out(0, Type::VEC4, "fragColor")
+ .vertex_source("overlay_edit_curve_handle_vert_no_geom.glsl")
+ .fragment_source("overlay_varying_color.glsl")
+ .additional_info("draw_mesh", "draw_globals");
+
GPU_SHADER_CREATE_INFO(overlay_edit_curve_handle_clipped)
.do_static_compilation(true)
.additional_info("overlay_edit_curve_handle", "drw_clipped");
+GPU_SHADER_CREATE_INFO(overlay_edit_curve_handle_clipped_no_geom)
+ .do_static_compilation(true)
+ .additional_info("overlay_edit_curve_handle_no_geom", "drw_clipped");
+
GPU_SHADER_CREATE_INFO(overlay_edit_curve_point)
.do_static_compilation(true)
.typedef_source("overlay_shader_shared.h")
@@ -527,7 +581,7 @@ GPU_SHADER_CREATE_INFO(overlay_depth_only_clipped)
GPU_SHADER_CREATE_INFO(overlay_uniform_color)
.do_static_compilation(true)
.vertex_in(0, Type::VEC3, "pos")
- .push_constant(Type::VEC4, "color")
+ .push_constant(Type::VEC4, "ucolor")
.fragment_out(0, Type::VEC4, "fragColor")
.vertex_source("overlay_depth_only_vert.glsl")
.fragment_source("overlay_uniform_color_frag.glsl")
diff --git a/source/blender/draw/engines/overlay/shaders/infos/overlay_extra_info.hh b/source/blender/draw/engines/overlay/shaders/infos/overlay_extra_info.hh
index 5b50bbcaa55..65084361f14 100644
--- a/source/blender/draw/engines/overlay/shaders/infos/overlay_extra_info.hh
+++ b/source/blender/draw/engines/overlay/shaders/infos/overlay_extra_info.hh
@@ -145,7 +145,7 @@ GPU_SHADER_CREATE_INFO(overlay_extra_point)
/* TODO(fclem): Move the vertex shader to Overlay engine and remove this bypass. */
.define("blender_srgb_to_framebuffer_space(a)", "a")
.vertex_in(0, Type::VEC3, "pos")
- .push_constant(Type::VEC4, "color")
+ .push_constant(Type::VEC4, "ucolor")
.vertex_out(overlay_extra_point_iface)
.fragment_out(0, Type::VEC4, "fragColor")
.vertex_source("overlay_extra_point_vert.glsl")
@@ -161,7 +161,7 @@ GPU_SHADER_INTERFACE_INFO(overlay_extra_loose_point_iface, "").smooth(Type::VEC4
GPU_SHADER_CREATE_INFO(overlay_extra_loose_point)
.do_static_compilation(true)
.vertex_in(0, Type::VEC3, "pos")
- .push_constant(Type::VEC4, "color")
+ .push_constant(Type::VEC4, "ucolor")
.vertex_out(overlay_extra_loose_point_iface)
.fragment_out(0, Type::VEC4, "fragColor")
.fragment_out(1, Type::VEC4, "lineOutput")
@@ -183,6 +183,9 @@ GPU_SHADER_INTERFACE_INFO(overlay_motion_path_line_iface, "interp")
.flat(Type::VEC2, "ss_pos")
.smooth(Type::VEC4, "color");
+GPU_SHADER_INTERFACE_INFO(overlay_motion_path_line_no_geom_iface, "interp")
+ .smooth(Type::VEC4, "color");
+
GPU_SHADER_CREATE_INFO(overlay_motion_path_line)
.do_static_compilation(true)
.vertex_in(0, Type::VEC3, "pos")
@@ -199,10 +202,27 @@ GPU_SHADER_CREATE_INFO(overlay_motion_path_line)
.fragment_source("overlay_motion_path_line_frag.glsl")
.additional_info("draw_view", "draw_globals");
+GPU_SHADER_CREATE_INFO(overlay_motion_path_line_no_geom)
+ .do_static_compilation(true)
+ .vertex_in(0, Type::VEC3, "pos")
+ .push_constant(Type::IVEC4, "mpathLineSettings")
+ .push_constant(Type::BOOL, "selected")
+ .push_constant(Type::VEC3, "customColor")
+ .push_constant(Type::INT, "lineThickness") /* In pixels. */
+ .vertex_out(overlay_motion_path_line_no_geom_iface)
+ .fragment_out(0, Type::VEC4, "fragColor")
+ .vertex_source("overlay_motion_path_line_vert_no_geom.glsl")
+ .fragment_source("overlay_motion_path_line_frag.glsl")
+ .additional_info("draw_view", "draw_globals");
+
GPU_SHADER_CREATE_INFO(overlay_motion_path_line_clipped)
.do_static_compilation(true)
.additional_info("overlay_motion_path_line", "drw_clipped");
+GPU_SHADER_CREATE_INFO(overlay_motion_path_line_clipped_no_geom)
+ .do_static_compilation(true)
+ .additional_info("overlay_motion_path_line_no_geom", "drw_clipped");
+
GPU_SHADER_INTERFACE_INFO(overlay_motion_path_point_iface, "").flat(Type::VEC4, "finalColor");
GPU_SHADER_CREATE_INFO(overlay_motion_path_point)
@@ -237,7 +257,7 @@ GPU_SHADER_CREATE_INFO(overlay_image)
.push_constant(Type::BOOL, "isCameraBackground")
.push_constant(Type::BOOL, "imgPremultiplied")
.push_constant(Type::BOOL, "imgAlphaBlend")
- .push_constant(Type::VEC4, "color")
+ .push_constant(Type::VEC4, "ucolor")
.vertex_in(0, Type::VEC3, "pos")
.vertex_out(overlay_image_iface)
.sampler(0, ImageType::FLOAT_2D, "imgTexture")
@@ -284,7 +304,7 @@ GPU_SHADER_INTERFACE_INFO(overlay_particle_iface, "").flat(Type::VEC4, "finalCol
GPU_SHADER_CREATE_INFO(overlay_particle)
.sampler(0, ImageType::FLOAT_1D, "weightTex")
- .push_constant(Type::VEC4, "color") /* Draw-size packed in alpha. */
+ .push_constant(Type::VEC4, "ucolor") /* Draw-size packed in alpha. */
.vertex_in(0, Type::VEC3, "part_pos")
.vertex_in(1, Type::VEC4, "part_rot")
.vertex_in(2, Type::FLOAT, "part_val")
diff --git a/source/blender/draw/engines/overlay/shaders/infos/overlay_grid_info.hh b/source/blender/draw/engines/overlay/shaders/infos/overlay_grid_info.hh
index a8f1281d53a..70175b7072f 100644
--- a/source/blender/draw/engines/overlay/shaders/infos/overlay_grid_info.hh
+++ b/source/blender/draw/engines/overlay/shaders/infos/overlay_grid_info.hh
@@ -32,7 +32,7 @@ GPU_SHADER_CREATE_INFO(overlay_grid_background)
GPU_SHADER_CREATE_INFO(overlay_grid_image)
.do_static_compilation(true)
.vertex_in(0, Type::VEC3, "pos")
- .push_constant(Type::VEC4, "color")
+ .push_constant(Type::VEC4, "ucolor")
.fragment_out(0, Type::VEC4, "fragColor")
.vertex_source("overlay_edit_uv_tiled_image_borders_vert.glsl")
.fragment_source("overlay_uniform_color_frag.glsl")
diff --git a/source/blender/draw/engines/overlay/shaders/infos/overlay_paint_info.hh b/source/blender/draw/engines/overlay/shaders/infos/overlay_paint_info.hh
index 3083d5a463b..08b421de3e6 100644
--- a/source/blender/draw/engines/overlay/shaders/infos/overlay_paint_info.hh
+++ b/source/blender/draw/engines/overlay/shaders/infos/overlay_paint_info.hh
@@ -12,7 +12,7 @@ GPU_SHADER_CREATE_INFO(overlay_paint_face)
.do_static_compilation(true)
.vertex_in(0, Type::VEC3, "pos")
.vertex_in(1, Type::VEC4, "nor") /* Select flag on the 4th component. */
- .push_constant(Type::VEC4, "color")
+ .push_constant(Type::VEC4, "ucolor")
.fragment_out(0, Type::VEC4, "fragColor")
.vertex_source("overlay_paint_face_vert.glsl")
.fragment_source("overlay_uniform_color_frag.glsl")
diff --git a/source/blender/draw/engines/overlay/shaders/overlay_armature_envelope_outline_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_armature_envelope_outline_vert.glsl
index 612ce8c6300..ca5a6aff2ca 100644
--- a/source/blender/draw/engines/overlay/shaders/overlay_armature_envelope_outline_vert.glsl
+++ b/source/blender/draw/engines/overlay/shaders/overlay_armature_envelope_outline_vert.glsl
@@ -130,7 +130,7 @@ void main()
gl_Position = p1;
/* compute position from 3 vertex because the change in direction
- * can happen very quicky and lead to very thin edges. */
+ * can happen very quickly and lead to very thin edges. */
vec2 ss0 = proj(p0);
vec2 ss1 = proj(p1);
vec2 ss2 = proj(p2);
diff --git a/source/blender/draw/engines/overlay/shaders/overlay_armature_shape_outline_vert_no_geom.glsl b/source/blender/draw/engines/overlay/shaders/overlay_armature_shape_outline_vert_no_geom.glsl
new file mode 100644
index 00000000000..191a9f98f02
--- /dev/null
+++ b/source/blender/draw/engines/overlay/shaders/overlay_armature_shape_outline_vert_no_geom.glsl
@@ -0,0 +1,182 @@
+
+#pragma USE_SSBO_VERTEX_FETCH(LineList, 2)
+#pragma BLENDER_REQUIRE(common_view_clipping_lib.glsl)
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+
+#define DISCARD_VERTEX \
+ gl_Position = finalColor = vec4(0.0); \
+ edgeStart = edgePos = vec2(0.0); \
+ return;
+
+/* Project to screen space. */
+vec2 proj(vec4 pos)
+{
+ return (0.5 * (pos.xy / pos.w) + 0.5) * sizeViewport.xy;
+}
+
+void do_vertex_shader(mat4 in_inst_obmat,
+ vec3 in_pos,
+ vec3 in_snor,
+ out vec4 out_pPos,
+ out vec3 out_vPos,
+ out vec2 out_ssPos,
+ out vec2 out_ssNor,
+ out vec4 out_vColSize,
+ out int out_inverted,
+ out vec4 out_wpos)
+{
+ vec4 bone_color, state_color;
+ mat4 model_mat = extract_matrix_packed_data(in_inst_obmat, state_color, bone_color);
+
+ vec4 worldPosition = model_mat * vec4(in_pos, 1.0);
+ vec4 viewpos = ViewMatrix * worldPosition;
+ out_wpos = worldPosition;
+ out_vPos = viewpos.xyz;
+ out_pPos = ProjectionMatrix * viewpos;
+
+ out_inverted = int(dot(cross(model_mat[0].xyz, model_mat[1].xyz), model_mat[2].xyz) < 0.0);
+
+ /* This is slow and run per vertex, but it's still faster than
+ * doing it per instance on CPU and sending it on via instance attribute. */
+ mat3 normal_mat = transpose(inverse(mat3(model_mat)));
+ /* TODO FIX: there is still a problem with this vector
+ * when the bone is scaled or in persp mode. But it's
+ * barely visible at the outline corners. */
+ out_ssNor = normalize(normal_world_to_view(normal_mat * in_snor).xy);
+
+ out_ssPos = proj(out_pPos);
+
+ out_vColSize = bone_color;
+}
+
+void main()
+{
+ /* Outputs a singular vertex as part of a LineList primitive, however, requires access to
+ * neighbouring 4 vertices. */
+ /* Fetch verts from input type lines adjacency. */
+ int line_prim_id = (gl_VertexID / 2);
+ int line_vertex_id = gl_VertexID % 2;
+ int base_vertex_id = line_prim_id * 2;
+
+ /* IF Input Primitive Type == Lines_Adjacency, then indices are accessed as per GL specification:
+ * i.e. 4 indices per unique prim (Provoking vert 4i-2)
+ *
+ * IF Input Primitive Type == LineStrip_Adjacency, then indices are accessed using:
+ * - 2 indices per unique prim, plus 1 index at each end, such that the strided
+ * - 4-index block can be walked. */
+ vec3 in_pos[4];
+ in_pos[0] = vertex_fetch_attribute_raw(vertex_id_from_index_id(4 * line_prim_id), pos, vec3);
+ in_pos[1] = vertex_fetch_attribute_raw(vertex_id_from_index_id(4 * line_prim_id + 1), pos, vec3);
+ in_pos[2] = vertex_fetch_attribute_raw(vertex_id_from_index_id(4 * line_prim_id + 2), pos, vec3);
+ in_pos[3] = vertex_fetch_attribute_raw(vertex_id_from_index_id(4 * line_prim_id + 3), pos, vec3);
+
+ vec3 in_snor[4];
+ in_snor[0] = vertex_fetch_attribute_raw(vertex_id_from_index_id(4 * line_prim_id), snor, vec3);
+ in_snor[1] = vertex_fetch_attribute_raw(
+ vertex_id_from_index_id(4 * line_prim_id + 1), snor, vec3);
+ in_snor[2] = vertex_fetch_attribute_raw(
+ vertex_id_from_index_id(4 * line_prim_id + 2), snor, vec3);
+ in_snor[3] = vertex_fetch_attribute_raw(
+ vertex_id_from_index_id(4 * line_prim_id + 3), snor, vec3);
+
+ mat4 in_inst_obmat = vertex_fetch_attribute(gl_VertexID, inst_obmat, mat4);
+
+ /* Run original GL vertex shader implementation per vertex in adjacency list. */
+ vec4 pPos[4];
+ vec3 vPos[4];
+ vec2 ssPos[4];
+ vec2 ssNor[4];
+ vec4 vColSize[4];
+ int inverted[4];
+ vec4 wPos[4];
+
+ for (int v = 0; v < 4; v++) {
+ do_vertex_shader(in_inst_obmat,
+ in_pos[v],
+ in_snor[v],
+ pPos[v],
+ vPos[v],
+ ssPos[v],
+ ssNor[v],
+ vColSize[v],
+ inverted[v],
+ wPos[v]);
+ }
+
+ /* Geometry Shader equivalent to calculate vertex output position. */
+ finalColor = vec4(vColSize[0].rgb, 1.0);
+
+ bool is_persp = (ProjectionMatrix[3][3] == 0.0);
+
+ vec3 view_vec = (is_persp) ? normalize(vPos[1]) : vec3(0.0, 0.0, -1.0);
+ vec3 v10 = vPos[0] - vPos[1];
+ vec3 v12 = vPos[2] - vPos[1];
+ vec3 v13 = vPos[3] - vPos[1];
+
+ vec3 n0 = cross(v12, v10);
+ vec3 n3 = cross(v13, v12);
+
+ float fac0 = dot(view_vec, n0);
+ float fac3 = dot(view_vec, n3);
+
+ /* If one of the face is perpendicular to the view,
+ * consider it and outline edge. */
+ if (abs(fac0) > 1e-5 && abs(fac3) > 1e-5) {
+ /* If both adjacent verts are facing the camera the same way,
+ * then it isn't an outline edge. */
+ if (sign(fac0) == sign(fac3)) {
+ DISCARD_VERTEX
+ }
+ }
+
+ n0 = (inverted[0] == 1) ? -n0 : n0;
+ /* Don't outline if concave edge. */
+ if (dot(n0, v13) > 0.0001) {
+ DISCARD_VERTEX
+ }
+
+ vec2 perp = normalize(ssPos[2] - ssPos[1]);
+ vec2 edge_dir = vec2(-perp.y, perp.x);
+
+ vec2 hidden_point;
+ /* Take the farthest point to compute edge direction
+ * (avoid problems with point behind near plane).
+ * If the chosen point is parallel to the edge in screen space,
+ * choose the other point anyway.
+ * This fixes some issue with cubes in orthographic views.*/
+ if (vPos[0].z < vPos[3].z) {
+ hidden_point = (abs(fac0) > 1e-5) ? ssPos[0] : ssPos[3];
+ }
+ else {
+ hidden_point = (abs(fac3) > 1e-5) ? ssPos[3] : ssPos[0];
+ }
+ vec2 hidden_dir = normalize(hidden_point - ssPos[1]);
+
+ float fac = dot(-hidden_dir, edge_dir);
+ edge_dir *= (fac < 0.0) ? -1.0 : 1.0;
+
+ /* Output corresponding value based on which vertex this corresponds to in the
+ * original input primitive. */
+ if (line_vertex_id == 0) {
+ gl_Position = pPos[1];
+ /* Offset away from the center to avoid overlap with solid shape. */
+ gl_Position.xy += (edge_dir - perp) * drw_view.viewport_size_inverse * gl_Position.w;
+ /* Improve AA bleeding inside bone silhouette. */
+ gl_Position.z -= (is_persp) ? 1e-4 : 1e-6;
+ edgeStart = edgePos = ((gl_Position.xy / gl_Position.w) * 0.5 + 0.5) * sizeViewport.xy;
+#ifdef USE_WORLD_CLIP_PLANES
+ world_clip_planes_calc_clip_distance(wPos[1].xyz);
+#endif
+ }
+ else {
+ gl_Position = pPos[2];
+ /* Offset away from the center to avoid overlap with solid shape. */
+ gl_Position.xy += (edge_dir + perp) * drw_view.viewport_size_inverse * gl_Position.w;
+ /* Improve AA bleeding inside bone silhouette. */
+ gl_Position.z -= (is_persp) ? 1e-4 : 1e-6;
+ edgeStart = edgePos = ((gl_Position.xy / gl_Position.w) * 0.5 + 0.5) * sizeViewport.xy;
+#ifdef USE_WORLD_CLIP_PLANES
+ world_clip_planes_calc_clip_distance(wPos[2].xyz);
+#endif
+ }
+} \ No newline at end of file
diff --git a/source/blender/draw/engines/overlay/shaders/overlay_edit_curve_handle_vert_no_geom.glsl b/source/blender/draw/engines/overlay/shaders/overlay_edit_curve_handle_vert_no_geom.glsl
new file mode 100644
index 00000000000..82b88a14961
--- /dev/null
+++ b/source/blender/draw/engines/overlay/shaders/overlay_edit_curve_handle_vert_no_geom.glsl
@@ -0,0 +1,16 @@
+/* TODO(Metal): Implement correct SSBO implementation for geom shader workaround.
+ * Currently included as placeholder to unblock failing compilation in Metal. */
+
+#pragma BLENDER_REQUIRE(common_view_clipping_lib.glsl)
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+
+void main()
+{
+ GPU_INTEL_VERTEX_SHADER_WORKAROUND
+
+ vec3 world_pos = point_object_to_world(pos);
+ gl_Position = point_world_to_ndc(world_pos);
+ vert.flag = data;
+
+ view_clipping_distances(world_pos);
+} \ No newline at end of file
diff --git a/source/blender/draw/engines/overlay/shaders/overlay_edit_mesh_vert_no_geom.glsl b/source/blender/draw/engines/overlay/shaders/overlay_edit_mesh_vert_no_geom.glsl
new file mode 100644
index 00000000000..81ca7480bee
--- /dev/null
+++ b/source/blender/draw/engines/overlay/shaders/overlay_edit_mesh_vert_no_geom.glsl
@@ -0,0 +1,236 @@
+
+#pragma USE_SSBO_VERTEX_FETCH(TriangleList, 6)
+
+#pragma BLENDER_REQUIRE(common_view_clipping_lib.glsl)
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+#pragma BLENDER_REQUIRE(overlay_edit_mesh_common_lib.glsl)
+
+#define DISCARD_VERTEX \
+ gl_Position = geometry_out.finalColorOuter = geometry_out.finalColor = vec4(0.0); \
+ geometry_out.edgeCoord = 0.0; \
+ return;
+
+bool test_occlusion(vec4 pos)
+{
+ vec3 ndc = (pos.xyz / pos.w) * 0.5 + 0.5;
+ return ndc.z > texture(depthTex, ndc.xy).r;
+}
+
+vec3 non_linear_blend_color(vec3 col1, vec3 col2, float fac)
+{
+ col1 = pow(col1, vec3(1.0 / 2.2));
+ col2 = pow(col2, vec3(1.0 / 2.2));
+ vec3 col = mix(col1, col2, fac);
+ return pow(col, vec3(2.2));
+}
+
+vec3 vec3_1010102_Inorm_to_vec3(vec3 data)
+{
+ return data;
+}
+
+vec3 vec3_1010102_Inorm_to_vec3(int data)
+{
+ vec3 out_vec;
+ out_vec.x = float(clamp(data, -512, 511)) / 511.0f;
+ out_vec.y = float(clamp(data >> 10, -512, 511)) / 511.0f;
+ out_vec.z = float(clamp(data >> 20, -512, 511)) / 511.0f;
+ return out_vec;
+}
+
+void do_vertex(vec4 color, vec4 pos, float coord, vec2 offset)
+{
+ geometry_out.finalColor = color;
+ geometry_out.edgeCoord = coord;
+ gl_Position = pos;
+ /* Multiply offset by 2 because gl_Position range is [-1..1]. */
+ gl_Position.xy += offset * 2.0 * pos.w;
+}
+
+void main()
+{
+ /* Index of the quad primitive -- corresponds to one line prim. */
+ int quad_id = gl_VertexID / 6;
+
+ /* Determine vertex within the output 2-triangle quad (A, B, C)(A, C, D). */
+ int quad_vertex_id = gl_VertexID % 6;
+
+ /* Base index of the line primitive:
+ * IF PrimType == LineList: base_vertex_id = quad_id*2
+ * IF PrimType == LineStrip: base_vertex_id = quad_id
+ *
+ * Note: This is currently used as LineList.
+ *
+ * Note: Primitive Restart Will not work with this setup as-is. We should avoid using
+ * input primitive types which use restart indices. */
+ int base_vertex_id = quad_id * 2;
+
+ /* Fetch attribute values for self and neighbouring vertex. */
+ vec3 in_pos0 = vertex_fetch_attribute(base_vertex_id, pos, vec3);
+ vec3 in_pos1 = vertex_fetch_attribute(base_vertex_id + 1, pos, vec3);
+ uchar4 in_data0 = vertex_fetch_attribute(base_vertex_id, data, uchar4);
+ uchar4 in_data1 = vertex_fetch_attribute(base_vertex_id + 1, data, uchar4);
+ vec3 in_vnor0 = vec3_1010102_Inorm_to_vec3(
+ vertex_fetch_attribute(base_vertex_id, vnor, vec3_1010102_Inorm));
+ vec3 in_vnor1 = vec3_1010102_Inorm_to_vec3(
+ vertex_fetch_attribute(base_vertex_id + 1, vnor, vec3_1010102_Inorm));
+
+ /* Calculate values for self and neighbouring vertex. */
+ vec4 out_finalColor[2];
+ vec4 out_finalColorOuter[2];
+ int selectOveride[2];
+
+ vec3 world_pos0 = point_object_to_world(in_pos0);
+ vec3 world_pos1 = point_object_to_world(in_pos1);
+ vec4 out_pos0 = point_world_to_ndc(world_pos0);
+ vec4 out_pos1 = point_world_to_ndc(world_pos1);
+ ivec4 m_data0 = ivec4(in_data0) & dataMask;
+ ivec4 m_data1 = ivec4(in_data1) & dataMask;
+
+#if defined(EDGE)
+# ifdef FLAT
+ out_finalColor[0] = EDIT_MESH_edge_color_inner(m_data0.y);
+ out_finalColor[1] = EDIT_MESH_edge_color_inner(m_data1.y);
+ selectOveride[0] = 1;
+ selectOveride[1] = 1;
+# else
+ out_finalColor[0] = EDIT_MESH_edge_vertex_color(m_data0.y);
+ out_finalColor[1] = EDIT_MESH_edge_vertex_color(m_data1.y);
+ selectOveride[0] = (m_data0.y & EDGE_SELECTED);
+ selectOveride[1] = (m_data1.y & EDGE_SELECTED);
+# endif
+
+ float crease0 = float(m_data0.z) / 255.0;
+ float crease1 = float(m_data1.z) / 255.0;
+ float bweight0 = float(m_data0.w) / 255.0;
+ float bweight1 = float(m_data1.w) / 255.0;
+ out_finalColorOuter[0] = EDIT_MESH_edge_color_outer(m_data0.y, m_data0.x, crease0, bweight0);
+ out_finalColorOuter[1] = EDIT_MESH_edge_color_outer(m_data1.y, m_data1.x, crease1, bweight1);
+
+ if (out_finalColorOuter[0].a > 0.0) {
+ out_pos0.z -= 5e-7 * abs(out_pos0.w);
+ }
+ if (out_finalColorOuter[1].a > 0.0) {
+ out_pos1.z -= 5e-7 * abs(out_pos1.w);
+ }
+
+ /* Occlusion done in fragment shader. */
+ bool occluded0 = false;
+ bool occluded1 = false;
+#endif
+
+ out_finalColor[0].a *= (occluded0) ? alpha : 1.0;
+ out_finalColor[1].a *= (occluded1) ? alpha : 1.0;
+
+#if !defined(FACE)
+ /* Facing based color blend */
+ vec3 vpos0 = point_world_to_view(world_pos0);
+ vec3 view_normal0 = normalize(normal_object_to_view(in_vnor0) + 1e-4);
+ vec3 view_vec0 = (ProjectionMatrix[3][3] == 0.0) ? normalize(vpos0) : vec3(0.0, 0.0, 1.0);
+ float facing0 = dot(view_vec0, view_normal0);
+ facing0 = 1.0 - abs(facing0) * 0.2;
+
+ vec3 vpos1 = point_world_to_view(world_pos1);
+ vec3 view_normal1 = normalize(normal_object_to_view(in_vnor1) + 1e-4);
+ vec3 view_vec1 = (ProjectionMatrix[3][3] == 0.0) ? normalize(vpos1) : vec3(0.0, 0.0, 1.0);
+ float facing1 = dot(view_vec1, view_normal1);
+ facing1 = 1.0 - abs(facing1) * 0.2;
+
+ /* Do interpolation in a non-linear space to have a better visual result. */
+ out_finalColor[0].rgb = non_linear_blend_color(
+ colorEditMeshMiddle.rgb, out_finalColor[0].rgb, facing0);
+ out_finalColor[1].rgb = non_linear_blend_color(
+ colorEditMeshMiddle.rgb, out_finalColor[1].rgb, facing1);
+#endif
+
+#ifdef USE_WORLD_CLIP_PLANES
+ float out_clipdistances0[6];
+ float out_clipdistances1[6];
+ vec4 clip_pos0 = vec4(world_pos0, 1.0);
+ out_clipdistances0[0] = dot(WorldClipPlanes[0], clip_pos0);
+ out_clipdistances0[1] = dot(WorldClipPlanes[1], clip_pos0);
+ out_clipdistances0[2] = dot(WorldClipPlanes[2], clip_pos0);
+ out_clipdistances0[3] = dot(WorldClipPlanes[3], clip_pos0);
+ out_clipdistances0[4] = dot(WorldClipPlanes[4], clip_pos0);
+ out_clipdistances0[5] = dot(WorldClipPlanes[5], clip_pos0);
+
+ vec4 clip_pos1 = vec4(world_pos1, 1.0);
+ out_clipdistances1[0] = dot(WorldClipPlanes[0], clip_pos1);
+ out_clipdistances1[1] = dot(WorldClipPlanes[1], clip_pos1);
+ out_clipdistances1[2] = dot(WorldClipPlanes[2], clip_pos1);
+ out_clipdistances1[3] = dot(WorldClipPlanes[3], clip_pos1);
+ out_clipdistances1[4] = dot(WorldClipPlanes[4], clip_pos1);
+ out_clipdistances1[5] = dot(WorldClipPlanes[5], clip_pos1);
+#endif
+
+ // -------- GEOM SHADER ALTERNATIVE ----------- //
+ vec2 ss_pos[2];
+
+ /* Clip line against near plane to avoid deformed lines. */
+ vec4 pos0 = out_pos0;
+ vec4 pos1 = out_pos1;
+ vec2 pz_ndc = vec2(pos0.z / pos0.w, pos1.z / pos1.w);
+ bvec2 clipped = lessThan(pz_ndc, vec2(-1.0));
+ if (all(clipped)) {
+ /* Totally clipped. */
+ DISCARD_VERTEX;
+ }
+
+ vec4 pos01 = pos0 - pos1;
+ float ofs = abs((pz_ndc.y + 1.0) / (pz_ndc.x - pz_ndc.y));
+ if (clipped.y) {
+ pos1 += pos01 * ofs;
+ }
+ else if (clipped.x) {
+ pos0 -= pos01 * (1.0 - ofs);
+ }
+
+ ss_pos[0] = pos0.xy / pos0.w;
+ ss_pos[1] = pos1.xy / pos1.w;
+
+ vec2 line = ss_pos[0] - ss_pos[1];
+ line = abs(line) * sizeViewport.xy;
+
+ geometry_out.finalColorOuter = out_finalColorOuter[0];
+ float half_size = sizeEdge;
+ /* Enlarge edge for flag display. */
+ half_size += (geometry_out.finalColorOuter.a > 0.0) ? max(sizeEdge, 1.0) : 0.0;
+
+#ifdef USE_SMOOTH_WIRE
+ /* Add 1 px for AA */
+ half_size += 0.5;
+#endif
+
+ vec3 edge_ofs = vec3(half_size * drw_view.viewport_size_inverse, 0.0);
+
+ bool horizontal = line.x > line.y;
+ edge_ofs = (horizontal) ? edge_ofs.zyz : edge_ofs.xzz;
+
+ vec4 final_color = (selectOveride[0] == 0) ? out_finalColor[1] : out_finalColor[0];
+
+ /* Output specific Vertex data depending on quad_vertex_id. */
+ if (quad_vertex_id == 0) {
+#ifdef USE_WORLD_CLIP_PLANES
+ world_clip_planes_set_clip_distance(out_clipdistances0);
+#endif
+ do_vertex(out_finalColor[0], pos0, half_size, edge_ofs.xy);
+ }
+ else if (quad_vertex_id == 1 || quad_vertex_id == 3) {
+#ifdef USE_WORLD_CLIP_PLANES
+ world_clip_planes_set_clip_distance(out_clipdistances0);
+#endif
+ do_vertex(out_finalColor[0], pos0, -half_size, -edge_ofs.xy);
+ }
+ else if (quad_vertex_id == 2 || quad_vertex_id == 5) {
+#ifdef USE_WORLD_CLIP_PLANES
+ world_clip_planes_set_clip_distance(out_clipdistances1);
+#endif
+ do_vertex(final_color, pos1, half_size, edge_ofs.xy);
+ }
+ else if (quad_vertex_id == 4) {
+#ifdef USE_WORLD_CLIP_PLANES
+ world_clip_planes_set_clip_distance(out_clipdistances1);
+#endif
+ do_vertex(final_color, pos1, -half_size, -edge_ofs.xy);
+ }
+} \ No newline at end of file
diff --git a/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_stretching_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_stretching_vert.glsl
index bb086e8d9f5..9a3036d5940 100644
--- a/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_stretching_vert.glsl
+++ b/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_stretching_vert.glsl
@@ -55,9 +55,9 @@ float angle_normalized_v2v2(vec2 v1, vec2 v2)
return (q) ? a : M_PI - a;
}
-float area_ratio_to_stretch(float ratio, float tot_ratio, float inv_tot_ratio)
+float area_ratio_to_stretch(float ratio, float tot_ratio)
{
- ratio *= (ratio > 0.0f) ? tot_ratio : -inv_tot_ratio;
+ ratio *= tot_ratio;
return (ratio > 1.0f) ? (1.0f / ratio) : ratio;
}
@@ -74,7 +74,7 @@ void main()
stretch = stretch;
stretch = 1.0 - stretch * stretch;
#else
- float stretch = 1.0 - area_ratio_to_stretch(ratio, totalAreaRatio, totalAreaRatioInv);
+ float stretch = 1.0 - area_ratio_to_stretch(ratio, totalAreaRatio);
#endif
diff --git a/source/blender/draw/engines/overlay/shaders/overlay_extra_point_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_extra_point_vert.glsl
index de999c241c0..179c3cb6d73 100644
--- a/source/blender/draw/engines/overlay/shaders/overlay_extra_point_vert.glsl
+++ b/source/blender/draw/engines/overlay/shaders/overlay_extra_point_vert.glsl
@@ -16,7 +16,7 @@ void main()
radii[3] = radius - outline_width - 1.0;
radii /= sizeObjectCenter;
- fillColor = color;
+ fillColor = ucolor;
outlineColor = colorOutline;
view_clipping_distances(world_pos);
diff --git a/source/blender/draw/engines/overlay/shaders/overlay_grid_frag.glsl b/source/blender/draw/engines/overlay/shaders/overlay_grid_frag.glsl
index 54a4231590e..2c81966fe50 100644
--- a/source/blender/draw/engines/overlay/shaders/overlay_grid_frag.glsl
+++ b/source/blender/draw/engines/overlay/shaders/overlay_grid_frag.glsl
@@ -1,6 +1,6 @@
/**
* Infinite grid:
- * Draw antialiazed grid and axes of different sizes with smooth blending between Level of details.
+ * Draw antialiased grid and axes of different sizes with smooth blending between levels of detail.
* We draw multiple triangles to avoid float precision issues due to perspective interpolation.
**/
@@ -8,29 +8,33 @@
#pragma BLENDER_REQUIRE(common_math_lib.glsl)
/**
- * We want to know how much a pixel is covered by a line.
- * We replace the square pixel with acircle of the same area and try to find the intersection area.
- * The area we search is the circular segment. https://en.wikipedia.org/wiki/Circular_segment
- * The formula for the area uses inverse trig function and is quite complexe. Instead,
- * we approximate it by using the smoothstep function and a 1.05 factor to the disc radius.
+ * We want to know how much of a pixel is covered by a line.
+ * Here, we imagine the square pixel is a circle with the same area and try to find the
+ * intersection area. The overlap area is a circular segment.
+ * https://en.wikipedia.org/wiki/Circular_segment The formula for the area uses inverse trig
+ * function and is quite complex. Instead, we approximate it by using the smoothstep function and
+ * a 1.05 factor to the disc radius.
+ *
+ * For an alternate approach, see:
+ * https://developer.nvidia.com/gpugems/gpugems2/part-iii-high-quality-rendering/chapter-22-fast-prefiltered-lines
*/
#define M_1_SQRTPI 0.5641895835477563 /* 1/sqrt(pi) */
#define DISC_RADIUS (M_1_SQRTPI * 1.05)
-#define GRID_LINE_SMOOTH_START (0.5 - DISC_RADIUS)
-#define GRID_LINE_SMOOTH_END (0.5 + DISC_RADIUS)
+#define GRID_LINE_SMOOTH_START (0.5 + DISC_RADIUS)
+#define GRID_LINE_SMOOTH_END (0.5 - DISC_RADIUS)
#define GRID_LINE_STEP(dist) smoothstep(GRID_LINE_SMOOTH_START, GRID_LINE_SMOOTH_END, dist)
-float get_grid(vec2 co, vec2 fwidthCos, float grid_scale)
+float get_grid(vec2 co, vec2 fwidthCos, vec2 grid_scale)
{
- float half_size = grid_scale / 2.0;
+ vec2 half_size = grid_scale / 2.0;
/* Triangular wave pattern, amplitude is [0, half_size]. */
- vec2 grid_domain = abs(mod(co + half_size, vec2(grid_scale)) - half_size);
+ vec2 grid_domain = abs(mod(co + half_size, grid_scale) - half_size);
/* Modulate by the absolute rate of change of the coordinates
* (make line have the same width under perspective). */
grid_domain /= fwidthCos;
/* Collapse waves. */
float line_dist = min(grid_domain.x, grid_domain.y);
- return 1.0 - GRID_LINE_STEP(line_dist - grid_buf.line_size);
+ return GRID_LINE_STEP(line_dist - grid_buf.line_size);
}
vec3 get_axes(vec3 co, vec3 fwidthCos, float line_size)
@@ -39,7 +43,7 @@ vec3 get_axes(vec3 co, vec3 fwidthCos, float line_size)
/* Modulate by the absolute rate of change of the coordinates
* (make line have the same width under perspective). */
axes_domain /= fwidthCos;
- return 1.0 - GRID_LINE_STEP(axes_domain - (line_size + grid_buf.line_size));
+ return GRID_LINE_STEP(axes_domain - (line_size + grid_buf.line_size));
}
#define linearstep(p0, p1, v) (clamp(((v) - (p0)) / abs((p1) - (p0)), 0.0, 1.0))
@@ -106,49 +110,30 @@ void main()
grid_res = grid_buf.zoom_factor;
}
- /* From biggest to smallest. */
- vec4 scale;
-#define grid_step(a) grid_buf.steps[a].x
-#if 0 /* Inefficient. */
- int step_id = 0;
- scale[0] = 0.0;
- scale[1] = grid_step(0);
- while (scale[1] < grid_res && step_id != STEPS_LEN - 1) {
- scale[0] = scale[1];
- scale[1] = grid_step(++step_id);
- }
- scale[2] = grid_step(min(step_id + 1, STEPS_LEN - 1));
- scale[3] = grid_step(min(step_id + 2, STEPS_LEN - 1));
-#else
- /* For more efficiency, unroll the loop above. */
- if (grid_step(0) > grid_res) {
- scale = vec4(0.0, grid_step(0), grid_step(1), grid_step(2));
- }
- else if (grid_step(1) > grid_res) {
- scale = vec4(grid_step(0), grid_step(1), grid_step(2), grid_step(3));
- }
- else if (grid_step(2) > grid_res) {
- scale = vec4(grid_step(1), grid_step(2), grid_step(3), grid_step(4));
- }
- else if (grid_step(3) > grid_res) {
- scale = vec4(grid_step(2), grid_step(3), grid_step(4), grid_step(5));
- }
- else if (grid_step(4) > grid_res) {
- scale = vec4(grid_step(3), grid_step(4), grid_step(5), grid_step(6));
- }
- else if (grid_step(5) > grid_res) {
- scale = vec4(grid_step(4), grid_step(5), grid_step(6), grid_step(7));
- }
- else if (grid_step(6) > grid_res) {
- scale = vec4(grid_step(5), grid_step(6), grid_step(7), grid_step(7));
- }
- else {
- scale = vec4(grid_step(6), grid_step(7), grid_step(7), grid_step(7));
+/** Keep in sync with `SI_GRID_STEPS_LEN` in `DNA_space_types.h`. */
+#define STEPS_LEN 8
+ int step_id_x = STEPS_LEN - 1;
+ int step_id_y = STEPS_LEN - 1;
+
+ /* Loop backwards a compile-time-constant number of steps. */
+ for (int i = STEPS_LEN - 2; i >= 0; --i) {
+ step_id_x = (grid_res < grid_buf.steps[i].x) ? i : step_id_x; /* Branchless. */
+ step_id_y = (grid_res < grid_buf.steps[i].y) ? i : step_id_y;
}
-#endif
-#undef grid_step
- float blend = 1.0 - linearstep(scale[0], scale[1], grid_res);
+ /* From biggest to smallest. */
+ float scale0x = step_id_x > 0 ? grid_buf.steps[step_id_x - 1].x : 0.0;
+ float scaleAx = grid_buf.steps[step_id_x].x;
+ float scaleBx = grid_buf.steps[min(step_id_x + 1, STEPS_LEN - 1)].x;
+ float scaleCx = grid_buf.steps[min(step_id_x + 2, STEPS_LEN - 1)].x;
+
+ float scale0y = step_id_y > 0 ? grid_buf.steps[step_id_y - 1].y : 0.0;
+ float scaleAy = grid_buf.steps[step_id_y].y;
+ float scaleBy = grid_buf.steps[min(step_id_y + 1, STEPS_LEN - 1)].y;
+ float scaleCy = grid_buf.steps[min(step_id_y + 2, STEPS_LEN - 1)].y;
+
+ /* Subtract from 1.0 to fix blending when `scale0x == scaleAx`. */
+ float blend = 1.0 - linearstep(scale0x + scale0y, scaleAx + scaleAy, grid_res + grid_res);
blend = blend * blend * blend;
vec2 grid_pos, grid_fwidth;
@@ -165,9 +150,9 @@ void main()
grid_fwidth = fwidthPos.xy;
}
- float gridA = get_grid(grid_pos, grid_fwidth, scale[1]);
- float gridB = get_grid(grid_pos, grid_fwidth, scale[2]);
- float gridC = get_grid(grid_pos, grid_fwidth, scale[3]);
+ float gridA = get_grid(grid_pos, grid_fwidth, vec2(scaleAx, scaleAy));
+ float gridB = get_grid(grid_pos, grid_fwidth, vec2(scaleBx, scaleBy));
+ float gridC = get_grid(grid_pos, grid_fwidth, vec2(scaleCx, scaleCy));
out_color = colorGrid;
out_color.a *= gridA * blend;
diff --git a/source/blender/draw/engines/overlay/shaders/overlay_motion_path_line_vert_no_geom.glsl b/source/blender/draw/engines/overlay/shaders/overlay_motion_path_line_vert_no_geom.glsl
new file mode 100644
index 00000000000..731c384803e
--- /dev/null
+++ b/source/blender/draw/engines/overlay/shaders/overlay_motion_path_line_vert_no_geom.glsl
@@ -0,0 +1,188 @@
+
+#pragma USE_SSBO_VERTEX_FETCH(TriangleList, 6)
+
+#pragma BLENDER_REQUIRE(common_view_clipping_lib.glsl)
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+
+#define frameCurrent mpathLineSettings.x
+#define frameStart mpathLineSettings.y
+#define frameEnd mpathLineSettings.z
+#define cacheStart mpathLineSettings.w
+
+/* Project to screen space. */
+vec2 proj(vec4 pos)
+{
+ return (0.5 * (pos.xy / pos.w) + 0.5) * sizeViewport.xy;
+}
+
+#define SET_INTENSITY(A, B, C, min, max) \
+ (((1.0 - (float(C - B) / float(C - A))) * (max - min)) + min)
+
+vec2 compute_dir(vec2 v0, vec2 v1)
+{
+ vec2 dir = normalize(v1 - v0 + 1e-8);
+ dir = vec2(-dir.y, dir.x);
+ return dir;
+}
+
+void do_vertex_shader(vec4 pos, int vertex_id, out vec2 out_sspos, out vec4 out_finalcolour)
+{
+ out_sspos = proj(pos);
+ out_finalcolour = vec4(0.0);
+
+ int frame = vertex_id + cacheStart;
+ float intensity; /* how faint */
+ vec3 blend_base = (abs(frame - frameCurrent) == 0) ?
+ colorCurrentFrame.rgb :
+ colorBackground.rgb; /* "bleed" cframe color to ease color blending */
+ bool use_custom_color = customColor.x >= 0.0;
+ /* TODO: We might want something more consistent with custom color and standard colors. */
+ if (frame < frameCurrent) {
+ if (use_custom_color) {
+ /* Custom color: previous frames color is darker than current frame */
+ out_finalcolour.rgb = customColor * 0.25;
+ }
+ else {
+ /* black - before frameCurrent */
+ if (selected) {
+ intensity = SET_INTENSITY(frameStart, frame, frameCurrent, 0.25, 0.75);
+ }
+ else {
+ intensity = SET_INTENSITY(frameStart, frame, frameCurrent, 0.68, 0.92);
+ }
+ out_finalcolour.rgb = mix(colorWire.rgb, blend_base, intensity);
+ }
+ }
+ else if (frame > frameCurrent) {
+ if (use_custom_color) {
+ /* Custom color: next frames color is equal to user selected color */
+ out_finalcolour.rgb = customColor;
+ }
+ else {
+ /* blue - after frameCurrent */
+ if (selected) {
+ intensity = SET_INTENSITY(frameCurrent, frame, frameEnd, 0.25, 0.75);
+ }
+ else {
+ intensity = SET_INTENSITY(frameCurrent, frame, frameEnd, 0.68, 0.92);
+ }
+
+ out_finalcolour.rgb = mix(colorBonePose.rgb, blend_base, intensity);
+ }
+ }
+ else {
+ if (use_custom_color) {
+ /* Custom color: current frame color is slightly darker than user selected color */
+ out_finalcolour.rgb = customColor * 0.5;
+ }
+ else {
+ /* green - on frameCurrent */
+ if (selected) {
+ intensity = 0.92f;
+ }
+ else {
+ intensity = 0.75f;
+ }
+ out_finalcolour.rgb = mix(colorBackground.rgb, blend_base, intensity);
+ }
+ }
+ out_finalcolour.a = 1.0;
+}
+
+void main()
+{
+ /** Determine Output Primitive ID and relative vertex. */
+ /* Index of the quad primitive. We generate one quad for each input line. */
+ int quad_id = gl_VertexID / 6;
+
+ /* Determine vertex within the quad (A, B, C)(A, C, D). */
+ int quad_vertex_id = gl_VertexID % 6;
+ /* Base index of the line primitive:
+ * - IF PrimType == LineList: base_vertex_id = quad_id*2
+ * - IF PrimType == LineStrip: base_vertex_id = quad_id
+ *
+ * Note: Primitive is LineStrip for this shader. */
+ int base_vertex_id = quad_id;
+
+ /* Fetch attributes for self and neighbouring vertex. */
+ vec3 in_pos0 = vertex_fetch_attribute(base_vertex_id, pos, vec3);
+ vec3 in_pos1 = vertex_fetch_attribute(base_vertex_id + 1, pos, vec3);
+
+ vec4 out_pos0 = ViewProjectionMatrix * vec4(in_pos0, 1.0);
+ vec4 out_pos1 = ViewProjectionMatrix * vec4(in_pos1, 1.0);
+
+ /* Final calculations required for Geometry Shader alternative.
+ * We need to calculate values for each vertex position to correctly determine the final output
+ * position. */
+ vec2 ssPos[2];
+ vec4 finalColor_geom[2];
+
+ do_vertex_shader(out_pos0, base_vertex_id, ssPos[0], finalColor_geom[0]);
+ do_vertex_shader(out_pos1, base_vertex_id + 1, ssPos[0], finalColor_geom[0]);
+
+ /* Calculate Vertex Clip distances. */
+#ifdef USE_WORLD_CLIP_PLANES
+ float out_ClipDistance0[6];
+
+ out_ClipDistance0[0] = dot(clipPlanes[0], out_pos0);
+ out_ClipDistance0[1] = dot(clipPlanes[1], out_pos0);
+ out_ClipDistance0[2] = dot(clipPlanes[2], out_pos0);
+ out_ClipDistance0[3] = dot(clipPlanes[3], out_pos0);
+ out_ClipDistance0[4] = dot(clipPlanes[4], out_pos0);
+ out_ClipDistance0[5] = dot(clipPlanes[5], out_pos0);
+
+ float out_ClipDistance1[6];
+ out_ClipDistance1[0] = dot(clipPlanes[0], out_pos1);
+ out_ClipDistance1[1] = dot(clipPlanes[1], out_pos1);
+ out_ClipDistance1[2] = dot(clipPlanes[2], out_pos1);
+ out_ClipDistance1[3] = dot(clipPlanes[3], out_pos1);
+ out_ClipDistance1[4] = dot(clipPlanes[4], out_pos1);
+ out_ClipDistance1[5] = dot(clipPlanes[5], out_pos1);
+#endif
+
+ /* Geometry shader alternative -- Output is trianglelist consisting of 6 vertices.
+ * Each vertex shader invocation is one vertex in the output primitive, so outptut
+ * required ID. */
+ vec2 t;
+ vec2 edge_dir = compute_dir(ssPos[0], ssPos[1]) * drw_view.viewport_size_inverse;
+
+ bool is_persp = (ProjectionMatrix[3][3] == 0.0);
+ float line_size = float(lineThickness) * sizePixel;
+
+ if (quad_vertex_id == 0) {
+#ifdef USE_WORLD_CLIP_PLANES
+ world_clip_planes_set_clip_distance(out_ClipDistance0);
+#endif
+
+ interp.color = finalColor_geom[0];
+ t = edge_dir * (line_size * (is_persp ? out_pos0.w : 1.0));
+ gl_Position = out_pos0 + vec4(t, 0.0, 0.0);
+ }
+ else if (quad_vertex_id == 1 || quad_vertex_id == 3) {
+#ifdef USE_WORLD_CLIP_PLANES
+ world_clip_planes_set_clip_distance(out_ClipDistance0);
+#endif
+
+ interp.color = finalColor_geom[0];
+ t = edge_dir * (line_size * (is_persp ? out_pos0.w : 1.0));
+ gl_Position = out_pos0 - vec4(t, 0.0, 0.0);
+ }
+ else if (quad_vertex_id == 2 || quad_vertex_id == 5) {
+#ifdef USE_WORLD_CLIP_PLANES
+ world_clip_planes_set_clip_distance(out_ClipDistance1);
+#endif
+
+ interp.color = finalColor_geom[1];
+ t = edge_dir * (line_size * (is_persp ? out_pos1.w : 1.0));
+ gl_Position = out_pos1 + vec4(t, 0.0, 0.0);
+ }
+ else if (quad_vertex_id == 4) {
+#ifdef USE_WORLD_CLIP_PLANES
+ world_clip_planes_set_clip_distance(out_ClipDistance1);
+#endif
+
+ interp.color = finalColor_geom[1];
+ t = edge_dir * (line_size * (is_persp ? out_pos1.w : 1.0));
+ gl_Position = out_pos1 - vec4(t, 0.0, 0.0);
+ }
+} \ No newline at end of file
diff --git a/source/blender/draw/engines/overlay/shaders/overlay_particle_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_particle_vert.glsl
index c48e7cce550..48038d0ca17 100644
--- a/source/blender/draw/engines/overlay/shaders/overlay_particle_vert.glsl
+++ b/source/blender/draw/engines/overlay/shaders/overlay_particle_vert.glsl
@@ -16,7 +16,7 @@ vec3 rotate(vec3 vec, vec4 quat)
void main()
{
/* Drawsize packed in alpha. */
- float draw_size = color.a;
+ float draw_size = ucolor.a;
vec3 world_pos = part_pos;
@@ -43,7 +43,7 @@ void main()
finalColor = vec4(clamp(pos * 10000.0, 0.0, 1.0), 1.0);
}
else if (part_val < 0.0) {
- finalColor = vec4(color.rgb, 1.0);
+ finalColor = vec4(ucolor.rgb, 1.0);
}
else {
finalColor = vec4(texture(weightTex, part_val).rgb, 1.0);
diff --git a/source/blender/draw/engines/overlay/shaders/overlay_uniform_color_frag.glsl b/source/blender/draw/engines/overlay/shaders/overlay_uniform_color_frag.glsl
index e1a4a3602e3..2794481489c 100644
--- a/source/blender/draw/engines/overlay/shaders/overlay_uniform_color_frag.glsl
+++ b/source/blender/draw/engines/overlay/shaders/overlay_uniform_color_frag.glsl
@@ -1,4 +1,4 @@
void main()
{
- fragColor = color;
+ fragColor = ucolor;
}
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_transparent_accum_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_transparent_accum_frag.glsl
index 213279b1913..32191835668 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_transparent_accum_frag.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_transparent_accum_frag.glsl
@@ -6,7 +6,7 @@
#pragma BLENDER_REQUIRE(workbench_world_light_lib.glsl)
/* Special function only to be used with calculate_transparent_weight(). */
-float linear_zdepth(float depth, vec4 viewvecs[2], mat4 proj_mat)
+float linear_zdepth(float depth, mat4 proj_mat)
{
if (proj_mat[3][3] == 0.0) {
float d = 2.0 * depth - 1.0;
@@ -14,7 +14,7 @@ float linear_zdepth(float depth, vec4 viewvecs[2], mat4 proj_mat)
}
else {
/* Return depth from near plane. */
- return depth * viewvecs[1].z;
+ return depth * drw_view.viewvecs[1].z;
}
}
@@ -24,7 +24,7 @@ float linear_zdepth(float depth, vec4 viewvecs[2], mat4 proj_mat)
*/
float calculate_transparent_weight(void)
{
- float z = linear_zdepth(gl_FragCoord.z, drw_view.viewvecs, drw_view.winmat);
+ float z = linear_zdepth(gl_FragCoord.z, drw_view.winmat);
#if 0
/* Eq 10 : Good for surfaces with varying opacity (like particles) */
float a = min(1.0, alpha * 10.0) + 0.01;
diff --git a/source/blender/draw/engines/workbench/workbench_engine.c b/source/blender/draw/engines/workbench/workbench_engine.c
index 9eb35c25bf4..ee9521289d9 100644
--- a/source/blender/draw/engines/workbench/workbench_engine.c
+++ b/source/blender/draw/engines/workbench/workbench_engine.c
@@ -29,6 +29,8 @@
#include "ED_paint.h"
+#include "GPU_context.h"
+
#include "workbench_engine.h"
#include "workbench_private.h"
@@ -36,6 +38,7 @@
void workbench_engine_init(void *ved)
{
+ GPU_render_begin();
WORKBENCH_Data *vedata = ved;
WORKBENCH_StorageList *stl = vedata->stl;
WORKBENCH_TextureList *txl = vedata->txl;
@@ -64,6 +67,7 @@ void workbench_engine_init(void *ved)
workbench_dof_engine_init(vedata);
workbench_antialiasing_engine_init(vedata);
workbench_volume_engine_init(vedata);
+ GPU_render_end();
}
void workbench_cache_init(void *ved)
@@ -409,7 +413,7 @@ void workbench_cache_populate(void *ved, Object *ob)
return;
}
- if (ELEM(ob->type, OB_MESH, OB_SURF, OB_MBALL, OB_POINTCLOUD)) {
+ if (ELEM(ob->type, OB_MESH, OB_POINTCLOUD)) {
bool use_sculpt_pbvh, use_texpaint_mode, draw_shadow, has_transp_mat = false;
eV3DShadingColorType color_type = workbench_color_type_get(
wpd, ob, &use_sculpt_pbvh, &use_texpaint_mode, &draw_shadow);