diff options
Diffstat (limited to 'source/blender/draw/engines')
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 (°_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 (°_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); |