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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeroen Bakker <j.bakker@atmind.nl>2018-04-16 21:35:59 +0300
committerJeroen Bakker <j.bakker@atmind.nl>2018-04-16 21:35:59 +0300
commitc7d6aa4338527c4fe580bcbf7f8533f582583e13 (patch)
treee14c93d1f9cde421374db161b276d29dc4289bc7 /source/blender/draw
parent4ed21f13608901b10f8f4b37cee9a054a91da0bd (diff)
parent34ab90f546f097cada951b2c9ca22bf271996980 (diff)
Merge branch 'blender2.8' into blender2.8-workbench
Diffstat (limited to 'source/blender/draw')
-rw-r--r--source/blender/draw/CMakeLists.txt1
-rw-r--r--source/blender/draw/engines/eevee/eevee_motion_blur.c5
-rw-r--r--source/blender/draw/intern/DRW_render.h2
-rw-r--r--source/blender/draw/intern/draw_armature.c2
-rw-r--r--source/blender/draw/intern/draw_cache_impl_particles.c6
-rw-r--r--source/blender/draw/intern/draw_manager.c24
-rw-r--r--source/blender/draw/intern/draw_manager.h1
-rw-r--r--source/blender/draw/intern/draw_manager_data.c1
-rw-r--r--source/blender/draw/intern/draw_manager_exec.c128
-rw-r--r--source/blender/draw/intern/draw_manager_texture.c2
-rw-r--r--source/blender/draw/modes/edit_curve_mode.c9
-rw-r--r--source/blender/draw/modes/edit_lattice_mode.c4
-rw-r--r--source/blender/draw/modes/edit_mesh_mode.c4
-rw-r--r--source/blender/draw/modes/edit_metaball_mode.c3
-rw-r--r--source/blender/draw/modes/object_mode.c116
-rw-r--r--source/blender/draw/modes/pose_mode.c4
-rw-r--r--source/blender/draw/modes/sculpt_mode.c2
-rw-r--r--source/blender/draw/modes/shaders/object_outline_detect_frag.glsl104
-rw-r--r--source/blender/draw/modes/shaders/object_outline_prepass_frag.glsl10
19 files changed, 221 insertions, 207 deletions
diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index f96f496a0f9..3bf1acaf79e 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -234,6 +234,7 @@ data_to_c_simple(modes/shaders/object_empty_image_vert.glsl SRC)
data_to_c_simple(modes/shaders/object_outline_resolve_frag.glsl SRC)
data_to_c_simple(modes/shaders/object_outline_expand_frag.glsl SRC)
data_to_c_simple(modes/shaders/object_outline_detect_frag.glsl SRC)
+data_to_c_simple(modes/shaders/object_outline_prepass_frag.glsl SRC)
data_to_c_simple(modes/shaders/object_grid_frag.glsl SRC)
data_to_c_simple(modes/shaders/object_grid_vert.glsl SRC)
data_to_c_simple(modes/shaders/object_lightprobe_grid_vert.glsl SRC)
diff --git a/source/blender/draw/engines/eevee/eevee_motion_blur.c b/source/blender/draw/engines/eevee/eevee_motion_blur.c
index 9b19163c8d7..4bac8ba2ebd 100644
--- a/source/blender/draw/engines/eevee/eevee_motion_blur.c
+++ b/source/blender/draw/engines/eevee/eevee_motion_blur.c
@@ -68,16 +68,13 @@ static void eevee_motion_blur_camera_get_matrix_at_time(
cam_cpy.data = &camdata_cpy;
const DRWContextState *draw_ctx = DRW_context_state_get();
- /* We will be modifying time, so we create copy of eval_ctx. */
- EvaluationContext eval_ctx = draw_ctx->eval_ctx;
- eval_ctx.ctime = time;
/* Past matrix */
/* FIXME : This is a temporal solution that does not take care of parent animations */
/* Recalc Anim manualy */
BKE_animsys_evaluate_animdata(scene, &cam_cpy.id, cam_cpy.adt, time, ADT_RECALC_ALL);
BKE_animsys_evaluate_animdata(scene, &camdata_cpy.id, camdata_cpy.adt, time, ADT_RECALC_ALL);
- BKE_object_where_is_calc_time(&eval_ctx, scene, &cam_cpy, time);
+ BKE_object_where_is_calc_time(draw_ctx->depsgraph, scene, &cam_cpy, time);
/* Compute winmat */
CameraParams params;
diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h
index 66ca8971a46..27f2d891cc0 100644
--- a/source/blender/draw/intern/DRW_render.h
+++ b/source/blender/draw/intern/DRW_render.h
@@ -187,6 +187,7 @@ typedef enum {
DRW_TEX_R_8,
DRW_TEX_R_16,
DRW_TEX_R_16I,
+ DRW_TEX_R_16U,
DRW_TEX_R_32,
DRW_TEX_DEPTH_16,
DRW_TEX_DEPTH_24,
@@ -506,7 +507,6 @@ typedef struct DRWContextState {
struct RenderEngineType *engine_type;
- EvaluationContext eval_ctx;
struct Depsgraph *depsgraph;
eObjectMode object_mode;
diff --git a/source/blender/draw/intern/draw_armature.c b/source/blender/draw/intern/draw_armature.c
index c14fe70e0c3..fe87e7f17fd 100644
--- a/source/blender/draw/intern/draw_armature.c
+++ b/source/blender/draw/intern/draw_armature.c
@@ -1228,7 +1228,7 @@ static void draw_armature_edit(Object *ob)
const bool show_text = DRW_state_show_text();
- for (eBone = arm->edbo->first, index = 0; eBone; eBone = eBone->next, index++) {
+ for (eBone = arm->edbo->first, index = ob->select_color; eBone; eBone = eBone->next, index += 0x10000) {
if (eBone->layer & arm->layer) {
if ((eBone->flag & BONE_HIDDEN_A) == 0) {
const int select_id = is_select ? index : (unsigned int)-1;
diff --git a/source/blender/draw/intern/draw_cache_impl_particles.c b/source/blender/draw/intern/draw_cache_impl_particles.c
index 0530d05c199..d7e8a6b71df 100644
--- a/source/blender/draw/intern/draw_cache_impl_particles.c
+++ b/source/blender/draw/intern/draw_cache_impl_particles.c
@@ -46,6 +46,8 @@
#include "GPU_batch.h"
+#include "DEG_depsgraph_query.h"
+
#include "draw_cache_impl.h" /* own include */
static void particle_batch_cache_clear(ParticleSystem *psys);
@@ -466,7 +468,7 @@ static void particle_batch_cache_ensure_pos(Object *object, ParticleSystem *psys
ParticleSimulationData sim = {NULL};
const DRWContextState *draw_ctx = DRW_context_state_get();
- sim.eval_ctx = &draw_ctx->eval_ctx;
+ sim.depsgraph = draw_ctx->depsgraph;
sim.scene = draw_ctx->scene;
sim.ob = object;
sim.psys = psys;
@@ -494,7 +496,7 @@ static void particle_batch_cache_ensure_pos(Object *object, ParticleSystem *psys
GWN_vertbuf_data_alloc(cache->pos, psys->totpart);
for (curr_point = 0, i = 0, pa = psys->particles; i < psys->totpart; i++, pa++) {
- state.time = draw_ctx->eval_ctx.ctime;
+ state.time = DEG_get_ctime(draw_ctx->depsgraph);
if (!psys_get_particle_state(&sim, curr_point, &state, 0)) {
continue;
}
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index b8ed341e2c5..7d4d27b7147 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -351,16 +351,6 @@ static void drw_viewport_cache_resize(void)
DRW_instance_data_list_resize(DST.idatalist);
}
-static void drw_state_eval_ctx_init(DRWManager *dst)
-{
- DRWContextState *draw_ctx = &dst->draw_ctx;
- DEG_evaluation_context_init_from_scene(
- &draw_ctx->eval_ctx,
- draw_ctx->scene,
- draw_ctx->view_layer,
- DST.options.is_scene_render ? DAG_EVAL_RENDER : DAG_EVAL_VIEWPORT);
-}
-
/* Not a viewport variable, we could split this out. */
static void drw_context_state_init(void)
{
@@ -389,8 +379,6 @@ static void drw_context_state_init(void)
else {
DST.draw_ctx.object_pose = NULL;
}
-
- drw_state_eval_ctx_init(&DST);
}
/* It also stores viewport variable to an immutable place: DST
@@ -1123,15 +1111,14 @@ void DRW_notify_id_update(const DRWUpdateContext *update_ctx, ID *id)
* for each relevant engine / mode engine. */
void DRW_draw_view(const bContext *C)
{
- EvaluationContext eval_ctx;
- CTX_data_eval_ctx(C, &eval_ctx);
+ Depsgraph *depsgraph = CTX_data_depsgraph(C);
RenderEngineType *engine_type = CTX_data_engine_type(C);
ARegion *ar = CTX_wm_region(C);
View3D *v3d = CTX_wm_view3d(C);
/* Reset before using it. */
drw_state_prepare_clean_for_draw(&DST);
- DRW_draw_render_loop_ex(eval_ctx.depsgraph, engine_type, ar, v3d, C);
+ DRW_draw_render_loop_ex(depsgraph, engine_type, ar, v3d, C);
}
/**
@@ -1555,7 +1542,14 @@ void DRW_draw_select_loop(
drw_engines_cache_init();
if (use_obedit) {
+#if 0
drw_engines_cache_populate(obact);
+#else
+ FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, obact->mode, ob_iter) {
+ drw_engines_cache_populate(ob_iter);
+ }
+ FOREACH_OBJECT_IN_MODE_END;
+#endif
}
else {
DEG_OBJECT_ITER_BEGIN(
diff --git a/source/blender/draw/intern/draw_manager.h b/source/blender/draw/intern/draw_manager.h
index dd7e84f67d4..4f322b11931 100644
--- a/source/blender/draw/intern/draw_manager.h
+++ b/source/blender/draw/intern/draw_manager.h
@@ -222,6 +222,7 @@ struct DRWShadingGroup {
int normalworld;
int orcotexfac;
int eye;
+ int callid;
uint16_t matflag; /* Matrices needed, same as DRWCall.flag */
#ifndef NDEBUG
diff --git a/source/blender/draw/intern/draw_manager_data.c b/source/blender/draw/intern/draw_manager_data.c
index ae7854b436c..544129ea124 100644
--- a/source/blender/draw/intern/draw_manager_data.c
+++ b/source/blender/draw/intern/draw_manager_data.c
@@ -498,6 +498,7 @@ static void drw_shgroup_init(DRWShadingGroup *shgroup, GPUShader *shader)
shgroup->normalworld = GPU_shader_get_builtin_uniform(shader, GWN_UNIFORM_WORLDNORMAL);
shgroup->orcotexfac = GPU_shader_get_builtin_uniform(shader, GWN_UNIFORM_ORCO);
shgroup->eye = GPU_shader_get_builtin_uniform(shader, GWN_UNIFORM_EYE);
+ shgroup->callid = GPU_shader_get_builtin_uniform(shader, GWN_UNIFORM_CALLID);
shgroup->matflag = 0;
if (shgroup->modelinverse > -1)
diff --git a/source/blender/draw/intern/draw_manager_exec.c b/source/blender/draw/intern/draw_manager_exec.c
index 2a5a595c682..dcd976805fd 100644
--- a/source/blender/draw/intern/draw_manager_exec.c
+++ b/source/blender/draw/intern/draw_manager_exec.c
@@ -384,100 +384,53 @@ void DRW_state_clip_planes_reset(void)
/** \name Clipping (DRW_clipping)
* \{ */
-/* Extract the 8 corners (world space).
+/* Extract the 8 corners from a Projection Matrix.
* Although less accurate, this solution can be simplified as follows:
* BKE_boundbox_init_from_minmax(&bbox, (const float[3]){-1.0f, -1.0f, -1.0f}, (const float[3]){1.0f, 1.0f, 1.0f});
- * for (int i = 0; i < 8; i++) {mul_project_m4_v3(viewprojinv, bbox.vec[i]);}
+ * for (int i = 0; i < 8; i++) {mul_project_m4_v3(projinv, bbox.vec[i]);}
*/
-static void draw_frustum_boundbox_calc(
- const float (*projmat)[4], const float (*viewinv)[4], BoundBox *r_bbox)
+static void draw_frustum_boundbox_calc(const float(*projmat)[4], BoundBox *r_bbox)
{
- float screenvecs[3][3], loc[3], near, far, w_half, h_half;
+ float near, far, left, right, bottom, top;
bool is_persp = projmat[3][3] == 0.0f;
- copy_m3_m4(screenvecs, viewinv);
- copy_v3_v3(loc, viewinv[3]);
- /* get the values of the minimum and maximum clipping planes distances
- * and half the width and height of the nearplane rectangle. */
if (is_persp) {
- near = projmat[3][2] / (projmat[2][2] - 1.0f);
- far = projmat[3][2] / (projmat[2][2] + 1.0f);
- w_half = near / projmat[0][0];
- h_half = near / projmat[1][1];
+ near = projmat[3][2] / (projmat[2][2] - 1.0f);
+ far = projmat[3][2] / (projmat[2][2] + 1.0f);
+ left = near * (projmat[2][0] - 1.0f) / projmat[0][0];
+ right = near * (projmat[2][0] + 1.0f) / projmat[0][0];
+ bottom = near * (projmat[2][1] - 1.0f) / projmat[1][1];
+ top = near * (projmat[2][1] + 1.0f) / projmat[1][1];
}
else {
- near = (projmat[3][2] + 1.0f) / projmat[2][2];
- far = (projmat[3][2] - 1.0f) / projmat[2][2];
- w_half = 1.0f / projmat[0][0];
- h_half = 1.0f / projmat[1][1];
+ near = ( projmat[3][2] + 1.0f) / projmat[2][2];
+ far = ( projmat[3][2] - 1.0f) / projmat[2][2];
+ left = (-projmat[3][0] - 1.0f) / projmat[0][0];
+ right = (-projmat[3][0] + 1.0f) / projmat[0][0];
+ bottom = (-projmat[3][1] - 1.0f) / projmat[1][1];
+ top = (-projmat[3][1] + 1.0f) / projmat[1][1];
}
- /* With vectors aligned to the screen, reconstruct
- * the near plane from the dimensions obtained earlier. */
- float mid[3], hor[3], ver[3];
- mul_v3_v3fl(hor, screenvecs[0], w_half);
- mul_v3_v3fl(ver, screenvecs[1], h_half);
- madd_v3_v3v3fl(mid, loc, screenvecs[2], -near);
-
- /* The case below is for non-symmetric frustum. */
- if (is_persp) {
- madd_v3_v3fl(mid, hor, projmat[2][0]);
- madd_v3_v3fl(mid, ver, projmat[2][1]);
- }
- else {
- madd_v3_v3fl(mid, hor, -projmat[3][0]);
- madd_v3_v3fl(mid, ver, -projmat[3][1]);
- }
-
- r_bbox->vec[0][0] = mid[0] - ver[0] - hor[0];
- r_bbox->vec[0][1] = mid[1] - ver[1] - hor[1];
- r_bbox->vec[0][2] = mid[2] - ver[2] - hor[2];
-
- r_bbox->vec[3][0] = mid[0] + ver[0] - hor[0];
- r_bbox->vec[3][1] = mid[1] + ver[1] - hor[1];
- r_bbox->vec[3][2] = mid[2] + ver[2] - hor[2];
-
- r_bbox->vec[7][0] = mid[0] + ver[0] + hor[0];
- r_bbox->vec[7][1] = mid[1] + ver[1] + hor[1];
- r_bbox->vec[7][2] = mid[2] + ver[2] + hor[2];
-
- r_bbox->vec[4][0] = mid[0] - ver[0] + hor[0];
- r_bbox->vec[4][1] = mid[1] - ver[1] + hor[1];
- r_bbox->vec[4][2] = mid[2] - ver[2] + hor[2];
+ r_bbox->vec[0][2] = r_bbox->vec[3][2] = r_bbox->vec[7][2] = r_bbox->vec[4][2] = -near;
+ r_bbox->vec[0][0] = r_bbox->vec[3][0] = left;
+ r_bbox->vec[4][0] = r_bbox->vec[7][0] = right;
+ r_bbox->vec[0][1] = r_bbox->vec[4][1] = bottom;
+ r_bbox->vec[7][1] = r_bbox->vec[3][1] = top;
/* Get the coordinates of the far plane. */
if (is_persp) {
float sca_far = far / near;
- mid[0] = mid[0] + (mid[0] - loc[0]) * sca_far;
- mid[1] = mid[1] + (mid[1] - loc[1]) * sca_far;
- mid[2] = mid[2] + (mid[2] - loc[2]) * sca_far;
-
- mul_v3_fl(hor, sca_far);
- mul_v3_fl(ver, sca_far);
+ left *= sca_far;
+ bottom *= sca_far;
+ right *= sca_far;
+ top *= sca_far;
}
- else {
- madd_v3_v3v3fl(mid, loc, screenvecs[2], -far);
- /* Non-symmetric frustum. */
- madd_v3_v3fl(mid, hor, -projmat[3][0]);
- madd_v3_v3fl(mid, ver, -projmat[3][1]);
- }
-
- r_bbox->vec[1][0] = mid[0] - ver[0] - hor[0];
- r_bbox->vec[1][1] = mid[1] - ver[1] - hor[1];
- r_bbox->vec[1][2] = mid[2] - ver[2] - hor[2];
-
- r_bbox->vec[2][0] = mid[0] + ver[0] - hor[0];
- r_bbox->vec[2][1] = mid[1] + ver[1] - hor[1];
- r_bbox->vec[2][2] = mid[2] + ver[2] - hor[2];
-
- r_bbox->vec[6][0] = mid[0] + ver[0] + hor[0];
- r_bbox->vec[6][1] = mid[1] + ver[1] + hor[1];
- r_bbox->vec[6][2] = mid[2] + ver[2] + hor[2];
-
- r_bbox->vec[5][0] = mid[0] - ver[0] + hor[0];
- r_bbox->vec[5][1] = mid[1] - ver[1] + hor[1];
- r_bbox->vec[5][2] = mid[2] - ver[2] + hor[2];
+ r_bbox->vec[1][2] = r_bbox->vec[2][2] = r_bbox->vec[6][2] = r_bbox->vec[5][2] = -far;
+ r_bbox->vec[1][0] = r_bbox->vec[2][0] = left;
+ r_bbox->vec[6][0] = r_bbox->vec[5][0] = right;
+ r_bbox->vec[1][1] = r_bbox->vec[5][1] = bottom;
+ r_bbox->vec[2][1] = r_bbox->vec[6][1] = top;
}
static void draw_clipping_setup_from_view(void)
@@ -495,11 +448,15 @@ static void draw_clipping_setup_from_view(void)
#if 0 /* It has accuracy problems. */
BKE_boundbox_init_from_minmax(&bbox, (const float[3]){-1.0f, -1.0f, -1.0f}, (const float[3]){1.0f, 1.0f, 1.0f});
for (int i = 0; i < 8; i++) {
- mul_project_m4_v3(DST.view_data.matstate.mat[DRW_MAT_PERSINV], bbox.vec[i]);
+ mul_project_m4_v3(projinv, bbox.vec[i]);
}
#else
- draw_frustum_boundbox_calc(projmat, viewinv, &bbox);
+ draw_frustum_boundbox_calc(projmat, &bbox);
#endif
+ /* Transform into world space. */
+ for (int i = 0; i < 8; i++) {
+ mul_m4_v3(viewinv, bbox.vec[i]);
+ }
/* Compute clip planes using the world space frustum corners. */
for (int p = 0; p < 6; p++) {
@@ -527,9 +484,6 @@ static void draw_clipping_setup_from_view(void)
float *nearpoint = bbox.vec[0];
float *farpoint = bbox.vec[6];
- mul_project_m4_v3(projinv, nearpoint);
- mul_project_m4_v3(projinv, farpoint);
-
/* just use median point */
mid_v3_v3v3(bsphere->center, farpoint, nearpoint);
bsphere->radius = len_v3v3(bsphere->center, farpoint);
@@ -553,7 +507,6 @@ static void draw_clipping_setup_from_view(void)
float h_sq = len_squared_v3v3(mid_min, mid_max);
float fac = (4 * h_sq + b_sq - a_sq) / (8 * h_sq);
- BLI_assert(fac >= 0.0f);
/* The goal is to get the smallest sphere,
* not the sphere that passes through each corner */
@@ -1010,7 +963,7 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state)
# define GPU_SELECT_LOAD_IF_PICKSEL_LIST_END(start, count)
# define GPU_SELECT_LOAD_IF_PICKSEL_LIST(_shgroup, _start, _count) \
_start = 0; \
- _count = _shgroup->interface.instance_count;
+ _count = _shgroup->instance_count;
#endif
@@ -1052,6 +1005,7 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state)
}
else {
bool prev_neg_scale = false;
+ int callid = 0;
for (DRWCall *call = shgroup->calls.first; call; call = call->next) {
/* OPTI/IDEA(clem): Do this preparation in another thread. */
@@ -1060,6 +1014,12 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state)
if ((call->state->flag & DRW_CALL_CULLED) != 0)
continue;
+ /* XXX small exception/optimisation for outline rendering. */
+ if (shgroup->callid != -1) {
+ GPU_shader_uniform_vector_int(shgroup->shader, shgroup->callid, 1, 1, &callid);
+ callid += 1;
+ }
+
/* Negative scale objects */
bool neg_scale = call->state->flag & DRW_CALL_NEGSCALE;
if (neg_scale != prev_neg_scale) {
diff --git a/source/blender/draw/intern/draw_manager_texture.c b/source/blender/draw/intern/draw_manager_texture.c
index 65856a6bf5c..f083e399ac2 100644
--- a/source/blender/draw/intern/draw_manager_texture.c
+++ b/source/blender/draw/intern/draw_manager_texture.c
@@ -36,6 +36,7 @@ void drw_texture_get_format(
* Generally they are multiple of 16bit. */
case DRW_TEX_R_16:
case DRW_TEX_R_16I:
+ case DRW_TEX_R_16U:
case DRW_TEX_R_32:
case DRW_TEX_RG_8:
case DRW_TEX_RG_16:
@@ -72,6 +73,7 @@ void drw_texture_get_format(
case DRW_TEX_R_8: *r_data_type = GPU_R8; break;
case DRW_TEX_R_16: *r_data_type = GPU_R16F; break;
case DRW_TEX_R_16I: *r_data_type = GPU_R16I; break;
+ case DRW_TEX_R_16U: *r_data_type = GPU_R16UI; break;
case DRW_TEX_R_32: *r_data_type = GPU_R32F; break;
#if 0
case DRW_TEX_RGB_8: *r_data_type = GPU_RGB8; break;
diff --git a/source/blender/draw/modes/edit_curve_mode.c b/source/blender/draw/modes/edit_curve_mode.c
index 73a4fb1e9e6..b33ebd8ba60 100644
--- a/source/blender/draw/modes/edit_curve_mode.c
+++ b/source/blender/draw/modes/edit_curve_mode.c
@@ -28,6 +28,8 @@
#include "DNA_curve_types.h"
+#include "BKE_object.h"
+
/* If builtin shaders are needed */
#include "GPU_shader.h"
#include "GPU_batch.h"
@@ -233,7 +235,12 @@ static void EDIT_CURVE_cache_populate(void *vedata, Object *ob)
UNUSED_VARS(psl, stl);
if (ob->type == OB_CURVE) {
- if (ob == draw_ctx->object_edit) {
+#if 0
+ if (ob == draw_ctx->object_edit)
+#else
+ if ((ob == draw_ctx->object_edit) || BKE_object_is_in_editmode_and_selected(ob))
+#endif
+ {
Curve *cu = ob->data;
/* Get geometry cache */
struct Gwn_Batch *geom;
diff --git a/source/blender/draw/modes/edit_lattice_mode.c b/source/blender/draw/modes/edit_lattice_mode.c
index 0268f4eb453..e8628711ffd 100644
--- a/source/blender/draw/modes/edit_lattice_mode.c
+++ b/source/blender/draw/modes/edit_lattice_mode.c
@@ -26,6 +26,8 @@
#include "DRW_engine.h"
#include "DRW_render.h"
+#include "BKE_object.h"
+
/* If builtin shaders are needed */
#include "GPU_shader.h"
@@ -192,7 +194,7 @@ static void EDIT_LATTICE_cache_populate(void *vedata, Object *ob)
UNUSED_VARS(psl);
if (ob->type == OB_LATTICE) {
- if (ob == draw_ctx->object_edit) {
+ if ((ob == draw_ctx->object_edit) || BKE_object_is_in_editmode_and_selected(ob)) {
/* Get geometry cache */
struct Gwn_Batch *geom;
diff --git a/source/blender/draw/modes/edit_mesh_mode.c b/source/blender/draw/modes/edit_mesh_mode.c
index 4bd69941809..c465fa38f04 100644
--- a/source/blender/draw/modes/edit_mesh_mode.c
+++ b/source/blender/draw/modes/edit_mesh_mode.c
@@ -37,6 +37,8 @@
#include "edit_mesh_mode_intern.h" /* own include */
+#include "BKE_object.h"
+
extern struct GPUUniformBuffer *globals_ubo; /* draw_common.c */
extern struct GlobalsUboStorage ts; /* draw_common.c */
@@ -448,7 +450,7 @@ static void EDIT_MESH_cache_populate(void *vedata, Object *ob)
struct Gwn_Batch *geom;
if (ob->type == OB_MESH) {
- if (ob == draw_ctx->object_edit) {
+ if ((ob == draw_ctx->object_edit) || BKE_object_is_in_editmode_and_selected(ob)) {
const Mesh *me = ob->data;
IDProperty *ces_mode_ed = BKE_layer_collection_engine_evaluated_get(ob, COLLECTION_MODE_EDIT, "");
bool do_occlude_wire = BKE_collection_engine_property_value_get_bool(ces_mode_ed, "show_occlude_wire");
diff --git a/source/blender/draw/modes/edit_metaball_mode.c b/source/blender/draw/modes/edit_metaball_mode.c
index bcabeef5bc3..f7b7113a4d6 100644
--- a/source/blender/draw/modes/edit_metaball_mode.c
+++ b/source/blender/draw/modes/edit_metaball_mode.c
@@ -28,6 +28,7 @@
#include "DNA_meta_types.h"
+#include "BKE_object.h"
#include "BKE_mball.h"
/* If builtin shaders are needed */
@@ -171,7 +172,7 @@ static void EDIT_METABALL_cache_populate(void *vedata, Object *ob)
const DRWContextState *draw_ctx = DRW_context_state_get();
DRWShadingGroup *group = stl->g_data->group;
- if (ob == draw_ctx->object_edit) {
+ if ((ob == draw_ctx->object_edit) || BKE_object_is_in_editmode_and_selected(ob)) {
MetaBall *mb = ob->data;
const bool is_select = DRW_state_is_select();
diff --git a/source/blender/draw/modes/object_mode.c b/source/blender/draw/modes/object_mode.c
index 939507a4f21..0d9e46d1268 100644
--- a/source/blender/draw/modes/object_mode.c
+++ b/source/blender/draw/modes/object_mode.c
@@ -40,6 +40,8 @@
#include "BIF_gl.h"
+#include "BLI_string_utils.h"
+
#include "BKE_anim.h"
#include "BKE_camera.h"
#include "BKE_curve.h"
@@ -69,6 +71,7 @@ extern struct GPUUniformBuffer *globals_ubo; /* draw_common.c */
extern struct GPUTexture *globals_ramp; /* draw_common.c */
extern GlobalsUboStorage ts;
+extern char datatoc_object_outline_prepass_frag_glsl[];
extern char datatoc_object_outline_resolve_frag_glsl[];
extern char datatoc_object_outline_detect_frag_glsl[];
extern char datatoc_object_outline_expand_frag_glsl[];
@@ -223,6 +226,13 @@ typedef struct OBJECT_PrivateData {
DRWShadingGroup *points_select;
DRWShadingGroup *points_select_group;
DRWShadingGroup *points_transform;
+
+ /* Outlines id offset */
+ int id_ofs_active;
+ int id_ofs_active_group;
+ int id_ofs_select;
+ int id_ofs_select_group;
+ int id_ofs_transform;
} OBJECT_PrivateData; /* Transient data */
static struct {
@@ -232,6 +242,7 @@ static struct {
struct Gwn_VertFormat *empty_image_wire_format;
/* fullscreen shaders */
+ GPUShader *outline_prepass_sh;
GPUShader *outline_resolve_sh;
GPUShader *outline_resolve_aa_sh;
GPUShader *outline_detect_sh;
@@ -259,6 +270,7 @@ static struct {
bool draw_grid;
/* Temp buffer textures */
struct GPUTexture *outlines_depth_tx;
+ struct GPUTexture *outlines_id_tx;
struct GPUTexture *outlines_color_tx;
struct GPUTexture *outlines_blur_tx;
} e_data = {NULL}; /* Engine data */
@@ -288,14 +300,20 @@ static void OBJECT_engine_init(void *vedata)
if (DRW_state_is_fbo()) {
e_data.outlines_depth_tx = DRW_texture_pool_query_2D(size[0], size[1], DRW_TEX_DEPTH_24,
&draw_engine_object_type);
- e_data.outlines_color_tx = DRW_texture_pool_query_2D(size[0], size[1], DRW_TEX_RGBA_8,
- &draw_engine_object_type);
+ /* XXX TODO DRW_TEX_R_16U can overflow, it would cause no harm
+ * (only bad colored or missing outlines) but we should
+ * use 32bits only if the scene have that many objects */
+ e_data.outlines_id_tx = DRW_texture_pool_query_2D(size[0], size[1], DRW_TEX_R_16U,
+ &draw_engine_object_type);
GPU_framebuffer_ensure_config(&fbl->outlines_fb, {
GPU_ATTACHMENT_TEXTURE(e_data.outlines_depth_tx),
- GPU_ATTACHMENT_TEXTURE(e_data.outlines_color_tx)
+ GPU_ATTACHMENT_TEXTURE(e_data.outlines_id_tx)
});
+ e_data.outlines_color_tx = DRW_texture_pool_query_2D(size[0], size[1], DRW_TEX_RGBA_8,
+ &draw_engine_object_type);
+
GPU_framebuffer_ensure_config(&fbl->expand_fb, {
GPU_ATTACHMENT_NONE,
GPU_ATTACHMENT_TEXTURE(e_data.outlines_color_tx)
@@ -310,66 +328,58 @@ static void OBJECT_engine_init(void *vedata)
});
}
+ /* Shaders */
if (!e_data.outline_resolve_sh) {
+ /* Outline */
+ e_data.outline_prepass_sh = DRW_shader_create_3D(datatoc_object_outline_prepass_frag_glsl, NULL);
+
e_data.outline_resolve_sh = DRW_shader_create_fullscreen(datatoc_object_outline_resolve_frag_glsl, NULL);
- }
- if (!e_data.outline_resolve_aa_sh) {
e_data.outline_resolve_aa_sh = DRW_shader_create_with_lib(
datatoc_common_fullscreen_vert_glsl, NULL,
datatoc_object_outline_resolve_frag_glsl,
datatoc_common_fxaa_lib_glsl,
"#define FXAA_ALPHA\n"
"#define USE_FXAA\n");
- }
- if (!e_data.outline_detect_sh) {
- e_data.outline_detect_sh = DRW_shader_create_fullscreen(datatoc_object_outline_detect_frag_glsl, NULL);
- }
+ e_data.outline_detect_sh = DRW_shader_create_with_lib(
+ datatoc_common_fullscreen_vert_glsl, NULL,
+ datatoc_object_outline_detect_frag_glsl,
+ datatoc_common_globals_lib_glsl,
+ NULL);
- if (!e_data.outline_fade_sh) {
e_data.outline_fade_sh = DRW_shader_create_fullscreen(datatoc_object_outline_expand_frag_glsl, NULL);
- }
- if (!e_data.object_empty_image_sh) {
+ /* Empty images */
e_data.object_empty_image_sh = DRW_shader_create_with_lib(
datatoc_object_empty_image_vert_glsl, NULL,
datatoc_object_empty_image_frag_glsl,
datatoc_common_globals_lib_glsl, NULL);
- }
- if (!e_data.object_empty_image_wire_sh) {
e_data.object_empty_image_wire_sh = DRW_shader_create_with_lib(
datatoc_object_empty_image_vert_glsl, NULL,
datatoc_object_empty_image_frag_glsl,
datatoc_common_globals_lib_glsl,
"#define USE_WIRE\n");
- }
- if (!e_data.grid_sh) {
+ /* Grid */
e_data.grid_sh = DRW_shader_create_with_lib(
datatoc_object_grid_vert_glsl, NULL,
datatoc_object_grid_frag_glsl,
datatoc_common_globals_lib_glsl, NULL);
- }
- if (!e_data.part_prim_sh) {
+ /* Particles */
e_data.part_prim_sh = DRW_shader_create(
datatoc_object_particle_prim_vert_glsl, NULL, datatoc_gpu_shader_flat_color_frag_glsl, NULL);
- }
- if (!e_data.part_axis_sh) {
e_data.part_axis_sh = DRW_shader_create(
datatoc_object_particle_prim_vert_glsl, NULL, datatoc_gpu_shader_flat_color_frag_glsl,
"#define USE_AXIS\n");
- }
- if (!e_data.part_dot_sh) {
e_data.part_dot_sh = DRW_shader_create(
datatoc_object_particle_dot_vert_glsl, NULL, datatoc_object_particle_dot_frag_glsl, NULL);
- }
- if (!e_data.lightprobe_grid_sh) {
+ /* Lightprobes */
e_data.lightprobe_grid_sh = DRW_shader_create(
datatoc_object_lightprobe_grid_vert_glsl, NULL, datatoc_gpu_shader_uniform_color_frag_glsl, NULL);
}
@@ -558,6 +568,7 @@ static void OBJECT_engine_free(void)
MEM_SAFE_FREE(e_data.particle_format);
MEM_SAFE_FREE(e_data.empty_image_format);
MEM_SAFE_FREE(e_data.empty_image_wire_format);
+ DRW_SHADER_FREE_SAFE(e_data.outline_prepass_sh);
DRW_SHADER_FREE_SAFE(e_data.outline_resolve_sh);
DRW_SHADER_FREE_SAFE(e_data.outline_resolve_aa_sh);
DRW_SHADER_FREE_SAFE(e_data.outline_detect_sh);
@@ -571,10 +582,10 @@ static void OBJECT_engine_free(void)
DRW_SHADER_FREE_SAFE(e_data.lightprobe_grid_sh);
}
-static DRWShadingGroup *shgroup_outline(DRWPass *pass, const float col[4], GPUShader *sh)
+static DRWShadingGroup *shgroup_outline(DRWPass *pass, const int *ofs, GPUShader *sh)
{
DRWShadingGroup *grp = DRW_shgroup_create(sh, pass);
- DRW_shgroup_uniform_vec4(grp, "color", col, 1);
+ DRW_shgroup_uniform_int(grp, "baseId", ofs, 1);
return grp;
}
@@ -602,12 +613,19 @@ static DRWShadingGroup *shgroup_theme_id_to_outline_or(
{
switch (theme_id) {
case TH_ACTIVE:
+ stl->g_data->id_ofs_active++;
return stl->g_data->outlines_active;
case TH_SELECT:
+ stl->g_data->id_ofs_select++;
return stl->g_data->outlines_select;
- case TH_GROUP_ACTIVE:
+ case TH_GROUP:
+ stl->g_data->id_ofs_select_group++;
return stl->g_data->outlines_select_group;
+ case TH_GROUP_ACTIVE:
+ stl->g_data->id_ofs_active_group++;
+ return stl->g_data->outlines_active_group;
case TH_TRANSFORM:
+ stl->g_data->id_ofs_transform++;
return stl->g_data->outlines_transform;
default:
return fallback;
@@ -622,8 +640,10 @@ static DRWShadingGroup *shgroup_theme_id_to_wire_or(
return stl->g_data->wire_active;
case TH_SELECT:
return stl->g_data->wire_select;
- case TH_GROUP_ACTIVE:
+ case TH_GROUP:
return stl->g_data->wire_select_group;
+ case TH_GROUP_ACTIVE:
+ return stl->g_data->wire_active_group;
case TH_TRANSFORM:
return stl->g_data->wire_transform;
default:
@@ -639,8 +659,10 @@ static DRWShadingGroup *shgroup_theme_id_to_point_or(
return stl->g_data->points_active;
case TH_SELECT:
return stl->g_data->points_select;
- case TH_GROUP_ACTIVE:
+ case TH_GROUP:
return stl->g_data->points_select_group;
+ case TH_GROUP_ACTIVE:
+ return stl->g_data->points_active_group;
case TH_TRANSFORM:
return stl->g_data->points_transform;
default:
@@ -786,18 +808,24 @@ static void OBJECT_cache_init(void *vedata)
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_WIRE;
psl->outlines = DRW_pass_create("Outlines Depth Pass", state);
- GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR);
+ GPUShader *sh = e_data.outline_prepass_sh;
/* Select */
- stl->g_data->outlines_select = shgroup_outline(psl->outlines, ts.colorSelect, sh);
- stl->g_data->outlines_select_group = shgroup_outline(psl->outlines, ts.colorGroupActive, sh);
+ stl->g_data->outlines_select = shgroup_outline(psl->outlines, &stl->g_data->id_ofs_select, sh);
+ stl->g_data->outlines_select_group = shgroup_outline(psl->outlines, &stl->g_data->id_ofs_select_group, sh);
/* Transform */
- stl->g_data->outlines_transform = shgroup_outline(psl->outlines, ts.colorTransform, sh);
+ stl->g_data->outlines_transform = shgroup_outline(psl->outlines, &stl->g_data->id_ofs_transform, sh);
/* Active */
- stl->g_data->outlines_active = shgroup_outline(psl->outlines, ts.colorActive, sh);
- stl->g_data->outlines_active_group = shgroup_outline(psl->outlines, ts.colorGroupActive, sh);
+ stl->g_data->outlines_active = shgroup_outline(psl->outlines, &stl->g_data->id_ofs_active, sh);
+ stl->g_data->outlines_active_group = shgroup_outline(psl->outlines, &stl->g_data->id_ofs_active_group, sh);
+
+ stl->g_data->id_ofs_select = 0;
+ stl->g_data->id_ofs_select_group = 0;
+ stl->g_data->id_ofs_active = 0;
+ stl->g_data->id_ofs_active_group = 0;
+ stl->g_data->id_ofs_transform = 0;
}
{
@@ -822,10 +850,12 @@ static void OBJECT_cache_init(void *vedata)
psl->outlines_search = DRW_pass_create("Outlines Detect Pass", state);
DRWShadingGroup *grp = DRW_shgroup_create(e_data.outline_detect_sh, psl->outlines_search);
- DRW_shgroup_uniform_texture_ref(grp, "outlineColor", &e_data.outlines_color_tx);
+ DRW_shgroup_uniform_texture_ref(grp, "outlineId", &e_data.outlines_id_tx);
DRW_shgroup_uniform_texture_ref(grp, "outlineDepth", &e_data.outlines_depth_tx);
DRW_shgroup_uniform_texture_ref(grp, "sceneDepth", &dtxl->depth);
+ DRW_shgroup_uniform_block(grp, "globalsBlock", globals_ubo);
DRW_shgroup_uniform_float(grp, "alphaOcclu", &alphaOcclu, 1);
+ DRW_shgroup_uniform_int(grp, "idOffsets", &stl->g_data->id_ofs_active, 5);
DRW_shgroup_call_add(grp, quad, NULL);
psl->outlines_expand = DRW_pass_create("Outlines Expand Pass", state);
@@ -2038,6 +2068,7 @@ static void OBJECT_draw_scene(void *vedata)
OBJECT_PassList *psl = ((OBJECT_Data *)vedata)->psl;
OBJECT_StorageList *stl = ((OBJECT_Data *)vedata)->stl;
OBJECT_FramebufferList *fbl = ((OBJECT_Data *)vedata)->fbl;
+ OBJECT_PrivateData *g_data = stl->g_data;
DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
@@ -2045,7 +2076,18 @@ static void OBJECT_draw_scene(void *vedata)
if (DRW_state_is_fbo()) {
DRW_stats_group_start("Outlines");
-
+
+ int id_ct_select = g_data->id_ofs_select;
+ int id_ct_select_group = g_data->id_ofs_select_group;
+ int id_ct_active = g_data->id_ofs_active;
+ int id_ct_active_group = g_data->id_ofs_active_group;
+
+ g_data->id_ofs_active = 1;
+ g_data->id_ofs_active_group = g_data->id_ofs_active + id_ct_active + 1;
+ g_data->id_ofs_select = g_data->id_ofs_active_group + id_ct_active_group + 1;
+ g_data->id_ofs_select_group = g_data->id_ofs_select + id_ct_select + 1;
+ g_data->id_ofs_transform = g_data->id_ofs_select_group + id_ct_select_group + 1;
+
/* Render filled polygon on a separate framebuffer */
GPU_framebuffer_bind(fbl->outlines_fb);
GPU_framebuffer_clear_color_depth(fbl->outlines_fb, clearcol, 1.0f);
diff --git a/source/blender/draw/modes/pose_mode.c b/source/blender/draw/modes/pose_mode.c
index 749c3e71368..1d3d31ab54d 100644
--- a/source/blender/draw/modes/pose_mode.c
+++ b/source/blender/draw/modes/pose_mode.c
@@ -139,7 +139,9 @@ bool DRW_pose_mode_armature(Object *ob, Object *active_ob)
const DRWContextState *draw_ctx = DRW_context_state_get();
/* Pode armature is handled by pose mode engine. */
- if ((ob == active_ob) && ((draw_ctx->object_mode & OB_MODE_POSE) != 0)) {
+ if (((ob == active_ob) || (ob->base_flag & BASE_SELECTED)) &&
+ ((draw_ctx->object_mode & OB_MODE_POSE) != 0))
+ {
return true;
}
diff --git a/source/blender/draw/modes/sculpt_mode.c b/source/blender/draw/modes/sculpt_mode.c
index 65f4653591f..4fb4464df06 100644
--- a/source/blender/draw/modes/sculpt_mode.c
+++ b/source/blender/draw/modes/sculpt_mode.c
@@ -202,7 +202,7 @@ static void SCULPT_cache_populate(void *vedata, Object *ob)
* but this avoids waiting on first stroke) */
Scene *scene = draw_ctx->scene;
- BKE_sculpt_update_mesh_elements(&draw_ctx->eval_ctx, scene, scene->toolsettings->sculpt, ob, false, false);
+ BKE_sculpt_update_mesh_elements(draw_ctx->depsgraph, scene, scene->toolsettings->sculpt, ob, false, false);
}
PBVH *pbvh = ob->sculpt->pbvh;
diff --git a/source/blender/draw/modes/shaders/object_outline_detect_frag.glsl b/source/blender/draw/modes/shaders/object_outline_detect_frag.glsl
index dc0ea938436..6b0f66d7c94 100644
--- a/source/blender/draw/modes/shaders/object_outline_detect_frag.glsl
+++ b/source/blender/draw/modes/shaders/object_outline_detect_frag.glsl
@@ -3,77 +3,67 @@ in vec4 uvcoordsvar;
out vec4 FragColor;
-uniform sampler2D outlineColor;
+uniform usampler2D outlineId;
uniform sampler2D outlineDepth;
uniform sampler2D sceneDepth;
+uniform int idOffsets[5];
+
uniform float alphaOcclu;
uniform vec2 viewportSize;
-void search_outline(ivec2 uv, vec4 ref_col, inout bool ref_occlu, inout bool outline)
+vec4 convert_id_to_color(int id)
{
- if (!outline) {
- vec4 color = texelFetch(outlineColor, uv, 0).rgba;
- if (color != ref_col) {
- outline = true;
- }
- else {
- float depth = texelFetch(outlineDepth, uv, 0).r;
- float scene_depth = texelFetch(sceneDepth, uv, 0).r;
- bool occlu = (depth > scene_depth);
-
- if (occlu != ref_occlu && !ref_occlu) {
- outline = true;
- }
- }
+ if (id == 0) {
+ return vec4(0.0);
+ }
+ if (id < idOffsets[1]) {
+ return colorActive;
+ }
+ else if (id < idOffsets[2]) {
+ return colorGroupActive;
+ }
+ else if (id < idOffsets[3]) {
+ return colorSelect;
+ }
+ else if (id < idOffsets[4]) {
+ return colorGroup;
+ }
+ else {
+ return colorTransform;
}
}
+const ivec2 ofs[4] = ivec2[4](
+ ivec2( 1, 0), ivec2( 0, 1),
+ ivec2(-1, 0), ivec2( 0, -1)
+);
+
void main()
{
- ivec2 uv = ivec2(gl_FragCoord.xy);
-
- vec4 color[4];
- /* Idea : Use a 16bit ID to identify the color
- * and store the colors in a UBO. And fetch all ids
- * for discontinuity check with one textureGather \o/ */
- vec4 ref_col = texelFetch(outlineColor, uv, 0).rgba;
- color[0] = texelFetchOffset(outlineColor, uv, 0, ivec2( 1, 0)).rgba;
- color[1] = texelFetchOffset(outlineColor, uv, 0, ivec2( 0, 1)).rgba;
- color[2] = texelFetchOffset(outlineColor, uv, 0, ivec2(-1, 0)).rgba;
- color[3] = texelFetchOffset(outlineColor, uv, 0, ivec2( 0, -1)).rgba;
-
- /* TODO GATHER */
- vec4 depths;
- float depth = texelFetch(outlineDepth, uv, 0).r;
- depths.x = texelFetchOffset(outlineDepth, uv, 0, ivec2( 1, 0)).r;
- depths.y = texelFetchOffset(outlineDepth, uv, 0, ivec2( 0, 1)).r;
- depths.z = texelFetchOffset(outlineDepth, uv, 0, ivec2(-1, 0)).r;
- depths.w = texelFetchOffset(outlineDepth, uv, 0, ivec2( 0, -1)).r;
-
- vec4 scene_depths;
- float scene_depth = texelFetch(sceneDepth, uv, 0).r;
- scene_depths.x = texelFetchOffset(sceneDepth, uv, 0, ivec2( 1, 0)).r;
- scene_depths.y = texelFetchOffset(sceneDepth, uv, 0, ivec2( 0, 1)).r;
- scene_depths.z = texelFetchOffset(sceneDepth, uv, 0, ivec2(-1, 0)).r;
- scene_depths.w = texelFetchOffset(sceneDepth, uv, 0, ivec2( 0, -1)).r;
+ ivec2 texel = ivec2(gl_FragCoord.xy);
+ vec2 uv = gl_FragCoord.xy / vec2(textureSize(outlineId, 0).xy);
- bool ref_occlu = (depth > scene_depth);
- bool outline = false;
-
-#if 1
- bvec4 occlu = (!ref_occlu) ? notEqual(greaterThan(depths, scene_depths), bvec4(ref_occlu)) : bvec4(false);
- outline = (!outline) ? (color[0] != ref_col) || occlu.x : true;
- outline = (!outline) ? (color[1] != ref_col) || occlu.y : true;
- outline = (!outline) ? (color[2] != ref_col) || occlu.z : true;
- outline = (!outline) ? (color[3] != ref_col) || occlu.w : true;
+ uvec4 id;
+ uint ref_id = texelFetch(outlineId, texel, 0).r;
+#if 0 /* commented out until being tested */
+ id = textureGatherOffsets(outlineId, uv, ofs);
#else
- search_outline(uv + ivec2( 1, 0), ref_col, ref_occlu, outline);
- search_outline(uv + ivec2( 0, 1), ref_col, ref_occlu, outline);
- search_outline(uv + ivec2(-1, 0), ref_col, ref_occlu, outline);
- search_outline(uv + ivec2( 0, -1), ref_col, ref_occlu, outline);
+ id.x = texelFetchOffset(outlineId, texel, 0, ofs[0]).r;
+ id.y = texelFetchOffset(outlineId, texel, 0, ofs[1]).r;
+ id.z = texelFetchOffset(outlineId, texel, 0, ofs[2]).r;
+ id.w = texelFetchOffset(outlineId, texel, 0, ofs[3]).r;
#endif
- FragColor = ref_col;
- FragColor.a *= (outline) ? (ref_occlu) ? alphaOcclu : 1.0 : 0.0;
+ float ref_depth = texelFetch(outlineDepth, texel, 0).r;
+ float scene_depth = texelFetch(sceneDepth, texel, 0).r;
+
+ /* Avoid bad cases of zfighting for occlusion only. */
+ const float epsilon = 3.0 / 8388608.0;
+ bool occluded = (ref_depth > scene_depth + epsilon);
+ bool outline = any(notEqual(id, uvec4(ref_id)));
+
+ FragColor = convert_id_to_color(int(ref_id));
+ FragColor.a *= (occluded) ? alphaOcclu : 1.0;
+ FragColor.a = (outline) ? FragColor.a : 0.0;
}
diff --git a/source/blender/draw/modes/shaders/object_outline_prepass_frag.glsl b/source/blender/draw/modes/shaders/object_outline_prepass_frag.glsl
new file mode 100644
index 00000000000..776adb787ad
--- /dev/null
+++ b/source/blender/draw/modes/shaders/object_outline_prepass_frag.glsl
@@ -0,0 +1,10 @@
+uniform int callId;
+uniform int baseId;
+
+/* using uint because 16bit uint can contain more ids than int. */
+out uint outId;
+
+void main()
+{
+ outId = uint(baseId + callId);
+}