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:
authorBrecht Van Lommel <brechtvanlommel@gmail.com>2019-05-02 17:05:23 +0300
committerBrecht Van Lommel <brechtvanlommel@gmail.com>2019-05-02 17:05:23 +0300
commit43e6bb85cee0802887eae9489a2bd73836daf41d (patch)
treeeaa106429af8341bf2123d7445fdab0af71b3dda /source/blender/draw
parent7daeb1f9aee284d958abe87622b43c70c21af967 (diff)
parentffaf91b5fc03f91e1fc90bd2f1d5dc5aa75656ff (diff)
Merge 'master' into 'collada'
Diffstat (limited to 'source/blender/draw')
-rw-r--r--source/blender/draw/CMakeLists.txt4
-rw-r--r--source/blender/draw/DRW_engine.h6
-rw-r--r--source/blender/draw/engines/basic/basic_engine.c4
-rw-r--r--source/blender/draw/engines/eevee/eevee_bloom.c37
-rw-r--r--source/blender/draw/engines/eevee/eevee_depth_of_field.c11
-rw-r--r--source/blender/draw/engines/eevee/eevee_effects.c67
-rw-r--r--source/blender/draw/engines/eevee/eevee_engine.c7
-rw-r--r--source/blender/draw/engines/eevee/eevee_lightcache.c97
-rw-r--r--source/blender/draw/engines/eevee/eevee_lightprobes.c3
-rw-r--r--source/blender/draw/engines/eevee/eevee_lights.c13
-rw-r--r--source/blender/draw/engines/eevee/eevee_lookdev.c154
-rw-r--r--source/blender/draw/engines/eevee/eevee_materials.c205
-rw-r--r--source/blender/draw/engines/eevee/eevee_motion_blur.c6
-rw-r--r--source/blender/draw/engines/eevee/eevee_private.h17
-rw-r--r--source/blender/draw/engines/eevee/eevee_screen_raytrace.c5
-rw-r--r--source/blender/draw/engines/eevee/eevee_temporal_sampling.c17
-rw-r--r--source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl3
-rw-r--r--source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl29
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_dof_frag.glsl9
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_temporal_aa.glsl7
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_velocity_resolve_frag.glsl3
-rw-r--r--source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl3
-rw-r--r--source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl11
-rw-r--r--source/blender/draw/engines/eevee/shaders/ltc_lib.glsl4
-rw-r--r--source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl4
-rw-r--r--source/blender/draw/engines/eevee/shaders/shadow_store_frag.glsl3
-rw-r--r--source/blender/draw/engines/external/external_engine.c118
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_cache_utils.c8
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c88
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_draw_utils.c156
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_engine.c3
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_engine.h4
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_render.c18
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_shader_fx.c9
-rw-r--r--source/blender/draw/engines/gpencil/shaders/gpencil_edit_point_geom.glsl14
-rw-r--r--source/blender/draw/engines/gpencil/shaders/gpencil_fill_frag.glsl5
-rw-r--r--source/blender/draw/engines/gpencil/shaders/gpencil_point_frag.glsl54
-rw-r--r--source/blender/draw/engines/gpencil/shaders/gpencil_point_geom.glsl2
-rw-r--r--source/blender/draw/engines/gpencil/shaders/gpencil_point_vert.glsl2
-rw-r--r--source/blender/draw/engines/gpencil/shaders/gpencil_stroke_frag.glsl28
-rw-r--r--source/blender/draw/engines/gpencil/shaders/gpencil_stroke_geom.glsl2
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_effect_dof_frag.glsl6
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl7
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_prepass_frag.glsl7
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_prepass_vert.glsl22
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl3
-rw-r--r--source/blender/draw/engines/workbench/workbench_deferred.c54
-rw-r--r--source/blender/draw/engines/workbench/workbench_effect_dof.c49
-rw-r--r--source/blender/draw/engines/workbench/workbench_forward.c53
-rw-r--r--source/blender/draw/engines/workbench/workbench_materials.c48
-rw-r--r--source/blender/draw/engines/workbench/workbench_private.h34
-rw-r--r--source/blender/draw/engines/workbench/workbench_studiolight.c12
-rw-r--r--source/blender/draw/intern/DRW_render.h2
-rw-r--r--source/blender/draw/intern/draw_anim_viz.c5
-rw-r--r--source/blender/draw/intern/draw_armature.c91
-rw-r--r--source/blender/draw/intern/draw_cache.c220
-rw-r--r--source/blender/draw/intern/draw_cache.h1
-rw-r--r--source/blender/draw/intern/draw_cache_impl.h23
-rw-r--r--source/blender/draw/intern/draw_cache_impl_curve.c8
-rw-r--r--source/blender/draw/intern/draw_cache_impl_mesh.c439
-rw-r--r--source/blender/draw/intern/draw_cache_impl_metaball.c2
-rw-r--r--source/blender/draw/intern/draw_cache_impl_particles.c15
-rw-r--r--source/blender/draw/intern/draw_common.c8
-rw-r--r--source/blender/draw/intern/draw_common.h1
-rw-r--r--source/blender/draw/intern/draw_hair.c3
-rw-r--r--source/blender/draw/intern/draw_instance_data.c10
-rw-r--r--source/blender/draw/intern/draw_manager.c216
-rw-r--r--source/blender/draw/intern/draw_manager.h21
-rw-r--r--source/blender/draw/intern/draw_manager_data.c48
-rw-r--r--source/blender/draw/intern/draw_manager_exec.c34
-rw-r--r--source/blender/draw/intern/draw_manager_shader.c9
-rw-r--r--source/blender/draw/intern/draw_view.c29
-rw-r--r--source/blender/draw/intern/draw_view.h2
-rw-r--r--source/blender/draw/modes/edit_armature_mode.c1
-rw-r--r--source/blender/draw/modes/edit_mesh_mode.c64
-rw-r--r--source/blender/draw/modes/edit_mesh_mode_text.c13
-rw-r--r--source/blender/draw/modes/edit_metaball_mode.c2
-rw-r--r--source/blender/draw/modes/object_mode.c47
-rw-r--r--source/blender/draw/modes/overlay_mode.c3
-rw-r--r--source/blender/draw/modes/paint_texture_mode.c2
-rw-r--r--source/blender/draw/modes/pose_mode.c16
-rw-r--r--source/blender/draw/modes/sculpt_mode.c12
-rw-r--r--source/blender/draw/modes/shaders/common_fxaa_lib.glsl8
-rw-r--r--source/blender/draw/modes/shaders/common_hair_lib.glsl4
-rw-r--r--source/blender/draw/modes/shaders/edit_mesh_overlay_common_lib.glsl36
-rw-r--r--source/blender/draw/modes/shaders/edit_mesh_overlay_frag.glsl12
-rw-r--r--source/blender/draw/modes/shaders/edit_mesh_overlay_geom.glsl31
-rw-r--r--source/blender/draw/modes/shaders/edit_mesh_overlay_mesh_analysis_frag.glsl14
-rw-r--r--source/blender/draw/modes/shaders/edit_mesh_overlay_mesh_analysis_vert.glsl23
-rw-r--r--source/blender/draw/modes/shaders/edit_mesh_overlay_vert.glsl12
-rw-r--r--source/blender/draw/modes/shaders/object_grid_frag.glsl4
-rw-r--r--source/blender/draw/modes/shaders/particle_strand_vert.glsl4
-rw-r--r--source/blender/draw/modes/shaders/sculpt_mask_vert.glsl3
93 files changed, 2054 insertions, 979 deletions
diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index 0d1752af4dc..abbf8a2b47b 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -39,9 +39,9 @@ set(INC
../render/intern/include
../windowmanager
+ ../../../intern/atomic
../../../intern/glew-mx
../../../intern/guardedalloc
- ../../../intern/atomic
)
set(INC_SYS
@@ -277,6 +277,8 @@ data_to_c_simple(modes/shaders/edit_mesh_overlay_geom.glsl SRC)
data_to_c_simple(modes/shaders/edit_mesh_overlay_mix_frag.glsl SRC)
data_to_c_simple(modes/shaders/edit_mesh_overlay_facefill_vert.glsl SRC)
data_to_c_simple(modes/shaders/edit_mesh_overlay_facefill_frag.glsl SRC)
+data_to_c_simple(modes/shaders/edit_mesh_overlay_mesh_analysis_frag.glsl SRC)
+data_to_c_simple(modes/shaders/edit_mesh_overlay_mesh_analysis_vert.glsl SRC)
data_to_c_simple(modes/shaders/edit_curve_overlay_handle_vert.glsl SRC)
data_to_c_simple(modes/shaders/edit_curve_overlay_handle_geom.glsl SRC)
data_to_c_simple(modes/shaders/edit_curve_overlay_loosevert_vert.glsl SRC)
diff --git a/source/blender/draw/DRW_engine.h b/source/blender/draw/DRW_engine.h
index 161e28db2d3..da1f5c7863a 100644
--- a/source/blender/draw/DRW_engine.h
+++ b/source/blender/draw/DRW_engine.h
@@ -132,6 +132,9 @@ void DRW_draw_depth_loop_gpencil(struct Depsgraph *depsgraph,
struct ARegion *ar,
struct View3D *v3d,
struct GPUViewport *viewport);
+void DRW_draw_depth_object(struct ARegion *ar,
+ struct GPUViewport *viewport,
+ struct Object *object);
void DRW_framebuffer_select_id_setup(struct ARegion *ar, const bool clear);
void DRW_framebuffer_select_id_release(struct ARegion *ar);
@@ -152,6 +155,9 @@ void DRW_opengl_context_destroy(void);
void DRW_opengl_context_enable(void);
void DRW_opengl_context_disable(void);
+/* For garbage collection */
+void DRW_cache_free_old_batches(struct Main *bmain);
+
/* Never use this. Only for closing blender. */
void DRW_opengl_context_enable_ex(bool restore);
void DRW_opengl_context_disable_ex(bool restore);
diff --git a/source/blender/draw/engines/basic/basic_engine.c b/source/blender/draw/engines/basic/basic_engine.c
index 16788c10680..05ee485e053 100644
--- a/source/blender/draw/engines/basic/basic_engine.c
+++ b/source/blender/draw/engines/basic/basic_engine.c
@@ -169,8 +169,8 @@ static void basic_cache_populate(void *vedata, Object *ob)
const bool do_cull = (draw_ctx->v3d &&
(draw_ctx->v3d->shading.flag & V3D_SHADING_BACKFACE_CULLING));
/* Depth Prepass */
- DRW_shgroup_call_add(
- (do_cull) ? stl->g_data->depth_shgrp_cull : stl->g_data->depth_shgrp, geom, ob->obmat);
+ DRW_shgroup_call_object_add(
+ (do_cull) ? stl->g_data->depth_shgrp_cull : stl->g_data->depth_shgrp, geom, ob);
}
}
diff --git a/source/blender/draw/engines/eevee/eevee_bloom.c b/source/blender/draw/engines/eevee/eevee_bloom.c
index e5d33daa0d0..b0013151a70 100644
--- a/source/blender/draw/engines/eevee/eevee_bloom.c
+++ b/source/blender/draw/engines/eevee/eevee_bloom.c
@@ -206,31 +206,32 @@ void EEVEE_bloom_cache_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *ved
if ((effects->enabled_effects & EFFECT_BLOOM) != 0) {
/** Bloom algorithm
*
- * Overview :
+ * Overview:
* - Downsample the color buffer doing a small blur during each step.
* - Accumulate bloom color using previously downsampled color buffers
* and do an upsample blur for each new accumulated layer.
* - Finally add accumulation buffer onto the source color buffer.
*
* [1/1] is original copy resolution (can be half or quarter res for performance)
+ * <pre>
+ * [DOWNSAMPLE CHAIN] [UPSAMPLE CHAIN]
*
- * [DOWNSAMPLE CHAIN] [UPSAMPLE CHAIN]
- *
- * Source Color ── [Blit] ──> Bright Color Extract [1/1] Final Color
- * | Λ
- * [Downsample First] Source Color ─> + [Resolve]
- * v |
- * Color Downsampled [1/2] ────────────> + Accumulation Buffer [1/2]
- * | Λ
- * ─── ───
- * Repeat Repeat
- * ─── ───
- * v |
- * Color Downsampled [1/N-1] ──────────> + Accumulation Buffer [1/N-1]
- * | Λ
- * [Downsample] [Upsample]
- * v |
- * Color Downsampled [1/N] ─────────────────────────┘
+ * Source Color ─ [Blit] ─> Bright Color Extract [1/1] Final Color
+ * | Λ
+ * [Downsample First] Source Color ─> + [Resolve]
+ * v |
+ * Color Downsampled [1/2] ────────────> + Accumulation Buffer [1/2]
+ * | Λ
+ * ─── ───
+ * Repeat Repeat
+ * ─── ───
+ * v |
+ * Color Downsampled [1/N-1] ──────────> + Accumulation Buffer [1/N-1]
+ * | Λ
+ * [Downsample] [Upsample]
+ * v |
+ * Color Downsampled [1/N] ─────────────────────────┘
+ * </pre>
*/
DRWShadingGroup *grp;
const bool use_highres = true;
diff --git a/source/blender/draw/engines/eevee/eevee_depth_of_field.c b/source/blender/draw/engines/eevee/eevee_depth_of_field.c
index 62ccf30e12c..8fb73bd605f 100644
--- a/source/blender/draw/engines/eevee/eevee_depth_of_field.c
+++ b/source/blender/draw/engines/eevee/eevee_depth_of_field.c
@@ -141,10 +141,12 @@ int EEVEE_depth_of_field_init(EEVEE_ViewLayerData *UNUSED(sldata),
float focus_dist = BKE_camera_object_dof_distance(camera);
float focal_len = cam->lens;
- /* this is factor that converts to the scene scale. focal length and sensor are expressed in mm
- * unit.scale_length is how many meters per blender unit we have. We want to convert to blender units though
- * because the shader reads coordinates in world space, which is in blender units.
- * Note however that focus_distance is already in blender units and shall not be scaled here (see T48157). */
+ /* this is factor that converts to the scene scale. focal length and sensor are expressed in
+ * mm unit.scale_length is how many meters per blender unit we have. We want to convert to
+ * blender units though because the shader reads coordinates in world space, which is in
+ * blender units.
+ * Note however that focus_distance is already in blender units and shall not be scaled here
+ * (see T48157). */
float scale = (scene_eval->unit.system) ? scene_eval->unit.scale_length : 1.0f;
float scale_camera = 0.001f / scale;
/* we want radius here for the aperture number */
@@ -239,6 +241,7 @@ void EEVEE_depth_of_field_cache_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_
if (use_alpha) {
DRW_shgroup_uniform_texture_ref(grp, "scatterAlphaBuffer", &effects->dof_blur_alpha);
+ DRW_shgroup_uniform_bool_copy(grp, "unpremult", DRW_state_is_image_render());
}
}
}
diff --git a/source/blender/draw/engines/eevee/eevee_effects.c b/source/blender/draw/engines/eevee/eevee_effects.c
index e77d7b16c78..a8b4159e030 100644
--- a/source/blender/draw/engines/eevee/eevee_effects.c
+++ b/source/blender/draw/engines/eevee/eevee_effects.c
@@ -168,6 +168,11 @@ void EEVEE_effects_init(EEVEE_ViewLayerData *sldata,
effects->enabled_effects |= EFFECT_NORMAL_BUFFER;
}
+ /* Alpha checker if background is not drawn in viewport. */
+ if (!DRW_state_is_image_render() && !DRW_state_draw_background()) {
+ effects->enabled_effects |= EFFECT_ALPHA_CHECKER;
+ }
+
/**
* Ping Pong buffer
*/
@@ -361,6 +366,23 @@ void EEVEE_effects_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
DRW_shgroup_uniform_mat4(grp, "pastPersmat", effects->velocity_past_persmat);
DRW_shgroup_call_add(grp, quad, NULL);
}
+
+ if ((effects->enabled_effects & EFFECT_ALPHA_CHECKER) != 0) {
+ psl->alpha_checker = DRW_pass_create("Alpha Checker",
+ DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_PREMUL_UNDER);
+
+ GPUShader *checker_sh = GPU_shader_get_builtin_shader(GPU_SHADER_2D_CHECKER);
+
+ DRWShadingGroup *grp = DRW_shgroup_create(checker_sh, psl->alpha_checker);
+
+ copy_v4_fl4(effects->color_checker_dark, 0.15f, 0.15f, 0.15f, 1.0f);
+ copy_v4_fl4(effects->color_checker_light, 0.2f, 0.2f, 0.2f, 1.0f);
+
+ DRW_shgroup_uniform_vec4(grp, "color1", effects->color_checker_dark, 1);
+ DRW_shgroup_uniform_vec4(grp, "color2", effects->color_checker_light, 1);
+ DRW_shgroup_uniform_int_copy(grp, "size", 8);
+ DRW_shgroup_call_add(grp, quad, NULL);
+ }
}
#if 0 /* Not required for now */
@@ -413,7 +435,8 @@ void EEVEE_create_minmax_buffer(EEVEE_Data *vedata, GPUTexture *depth_src, int l
GPU_framebuffer_texture_detach(stl->g_data->minzbuffer);
/* Create lower levels */
- GPU_framebuffer_recursive_downsample(fbl->downsample_fb, stl->g_data->minzbuffer, 8, &min_downsample_cb, vedata);
+ GPU_framebuffer_recursive_downsample(
+ fbl->downsample_fb, stl->g_data->minzbuffer, 8, &min_downsample_cb, vedata);
DRW_stats_group_end();
#endif
int minmax_size[3], depth_size[3];
@@ -490,22 +513,50 @@ void EEVEE_downsample_cube_buffer(EEVEE_Data *vedata, GPUTexture *texture_src, i
DRW_stats_group_end();
}
-void EEVEE_draw_effects(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
+void EEVEE_draw_alpha_checker(EEVEE_Data *vedata)
+{
+ EEVEE_PassList *psl = vedata->psl;
+ EEVEE_StorageList *stl = vedata->stl;
+ EEVEE_EffectsInfo *effects = stl->effects;
+
+ if ((effects->enabled_effects & EFFECT_ALPHA_CHECKER) != 0) {
+ float mat[4][4];
+ unit_m4(mat);
+
+ /* Fragile, rely on the fact that GPU_SHADER_2D_CHECKER
+ * only use the persmat. */
+ DRW_viewport_matrix_override_set(mat, DRW_MAT_PERS);
+
+ DRW_draw_pass(psl->alpha_checker);
+
+ DRW_viewport_matrix_override_unset(DRW_MAT_PERS);
+ }
+}
+
+static void EEVEE_velocity_resolve(EEVEE_Data *vedata)
{
EEVEE_PassList *psl = vedata->psl;
- EEVEE_TextureList *txl = vedata->txl;
EEVEE_FramebufferList *fbl = vedata->fbl;
EEVEE_StorageList *stl = vedata->stl;
EEVEE_EffectsInfo *effects = stl->effects;
- /* First resolve the velocity. */
if ((effects->enabled_effects & EFFECT_VELOCITY_BUFFER) != 0) {
+ DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
+ e_data.depth_src = dtxl->depth;
DRW_viewport_matrix_get(effects->velocity_curr_persinv, DRW_MAT_PERSINV);
GPU_framebuffer_bind(fbl->velocity_resolve_fb);
DRW_draw_pass(psl->velocity_resolve);
}
DRW_viewport_matrix_get(effects->velocity_past_persmat, DRW_MAT_PERS);
+}
+
+void EEVEE_draw_effects(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
+{
+ EEVEE_TextureList *txl = vedata->txl;
+ EEVEE_FramebufferList *fbl = vedata->fbl;
+ EEVEE_StorageList *stl = vedata->stl;
+ EEVEE_EffectsInfo *effects = stl->effects;
/* only once per frame after the first post process */
effects->swap_double_buffer = ((effects->enabled_effects & EFFECT_DOUBLE_BUFFER) != 0);
@@ -517,6 +568,14 @@ void EEVEE_draw_effects(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
/* Post process stack (order matters) */
EEVEE_motion_blur_draw(vedata);
EEVEE_depth_of_field_draw(vedata);
+
+ /* NOTE: Lookdev drawing happens before TAA but after
+ * motion blur and dof to avoid distortions.
+ * Velocity resolve use a hack to exclude lookdev
+ * balls from creating shimering reprojection vectors. */
+ EEVEE_lookdev_draw(vedata);
+ EEVEE_velocity_resolve(vedata);
+
EEVEE_temporal_sampling_draw(vedata);
EEVEE_bloom_draw(vedata);
diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c
index 6232640aac8..962bc8e5efb 100644
--- a/source/blender/draw/engines/eevee/eevee_engine.c
+++ b/source/blender/draw/engines/eevee/eevee_engine.c
@@ -301,16 +301,15 @@ static void eevee_draw_background(void *vedata)
}
}
- /* LookDev */
- EEVEE_lookdev_draw_background(vedata);
- /* END */
-
/* Tonemapping and transfer result to default framebuffer. */
bool use_render_settings = stl->g_data->use_color_render_settings;
GPU_framebuffer_bind(dfbl->default_fb);
DRW_transform_to_display(stl->effects->final_tx, true, use_render_settings);
+ /* Draw checkerboard with alpha under. */
+ EEVEE_draw_alpha_checker(vedata);
+
/* Debug : Output buffer to view. */
switch (G.debug_value) {
case 1:
diff --git a/source/blender/draw/engines/eevee/eevee_lightcache.c b/source/blender/draw/engines/eevee/eevee_lightcache.c
index 9ebd9542ef5..33cb2e87dc7 100644
--- a/source/blender/draw/engines/eevee/eevee_lightcache.c
+++ b/source/blender/draw/engines/eevee/eevee_lightcache.c
@@ -92,38 +92,64 @@ typedef struct EEVEE_LightBake {
struct Main *bmain;
EEVEE_ViewLayerData *sldata;
- LightProbe **probe; /* Current probe being rendered. */
- GPUTexture *rt_color; /* Target cube color texture. */
- GPUTexture *rt_depth; /* Target cube depth texture. */
- GPUFrameBuffer *rt_fb[6]; /* Target cube framebuffers. */
- GPUFrameBuffer *store_fb; /* Storage framebuffer. */
- int rt_res; /* Cube render target resolution. */
+ /** Current probe being rendered. */
+ LightProbe **probe;
+ /** Target cube color texture. */
+ GPUTexture *rt_color;
+ /** Target cube depth texture. */
+ GPUTexture *rt_depth;
+ /** Target cube framebuffers. */
+ GPUFrameBuffer *rt_fb[6];
+ /** Storage framebuffer. */
+ GPUFrameBuffer *store_fb;
+ /** Cube render target resolution. */
+ int rt_res;
/* Shared */
- int layer; /* Target layer to store the data to. */
- float samples_ct, invsamples_ct; /* Sample count for the convolution. */
- float lod_factor; /* Sampling bias during convolution step. */
- float lod_max; /* Max cubemap LOD to sample when convolving. */
- int cube_len, grid_len; /* Number of probes to render + world probe. */
+ /** Target layer to store the data to. */
+ int layer;
+ /** Sample count for the convolution. */
+ float samples_ct, invsamples_ct;
+ /** Sampling bias during convolution step. */
+ float lod_factor;
+ /** Max cubemap LOD to sample when convolving. */
+ float lod_max;
+ /** Number of probes to render + world probe. */
+ int cube_len, grid_len;
/* Irradiance grid */
- EEVEE_LightGrid *grid; /* Current probe being rendered (UBO data). */
- int irr_cube_res; /* Target cubemap at MIP 0. */
- int irr_size[3]; /* Size of the irradiance texture. */
- int total_irr_samples; /* Total for all grids */
- int grid_sample; /* Nth sample of the current grid being rendered. */
- int grid_sample_len; /* Total number of samples for the current grid. */
- int grid_curr; /* Nth grid in the cache being rendered. */
- int bounce_curr, bounce_len; /* The current light bounce being evaluated. */
- float vis_res; /* Resolution of the Visibility shadowmap. */
- GPUTexture *grid_prev; /* Result of previous light bounce. */
- LightProbe **grid_prb; /* Pointer to the id.data of the probe object. */
+ /** Current probe being rendered (UBO data). */
+ EEVEE_LightGrid *grid;
+ /** Target cubemap at MIP 0. */
+ int irr_cube_res;
+ /** Size of the irradiance texture. */
+ int irr_size[3];
+ /** Total for all grids */
+ int total_irr_samples;
+ /** Nth sample of the current grid being rendered. */
+ int grid_sample;
+ /** Total number of samples for the current grid. */
+ int grid_sample_len;
+ /** Nth grid in the cache being rendered. */
+ int grid_curr;
+ /** The current light bounce being evaluated. */
+ int bounce_curr, bounce_len;
+ /** Resolution of the Visibility shadowmap. */
+ float vis_res;
+ /** Result of previous light bounce. */
+ GPUTexture *grid_prev;
+ /** Pointer to the id.data of the probe object. */
+ LightProbe **grid_prb;
/* Reflection probe */
- EEVEE_LightProbe *cube; /* Current probe being rendered (UBO data). */
- int ref_cube_res; /* Target cubemap at MIP 0. */
- int cube_offset; /* Index of the current cube. */
- LightProbe **cube_prb; /* Pointer to the id.data of the probe object. */
+ /** Current probe being rendered (UBO data). */
+ EEVEE_LightProbe *cube;
+ /** Target cubemap at MIP 0. */
+ int ref_cube_res;
+ /** Index of the current cube. */
+ int cube_offset;
+ /** Pointer to the id.data of the probe object. */
+ LightProbe **cube_prb;
/* Dummy Textures */
struct GPUTexture *dummy_color, *dummy_depth;
@@ -133,15 +159,18 @@ typedef struct EEVEE_LightBake {
short *stop, *do_update;
float *progress;
- bool resource_only; /* For only handling the resources. */
+ /** For only handling the resources. */
+ bool resource_only;
bool own_resources;
- bool
- own_light_cache; /* If the lightcache was created for baking, it's first owned by the baker. */
- int delay; /* ms. delay the start of the baking to not slowdown interactions (TODO remove) */
- int frame; /* Scene frame to bake. */
-
- void *gl_context,
- *gpu_context; /* If running in parallel (in a separate thread), use this context. */
+ /** If the lightcache was created for baking, it's first owned by the baker. */
+ bool own_light_cache;
+ /** ms. delay the start of the baking to not slowdown interactions (TODO remove) */
+ int delay;
+ /** Scene frame to bake. */
+ int frame;
+
+ /** If running in parallel (in a separate thread), use this context. */
+ void *gl_context, *gpu_context;
ThreadMutex *mutex;
} EEVEE_LightBake;
diff --git a/source/blender/draw/engines/eevee/eevee_lightprobes.c b/source/blender/draw/engines/eevee/eevee_lightprobes.c
index 550821ee92a..a4a17de7a57 100644
--- a/source/blender/draw/engines/eevee/eevee_lightprobes.c
+++ b/source/blender/draw/engines/eevee/eevee_lightprobes.c
@@ -145,7 +145,8 @@ static void planar_pool_ensure_alloc(EEVEE_Data *vedata, int num_planar_ref)
width, height, max_ii(1, num_planar_ref), GPU_DEPTH_COMPONENT24, 0, NULL);
}
else if (num_planar_ref == 0) {
- /* Makes Opengl Happy : Create a placeholder texture that will never be sampled but still bound to shader. */
+ /* Makes Opengl Happy : Create a placeholder texture that will never be sampled but still
+ * bound to shader. */
txl->planar_pool = DRW_texture_create_2d_array(
1, 1, 1, GPU_RGBA8, DRW_TEX_FILTER | DRW_TEX_MIPMAP, NULL);
txl->planar_depth = DRW_texture_create_2d_array(1, 1, 1, GPU_DEPTH_COMPONENT24, 0, NULL);
diff --git a/source/blender/draw/engines/eevee/eevee_lights.c b/source/blender/draw/engines/eevee/eevee_lights.c
index b118d7be3d0..270defb039b 100644
--- a/source/blender/draw/engines/eevee/eevee_lights.c
+++ b/source/blender/draw/engines/eevee/eevee_lights.c
@@ -680,7 +680,8 @@ static float light_shape_power_get(const Light *la, const EEVEE_Light *evli)
power = 1.0f / (evli->sizex * evli->sizey * 4.0f * M_PI) * /* 1/(w*h*Pi) */
80.0f; /* XXX : Empirical, Fit cycles power */
if (ELEM(la->area_shape, LA_AREA_DISK, LA_AREA_ELLIPSE)) {
- /* Scale power to account for the lower area of the ellipse compared to the surrounding rectangle. */
+ /* Scale power to account for the lower area of the ellipse compared to the surrounding
+ * rectangle. */
power *= 4.0f / M_PI;
}
}
@@ -693,8 +694,9 @@ static float light_shape_power_get(const Light *la, const EEVEE_Light *evli)
}
else {
power = 1.0f / (evli->radius * evli->radius * M_PI); /* 1/(r²*Pi) */
- /* Make illumation power closer to cycles for bigger radii. Cycles uses a cos^3 term that we cannot reproduce
- * so we account for that by scaling the light power. This function is the result of a rough manual fitting. */
+ /* Make illumation power closer to cycles for bigger radii. Cycles uses a cos^3 term that we
+ * cannot reproduce so we account for that by scaling the light power. This function is the
+ * result of a rough manual fitting. */
power += 1.0f / (2.0f * M_PI); /* power *= 1 + r²/2 */
}
return power;
@@ -952,7 +954,7 @@ static void frustum_min_bounding_sphere(const float corners[8][3],
}
/* TODO try to reduce the radius further by moving the center.
- * Remember we need a __stable__ solution! */
+ * Remember we need a __stable__ solution! */
/* Try to reduce float imprecision leading to shimmering. */
*r_radius = (float)round_to_digits(sqrtf(*r_radius), 3);
@@ -1383,7 +1385,8 @@ void EEVEE_draw_shadows(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
DRW_draw_pass(psl->shadow_pass);
}
- /* 0.001f is arbitrary, but it should be relatively small so that filter size is not too big. */
+ /* 0.001f is arbitrary, but it should be relatively small so that filter size is not too big.
+ */
float filter_texture_size = la->soft * 0.001f;
float filter_pixel_size = ceil(filter_texture_size / srd->cube_texel_size);
linfo->filter_size = srd->cube_texel_size * ((filter_pixel_size > 1.0f) ? 1.5f : 0.0f);
diff --git a/source/blender/draw/engines/eevee/eevee_lookdev.c b/source/blender/draw/engines/eevee/eevee_lookdev.c
index b000eebb92e..4be87bf1a5e 100644
--- a/source/blender/draw/engines/eevee/eevee_lookdev.c
+++ b/source/blender/draw/engines/eevee/eevee_lookdev.c
@@ -24,6 +24,9 @@
#include "BKE_camera.h"
#include "BKE_studiolight.h"
+#include "BLI_rect.h"
+#include "BLI_rand.h"
+
#include "DNA_screen_types.h"
#include "DNA_world_types.h"
@@ -62,11 +65,30 @@ void EEVEE_lookdev_cache_init(EEVEE_Data *vedata,
{
EEVEE_StorageList *stl = vedata->stl;
EEVEE_TextureList *txl = vedata->txl;
+ EEVEE_EffectsInfo *effects = stl->effects;
EEVEE_PrivateData *g_data = stl->g_data;
const DRWContextState *draw_ctx = DRW_context_state_get();
View3D *v3d = draw_ctx->v3d;
Scene *scene = draw_ctx->scene;
+ if (LOOK_DEV_OVERLAY_ENABLED(v3d)) {
+ /* Viewport / Ball size. */
+ rcti rect;
+ ED_region_visible_rect(draw_ctx->ar, &rect);
+
+ const int ball_size = max_ii(BLI_rcti_size_x(&rect) * 0.1f, 100.0f) * U.dpi_fac;
+
+ if (ball_size != effects->ball_size || rect.xmax != effects->anchor[0] ||
+ rect.ymin != effects->anchor[1]) {
+ /* If ball size or anchor point moves, reset TAA to avoid ghosting issue.
+ * This needs to happen early because we are changing taa_current_sample. */
+ effects->ball_size = ball_size;
+ effects->anchor[0] = rect.xmax;
+ effects->anchor[1] = rect.ymin;
+ EEVEE_temporal_sampling_reset(vedata);
+ }
+ }
+
if (LOOK_DEV_STUDIO_LIGHT_ENABLED(v3d)) {
StudioLight *sl = BKE_studiolight_find(v3d->shading.lookdev_light,
STUDIOLIGHT_ORIENTATIONS_MATERIAL_MODE);
@@ -157,56 +179,35 @@ void EEVEE_lookdev_cache_init(EEVEE_Data *vedata,
}
}
-void EEVEE_lookdev_draw_background(EEVEE_Data *vedata)
+static void eevee_lookdev_apply_taa(const EEVEE_EffectsInfo *effects,
+ int ball_size,
+ float winmat[4][4])
+{
+ if (DRW_state_is_image_render() || ((effects->enabled_effects & EFFECT_TAA) != 0)) {
+ double ht_point[2];
+ double ht_offset[2] = {0.0, 0.0};
+ uint ht_primes[2] = {2, 3};
+ float ofs[2];
+
+ BLI_halton_2d(ht_primes, ht_offset, effects->taa_current_sample, ht_point);
+ EEVEE_temporal_sampling_offset_calc(ht_point, 1.5f, ofs);
+ winmat[3][0] += ofs[0] / ball_size;
+ winmat[3][1] += ofs[1] / ball_size;
+ }
+}
+
+void EEVEE_lookdev_draw(EEVEE_Data *vedata)
{
EEVEE_PassList *psl = vedata->psl;
+ EEVEE_FramebufferList *fbl = vedata->fbl;
EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl;
EEVEE_EffectsInfo *effects = stl->effects;
EEVEE_ViewLayerData *sldata = EEVEE_view_layer_data_ensure();
- DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
const DRWContextState *draw_ctx = DRW_context_state_get();
- if (psl->lookdev_pass && LOOK_DEV_OVERLAY_ENABLED(draw_ctx->v3d)) {
- DRW_stats_group_start("Look Dev");
- CameraParams params;
- BKE_camera_params_init(&params);
- View3D *v3d = draw_ctx->v3d;
- RegionView3D *rv3d = draw_ctx->rv3d;
- ARegion *ar = draw_ctx->ar;
-
- const float *viewport_size = DRW_viewport_size_get();
- rcti rect;
- ED_region_visible_rect(draw_ctx->ar, &rect);
-
- const float viewport_size_target[2] = {
- viewport_size[0] / 4,
- viewport_size[1] / 4,
- };
- const int viewport_inset[2] = {
- max_ii(viewport_size_target[0], 300),
- max_ii(viewport_size_target[0], 300) / 2, /* intentionally use 'x' here for 'y' value. */
- };
-
- /* minimum size for preview spheres viewport */
- const float aspect[2] = {
- viewport_inset[0] / viewport_size_target[0],
- viewport_inset[1] / viewport_size_target[1],
- };
-
- BKE_camera_params_from_view3d(&params, draw_ctx->depsgraph, v3d, rv3d);
- params.is_ortho = true;
- params.ortho_scale = 3.0f;
- params.zoom = CAMERA_PARAM_ZOOM_INIT_PERSP;
- params.offsetx = 0.0f;
- params.offsety = 0.0f;
- params.shiftx = 0.0f;
- params.shifty = 0.0f;
- params.clip_start = 0.001f;
- params.clip_end = 20.0f;
- BKE_camera_params_compute_viewplane(&params, ar->winx, ar->winy, aspect[0], aspect[1]);
- BKE_camera_params_compute_matrix(&params);
-
+ if (psl->lookdev_diffuse_pass && LOOK_DEV_OVERLAY_ENABLED(draw_ctx->v3d)) {
+ /* Config renderer. */
EEVEE_CommonUniformBuffer *common = &sldata->common_data;
common->la_num_light = 0;
common->prb_num_planar = 0;
@@ -218,34 +219,53 @@ void EEVEE_lookdev_draw_background(EEVEE_Data *vedata)
DRW_uniformbuffer_update(sldata->common_ubo, common);
/* override matrices */
- float winmat[4][4];
- float winmat_inv[4][4];
- copy_m4_m4(winmat, params.winmat);
- invert_m4_m4(winmat_inv, winmat);
- DRW_viewport_matrix_override_set(winmat, DRW_MAT_WIN);
- DRW_viewport_matrix_override_set(winmat_inv, DRW_MAT_WININV);
- float viewmat[4][4];
- DRW_viewport_matrix_get(viewmat, DRW_MAT_VIEW);
- float persmat[4][4];
- float persmat_inv[4][4];
- mul_m4_m4m4(persmat, winmat, viewmat);
- invert_m4_m4(persmat_inv, persmat);
- DRW_viewport_matrix_override_set(persmat, DRW_MAT_PERS);
- DRW_viewport_matrix_override_set(persmat_inv, DRW_MAT_PERSINV);
-
- GPUFrameBuffer *fb = effects->final_fb;
- GPU_framebuffer_bind(fb);
- GPU_framebuffer_viewport_set(
- fb, rect.xmax - viewport_inset[0], rect.ymin, viewport_inset[0], viewport_inset[1]);
- DRW_draw_pass(psl->lookdev_pass);
+ DRWMatrixState matstate;
+ unit_m4(matstate.winmat);
+
+ eevee_lookdev_apply_taa(effects, effects->ball_size, matstate.winmat);
+
+ /* "Remove" view matrix location. Leaving only rotation. */
+ DRW_viewport_matrix_get(matstate.viewmat, DRW_MAT_VIEW);
+ zero_v3(matstate.viewmat[3]);
+ mul_m4_m4m4(matstate.persmat, matstate.winmat, matstate.viewmat);
+ invert_m4_m4(matstate.wininv, matstate.winmat);
+ invert_m4_m4(matstate.viewinv, matstate.viewmat);
+ invert_m4_m4(matstate.persinv, matstate.persmat);
+
+ DRW_viewport_matrix_override_set_all(&matstate);
+
+ /* Find the right framebuffers to render to. */
+ GPUFrameBuffer *fb = (effects->target_buffer == fbl->effect_color_fb) ? fbl->main_fb :
+ fbl->effect_fb;
+
+ DRW_stats_group_start("Look Dev");
- fb = dfbl->depth_only_fb;
GPU_framebuffer_bind(fb);
- GPU_framebuffer_viewport_set(
- fb, rect.xmax - viewport_inset[0], rect.ymin, viewport_inset[0], viewport_inset[1]);
- DRW_draw_pass(psl->lookdev_pass);
- DRW_viewport_matrix_override_unset_all();
+ const int ball_margin = effects->ball_size / 6.0f;
+ float offset[2] = {0.0f, ball_margin};
+
+ offset[0] = effects->ball_size + ball_margin;
+ GPU_framebuffer_viewport_set(fb,
+ effects->anchor[0] - offset[0],
+ effects->anchor[1] + offset[1],
+ effects->ball_size,
+ effects->ball_size);
+
+ DRW_draw_pass(psl->lookdev_diffuse_pass);
+
+ offset[0] = (effects->ball_size + ball_margin) +
+ (ball_margin + effects->ball_size + ball_margin);
+ GPU_framebuffer_viewport_set(fb,
+ effects->anchor[0] - offset[0],
+ effects->anchor[1] + offset[1],
+ effects->ball_size,
+ effects->ball_size);
+
+ DRW_draw_pass(psl->lookdev_glossy_pass);
+
DRW_stats_group_end();
+
+ DRW_viewport_matrix_override_unset_all();
}
}
diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c
index 9268f2e8a46..456f4bdb5f1 100644
--- a/source/blender/draw/engines/eevee/eevee_materials.c
+++ b/source/blender/draw/engines/eevee/eevee_materials.c
@@ -115,15 +115,15 @@ static struct GPUTexture *create_ggx_lut_texture(int UNUSED(w), int UNUSED(h))
static float samples_len = 8192.0f;
static float inv_samples_len = 1.0f / 8192.0f;
- char *lib_str = BLI_string_joinN(
- datatoc_bsdf_common_lib_glsl,
- datatoc_bsdf_sampling_lib_glsl);
+ char *lib_str = BLI_string_joinN(datatoc_bsdf_common_lib_glsl, datatoc_bsdf_sampling_lib_glsl);
- struct GPUShader *sh = DRW_shader_create_with_lib(
- datatoc_lightprobe_vert_glsl, datatoc_lightprobe_geom_glsl, datatoc_bsdf_lut_frag_glsl, lib_str,
- "#define HAMMERSLEY_SIZE 8192\n"
- "#define BRDF_LUT_SIZE 64\n"
- "#define NOISE_SIZE 64\n");
+ struct GPUShader *sh = DRW_shader_create_with_lib(datatoc_lightprobe_vert_glsl,
+ datatoc_lightprobe_geom_glsl,
+ datatoc_bsdf_lut_frag_glsl,
+ lib_str,
+ "#define HAMMERSLEY_SIZE 8192\n"
+ "#define BRDF_LUT_SIZE 64\n"
+ "#define NOISE_SIZE 64\n");
DRWPass *pass = DRW_pass_create("LightProbe Filtering", DRW_STATE_WRITE_COLOR);
DRWShadingGroup *grp = DRW_shgroup_create(sh, pass);
@@ -150,11 +150,14 @@ static struct GPUTexture *create_ggx_lut_texture(int UNUSED(w), int UNUSED(h))
glReadPixels(0, 0, w, h, GL_RGB, GL_FLOAT, data);
printf("{");
- for (int i = 0; i < w*h * 3; i+=3) {
- printf("%ff, %ff, ", data[i], data[i+1]); i+=3;
- printf("%ff, %ff, ", data[i], data[i+1]); i+=3;
- printf("%ff, %ff, ", data[i], data[i+1]); i+=3;
- printf("%ff, %ff, \n", data[i], data[i+1]);
+ for (int i = 0; i < w * h * 3; i += 3) {
+ printf("%ff, %ff, ", data[i], data[i + 1]);
+ i += 3;
+ printf("%ff, %ff, ", data[i], data[i + 1]);
+ i += 3;
+ printf("%ff, %ff, ", data[i], data[i + 1]);
+ i += 3;
+ printf("%ff, %ff, \n", data[i], data[i + 1]);
}
printf("}");
@@ -174,15 +177,13 @@ static struct GPUTexture *create_ggx_refraction_lut_texture(int w, int h)
static float inv_samples_len = 1.0f / 8192.0f;
char *frag_str = BLI_string_joinN(
- datatoc_bsdf_common_lib_glsl,
- datatoc_bsdf_sampling_lib_glsl,
- datatoc_btdf_lut_frag_glsl);
+ datatoc_bsdf_common_lib_glsl, datatoc_bsdf_sampling_lib_glsl, datatoc_btdf_lut_frag_glsl);
struct GPUShader *sh = DRW_shader_create_fullscreen(frag_str,
- "#define HAMMERSLEY_SIZE 8192\n"
- "#define BRDF_LUT_SIZE 64\n"
- "#define NOISE_SIZE 64\n"
- "#define LUT_SIZE 64\n");
+ "#define HAMMERSLEY_SIZE 8192\n"
+ "#define BRDF_LUT_SIZE 64\n"
+ "#define NOISE_SIZE 64\n"
+ "#define LUT_SIZE 64\n");
MEM_freeN(frag_str);
@@ -222,20 +223,28 @@ static struct GPUTexture *create_ggx_refraction_lut_texture(int w, int h)
# if 1
fprintf(f, "\t{\n\t\t");
- for (int i = 0; i < w*h * 3; i+=3) {
+ for (int i = 0; i < w * h * 3; i += 3) {
fprintf(f, "%ff,", data[i]);
- if (((i/3)+1) % 12 == 0) fprintf(f, "\n\t\t");
- else fprintf(f, " ");
+ if (((i / 3) + 1) % 12 == 0)
+ fprintf(f, "\n\t\t");
+ else
+ fprintf(f, " ");
}
fprintf(f, "\n\t},\n");
# else
- for (int i = 0; i < w*h * 3; i+=3) {
- if (data[i] < 0.01) printf(" ");
- else if (data[i] < 0.3) printf(".");
- else if (data[i] < 0.6) printf("+");
- else if (data[i] < 0.9) printf("%%");
- else printf("#");
- if ((i/3+1) % 64 == 0) printf("\n");
+ for (int i = 0; i < w * h * 3; i += 3) {
+ if (data[i] < 0.01)
+ printf(" ");
+ else if (data[i] < 0.3)
+ printf(".");
+ else if (data[i] < 0.6)
+ printf("+");
+ else if (data[i] < 0.9)
+ printf("%%");
+ else
+ printf("#");
+ if ((i / 3 + 1) % 64 == 0)
+ printf("\n");
}
# endif
@@ -327,7 +336,10 @@ static char *eevee_get_defines(int options)
BLI_dynstr_append(ds, "#define USE_ALPHA_BLEND_VOLUMETRICS\n");
}
if ((options & VAR_MAT_LOOKDEV) != 0) {
+ /* Auto config shadow method. Avoid more permutation. */
+ BLI_assert((options & (VAR_MAT_VSM | VAR_MAT_ESM)) == 0);
BLI_dynstr_append(ds, "#define LOOKDEV\n");
+ BLI_dynstr_append(ds, "#define SHADOW_ESM\n");
}
str = BLI_dynstr_get_cstring(ds);
@@ -457,7 +469,7 @@ static void eevee_init_util_texture(void)
texels_layer += 64 * 64;
/* Copy bsdf_split_sum_ggx into 2nd layer red and green channels.
- Copy ltc_mag_ggx into 2nd layer blue and alpha channel. */
+ * Copy ltc_mag_ggx into 2nd layer blue and alpha channel. */
for (int i = 0; i < 64 * 64; i++) {
texels_layer[i][0] = bsdf_split_sum_ggx[i * 2 + 0];
texels_layer[i][1] = bsdf_split_sum_ggx[i * 2 + 1];
@@ -582,6 +594,7 @@ void EEVEE_materials_init(EEVEE_ViewLayerData *sldata,
datatoc_lit_surface_frag_glsl,
datatoc_lit_surface_frag_glsl,
datatoc_lit_surface_frag_glsl,
+ datatoc_lit_surface_frag_glsl,
datatoc_volumetric_lib_glsl);
e_data.volume_shader_lib = BLI_string_joinN(datatoc_common_view_lib_glsl,
@@ -985,42 +998,11 @@ static struct DRWShadingGroup *EEVEE_default_shading_group_get(EEVEE_ViewLayerDa
}
}
-/**
- * Create a default shading group inside the lookdev pass without standard uniforms.
- */
-static struct DRWShadingGroup *EEVEE_lookdev_shading_group_get(EEVEE_ViewLayerData *sldata,
- EEVEE_Data *vedata,
- bool use_ssr,
- int shadow_method)
-{
- static int ssr_id;
- ssr_id = (use_ssr) ? 1 : -1;
- int options = VAR_MAT_MESH | VAR_MAT_LOOKDEV;
-
- options |= eevee_material_shadow_option(shadow_method);
-
- if (e_data.default_lit[options] == NULL) {
- create_default_shader(options);
- }
-
- if (vedata->psl->lookdev_pass == NULL) {
- DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_ALWAYS |
- DRW_STATE_CULL_BACK;
- vedata->psl->lookdev_pass = DRW_pass_create("LookDev Pass", state);
-
- DRWShadingGroup *shgrp = DRW_shgroup_create(e_data.default_lit[options],
- vedata->psl->lookdev_pass);
- /* XXX / WATCH: This creates non persistent binds for the ubos and textures.
- * But it's currently OK because the following shgroups does not add any bind. */
- add_standard_uniforms(shgrp, sldata, vedata, &ssr_id, NULL, true, true, false, false, false);
- }
-
- return DRW_shgroup_create(e_data.default_lit[options], vedata->psl->lookdev_pass);
-}
void EEVEE_materials_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
{
EEVEE_PassList *psl = ((EEVEE_Data *)vedata)->psl;
EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl;
+ const DRWContextState *draw_ctx = DRW_context_state_get();
/* Create Material Ghash */
{
@@ -1034,16 +1016,13 @@ void EEVEE_materials_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
struct GPUBatch *geom = DRW_cache_fullscreen_quad_get();
DRWShadingGroup *grp = NULL;
- const DRWContextState *draw_ctx = DRW_context_state_get();
Scene *scene = draw_ctx->scene;
World *wo = scene->world;
const float *col = G_draw.block.colorBackground;
- /* LookDev */
EEVEE_lookdev_cache_init(
vedata, &grp, psl->background_pass, stl->g_data->background_alpha, wo, NULL);
- /* END */
if (!grp && wo) {
col = &wo->horr;
@@ -1174,6 +1153,39 @@ void EEVEE_materials_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
DRW_shgroup_uniform_vec3(grp, "offsets", e_data.noise_offsets, 1);
DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
}
+
+ if (LOOK_DEV_OVERLAY_ENABLED(draw_ctx->v3d)) {
+ DRWShadingGroup *shgrp;
+
+ struct GPUBatch *sphere = DRW_cache_sphere_get();
+ static float color_chrome[3] = {1.0f, 1.0f, 1.0f};
+ static float color_diffuse[3] = {0.8f, 0.8f, 0.8f};
+ int options = VAR_MAT_MESH | VAR_MAT_LOOKDEV;
+
+ if (e_data.default_lit[options] == NULL) {
+ create_default_shader(options);
+ }
+
+ DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_ALWAYS |
+ DRW_STATE_CULL_BACK;
+
+ psl->lookdev_diffuse_pass = DRW_pass_create("LookDev Diffuse Pass", state);
+ shgrp = DRW_shgroup_create(e_data.default_lit[options], psl->lookdev_diffuse_pass);
+ add_standard_uniforms(shgrp, sldata, vedata, NULL, NULL, true, true, false, false, false);
+ DRW_shgroup_uniform_vec3(shgrp, "basecol", color_diffuse, 1);
+ DRW_shgroup_uniform_float_copy(shgrp, "metallic", 0.0f);
+ DRW_shgroup_uniform_float_copy(shgrp, "specular", 0.5f);
+ DRW_shgroup_uniform_float_copy(shgrp, "roughness", 1.0f);
+ DRW_shgroup_call_add(shgrp, sphere, NULL);
+
+ psl->lookdev_glossy_pass = DRW_pass_create("LookDev Glossy Pass", state);
+ shgrp = DRW_shgroup_create(e_data.default_lit[options], psl->lookdev_glossy_pass);
+ add_standard_uniforms(shgrp, sldata, vedata, NULL, NULL, true, true, false, false, false);
+ DRW_shgroup_uniform_vec3(shgrp, "basecol", color_chrome, 1);
+ DRW_shgroup_uniform_float_copy(shgrp, "metallic", 1.0f);
+ DRW_shgroup_uniform_float_copy(shgrp, "roughness", 0.0f);
+ DRW_shgroup_call_add(shgrp, sphere, NULL);
+ }
}
#define ADD_SHGROUP_CALL(shgrp, ob, ma, geom, oedata) \
@@ -1399,9 +1411,9 @@ static void material_opaque(Material *ma,
}
else {
if (use_translucency) {
- /* NOTE: This is a nasty workaround, because the sss profile might not have been generated
- * but the UBO is still declared in this case even if not used. But rendering without a
- * bound UBO might result in crashes on certain platform. */
+ /* NOTE: This is a nasty workaround, because the sss profile might not have been
+ * generated but the UBO is still declared in this case even if not used.
+ * But rendering without a bound UBO might result in crashes on certain platform. */
DRW_shgroup_uniform_block(*shgrp, "sssProfile", e_data.dummy_sss_profile);
}
}
@@ -1605,12 +1617,10 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata,
const bool do_cull = (draw_ctx->v3d &&
(draw_ctx->v3d->shading.flag & V3D_SHADING_BACKFACE_CULLING));
- const bool is_active = (ob == draw_ctx->obact);
- const bool is_sculpt_mode = is_active && (draw_ctx->object_mode & OB_MODE_SCULPT) != 0;
+ const bool is_sculpt_mode = (ob->sculpt != NULL);
/* For now just force fully shaded with eevee when supported. */
- const bool is_sculpt_mode_draw = is_sculpt_mode &&
- ((ob->sculpt && ob->sculpt->pbvh) &&
- (BKE_pbvh_type(ob->sculpt->pbvh) != PBVH_FACES));
+ const bool is_sculpt_mode_draw = ob->sculpt && ob->sculpt->pbvh &&
+ BKE_pbvh_type(ob->sculpt->pbvh) != PBVH_FACES;
const bool is_default_mode_shader = is_sculpt_mode;
/* First get materials for this mesh. */
@@ -1871,6 +1881,13 @@ void EEVEE_hair_cache_populate(EEVEE_Data *vedata,
shgrp = DRW_shgroup_material_hair_create(ob, psys, md, psl->material_pass, gpumat);
+ if (!use_diffuse && !use_glossy && !use_refract) {
+ /* FIXME: Small hack to avoid issue when utilTex is needed for
+ * world_normals_get and none of the bsdfs that need it are present.
+ * This can try to bind utilTex even if not needed. */
+ DRW_shgroup_uniform_texture(shgrp, "utilTex", e_data.util_tex);
+ }
+
add_standard_uniforms(shgrp,
sldata,
vedata,
@@ -1918,46 +1935,6 @@ void EEVEE_materials_cache_finish(EEVEE_Data *vedata)
{
EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl;
- /* Look-Dev */
- const DRWContextState *draw_ctx = DRW_context_state_get();
- const View3D *v3d = draw_ctx->v3d;
- if (LOOK_DEV_OVERLAY_ENABLED(v3d)) {
- EEVEE_ViewLayerData *sldata = EEVEE_view_layer_data_ensure();
- EEVEE_LightsInfo *linfo = sldata->lights;
- struct GPUBatch *sphere = DRW_cache_sphere_get();
- static float mat1[4][4];
- static float color[3] = {0.8f, 0.8f, 0.8f};
- static float metallic_on = 1.0f;
- static float metallic_off = 0.00f;
- static float specular_off = 0.5f;
- static float specular_on = 1.0f;
- static float roughness_off = 0.05f;
- static float roughness_on = 1.00f;
-
- float view_mat[4][4];
- DRW_viewport_matrix_get(view_mat, DRW_MAT_VIEWINV);
-
- DRWShadingGroup *shgrp = EEVEE_lookdev_shading_group_get(
- sldata, vedata, false, linfo->shadow_method);
- DRW_shgroup_uniform_vec3(shgrp, "basecol", color, 1);
- DRW_shgroup_uniform_float(shgrp, "metallic", &metallic_on, 1);
- DRW_shgroup_uniform_float(shgrp, "specular", &specular_on, 1);
- DRW_shgroup_uniform_float(shgrp, "roughness", &roughness_off, 1);
- unit_m4(mat1);
- mul_m4_m4m4(mat1, mat1, view_mat);
- translate_m4(mat1, -1.5f, 0.0f, -5.0f);
- DRW_shgroup_call_add(shgrp, sphere, mat1);
-
- shgrp = EEVEE_lookdev_shading_group_get(sldata, vedata, false, linfo->shadow_method);
- DRW_shgroup_uniform_vec3(shgrp, "basecol", color, 1);
- DRW_shgroup_uniform_float(shgrp, "metallic", &metallic_off, 1);
- DRW_shgroup_uniform_float(shgrp, "specular", &specular_off, 1);
- DRW_shgroup_uniform_float(shgrp, "roughness", &roughness_on, 1);
- translate_m4(mat1, 3.0f, 0.0f, 0.0f);
- DRW_shgroup_call_add(shgrp, sphere, mat1);
- }
- /* END */
-
BLI_ghash_free(stl->g_data->material_hash, NULL, MEM_freeN);
}
diff --git a/source/blender/draw/engines/eevee/eevee_motion_blur.c b/source/blender/draw/engines/eevee/eevee_motion_blur.c
index f2863d572c4..f8795a7ff0e 100644
--- a/source/blender/draw/engines/eevee/eevee_motion_blur.c
+++ b/source/blender/draw/engines/eevee/eevee_motion_blur.c
@@ -165,11 +165,7 @@ int EEVEE_motion_blur_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *veda
#if 0 /* for future high quality blur */
/* Future matrix */
eevee_motion_blur_camera_get_matrix_at_time(
- scene,
- ar, rv3d, v3d,
- ob_camera_eval,
- ctime + delta,
- effects->future_world_to_ndc);
+ scene, ar, rv3d, v3d, ob_camera_eval, ctime + delta, effects->future_world_to_ndc);
#endif
invert_m4_m4(effects->current_ndc_to_world, effects->current_world_to_ndc);
}
diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h
index 8e21c7f389c..c3cd25923b2 100644
--- a/source/blender/draw/engines/eevee/eevee_private.h
+++ b/source/blender/draw/engines/eevee/eevee_private.h
@@ -246,6 +246,7 @@ typedef struct EEVEE_PassList {
struct DRWPass *color_downsample_cube_ps;
struct DRWPass *velocity_resolve;
struct DRWPass *taa_resolve;
+ struct DRWPass *alpha_checker;
/* HiZ */
struct DRWPass *minz_downlevel_ps;
@@ -275,7 +276,8 @@ typedef struct EEVEE_PassList {
struct DRWPass *transparent_pass;
struct DRWPass *background_pass;
struct DRWPass *update_noise_pass;
- struct DRWPass *lookdev_pass;
+ struct DRWPass *lookdev_glossy_pass;
+ struct DRWPass *lookdev_diffuse_pass;
} EEVEE_PassList;
typedef struct EEVEE_FramebufferList {
@@ -537,6 +539,7 @@ typedef enum EEVEE_EffectsFlag {
EFFECT_VELOCITY_BUFFER = (1 << 12), /* Not really an effect but a feature */
EFFECT_TAA_REPROJECT = (1 << 13), /* should be mutually exclusive with EFFECT_TAA */
EFFECT_DEPTH_DOUBLE_BUFFER = (1 << 14), /* Not really an effect but a feature */
+ EFFECT_ALPHA_CHECKER = (1 << 15), /* Not really an effect but a feature */
} EEVEE_EffectsFlag;
typedef struct EEVEE_EffectsInfo {
@@ -598,8 +601,14 @@ typedef struct EEVEE_EffectsInfo {
struct GPUTexture *dof_coc;
struct GPUTexture *dof_blur;
struct GPUTexture *dof_blur_alpha;
+ /* Alpha Checker */
+ float color_checker_dark[4];
+ float color_checker_light[4];
/* Other */
float prev_persmat[4][4];
+ /* Lookdev */
+ int ball_size;
+ int anchor[2];
/* Bloom */
int bloom_iteration_len;
float source_texel_size[2];
@@ -1044,6 +1053,9 @@ void EEVEE_mist_free(void);
/* eevee_temporal_sampling.c */
void EEVEE_temporal_sampling_reset(EEVEE_Data *vedata);
int EEVEE_temporal_sampling_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
+void EEVEE_temporal_sampling_offset_calc(const double ht_point[2],
+ const float filter_size,
+ float r_offset[2]);
void EEVEE_temporal_sampling_matrices_calc(EEVEE_EffectsInfo *effects,
float viewmat[4][4],
float persmat[4][4],
@@ -1073,6 +1085,7 @@ void EEVEE_effects_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_create_minmax_buffer(EEVEE_Data *vedata, struct GPUTexture *depth_src, int layer);
void EEVEE_downsample_buffer(EEVEE_Data *vedata, struct GPUTexture *texture_src, int level);
void EEVEE_downsample_cube_buffer(EEVEE_Data *vedata, struct GPUTexture *texture_src, int level);
+void EEVEE_draw_alpha_checker(EEVEE_Data *vedata);
void EEVEE_draw_effects(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_effects_free(void);
@@ -1099,7 +1112,7 @@ void EEVEE_lookdev_cache_init(EEVEE_Data *vedata,
float background_alpha,
struct World *world,
EEVEE_LightProbesInfo *pinfo);
-void EEVEE_lookdev_draw_background(EEVEE_Data *vedata);
+void EEVEE_lookdev_draw(EEVEE_Data *vedata);
/** eevee_engine.c */
void EEVEE_cache_populate(void *vedata, Object *ob);
diff --git a/source/blender/draw/engines/eevee/eevee_screen_raytrace.c b/source/blender/draw/engines/eevee/eevee_screen_raytrace.c
index a3603fc3d64..22c7dd00b97 100644
--- a/source/blender/draw/engines/eevee/eevee_screen_raytrace.c
+++ b/source/blender/draw/engines/eevee/eevee_screen_raytrace.c
@@ -296,8 +296,9 @@ void EEVEE_reflection_compute(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *v
/* Resolve at fullres */
int sample = (DRW_state_is_image_render()) ? effects->taa_render_sample :
effects->taa_current_sample;
- /* Doing a neighbor shift only after a few iteration. We wait for a prime number of cycles to avoid
- * noise correlation. This reduces variance faster. */
+ /* Doing a neighbor shift only after a few iteration.
+ * We wait for a prime number of cycles to avoid noise correlation.
+ * This reduces variance faster. */
effects->ssr_neighbor_ofs = ((sample / 5) % 8) * 4;
switch ((sample / 11) % 4) {
case 0:
diff --git a/source/blender/draw/engines/eevee/eevee_temporal_sampling.c b/source/blender/draw/engines/eevee/eevee_temporal_sampling.c
index 54ceb1a167a..194fff9b93c 100644
--- a/source/blender/draw/engines/eevee/eevee_temporal_sampling.c
+++ b/source/blender/draw/engines/eevee/eevee_temporal_sampling.c
@@ -131,6 +131,14 @@ static void eevee_create_cdf_table_temporal_sampling(void)
e_data.inited = true;
}
+void EEVEE_temporal_sampling_offset_calc(const double ht_point[2],
+ const float filter_size,
+ float r_offset[2])
+{
+ r_offset[0] = eval_table(e_data.inverted_cdf, (float)(ht_point[0])) * filter_size;
+ r_offset[1] = eval_table(e_data.inverted_cdf, (float)(ht_point[1])) * filter_size;
+}
+
void EEVEE_temporal_sampling_matrices_calc(EEVEE_EffectsInfo *effects,
float viewmat[4][4],
float persmat[4][4],
@@ -141,13 +149,11 @@ void EEVEE_temporal_sampling_matrices_calc(EEVEE_EffectsInfo *effects,
Scene *scene = draw_ctx->scene;
RenderData *rd = &scene->r;
- float filter_size = rd->gauss; /* Sigh.. Stupid legacy naming. */
-
- float ofs_x = eval_table(e_data.inverted_cdf, (float)(ht_point[0])) * filter_size;
- float ofs_y = eval_table(e_data.inverted_cdf, (float)(ht_point[1])) * filter_size;
+ float ofs[2];
+ EEVEE_temporal_sampling_offset_calc(ht_point, rd->gauss, ofs);
window_translate_m4(
- effects->overide_winmat, persmat, ofs_x / viewport_size[0], ofs_y / viewport_size[1]);
+ effects->overide_winmat, persmat, ofs[0] / viewport_size[0], ofs[1] / viewport_size[1]);
mul_m4_m4m4(effects->overide_persmat, effects->overide_winmat, viewmat);
invert_m4_m4(effects->overide_persinv, effects->overide_persmat);
@@ -157,6 +163,7 @@ void EEVEE_temporal_sampling_matrices_calc(EEVEE_EffectsInfo *effects,
void EEVEE_temporal_sampling_reset(EEVEE_Data *vedata)
{
vedata->stl->effects->taa_render_sample = 1;
+ vedata->stl->effects->taa_current_sample = 1;
}
int EEVEE_temporal_sampling_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
diff --git a/source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl b/source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl
index f23303c5b93..32076b47d8c 100644
--- a/source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl
@@ -1,7 +1,8 @@
/* Based on Practical Realtime Strategies for Accurate Indirect Occlusion
* http://blog.selfshadow.com/publications/s2016-shading-course/activision/s2016_pbs_activision_occlusion.pdf
- * http://blog.selfshadow.com/publications/s2016-shading-course/activision/s2016_pbs_activision_occlusion.pptx */
+ * http://blog.selfshadow.com/publications/s2016-shading-course/activision/s2016_pbs_activision_occlusion.pptx
+ */
#if defined(MESH_SHADER)
# if !defined(USE_ALPHA_HASH)
diff --git a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
index fdaec58977f..3a5f20b952e 100644
--- a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
@@ -319,7 +319,8 @@ float line_unit_sphere_intersect_dist(vec3 lineorigin, vec3 linedirection)
float line_unit_box_intersect_dist(vec3 lineorigin, vec3 linedirection)
{
- /* https://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/ */
+ /* https://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/
+ */
vec3 firstplane = (vec3(1.0) - lineorigin) / linedirection;
vec3 secondplane = (vec3(-1.0) - lineorigin) / linedirection;
vec3 furthestplane = max(firstplane, secondplane);
@@ -837,9 +838,16 @@ Closure closure_mix(Closure cl1, Closure cl2, float fac)
# ifdef USE_SSS
cl.sss_data.rgb = mix(cl1.sss_data.rgb, cl2.sss_data.rgb, fac);
cl.sss_data.a = (cl1.sss_data.a > 0.0) ? cl1.sss_data.a : cl2.sss_data.a;
+
# ifdef USE_SSS_ALBEDO
/* TODO Find a solution to this. Dither? */
cl.sss_albedo = (cl1.sss_data.a > 0.0) ? cl1.sss_albedo : cl2.sss_albedo;
+ /* Add radiance that was supposed to be filtered but was rejected. */
+ cl.radiance += (cl1.sss_data.a > 0.0) ? cl2.sss_data.rgb * cl2.sss_albedo :
+ cl1.sss_data.rgb * cl1.sss_albedo;
+# else
+ /* Add radiance that was supposed to be filtered but was rejected. */
+ cl.radiance += (cl1.sss_data.a > 0.0) ? cl2.sss_data.rgb : cl1.sss_data.rgb;
# endif
# endif
@@ -870,8 +878,10 @@ Closure closure_emission(vec3 rgb)
return cl;
}
-# if defined(MESH_SHADER) && !defined(USE_ALPHA_HASH) && !defined(USE_ALPHA_CLIP) && \
- !defined(SHADOW_SHADER) && !defined(USE_MULTIPLY)
+/* Breaking this across multiple lines causes issues for some older GLSL compilers. */
+/* clang-format off */
+# if defined(MESH_SHADER) && !defined(USE_ALPHA_HASH) && !defined(USE_ALPHA_CLIP) && !defined(SHADOW_SHADER) && !defined(USE_MULTIPLY)
+/* clang-format on */
layout(location = 0) out vec4 fragColor;
layout(location = 1) out vec4 ssrNormals;
layout(location = 2) out vec4 ssrData;
@@ -918,10 +928,19 @@ void main()
/* For Probe capture */
# ifdef USE_SSS
+ float fac = float(!sssToggle);
+
+# ifdef USE_REFRACTION
+ /* SSRefraction pass is done after the SSS pass.
+ * In order to not loose the diffuse light totally we
+ * need to merge the SSS radiance to the main radiance. */
+ fac = 1.0;
+# endif
+
# ifdef USE_SSS_ALBEDO
- fragColor.rgb += cl.sss_data.rgb * cl.sss_albedo.rgb * float(!sssToggle);
+ fragColor.rgb += cl.sss_data.rgb * cl.sss_albedo.rgb * fac;
# else
- fragColor.rgb += cl.sss_data.rgb * float(!sssToggle);
+ fragColor.rgb += cl.sss_data.rgb * fac;
# endif
# endif
}
diff --git a/source/blender/draw/engines/eevee/shaders/effect_dof_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_dof_frag.glsl
index 8a10962c6ef..d8cec17af58 100644
--- a/source/blender/draw/engines/eevee/shaders/effect_dof_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/effect_dof_frag.glsl
@@ -5,6 +5,7 @@ uniform sampler2D colorBuffer;
uniform sampler2D depthBuffer;
uniform vec2 dofParams;
+uniform bool unpremult;
#define dof_mul dofParams.x /* distance * aperturesize * invsensorsize */
#define dof_bias dofParams.y /* aperturesize * invsensorsize */
@@ -241,8 +242,12 @@ void main(void)
fragColor = (far_col + near_col + focus_col) * inv_weight_sum;
# ifdef USE_ALPHA_DOF
- /* Unpremult */
- fragColor.rgb /= (fragColor.a > 0.0) ? fragColor.a : 1.0;
+ /* Sigh... viewport expect premult output but
+ * the final render output needs to be with
+ * associated alpha. */
+ if (unpremult) {
+ fragColor.rgb /= (fragColor.a > 0.0) ? fragColor.a : 1.0;
+ }
# endif
}
diff --git a/source/blender/draw/engines/eevee/shaders/effect_temporal_aa.glsl b/source/blender/draw/engines/eevee/shaders/effect_temporal_aa.glsl
index 3ec695fcdbc..ac6751fb5fb 100644
--- a/source/blender/draw/engines/eevee/shaders/effect_temporal_aa.glsl
+++ b/source/blender/draw/engines/eevee/shaders/effect_temporal_aa.glsl
@@ -14,7 +14,8 @@ vec4 safe_color(vec4 c)
/**
* Adapted from https://casual-effects.com/g3d/G3D10/data-files/shader/Film/Film_temporalAA.pix
- * which is adapted from https://github.com/gokselgoktas/temporal-anti-aliasing/blob/master/Assets/Resources/Shaders/TemporalAntiAliasing.cginc
+ * which is adapted from
+ * https://github.com/gokselgoktas/temporal-anti-aliasing/blob/master/Assets/Resources/Shaders/TemporalAntiAliasing.cginc
* which is adapted from https://github.com/playdeadgames/temporal
* Optimization by Stubbesaurus and epsilon adjustment to avoid division by zero.
*
@@ -38,7 +39,6 @@ vec3 clip_to_aabb(vec3 color, vec3 minimum, vec3 maximum, vec3 average)
void main()
{
ivec2 texel = ivec2(gl_FragCoord.xy);
- float depth = texelFetch(depthBuffer, texel, 0).r;
vec2 motion = texelFetch(velocityBuffer, texel, 0).rg;
/* Decode from unsigned normalized 16bit texture. */
@@ -95,6 +95,9 @@ void main()
color_history = (out_of_view) ? color : color_history;
FragColor = safe_color(color_history);
+ /* There is some ghost issue if we use the alpha
+ * in the viewport. Overwritting alpha fixes it. */
+ FragColor.a = color.a;
}
#else
diff --git a/source/blender/draw/engines/eevee/shaders/effect_velocity_resolve_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_velocity_resolve_frag.glsl
index b9e038ceeaf..7d701bce5cb 100644
--- a/source/blender/draw/engines/eevee/shaders/effect_velocity_resolve_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/effect_velocity_resolve_frag.glsl
@@ -17,6 +17,9 @@ void main()
outData = uv - uv_history;
+ /* HACK: Reject lookdev spheres from TAA reprojection. */
+ outData = (depth > 0.0) ? outData : vec2(0.0);
+
/* Encode to unsigned normalized 16bit texture. */
outData = outData * 0.5 + 0.5;
}
diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl
index 0c7be71d914..a70ac686efd 100644
--- a/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl
@@ -161,7 +161,8 @@ vec3 probe_evaluate_cube(int pd_id, vec3 W, vec3 R, float roughness)
/* From Frostbite PBR Course
* Distance based roughness
- * http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf */
+ * http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf
+ */
float original_roughness = roughness;
float linear_roughness = sqrt(roughness);
float distance_roughness = saturate(dist * linear_roughness / length(intersection));
diff --git a/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl b/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl
index 7dba3738c12..37b0ebb33cf 100644
--- a/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl
@@ -44,6 +44,14 @@ uniform int hairThicknessRes = 1;
#define CLOSURE_GLOSSY
#endif /* SURFACE_DEFAULT */
+#if !defined(SURFACE_DEFAULT_CLEARCOAT) && !defined(CLOSURE_NAME)
+#define SURFACE_DEFAULT_CLEARCOAT
+#define CLOSURE_NAME eevee_closure_default_clearcoat
+#define CLOSURE_DIFFUSE
+#define CLOSURE_GLOSSY
+#define CLOSURE_CLEARCOAT
+#endif /* SURFACE_DEFAULT_CLEARCOAT */
+
#if !defined(SURFACE_PRINCIPLED) && !defined(CLOSURE_NAME)
#define SURFACE_PRINCIPLED
#define CLOSURE_NAME eevee_closure_principled
@@ -274,7 +282,8 @@ void CLOSURE_NAME(vec3 N
/* ---------------- SPECULAR ENVIRONMENT LIGHTING ----------------- */
/* ---------------------------------------------------------------- */
- /* Accumulate incoming light from all sources until accumulator is full. Then apply Occlusion and BRDF. */
+ /* Accumulate incoming light from all sources until accumulator is full. Then apply Occlusion and
+ * BRDF. */
#ifdef CLOSURE_GLOSSY
vec4 spec_accum = vec4(0.0);
#endif
diff --git a/source/blender/draw/engines/eevee/shaders/ltc_lib.glsl b/source/blender/draw/engines/eevee/shaders/ltc_lib.glsl
index 88dd9f46b55..2cf8501de9b 100644
--- a/source/blender/draw/engines/eevee/shaders/ltc_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/ltc_lib.glsl
@@ -164,8 +164,8 @@ void ltc_transform_quad(vec3 N, vec3 V, mat3 Minv, inout vec3 corners[4])
corners[3] = normalize(Minv * corners[3]);
}
-/* If corners have already pass through ltc_transform_quad(), then N **MUST** be vec3(0.0, 0.0, 1.0),
- * corresponding to the Up axis of the shading basis. */
+/* If corners have already pass through ltc_transform_quad(),
+ * then N **MUST** be vec3(0.0, 0.0, 1.0), corresponding to the Up axis of the shading basis. */
float ltc_evaluate_quad(vec3 corners[4], vec3 N)
{
/* Approximation using a sphere of the same solid angle than the quad.
diff --git a/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl b/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl
index 49c4569f585..82581f2327b 100644
--- a/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl
@@ -84,8 +84,8 @@ void prepare_raycast(vec3 ray_origin,
ss_end.w = project_point(ProjectionMatrix, ray_end).z;
/* XXX This is a hack a better method is welcome ! */
- /* We take the delta between the offseted depth and the depth and substract it from the ray depth.
- * This will change the world space thickness appearance a bit but we can have negative
+ /* We take the delta between the offseted depth and the depth and substract it from the ray
+ * depth. This will change the world space thickness appearance a bit but we can have negative
* values without worries. We cannot do this in viewspace because of the perspective division. */
ss_start.w = 2.0 * ss_start.z - ss_start.w;
ss_end.w = 2.0 * ss_end.z - ss_end.w;
diff --git a/source/blender/draw/engines/eevee/shaders/shadow_store_frag.glsl b/source/blender/draw/engines/eevee/shaders/shadow_store_frag.glsl
index 5c0f5adda27..f24032c4360 100644
--- a/source/blender/draw/engines/eevee/shaders/shadow_store_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/shadow_store_frag.glsl
@@ -36,7 +36,8 @@ vec3 octahedral_to_cubemap_proj(vec2 co)
}
/* Marco Salvi's GDC 2008 presentation about shadow maps pre-filtering techniques slide 24 */
-/* http://advances.realtimerendering.com/s2009/SIGGRAPH%202009%20-%20Lighting%20Research%20at%20Bungie.pdf Slide 55*/
+/* http://advances.realtimerendering.com/s2009/SIGGRAPH%202009%20-%20Lighting%20Research%20at%20Bungie.pdf
+ * Slide 55. */
#define ln_space_prefilter_step(ref, sample) exp(sample - ref)
#define ln_space_prefilter_finalize(ref, sum) (ref + log(shadowInvSampleCount * sum))
diff --git a/source/blender/draw/engines/external/external_engine.c b/source/blender/draw/engines/external/external_engine.c
index 29749ce6712..ed8c609c01f 100644
--- a/source/blender/draw/engines/external/external_engine.c
+++ b/source/blender/draw/engines/external/external_engine.c
@@ -54,12 +54,12 @@ typedef struct EXTERNAL_StorageList {
} EXTERNAL_StorageList;
typedef struct EXTERNAL_FramebufferList {
- struct GPUFrameBuffer *default_fb;
+ struct GPUFrameBuffer *depth_buffer_fb;
} EXTERNAL_FramebufferList;
typedef struct EXTERNAL_TextureList {
/* default */
- struct GPUTexture *depth;
+ struct GPUTexture *depth_buffer_tx;
} EXTERNAL_TextureList;
typedef struct EXTERNAL_PassList {
@@ -80,30 +80,77 @@ typedef struct EXTERNAL_Data {
static struct {
/* Depth Pre Pass */
struct GPUShader *depth_sh;
+ bool draw_depth;
} e_data = {NULL}; /* Engine data */
typedef struct EXTERNAL_PrivateData {
DRWShadingGroup *depth_shgrp;
+
+ /* Do we need to update the depth or can we reuse the last calculated texture. */
+ bool update_depth;
+ bool view_updated;
+
+ float last_mat[4][4];
+ float curr_mat[4][4];
} EXTERNAL_PrivateData; /* Transient data */
/* Functions */
-static void external_engine_init(void *UNUSED(vedata))
+static void external_engine_init(void *vedata)
{
+ EXTERNAL_StorageList *stl = ((EXTERNAL_Data *)vedata)->stl;
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ RegionView3D *rv3d = draw_ctx->rv3d;
+
/* Depth prepass */
if (!e_data.depth_sh) {
e_data.depth_sh = DRW_shader_create_3d_depth_only(GPU_SHADER_CFG_DEFAULT);
}
+
+ if (!stl->g_data) {
+ /* Alloc transient pointers */
+ stl->g_data = MEM_mallocN(sizeof(*stl->g_data), __func__);
+ stl->g_data->update_depth = true;
+ stl->g_data->view_updated = false;
+ }
+
+ if (stl->g_data->update_depth == false) {
+ if (rv3d && rv3d->rflag & RV3D_NAVIGATING) {
+ stl->g_data->update_depth = true;
+ }
+ }
+
+ if (stl->g_data->view_updated) {
+ stl->g_data->update_depth = true;
+ stl->g_data->view_updated = false;
+ }
+
+ {
+ float view[4][4];
+ float win[4][4];
+ DRW_viewport_matrix_get(view, DRW_MAT_VIEW);
+ DRW_viewport_matrix_get(win, DRW_MAT_WIN);
+ mul_m4_m4m4(stl->g_data->curr_mat, view, win);
+ if (!equals_m4m4(stl->g_data->curr_mat, stl->g_data->last_mat)) {
+ stl->g_data->update_depth = true;
+ }
+ }
}
static void external_cache_init(void *vedata)
{
EXTERNAL_PassList *psl = ((EXTERNAL_Data *)vedata)->psl;
EXTERNAL_StorageList *stl = ((EXTERNAL_Data *)vedata)->stl;
+ EXTERNAL_TextureList *txl = ((EXTERNAL_Data *)vedata)->txl;
+ EXTERNAL_FramebufferList *fbl = ((EXTERNAL_Data *)vedata)->fbl;
- if (!stl->g_data) {
- /* Alloc transient pointers */
- stl->g_data = MEM_mallocN(sizeof(*stl->g_data), __func__);
+ {
+ DRW_texture_ensure_fullscreen_2d(&txl->depth_buffer_tx, GPU_DEPTH24_STENCIL8, 0);
+
+ GPU_framebuffer_ensure_config(&fbl->depth_buffer_fb,
+ {
+ GPU_ATTACHMENT_TEXTURE(txl->depth_buffer_tx),
+ });
}
/* Depth Pass */
@@ -112,6 +159,16 @@ static void external_cache_init(void *vedata)
DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL);
stl->g_data->depth_shgrp = DRW_shgroup_create(e_data.depth_sh, psl->depth_pass);
}
+
+ /* Do not draw depth pass when overlays are turned off. */
+ e_data.draw_depth = false;
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ const View3D *v3d = draw_ctx->v3d;
+ if (v3d->flag2 & V3D_HIDE_OVERLAYS) {
+ /* mark `update_depth` for when overlays are turned on again. */
+ stl->g_data->update_depth = true;
+ return;
+ }
}
static void external_cache_populate(void *vedata, Object *ob)
@@ -122,10 +179,20 @@ static void external_cache_populate(void *vedata, Object *ob)
return;
}
- struct GPUBatch *geom = DRW_cache_object_surface_get(ob);
- if (geom) {
- /* Depth Prepass */
- DRW_shgroup_call_add(stl->g_data->depth_shgrp, geom, ob->obmat);
+ /* Do not draw depth pass when overlays are turned off. */
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ const View3D *v3d = draw_ctx->v3d;
+ if (v3d->flag2 & V3D_HIDE_OVERLAYS) {
+ return;
+ }
+
+ if (stl->g_data->update_depth) {
+ e_data.draw_depth = true;
+ struct GPUBatch *geom = DRW_cache_object_surface_get(ob);
+ if (geom) {
+ /* Depth Prepass */
+ DRW_shgroup_call_add(stl->g_data->depth_shgrp, geom, ob->obmat);
+ }
}
}
@@ -181,7 +248,10 @@ static void external_draw_scene_do(void *vedata)
static void external_draw_scene(void *vedata)
{
const DRWContextState *draw_ctx = DRW_context_state_get();
+ EXTERNAL_StorageList *stl = ((EXTERNAL_Data *)vedata)->stl;
EXTERNAL_PassList *psl = ((EXTERNAL_Data *)vedata)->psl;
+ EXTERNAL_FramebufferList *fbl = ((EXTERNAL_Data *)vedata)->fbl;
+ const DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
/* Will be NULL during OpenGL render.
* OpenGL render is used for quick preview (thumbnails or sequencer preview)
@@ -189,7 +259,28 @@ static void external_draw_scene(void *vedata)
if (draw_ctx->evil_C) {
external_draw_scene_do(vedata);
}
- DRW_draw_pass(psl->depth_pass);
+
+ if (e_data.draw_depth) {
+ DRW_draw_pass(psl->depth_pass);
+ // copy result to tmp buffer
+ GPU_framebuffer_blit(dfbl->depth_only_fb, 0, fbl->depth_buffer_fb, 0, GPU_DEPTH_BIT);
+ stl->g_data->update_depth = false;
+ }
+ else {
+ // copy tmp buffer to default
+ GPU_framebuffer_blit(fbl->depth_buffer_fb, 0, dfbl->depth_only_fb, 0, GPU_DEPTH_BIT);
+ }
+
+ copy_m4_m4(stl->g_data->last_mat, stl->g_data->curr_mat);
+}
+
+static void external_view_update(void *vedata)
+{
+ EXTERNAL_Data *data = vedata;
+ EXTERNAL_StorageList *stl = data->stl;
+ if (stl && stl->g_data) {
+ stl->g_data->view_updated = true;
+ }
}
static void external_engine_free(void)
@@ -211,12 +302,13 @@ static DrawEngineType draw_engine_external_type = {
&external_cache_finish,
NULL,
&external_draw_scene,
- NULL,
+ &external_view_update,
NULL,
NULL,
};
-/* Note: currently unused, we should not register unless we want to see this when debugging the view. */
+/* Note: currently unused,
+ * we should not register unless we want to see this when debugging the view. */
RenderEngineType DRW_engine_viewport_external_type = {
NULL,
diff --git a/source/blender/draw/engines/gpencil/gpencil_cache_utils.c b/source/blender/draw/engines/gpencil/gpencil_cache_utils.c
index 76ec0a61b8c..67ffe62f3c6 100644
--- a/source/blender/draw/engines/gpencil/gpencil_cache_utils.c
+++ b/source/blender/draw/engines/gpencil/gpencil_cache_utils.c
@@ -78,8 +78,8 @@ tGPencilObjectCache *gpencil_object_cache_add(tGPencilObjectCache *cache_array,
tGPencilObjectCache *p = NULL;
/* By default a cache is created with one block with a predefined number of free slots,
- if the size is not enough, the cache is reallocated adding a new block of free slots.
- This is done in order to keep cache small */
+ * if the size is not enough, the cache is reallocated adding a new block of free slots.
+ * This is done in order to keep cache small. */
if (*gp_cache_used + 1 > *gp_cache_size) {
if ((*gp_cache_size == 0) || (cache_array == NULL)) {
p = MEM_callocN(sizeof(struct tGPencilObjectCache) * GP_CACHE_BLOCK_SIZE,
@@ -187,8 +187,8 @@ GpencilBatchGroup *gpencil_group_cache_add(GpencilBatchGroup *cache_array,
GpencilBatchGroup *p = NULL;
/* By default a cache is created with one block with a predefined number of free slots,
- if the size is not enough, the cache is reallocated adding a new block of free slots.
- This is done in order to keep cache small */
+ * if the size is not enough, the cache is reallocated adding a new block of free slots.
+ * This is done in order to keep cache small. */
if (*grp_used + 1 > *grp_size) {
if ((*grp_size == 0) || (cache_array == NULL)) {
p = MEM_callocN(sizeof(struct GpencilBatchGroup) * GPENCIL_GROUPS_BLOCK_SIZE,
diff --git a/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c b/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c
index 9e71791fbf3..7dabbcf4c41 100644
--- a/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c
+++ b/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c
@@ -71,6 +71,40 @@ static void gpencil_set_stroke_point(GPUVertBuf *vbo,
GPU_vertbuf_attr_set(vbo, pos_id, idx, &pt->x);
}
+/* Helper to add buffer_stroke point to vbo */
+static void gpencil_set_buffer_stroke_point(GPUVertBuf *vbo,
+ const bGPDspoint *pt,
+ int idx,
+ uint pos_id,
+ uint color_id,
+ uint thickness_id,
+ uint uvdata_id,
+ uint prev_pos_id,
+ float ref_pt[3],
+ short thickness,
+ const float ink[4])
+{
+
+ float alpha = ink[3] * pt->strength;
+ CLAMP(alpha, GPENCIL_STRENGTH_MIN, 1.0f);
+ float col[4];
+ ARRAY_SET_ITEMS(col, ink[0], ink[1], ink[2], alpha);
+
+ GPU_vertbuf_attr_set(vbo, color_id, idx, col);
+
+ /* transfer both values using the same shader variable */
+ float uvdata[2] = {pt->uv_fac, pt->uv_rot};
+ GPU_vertbuf_attr_set(vbo, uvdata_id, idx, uvdata);
+
+ /* the thickness of the stroke must be affected by zoom, so a pixel scale is calculated */
+ float thick = max_ff(pt->pressure * thickness, 1.0f);
+ GPU_vertbuf_attr_set(vbo, thickness_id, idx, &thick);
+
+ GPU_vertbuf_attr_set(vbo, pos_id, idx, &pt->x);
+ /* reference point to follow drawing path */
+ GPU_vertbuf_attr_set(vbo, prev_pos_id, idx, ref_pt);
+}
+
/* Helper to add a new fill point and texture coordinates to vertex buffer */
static void gpencil_set_fill_point(GPUVertBuf *vbo,
int idx,
@@ -142,16 +176,20 @@ void DRW_gpencil_get_point_geom(GpencilBatchCacheElem *be,
/* use previous point to determine stroke direction */
bGPDspoint *pt2 = NULL;
+ float fpt[3];
if (i == 0) {
if (gps->totpoints > 1) {
/* extrapolate a point before first point */
- float fpt[3];
pt2 = &gps->points[1];
interp_v3_v3v3(fpt, &pt2->x, &pt->x, 1.5f);
GPU_vertbuf_attr_set(be->vbo, be->prev_pos_id, be->vbo_len, fpt);
}
else {
- GPU_vertbuf_attr_set(be->vbo, be->prev_pos_id, be->vbo_len, &pt->x);
+ /* add small offset to get a vector */
+ copy_v3_v3(fpt, &pt->x);
+ fpt[0] += 0.00001f;
+ fpt[1] += 0.00001f;
+ GPU_vertbuf_attr_set(be->vbo, be->prev_pos_id, be->vbo_len, fpt);
}
}
else {
@@ -433,12 +471,13 @@ GPUBatch *DRW_gpencil_get_buffer_point_geom(bGPdata *gpd, short thickness)
int totpoints = gpd->runtime.sbuffer_size;
static GPUVertFormat format = {0};
- static uint pos_id, color_id, thickness_id, uvdata_id;
+ static uint pos_id, color_id, thickness_id, uvdata_id, prev_pos_id;
if (format.attr_len == 0) {
pos_id = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
color_id = GPU_vertformat_attr_add(&format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
thickness_id = GPU_vertformat_attr_add(&format, "thickness", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
uvdata_id = GPU_vertformat_attr_add(&format, "uvdata", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ prev_pos_id = GPU_vertformat_attr_add(&format, "prev_pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
}
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
@@ -458,9 +497,43 @@ GPUBatch *DRW_gpencil_get_buffer_point_geom(bGPdata *gpd, short thickness)
ED_gpencil_tpoint_to_point(ar, origin, tpt, &pt);
ED_gp_project_point_to_plane(scene, ob, rv3d, origin, ts->gp_sculpt.lock_axis - 1, &pt);
+ /* use previous point to determine stroke direction (drawing path) */
+ bGPDspoint pt2;
+ float ref_pt[3];
+
+ if (i == 0) {
+ if (totpoints > 1) {
+ /* extrapolate a point before first point */
+ tGPspoint *tpt2 = &points[1];
+ ED_gpencil_tpoint_to_point(ar, origin, tpt2, &pt2);
+ ED_gp_project_point_to_plane(scene, ob, rv3d, origin, ts->gp_sculpt.lock_axis - 1, &pt2);
+
+ interp_v3_v3v3(ref_pt, &pt2.x, &pt.x, 1.5f);
+ }
+ else {
+ copy_v3_v3(ref_pt, &pt.x);
+ }
+ }
+ else {
+ tGPspoint *tpt2 = &points[i - 1];
+ ED_gpencil_tpoint_to_point(ar, origin, tpt2, &pt2);
+ ED_gp_project_point_to_plane(scene, ob, rv3d, origin, ts->gp_sculpt.lock_axis - 1, &pt2);
+
+ copy_v3_v3(ref_pt, &pt2.x);
+ }
+
/* set point */
- gpencil_set_stroke_point(
- vbo, &pt, idx, pos_id, color_id, thickness_id, uvdata_id, thickness, gpd->runtime.scolor);
+ gpencil_set_buffer_stroke_point(vbo,
+ &pt,
+ idx,
+ pos_id,
+ color_id,
+ thickness_id,
+ uvdata_id,
+ prev_pos_id,
+ ref_pt,
+ thickness,
+ gpd->runtime.scolor);
idx++;
}
@@ -561,8 +634,9 @@ GPUBatch *DRW_gpencil_get_buffer_fill_geom(bGPdata *gpd)
float(*points2d)[2] = MEM_mallocN(sizeof(*points2d) * totpoints, __func__);
/* Convert points to array and triangulate
- * Here a cache is not used because while drawing the information changes all the time, so the cache
- * would be recalculated constantly, so it is better to do direct calculation for each function call
+ * Here a cache is not used because while drawing the information changes all the time, so the
+ * cache would be recalculated constantly, so it is better to do direct calculation for each
+ * function call
*/
for (int i = 0; i < totpoints; i++) {
const tGPspoint *pt = &points[i];
diff --git a/source/blender/draw/engines/gpencil/gpencil_draw_utils.c b/source/blender/draw/engines/gpencil/gpencil_draw_utils.c
index 320b621f903..4b6c913785d 100644
--- a/source/blender/draw/engines/gpencil/gpencil_draw_utils.c
+++ b/source/blender/draw/engines/gpencil/gpencil_draw_utils.c
@@ -421,7 +421,7 @@ static DRWShadingGroup *DRW_gpencil_shgroup_fill_create(GPENCIL_e_data *e_data,
DRW_shgroup_uniform_float(grp, "texture_opacity", &gp_style->texture_opacity, 1);
DRW_shgroup_uniform_float(grp, "layer_opacity", &gpl->opacity, 1);
- stl->shgroups[id].texture_mix = gp_style->flag & GP_STYLE_COLOR_TEX_MIX ? 1 : 0;
+ stl->shgroups[id].texture_mix = gp_style->flag & GP_STYLE_FILL_TEX_MIX ? 1 : 0;
DRW_shgroup_uniform_int(grp, "texture_mix", &stl->shgroups[id].texture_mix, 1);
stl->shgroups[id].texture_flip = gp_style->flag & GP_STYLE_COLOR_FLIP_FILL ? 1 : 0;
@@ -450,7 +450,7 @@ static DRWShadingGroup *DRW_gpencil_shgroup_fill_create(GPENCIL_e_data *e_data,
DRW_shgroup_uniform_vec4(grp, "wire_color", stl->shgroups[id].wire_color, 1);
/* image texture */
- if ((gp_style->flag & GP_STYLE_COLOR_TEX_MIX) ||
+ if ((gp_style->flag & GP_STYLE_FILL_TEX_MIX) ||
(gp_style->fill_style & GP_STYLE_FILL_STYLE_TEXTURE)) {
ImBuf *ibuf;
Image *image = gp_style->ima;
@@ -569,6 +569,12 @@ DRWShadingGroup *DRW_gpencil_shgroup_stroke_create(GPENCIL_e_data *e_data,
/* wire color */
set_wireframe_color(ob, gpl, v3d, stl, gp_style, id, false);
DRW_shgroup_uniform_vec4(grp, "wire_color", stl->shgroups[id].wire_color, 1);
+
+ /* mix stroke factor */
+ stl->shgroups[id].mix_stroke_factor = (gp_style->flag & GP_STYLE_STROKE_TEX_MIX) ?
+ gp_style->mix_stroke_factor :
+ 0.0f;
+ DRW_shgroup_uniform_float(grp, "mix_stroke_factor", &stl->shgroups[id].mix_stroke_factor, 1);
}
else {
stl->storage->obj_scale = 1.0f;
@@ -591,8 +597,16 @@ DRWShadingGroup *DRW_gpencil_shgroup_stroke_create(GPENCIL_e_data *e_data,
/* viewport x-ray */
DRW_shgroup_uniform_int(grp, "viewport_xray", &stl->storage->is_xray, 1);
DRW_shgroup_uniform_int(grp, "shading_type", (const int *)&stl->storage->shade_render, 2);
+
+ /* mix stroke factor */
+ stl->storage->mix_stroke_factor = (gp_style->flag & GP_STYLE_STROKE_TEX_MIX) ?
+ gp_style->mix_stroke_factor :
+ 0.0f;
+ DRW_shgroup_uniform_float(grp, "mix_stroke_factor", &stl->storage->mix_stroke_factor, 1);
}
+ DRW_shgroup_uniform_vec4(grp, "colormix", gp_style->stroke_rgba, 1);
+
if ((gpd) && (id > -1)) {
stl->shgroups[id].xray_mode = (ob->dtx & OB_DRAWXRAY) ? GP_XRAY_FRONT : GP_XRAY_3DSPACE;
DRW_shgroup_uniform_int(grp, "xraymode", &stl->shgroups[id].xray_mode, 1);
@@ -703,6 +717,16 @@ static DRWShadingGroup *DRW_gpencil_shgroup_point_create(GPENCIL_e_data *e_data,
/* wire color */
set_wireframe_color(ob, gpl, v3d, stl, gp_style, id, false);
DRW_shgroup_uniform_vec4(grp, "wire_color", stl->shgroups[id].wire_color, 1);
+
+ /* mix stroke factor */
+ stl->shgroups[id].mix_stroke_factor = (gp_style->flag & GP_STYLE_STROKE_TEX_MIX) ?
+ gp_style->mix_stroke_factor :
+ 0.0f;
+ DRW_shgroup_uniform_float(grp, "mix_stroke_factor", &stl->shgroups[id].mix_stroke_factor, 1);
+
+ /* lock rotation of dots and boxes */
+ stl->shgroups[id].use_follow_path = (gp_style->flag & GP_STYLE_COLOR_LOCK_DOTS) ? 0 : 1;
+ DRW_shgroup_uniform_int(grp, "use_follow_path", &stl->shgroups[id].use_follow_path, 1);
}
else {
stl->storage->obj_scale = 1.0f;
@@ -724,25 +748,28 @@ static DRWShadingGroup *DRW_gpencil_shgroup_point_create(GPENCIL_e_data *e_data,
DRW_shgroup_uniform_vec2(grp, "gradient_s", stl->storage->gradient_s, 1);
/* viewport x-ray */
- stl->shgroups[id].is_xray = ((ob) && (ob->dt == OB_WIRE)) ? 1 : stl->storage->is_xray;
- DRW_shgroup_uniform_int(grp, "viewport_xray", (const int *)&stl->shgroups[id].is_xray, 1);
+ DRW_shgroup_uniform_int(grp, "viewport_xray", &stl->storage->is_xray, 1);
DRW_shgroup_uniform_int(grp, "shading_type", (const int *)&stl->storage->shade_render, 2);
+
+ /* mix stroke factor */
+ stl->storage->mix_stroke_factor = (gp_style->flag & GP_STYLE_STROKE_TEX_MIX) ?
+ gp_style->mix_stroke_factor :
+ 0.0f;
+ DRW_shgroup_uniform_float(grp, "mix_stroke_factor", &stl->storage->mix_stroke_factor, 1);
+
+ /* lock rotation of dots and boxes */
+ DRW_shgroup_uniform_int(grp, "use_follow_path", &stl->storage->use_follow_path, 1);
}
+ DRW_shgroup_uniform_vec4(grp, "colormix", gp_style->stroke_rgba, 1);
+
if ((gpd) && (id > -1)) {
stl->shgroups[id].xray_mode = (ob->dtx & OB_DRAWXRAY) ? GP_XRAY_FRONT : GP_XRAY_3DSPACE;
DRW_shgroup_uniform_int(grp, "xraymode", (const int *)&stl->shgroups[id].xray_mode, 1);
-
- /* lock rotation of dots and boxes */
- stl->shgroups[id].use_follow_path = (gp_style->flag & GP_STYLE_COLOR_LOCK_DOTS) ? 0 : 1;
- DRW_shgroup_uniform_int(grp, "use_follow_path", &stl->shgroups[id].use_follow_path, 1);
}
else {
/* for drawing always on predefined z-depth */
DRW_shgroup_uniform_int(grp, "xraymode", &stl->storage->xray, 1);
-
- /* lock rotation of dots and boxes */
- DRW_shgroup_uniform_int(grp, "use_follow_path", &stl->storage->use_follow_path, 1);
}
/* image texture */
@@ -1045,7 +1072,8 @@ static void gpencil_draw_strokes(GpencilBatchCache *cache,
DRW_gpencil_recalc_geometry_caches(ob, gpl, gp_style, src_gps);
}
- /* if the fill has any value, it's considered a fill and is not drawn if simplify fill is enabled */
+ /* if the fill has any value, it's considered a fill and is not drawn if simplify fill is
+ * enabled */
if ((stl->storage->simplify_fill) &&
(scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_REMOVE_FILL_LINE)) {
if ((gp_style->fill_rgba[3] > GPENCIL_ALPHA_OPACITY_THRESH) ||
@@ -1340,7 +1368,8 @@ static void gpencil_copy_frame(bGPDframe *gpf, bGPDframe *derived_gpf)
}
}
-/* Triangulate stroke for high quality fill (this is done only if cache is null or stroke was modified) */
+/* Triangulate stroke for high quality fill (this is done only if cache is null or stroke was
+ * modified) */
void DRW_gpencil_triangulate_stroke_fill(Object *ob, bGPDstroke *gps)
{
BLI_assert(gps->totpoints >= 3);
@@ -1429,6 +1458,7 @@ void DRW_gpencil_populate_buffer_strokes(GPENCIL_e_data *e_data,
View3D *v3d = draw_ctx->v3d;
const bool overlay = v3d != NULL ? (bool)((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0) : true;
Brush *brush = BKE_paint_brush(&ts->gp_paint->paint);
+ const bool is_paint_tool = (bool)((brush) && (brush->gpencil_tool == GPAINT_TOOL_DRAW));
bGPdata *gpd_eval = ob->data;
/* need the original to avoid cow overhead while drawing */
bGPdata *gpd = (bGPdata *)DEG_get_original_id(&gpd_eval->id);
@@ -1554,7 +1584,7 @@ void DRW_gpencil_populate_buffer_strokes(GPENCIL_e_data *e_data,
const bool is_show_gizmo = (((v3d->gizmo_flag & V3D_GIZMO_HIDE) == 0) &&
((v3d->gizmo_flag & V3D_GIZMO_HIDE_TOOL) == 0));
- if ((overlay) && (is_cppoint || is_speed_guide) && (is_show_gizmo) &&
+ if ((overlay) && (is_paint_tool) && (is_cppoint || is_speed_guide) && (is_show_gizmo) &&
((gpd->runtime.sbuffer_sflag & GP_STROKE_ERASER) == 0)) {
DRWShadingGroup *shgrp = DRW_shgroup_create(e_data->gpencil_edit_point_sh, psl->drawing_pass);
const float *viewport_size = DRW_viewport_size_get();
@@ -1621,6 +1651,16 @@ static void DRW_gpencil_shgroups_create(GPENCIL_e_data *e_data,
int idx = 0;
bool tag_first = false;
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ const View3D *v3d = draw_ctx->v3d;
+
+ const bool overlay = draw_ctx->v3d != NULL ?
+ (bool)((draw_ctx->v3d->flag2 & V3D_HIDE_OVERLAYS) == 0) :
+ true;
+ const bool main_onion = v3d != NULL ? (v3d->gp_flag & V3D_GP_SHOW_ONION_SKIN) : true;
+ const bool do_onion = (bool)((gpd->flag & GP_DATA_STROKE_WEIGHTMODE) == 0) && main_onion &&
+ DRW_gpencil_onion_active(gpd) && overlay;
+
int start_stroke = 0;
int start_point = 0;
int start_fill = 0;
@@ -1680,14 +1720,14 @@ static void DRW_gpencil_shgroups_create(GPENCIL_e_data *e_data,
elm->onion,
scale,
cache_ob->shading_type);
-
- DRW_shgroup_call_range_add(shgrp,
- cache->b_stroke.batch,
- (!cache_ob->is_dup_ob) ? gpf->runtime.viewmatrix :
- cache_ob->obmat,
- start_stroke,
- len);
-
+ if ((do_onion) || (elm->onion == false)) {
+ DRW_shgroup_call_range_add(shgrp,
+ cache->b_stroke.batch,
+ (!cache_ob->is_dup_ob) ? gpf->runtime.viewmatrix :
+ cache_ob->obmat,
+ start_stroke,
+ len);
+ }
stl->storage->shgroup_id++;
start_stroke = elm->vertex_idx;
break;
@@ -1709,13 +1749,14 @@ static void DRW_gpencil_shgroups_create(GPENCIL_e_data *e_data,
scale,
cache_ob->shading_type);
- DRW_shgroup_call_range_add(shgrp,
- cache->b_point.batch,
- (!cache_ob->is_dup_ob) ? gpf->runtime.viewmatrix :
- cache_ob->obmat,
- start_point,
- len);
-
+ if ((do_onion) || (elm->onion == false)) {
+ DRW_shgroup_call_range_add(shgrp,
+ cache->b_point.batch,
+ (!cache_ob->is_dup_ob) ? gpf->runtime.viewmatrix :
+ cache_ob->obmat,
+ start_point,
+ len);
+ }
stl->storage->shgroup_id++;
start_point = elm->vertex_idx;
break;
@@ -1734,13 +1775,14 @@ static void DRW_gpencil_shgroups_create(GPENCIL_e_data *e_data,
stl->storage->shgroup_id,
cache_ob->shading_type);
- DRW_shgroup_call_range_add(shgrp,
- cache->b_fill.batch,
- (!cache_ob->is_dup_ob) ? gpf->runtime.viewmatrix :
- cache_ob->obmat,
- start_fill,
- len);
-
+ if ((do_onion) || (elm->onion == false)) {
+ DRW_shgroup_call_range_add(shgrp,
+ cache->b_fill.batch,
+ (!cache_ob->is_dup_ob) ? gpf->runtime.viewmatrix :
+ cache_ob->obmat,
+ start_fill,
+ len);
+ }
stl->storage->shgroup_id++;
start_fill = elm->vertex_idx;
break;
@@ -1870,6 +1912,28 @@ void DRW_gpencil_populate_multiedit(GPENCIL_e_data *e_data,
cache->is_dirty = false;
}
+/* ensure there is a derived frame */
+static void gpencil_ensure_derived_frame(bGPdata *gpd,
+ bGPDlayer *gpl,
+ bGPDframe *gpf,
+ GpencilBatchCache *cache,
+ bGPDframe **derived_gpf)
+{
+ /* create derived frames array data or expand */
+ int derived_idx = BLI_findindex(&gpd->layers, gpl);
+ *derived_gpf = &cache->derived_array[derived_idx];
+
+ /* if no derived frame or dirty cache, create a new one */
+ if ((*derived_gpf == NULL) || (cache->is_dirty)) {
+ if (*derived_gpf != NULL) {
+ /* first clear temp data */
+ BKE_gpencil_free_frame_runtime_data(*derived_gpf);
+ }
+ /* create new data (do not assign new memory)*/
+ gpencil_copy_frame(gpf, *derived_gpf);
+ }
+}
+
/* helper for populate a complete grease pencil datablock */
void DRW_gpencil_populate_datablock(GPENCIL_e_data *e_data,
void *vedata,
@@ -1887,9 +1951,6 @@ void DRW_gpencil_populate_datablock(GPENCIL_e_data *e_data,
int cfra_eval = (int)DEG_get_ctime(draw_ctx->depsgraph);
bGPDframe *derived_gpf = NULL;
- const bool main_onion = v3d != NULL ? (v3d->gp_flag & V3D_GP_SHOW_ONION_SKIN) : true;
- const bool do_onion = (bool)((gpd->flag & GP_DATA_STROKE_WEIGHTMODE) == 0) && main_onion &&
- DRW_gpencil_onion_active(gpd);
const bool overlay = v3d != NULL ? (bool)((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0) : true;
const bool time_remap = BKE_gpencil_has_time_modifiers(ob);
@@ -1965,25 +2026,14 @@ void DRW_gpencil_populate_datablock(GPENCIL_e_data *e_data,
}
/* create derived frames array data or expand */
- int derived_idx = BLI_findindex(&gpd->layers, gpl);
- derived_gpf = &cache->derived_array[derived_idx];
-
- /* if no derived frame or dirty cache, create a new one */
- if ((derived_gpf == NULL) || (cache->is_dirty)) {
- if (derived_gpf != NULL) {
- /* first clear temp data */
- BKE_gpencil_free_frame_runtime_data(derived_gpf);
- }
- /* create new data (do not assign new memory)*/
- gpencil_copy_frame(gpf, derived_gpf);
- }
+ gpencil_ensure_derived_frame(gpd, gpl, gpf, cache, &derived_gpf);
/* draw onion skins */
if (!ID_IS_LINKED(&gpd->id)) {
- if ((do_onion) && (gpl->onion_flag & GP_LAYER_ONIONSKIN) &&
+ if ((gpl->onion_flag & GP_LAYER_ONIONSKIN) &&
((!playing) || (gpd->onion_flag & GP_ONION_GHOST_ALWAYS)) && (!cache_ob->is_dup_ob) &&
(gpd->id.us <= 1)) {
- if (((!stl->storage->is_render) && (overlay)) ||
+ if ((!stl->storage->is_render) ||
((stl->storage->is_render) && (gpd->onion_flag & GP_ONION_GHOST_ALWAYS))) {
gpencil_draw_onionskins(cache, vedata, ob, gpd, gpl, gpf);
}
diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.c b/source/blender/draw/engines/gpencil/gpencil_engine.c
index 6fa07245396..ea578187765 100644
--- a/source/blender/draw/engines/gpencil/gpencil_engine.c
+++ b/source/blender/draw/engines/gpencil/gpencil_engine.c
@@ -328,7 +328,8 @@ void GPENCIL_cache_init(void *vedata)
stl->g_data->shgrps_edit_point = NULL;
if (!stl->shgroups) {
- /* Alloc maximum size because count strokes is very slow and can be very complex due onion skinning.
+ /* Alloc maximum size because count strokes is very slow and can be very complex due onion
+ * skinning.
*/
stl->shgroups = MEM_mallocN(sizeof(GPENCIL_shgroup) * GPENCIL_MAX_SHGROUPS, "GPENCIL_shgroup");
}
diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.h b/source/blender/draw/engines/gpencil/gpencil_engine.h
index 3add2cb0f1b..2ac1dc3211c 100644
--- a/source/blender/draw/engines/gpencil/gpencil_engine.h
+++ b/source/blender/draw/engines/gpencil/gpencil_engine.h
@@ -134,6 +134,8 @@ typedef struct GPENCIL_shgroup {
float gradient_f;
float gradient_s[2];
+ float mix_stroke_factor;
+
/* color of the wireframe */
float wire_color[4];
/* shading type and mode */
@@ -182,6 +184,8 @@ typedef struct GPENCIL_Storage {
float gradient_s[2];
int use_follow_path;
+ float mix_stroke_factor;
+
/* Render Matrices and data */
float persmat[4][4], persinv[4][4];
float viewmat[4][4], viewinv[4][4];
diff --git a/source/blender/draw/engines/gpencil/gpencil_render.c b/source/blender/draw/engines/gpencil/gpencil_render.c
index 282c4ca3a77..e6a3f45d60d 100644
--- a/source/blender/draw/engines/gpencil/gpencil_render.c
+++ b/source/blender/draw/engines/gpencil/gpencil_render.c
@@ -18,7 +18,7 @@
/** \file
* \ingroup draw
- */
+ */
#include "BLI_rect.h"
#include "DRW_render.h"
@@ -36,9 +36,9 @@
#include "gpencil_engine.h"
/* Get pixel size for render
- * This function uses the same calculation used for viewport, because if use
- * camera pixelsize, the result is not correct.
- */
+ * This function uses the same calculation used for viewport, because if use
+ * camera pixelsize, the result is not correct.
+ */
static float get_render_pixelsize(float persmat[4][4], int winx, int winy)
{
float v1[3], v2[3];
@@ -138,10 +138,12 @@ static void GPENCIL_render_update_viewvecs(float invproj[4][4],
{
/* view vectors for the corners of the view frustum.
* Can be used to recreate the world space position easily */
- float view_vecs[4][4] = {{-1.0f, -1.0f, -1.0f, 1.0f},
- {1.0f, -1.0f, -1.0f, 1.0f},
- {-1.0f, 1.0f, -1.0f, 1.0f},
- {-1.0f, -1.0f, 1.0f, 1.0f}};
+ float view_vecs[4][4] = {
+ {-1.0f, -1.0f, -1.0f, 1.0f},
+ {1.0f, -1.0f, -1.0f, 1.0f},
+ {-1.0f, 1.0f, -1.0f, 1.0f},
+ {-1.0f, -1.0f, 1.0f, 1.0f},
+ };
/* convert the view vectors to view space */
const bool is_persp = (winmat[3][3] == 0.0f);
diff --git a/source/blender/draw/engines/gpencil/gpencil_shader_fx.c b/source/blender/draw/engines/gpencil/gpencil_shader_fx.c
index b133d9310b0..355235618f6 100644
--- a/source/blender/draw/engines/gpencil/gpencil_shader_fx.c
+++ b/source/blender/draw/engines/gpencil/gpencil_shader_fx.c
@@ -119,10 +119,11 @@ static void GPENCIL_dof_nearfar(Object *camera, float coc, float nearfar[2])
float focus_dist = BKE_camera_object_dof_distance(camera);
float focal_len = cam->lens;
- /* this is factor that converts to the scene scale. focal length and sensor are expressed in mm
- * unit.scale_length is how many meters per blender unit we have. We want to convert to blender units though
- * because the shader reads coordinates in world space, which is in blender units.
- * Note however that focus_distance is already in blender units and shall not be scaled here (see T48157). */
+ /* This is factor that converts to the scene scale. focal length and sensor are expressed in mm
+ * unit.scale_length is how many meters per blender unit we have. We want to convert to blender
+ * units though because the shader reads coordinates in world space, which is in blender units.
+ * Note however that focus_distance is already in blender units and shall not be scaled here
+ * (see T48157). */
float scale = (scene->unit.system) ? scene->unit.scale_length : 1.0f;
float scale_camera = 0.001f / scale;
/* we want radius here for the aperture number */
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_edit_point_geom.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_edit_point_geom.glsl
index b5d0a5bce71..8c3fd022004 100644
--- a/source/blender/draw/engines/gpencil/shaders/gpencil_edit_point_geom.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_edit_point_geom.glsl
@@ -16,6 +16,12 @@ vec2 toScreenSpace(vec4 vertex)
return vec2(vertex.xy / vertex.w) * Viewport;
}
+/* get zdepth value */
+float getZdepth(vec4 point)
+{
+ return min(-0.05, (point.z / point.w));
+}
+
void main(void)
{
vec4 P0 = gl_in[0].gl_Position;
@@ -26,22 +32,22 @@ void main(void)
/* generate the triangle strip */
mTexCoord = vec2(0, 1);
mColor = finalColor[0];
- gl_Position = vec4(vec2(sp0.x - size, sp0.y + size) / Viewport, 0, 1.0);
+ gl_Position = vec4(vec2(sp0.x - size, sp0.y + size) / Viewport, getZdepth(P0), 1.0);
EmitVertex();
mTexCoord = vec2(0, 0);
mColor = finalColor[0];
- gl_Position = vec4(vec2(sp0.x - size, sp0.y - size) / Viewport, 0, 1.0);
+ gl_Position = vec4(vec2(sp0.x - size, sp0.y - size) / Viewport, getZdepth(P0), 1.0);
EmitVertex();
mTexCoord = vec2(1, 1);
mColor = finalColor[0];
- gl_Position = vec4(vec2(sp0.x + size, sp0.y + size) / Viewport, 0, 1.0);
+ gl_Position = vec4(vec2(sp0.x + size, sp0.y + size) / Viewport, getZdepth(P0), 1.0);
EmitVertex();
mTexCoord = vec2(1, 0);
mColor = finalColor[0];
- gl_Position = vec4(vec2(sp0.x + size, sp0.y - size) / Viewport, 0, 1.0);
+ gl_Position = vec4(vec2(sp0.x + size, sp0.y - size) / Viewport, getZdepth(P0), 1.0);
EmitVertex();
EndPrimitive();
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_fill_frag.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_fill_frag.glsl
index 632c63a39aa..acf60fc2d59 100644
--- a/source/blender/draw/engines/gpencil/shaders/gpencil_fill_frag.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_fill_frag.glsl
@@ -177,10 +177,11 @@ void main()
/* set zdepth */
if (xraymode == GP_XRAY_FRONT) {
- gl_FragDepth = 0.000001;
+ gl_FragDepth = min(-0.05, (gl_FragCoord.z / gl_FragCoord.w));
}
else if (xraymode == GP_XRAY_3DSPACE) {
- /* if 3D mode, move slightly the fill to avoid z-fighting between stroke and fill on same stroke */
+ /* if 3D mode, move slightly the fill to avoid z-fighting between stroke and fill on same
+ * stroke */
if (drawmode == GP_DRAWMODE_3D) {
gl_FragDepth = gl_FragCoord.z * 1.0001;
}
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_point_frag.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_point_frag.glsl
index c8af822bc9e..cc47e12b303 100644
--- a/source/blender/draw/engines/gpencil/shaders/gpencil_point_frag.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_point_frag.glsl
@@ -5,6 +5,10 @@ uniform sampler2D myTexture;
uniform float gradient_f;
uniform vec2 gradient_s;
+uniform vec4 colormix;
+uniform float mix_stroke_factor;
+uniform int shading_type[2];
+
in vec4 mColor;
in vec2 mTexCoord;
out vec4 fragColor;
@@ -20,50 +24,82 @@ out vec4 fragColor;
#define GPENCIL_COLOR_TEXTURE 1
#define GPENCIL_COLOR_PATTERN 2
+#define OB_SOLID 3
+#define V3D_SHADING_TEXTURE_COLOR 3
+
+bool no_texture = (shading_type[0] == OB_SOLID) && (shading_type[1] != V3D_SHADING_TEXTURE_COLOR);
+
/* Function to check the point inside ellipse */
-float checkpoint(vec2 pt, vec2 radius)
+float check_ellipse_point(vec2 pt, vec2 radius)
{
float p = (pow(pt.x, 2) / pow(radius.x, 2)) + (pow(pt.y, 2) / pow(radius.y, 2));
return p;
}
+/* Function to check the point inside box */
+vec2 check_box_point(vec2 pt, vec2 radius)
+{
+ vec2 rtn;
+ rtn.x = abs(pt.x) / radius.x;
+ rtn.y = abs(pt.y) / radius.y;
+
+ return rtn;
+}
+
void main()
{
vec2 centered = mTexCoord - vec2(0.5);
- float ellip = checkpoint(centered, vec2(gradient_s / 2.0));
+ float ellip = check_ellipse_point(centered, vec2(gradient_s / 2.0));
+ vec2 box;
if (mode != GPENCIL_MODE_BOX) {
if (ellip > 1.0) {
discard;
}
}
+ else {
+ box = check_box_point(centered, vec2(gradient_s / 2.0));
+ if ((box.x > 1.0) || (box.y > 1.0)) {
+ discard;
+ }
+ }
vec4 tmp_color = texture2D(myTexture, mTexCoord);
/* Solid */
- if (color_type == GPENCIL_COLOR_SOLID) {
+ if ((color_type == GPENCIL_COLOR_SOLID) || (no_texture)) {
fragColor = mColor;
}
/* texture */
- if (color_type == GPENCIL_COLOR_TEXTURE) {
- fragColor = texture2D(myTexture, mTexCoord);
+ if ((color_type == GPENCIL_COLOR_TEXTURE) && (!no_texture)) {
+ vec4 text_color = texture2D(myTexture, mTexCoord);
+ if (mix_stroke_factor > 0.0) {
+ fragColor.rgb = mix(text_color.rgb, colormix.rgb, mix_stroke_factor);
+ fragColor.a = text_color.a;
+ }
+ else {
+ fragColor = text_color;
+ }
+
/* mult both alpha factor to use strength factor with texture */
fragColor.a = min(fragColor.a * mColor.a, fragColor.a);
}
/* pattern */
- if (color_type == GPENCIL_COLOR_PATTERN) {
+ if ((color_type == GPENCIL_COLOR_PATTERN) && (!no_texture)) {
vec4 text_color = texture2D(myTexture, mTexCoord);
fragColor = mColor;
/* mult both alpha factor to use strength factor with color alpha limit */
fragColor.a = min(text_color.a * mColor.a, mColor.a);
}
- if ((mode == GPENCIL_MODE_DOTS) && (gradient_f < 1.0)) {
- float dist = length(centered) * 2;
+ if (gradient_f < 1.0) {
+ float dist = length(centered) * 2.0;
float decay = dist * (1.0 - gradient_f) * fragColor.a;
fragColor.a = clamp(fragColor.a - decay, 0.0, 1.0);
- fragColor.a = fragColor.a * (1.0 - ellip);
+ if (mode == GPENCIL_MODE_DOTS) {
+ fragColor.a = fragColor.a * (1.0 - ellip);
+ }
}
if (fragColor.a < 0.0035) {
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_point_geom.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_point_geom.glsl
index 2fb48ac5147..a64a7ecb9be 100644
--- a/source/blender/draw/engines/gpencil/shaders/gpencil_point_geom.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_point_geom.glsl
@@ -31,7 +31,7 @@ vec2 toScreenSpace(vec4 vertex)
float getZdepth(vec4 point)
{
if (xraymode == GP_XRAY_FRONT) {
- return 0.000001;
+ return min(-0.05, (point.z / point.w));
}
if (xraymode == GP_XRAY_3DSPACE) {
return (point.z / point.w);
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_point_vert.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_point_vert.glsl
index 92c9acf1f2a..9cef7601770 100644
--- a/source/blender/draw/engines/gpencil/shaders/gpencil_point_vert.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_point_vert.glsl
@@ -42,7 +42,7 @@ void main()
else {
float size = (ProjectionMatrix[3][3] == 0.0) ? (thickness / (gl_Position.z * defaultpixsize)) :
(thickness / defaultpixsize);
- finalThickness = max(size * objscale, 4.0); /* minimum 4 pixels */
+ finalThickness = max(size * objscale, 0.5); /* set a minimum size */
}
/* for wireframe override size and color */
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_frag.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_frag.glsl
index 35d07306361..6b7cee888ea 100644
--- a/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_frag.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_frag.glsl
@@ -3,6 +3,10 @@ uniform sampler2D myTexture;
uniform float gradient_f;
+uniform vec4 colormix;
+uniform float mix_stroke_factor;
+uniform int shading_type[2];
+
in vec4 mColor;
in vec2 mTexCoord;
in vec2 uvfac;
@@ -18,6 +22,11 @@ out vec4 fragColor;
#define ENDCAP 1.0
+#define OB_SOLID 3
+#define V3D_SHADING_TEXTURE_COLOR 3
+
+bool no_texture = (shading_type[0] == OB_SOLID) && (shading_type[1] != V3D_SHADING_TEXTURE_COLOR);
+
void main()
{
@@ -30,8 +39,8 @@ void main()
discard;
}
}
- /* Solid */
- if (color_type == GPENCIL_COLOR_SOLID) {
+
+ if ((color_type == GPENCIL_COLOR_SOLID) || (no_texture)) {
fragColor = tColor;
}
@@ -45,13 +54,20 @@ void main()
}
/* texture */
- if (color_type == GPENCIL_COLOR_TEXTURE) {
- fragColor = text_color;
+ if ((color_type == GPENCIL_COLOR_TEXTURE) && (!no_texture)) {
+ if (mix_stroke_factor > 0.0) {
+ fragColor.rgb = mix(text_color.rgb, colormix.rgb, mix_stroke_factor);
+ fragColor.a = text_color.a;
+ }
+ else {
+ fragColor = text_color;
+ }
+
/* mult both alpha factor to use strength factor */
fragColor.a = min(fragColor.a * tColor.a, fragColor.a);
}
/* pattern */
- if (color_type == GPENCIL_COLOR_PATTERN) {
+ if ((color_type == GPENCIL_COLOR_PATTERN) && (!no_texture)) {
fragColor = tColor;
/* mult both alpha factor to use strength factor with color alpha limit */
fragColor.a = min(text_color.a * tColor.a, tColor.a);
@@ -63,7 +79,7 @@ void main()
float d = abs(mTexCoord.y - 0.5) * (1.1 - gradient_f);
float alpha = 1.0 - clamp((fragColor.a - (d * 2.0)), 0.03, 1.0);
fragColor.a = smoothstep(fragColor.a, 0.0, alpha);
-
+
}
*/
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_geom.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_geom.glsl
index 7e62d6f0d64..b90f5b33a57 100644
--- a/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_geom.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_geom.glsl
@@ -35,7 +35,7 @@ vec2 toScreenSpace(vec4 vertex)
float getZdepth(vec4 point)
{
if (xraymode == GP_XRAY_FRONT) {
- return 0.000001;
+ return min(-0.05, (point.z / point.w));
}
if (xraymode == GP_XRAY_3DSPACE) {
return (point.z / point.w);
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_effect_dof_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_effect_dof_frag.glsl
index 54440f7b120..0428b0d408c 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_effect_dof_frag.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_effect_dof_frag.glsl
@@ -362,9 +362,9 @@ void main()
for (int dX = -1; dX <= 1; ++dX) {
for (int dY = -1; dY <= 1; ++dY) {
vec2 offset = vec2(float(dX), float(dY));
- /* If a pixel in the window is located at (x+dX, y+dY), put it at index (dX + R)(2R + 1) + (dY + R) of the
- * pixel array. This will fill the pixel array, with the top left pixel of the window at pixel[0] and the
- * bottom right pixel of the window at pixel[N-1]. */
+ /* If a pixel in the window is located at (x+dX, y+dY), put it at index (dX + R)(2R + 1) +
+ * (dY + R) of the pixel array. This will fill the pixel array, with the top left pixel of
+ * the window at pixel[0] and the bottom right pixel of the window at pixel[N-1]. */
v[(dX + 1) * 3 + (dY + 1)] = toVec(texture(blurTex, uv + offset * pixel_size * rad));
}
}
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl
index e654141df5c..5eff0b41e20 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl
@@ -25,6 +25,9 @@ in vec3 normal_viewport;
#ifdef V3D_SHADING_TEXTURE_COLOR
in vec2 uv_interp;
#endif
+#ifdef V3D_SHADING_VERTEX_COLOR
+in vec3 vertexColor;
+#endif
#ifdef V3D_LIGHTING_MATCAP
uniform sampler2D matcapImage;
#endif
@@ -42,11 +45,13 @@ void main()
{
vec4 diffuse_color;
-#ifdef V3D_SHADING_TEXTURE_COLOR
+#if defined(V3D_SHADING_TEXTURE_COLOR)
diffuse_color = workbench_sample_texture(image, uv_interp, imageSrgb, imageNearest);
if (diffuse_color.a < ImageTransparencyCutoff) {
discard;
}
+#elif defined(V3D_SHADING_VERTEX_COLOR)
+ diffuse_color = vec4(vertexColor, 1.0);
#else
diffuse_color = vec4(materialDiffuseColor, 1.0);
#endif /* V3D_SHADING_TEXTURE_COLOR */
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_prepass_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_prepass_frag.glsl
index 6b2962a66da..2596fc4cf88 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_prepass_frag.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_prepass_frag.glsl
@@ -16,6 +16,9 @@ in vec3 normal_viewport;
#ifdef V3D_SHADING_TEXTURE_COLOR
in vec2 uv_interp;
#endif
+#ifdef V3D_SHADING_VERTEX_COLOR
+in vec3 vertexColor;
+#endif
#ifdef HAIR_SHADER
flat in float hair_rand;
@@ -37,11 +40,13 @@ void main()
float metallic, roughness;
vec4 color;
-# ifdef V3D_SHADING_TEXTURE_COLOR
+# if defined(V3D_SHADING_TEXTURE_COLOR)
color = workbench_sample_texture(image, uv_interp, imageSrgb, imageNearest);
if (color.a < ImageTransparencyCutoff) {
discard;
}
+# elif defined(V3D_SHADING_VERTEX_COLOR)
+ color.rgb = vertexColor;
# else
color.rgb = materialDiffuseColor;
# endif
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_prepass_vert.glsl b/source/blender/draw/engines/workbench/shaders/workbench_prepass_vert.glsl
index dd737063f61..f2c684cdb6a 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_prepass_vert.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_prepass_vert.glsl
@@ -10,6 +10,9 @@ uniform mat3 NormalMatrix;
in vec3 pos;
in vec3 nor;
in vec2 u; /* active texture layer */
+# ifdef V3D_SHADING_VERTEX_COLOR
+in vec3 c; /* active color */
+# endif
# define uv u
#else /* HAIR_SHADER */
# ifdef V3D_SHADING_TEXTURE_COLOR
@@ -25,6 +28,9 @@ out vec3 normal_viewport;
#ifdef V3D_SHADING_TEXTURE_COLOR
out vec2 uv_interp;
#endif
+#ifdef V3D_SHADING_VERTEX_COLOR
+out vec3 vertexColor;
+#endif
/* From http://libnoise.sourceforge.net/noisegen/index.html */
float integer_noise(int n)
@@ -34,6 +40,16 @@ float integer_noise(int n)
return (float(nn) / 1073741824.0);
}
+#ifdef V3D_SHADING_VERTEX_COLOR
+vec3 srgb_to_linear_attr(vec3 c)
+{
+ c = max(c, vec3(0.0));
+ vec3 c1 = c * (1.0 / 12.92);
+ vec3 c2 = pow((c + 0.055) * (1.0 / 1.055), vec3(2.4));
+ return mix(c1, c2, step(vec3(0.04045), c));
+}
+#endif
+
void main()
{
#ifdef HAIR_SHADER
@@ -68,6 +84,12 @@ void main()
uv_interp = uv;
#endif
+#ifdef V3D_SHADING_VERTEX_COLOR
+# ifndef HAIR_SHADER
+ vertexColor = srgb_to_linear_attr(c);
+# endif
+#endif
+
#ifdef NORMAL_VIEWPORT_PASS_ENABLED
normal_viewport = NormalMatrix * nor;
# ifndef HAIR_SHADER
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl
index 26ebe7a4553..a1c269d5a65 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl
@@ -64,7 +64,8 @@ float max_v3(vec3 v)
float line_unit_box_intersect_dist(vec3 lineorigin, vec3 linedirection)
{
- /* https://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/ */
+ /* https://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/
+ */
vec3 firstplane = (vec3(1.0) - lineorigin) / linedirection;
vec3 secondplane = (vec3(-1.0) - lineorigin) / linedirection;
vec3 furthestplane = min(firstplane, secondplane);
diff --git a/source/blender/draw/engines/workbench/workbench_deferred.c b/source/blender/draw/engines/workbench/workbench_deferred.c
index 91f4f351c7b..5d7bdc72546 100644
--- a/source/blender/draw/engines/workbench/workbench_deferred.c
+++ b/source/blender/draw/engines/workbench/workbench_deferred.c
@@ -209,15 +209,15 @@ static GPUShader *workbench_cavity_shader_get(bool cavity, bool curvature)
}
static GPUShader *ensure_deferred_prepass_shader(WORKBENCH_PrivateData *wpd,
- bool use_textures,
+ bool is_uniform_color,
bool is_hair,
eGPUShaderConfig sh_cfg)
{
WORKBENCH_DEFERRED_Shaders *sh_data = &e_data.sh_data[sh_cfg];
- int index = workbench_material_get_prepass_shader_index(wpd, use_textures, is_hair);
+ int index = workbench_material_get_prepass_shader_index(wpd, is_uniform_color, is_hair);
if (sh_data->prepass_sh_cache[index] == NULL) {
const GPUShaderConfigData *sh_cfg_data = &GPU_shader_cfg_data[sh_cfg];
- char *defines = workbench_material_build_defines(wpd, use_textures, is_hair);
+ char *defines = workbench_material_build_defines(wpd, is_uniform_color, is_hair);
char *prepass_vert = workbench_build_prepass_vert(is_hair);
char *prepass_frag = workbench_build_prepass_frag();
sh_data->prepass_sh_cache[index] = GPU_shader_create_from_arrays({
@@ -263,10 +263,10 @@ static GPUShader *ensure_background_shader(WORKBENCH_PrivateData *wpd)
static void select_deferred_shaders(WORKBENCH_PrivateData *wpd, eGPUShaderConfig sh_cfg)
{
- wpd->prepass_solid_sh = ensure_deferred_prepass_shader(wpd, false, false, sh_cfg);
- wpd->prepass_solid_hair_sh = ensure_deferred_prepass_shader(wpd, false, true, sh_cfg);
- wpd->prepass_texture_sh = ensure_deferred_prepass_shader(wpd, true, false, sh_cfg);
- wpd->prepass_texture_hair_sh = ensure_deferred_prepass_shader(wpd, true, true, sh_cfg);
+ wpd->prepass_sh = ensure_deferred_prepass_shader(wpd, false, false, sh_cfg);
+ wpd->prepass_hair_sh = ensure_deferred_prepass_shader(wpd, false, true, sh_cfg);
+ wpd->prepass_uniform_sh = ensure_deferred_prepass_shader(wpd, true, false, sh_cfg);
+ wpd->prepass_uniform_hair_sh = ensure_deferred_prepass_shader(wpd, true, true, sh_cfg);
wpd->composite_sh = ensure_deferred_composite_shader(wpd);
wpd->background_sh = ensure_background_shader(wpd);
}
@@ -846,8 +846,7 @@ static WORKBENCH_MaterialData *get_or_create_material_data(WORKBENCH_Data *vedat
if (material == NULL) {
material = MEM_mallocN(sizeof(WORKBENCH_MaterialData), __func__);
material->shgrp = DRW_shgroup_create(
- (color_type == V3D_SHADING_TEXTURE_COLOR) ? wpd->prepass_texture_sh :
- wpd->prepass_solid_sh,
+ (wpd->shading.color_type == color_type) ? wpd->prepass_sh : wpd->prepass_uniform_sh,
(ob->dtx & OB_DRAWXRAY) ? psl->ghost_prepass_pass : psl->prepass_pass);
workbench_material_copy(material, &material_template);
DRW_shgroup_stencil_mask(material->shgrp, (ob->dtx & OB_DRAWXRAY) ? 0x00 : 0xFF);
@@ -881,13 +880,13 @@ static void workbench_cache_populate_particles(WORKBENCH_Data *vedata, Object *o
ImageUser *iuser;
int interp;
workbench_material_get_image_and_mat(ob, part->omat, &image, &iuser, &interp, &mat);
- int color_type = workbench_material_determine_color_type(wpd, image, ob);
+ int color_type = workbench_material_determine_color_type(wpd, image, ob, false);
WORKBENCH_MaterialData *material = get_or_create_material_data(
vedata, ob, mat, image, iuser, color_type, interp);
- struct GPUShader *shader = (color_type != V3D_SHADING_TEXTURE_COLOR) ?
- wpd->prepass_solid_hair_sh :
- wpd->prepass_texture_hair_sh;
+ struct GPUShader *shader = (wpd->shading.color_type == color_type) ?
+ wpd->prepass_hair_sh :
+ wpd->prepass_uniform_hair_sh;
DRWShadingGroup *shgrp = DRW_shgroup_hair_create(
ob,
psys,
@@ -936,7 +935,7 @@ void workbench_deferred_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob)
WORKBENCH_MaterialData *material;
if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL)) {
const bool is_active = (ob == draw_ctx->obact);
- const bool is_sculpt_mode = is_active && (draw_ctx->object_mode & OB_MODE_SCULPT) != 0;
+ const bool is_sculpt_mode = (ob->sculpt != NULL);
const bool use_hide = is_active && DRW_object_use_hide_faces(ob);
const int materials_len = MAX2(1, (is_sculpt_mode ? 1 : ob->totcol));
const Mesh *me = (ob->type == OB_MESH) ? ob->data : NULL;
@@ -952,10 +951,10 @@ void workbench_deferred_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob)
ImageUser *iuser;
int interp;
workbench_material_get_image_and_mat(ob, i + 1, &image, &iuser, &interp, &mat);
- int color_type = workbench_material_determine_color_type(wpd, image, ob);
+ int color_type = workbench_material_determine_color_type(wpd, image, ob, is_sculpt_mode);
if (color_type == V3D_SHADING_MATERIAL_COLOR && mat && mat->a < 1.0) {
material = workbench_forward_get_or_create_material_data(
- vedata, ob, mat, image, iuser, color_type, 0);
+ vedata, ob, mat, image, iuser, color_type, 0, is_sculpt_mode);
has_transp_mat = true;
}
else {
@@ -969,24 +968,33 @@ void workbench_deferred_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob)
else if (ELEM(wpd->shading.color_type,
V3D_SHADING_SINGLE_COLOR,
V3D_SHADING_OBJECT_COLOR,
- V3D_SHADING_RANDOM_COLOR)) {
- if ((ob->color[3] < 1.0f) && (wpd->shading.color_type == V3D_SHADING_OBJECT_COLOR)) {
+ V3D_SHADING_RANDOM_COLOR,
+ V3D_SHADING_VERTEX_COLOR)) {
+ int color_type = workbench_material_determine_color_type(wpd, NULL, ob, is_sculpt_mode);
+
+ if ((ob->color[3] < 1.0f) && (color_type == V3D_SHADING_OBJECT_COLOR)) {
/* Hack */
wpd->shading.xray_alpha = ob->color[3];
material = workbench_forward_get_or_create_material_data(
- vedata, ob, NULL, NULL, NULL, wpd->shading.color_type, 0);
+ vedata, ob, NULL, NULL, NULL, color_type, 0, is_sculpt_mode);
has_transp_mat = true;
}
else {
/* Draw solid color */
- material = get_or_create_material_data(
- vedata, ob, NULL, NULL, NULL, wpd->shading.color_type, 0);
+ material = get_or_create_material_data(vedata, ob, NULL, NULL, NULL, color_type, 0);
}
if (is_sculpt_mode) {
DRW_shgroup_call_sculpt_add(material->shgrp, ob, ob->obmat);
}
else {
- struct GPUBatch *geom = DRW_cache_object_surface_get(ob);
+ struct GPUBatch *geom;
+ if (color_type == V3D_SHADING_VERTEX_COLOR) {
+ geom = DRW_cache_mesh_surface_vertpaint_get(ob);
+ }
+ else {
+ geom = DRW_cache_object_surface_get(ob);
+ }
+
if (geom) {
DRW_shgroup_call_object_add(material->shgrp, geom, ob);
}
@@ -1015,7 +1023,7 @@ void workbench_deferred_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob)
/* Hack */
wpd->shading.xray_alpha = mat->a;
material = workbench_forward_get_or_create_material_data(
- vedata, ob, mat, NULL, NULL, V3D_SHADING_MATERIAL_COLOR, 0);
+ vedata, ob, mat, NULL, NULL, V3D_SHADING_MATERIAL_COLOR, 0, is_sculpt_mode);
has_transp_mat = true;
}
else {
diff --git a/source/blender/draw/engines/workbench/workbench_effect_dof.c b/source/blender/draw/engines/workbench/workbench_effect_dof.c
index 3e35f8120d7..3dea99a76cf 100644
--- a/source/blender/draw/engines/workbench/workbench_effect_dof.c
+++ b/source/blender/draw/engines/workbench/workbench_effect_dof.c
@@ -185,9 +185,12 @@ void workbench_dof_engine_init(WORKBENCH_Data *vedata, Object *camera)
wpd->dof_blur_tx = DRW_texture_pool_query_2d(
size[0], size[1], GPU_R11F_G11F_B10F, &draw_engine_workbench_solid);
#if 0
- wpd->coc_temp_tx = DRW_texture_pool_query_2d(shrink_h_size[0], shrink_h_size[1], GPU_RG8, &draw_engine_workbench_solid);
- wpd->coc_tiles_tx[0] = DRW_texture_pool_query_2d(shrink_w_size[0], shrink_w_size[1], GPU_RG8, &draw_engine_workbench_solid);
- wpd->coc_tiles_tx[1] = DRW_texture_pool_query_2d(shrink_w_size[0], shrink_w_size[1], GPU_RG8, &draw_engine_workbench_solid);
+ wpd->coc_temp_tx = DRW_texture_pool_query_2d(
+ shrink_h_size[0], shrink_h_size[1], GPU_RG8, &draw_engine_workbench_solid);
+ wpd->coc_tiles_tx[0] = DRW_texture_pool_query_2d(
+ shrink_w_size[0], shrink_w_size[1], GPU_RG8, &draw_engine_workbench_solid);
+ wpd->coc_tiles_tx[1] = DRW_texture_pool_query_2d(
+ shrink_w_size[0], shrink_w_size[1], GPU_RG8, &draw_engine_workbench_solid);
#endif
GPU_framebuffer_ensure_config(&fbl->dof_downsample_fb,
@@ -197,18 +200,21 @@ void workbench_dof_engine_init(WORKBENCH_Data *vedata, Object *camera)
GPU_ATTACHMENT_TEXTURE(txl->coc_halfres_tx),
});
#if 0
- GPU_framebuffer_ensure_config(&fbl->dof_coc_tile_h_fb, {
- GPU_ATTACHMENT_NONE,
- GPU_ATTACHMENT_TEXTURE(wpd->coc_temp_tx),
- });
- GPU_framebuffer_ensure_config(&fbl->dof_coc_tile_v_fb, {
- GPU_ATTACHMENT_NONE,
- GPU_ATTACHMENT_TEXTURE(wpd->coc_tiles_tx[0]),
- });
- GPU_framebuffer_ensure_config(&fbl->dof_coc_dilate_fb, {
- GPU_ATTACHMENT_NONE,
- GPU_ATTACHMENT_TEXTURE(wpd->coc_tiles_tx[1]),
- });
+ GPU_framebuffer_ensure_config(&fbl->dof_coc_tile_h_fb,
+ {
+ GPU_ATTACHMENT_NONE,
+ GPU_ATTACHMENT_TEXTURE(wpd->coc_temp_tx),
+ });
+ GPU_framebuffer_ensure_config(&fbl->dof_coc_tile_v_fb,
+ {
+ GPU_ATTACHMENT_NONE,
+ GPU_ATTACHMENT_TEXTURE(wpd->coc_tiles_tx[0]),
+ });
+ GPU_framebuffer_ensure_config(&fbl->dof_coc_dilate_fb,
+ {
+ GPU_ATTACHMENT_NONE,
+ GPU_ATTACHMENT_TEXTURE(wpd->coc_tiles_tx[1]),
+ });
#endif
GPU_framebuffer_ensure_config(&fbl->dof_blur1_fb,
{
@@ -237,9 +243,10 @@ void workbench_dof_engine_init(WORKBENCH_Data *vedata, Object *camera)
/* TODO(fclem) deduplicate with eevee */
/* this is factor that converts to the scene scale. focal length and sensor are expressed in mm
- * unit.scale_length is how many meters per blender unit we have. We want to convert to blender units though
- * because the shader reads coordinates in world space, which is in blender units.
- * Note however that focus_distance is already in blender units and shall not be scaled here (see T48157). */
+ * unit.scale_length is how many meters per blender unit we have. We want to convert to blender
+ * units though because the shader reads coordinates in world space, which is in blender units.
+ * Note however that focus_distance is already in blender units and shall not be scaled here
+ * (see T48157). */
float scale = (scene_eval->unit.system) ? scene_eval->unit.scale_length : 1.0f;
float scale_camera = 0.001f / scale;
/* we want radius here for the aperture number */
@@ -318,12 +325,14 @@ void workbench_dof_create_pass(WORKBENCH_Data *vedata,
}
#if 0
{
- DRWShadingGroup *grp = DRW_shgroup_create(e_data.effect_dof_flatten_h_sh, psl->dof_flatten_h_ps);
+ DRWShadingGroup *grp = DRW_shgroup_create(e_data.effect_dof_flatten_h_sh,
+ psl->dof_flatten_h_ps);
DRW_shgroup_uniform_texture(grp, "inputCocTex", txl->coc_halfres_tx);
DRW_shgroup_call_add(grp, quad, NULL);
}
{
- DRWShadingGroup *grp = DRW_shgroup_create(e_data.effect_dof_flatten_v_sh, psl->dof_flatten_v_ps);
+ DRWShadingGroup *grp = DRW_shgroup_create(e_data.effect_dof_flatten_v_sh,
+ psl->dof_flatten_v_ps);
DRW_shgroup_uniform_texture(grp, "inputCocTex", wpd->coc_temp_tx);
DRW_shgroup_call_add(grp, quad, NULL);
}
diff --git a/source/blender/draw/engines/workbench/workbench_forward.c b/source/blender/draw/engines/workbench/workbench_forward.c
index 782e85597d7..00590940ac3 100644
--- a/source/blender/draw/engines/workbench/workbench_forward.c
+++ b/source/blender/draw/engines/workbench/workbench_forward.c
@@ -137,7 +137,8 @@ WORKBENCH_MaterialData *workbench_forward_get_or_create_material_data(WORKBENCH_
Image *ima,
ImageUser *iuser,
int color_type,
- int interp)
+ int interp,
+ bool is_sculpt_mode)
{
const DRWContextState *draw_ctx = DRW_context_state_get();
WORKBENCH_FORWARD_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg];
@@ -168,9 +169,9 @@ WORKBENCH_MaterialData *workbench_forward_get_or_create_material_data(WORKBENCH_
material = MEM_mallocN(sizeof(WORKBENCH_MaterialData), __func__);
/* transparent accum */
- grp = DRW_shgroup_create(color_type == V3D_SHADING_TEXTURE_COLOR ?
- wpd->transparent_accum_texture_sh :
- wpd->transparent_accum_sh,
+ grp = DRW_shgroup_create(wpd->shading.color_type == color_type ?
+ wpd->transparent_accum_sh :
+ wpd->transparent_accum_uniform_sh,
psl->transparent_accum_pass);
DRW_shgroup_uniform_block(grp, "world_block", wpd->world_ubo);
DRW_shgroup_uniform_float_copy(grp, "alpha", wpd->shading.xray_alpha);
@@ -194,7 +195,7 @@ WORKBENCH_MaterialData *workbench_forward_get_or_create_material_data(WORKBENCH_
material->shgrp = grp;
/* Depth */
- if (workbench_material_determine_color_type(wpd, material->ima, ob) ==
+ if (workbench_material_determine_color_type(wpd, material->ima, ob, is_sculpt_mode) ==
V3D_SHADING_TEXTURE_COLOR) {
material->shgrp_object_outline = DRW_shgroup_create(sh_data->object_outline_texture_sh,
psl->object_outline_pass);
@@ -217,15 +218,15 @@ WORKBENCH_MaterialData *workbench_forward_get_or_create_material_data(WORKBENCH_
}
static GPUShader *ensure_forward_accum_shaders(WORKBENCH_PrivateData *wpd,
- bool use_textures,
+ bool is_uniform_color,
bool is_hair,
eGPUShaderConfig sh_cfg)
{
WORKBENCH_FORWARD_Shaders *sh_data = &e_data.sh_data[sh_cfg];
- int index = workbench_material_get_accum_shader_index(wpd, use_textures, is_hair);
+ int index = workbench_material_get_accum_shader_index(wpd, is_uniform_color, is_hair);
if (sh_data->transparent_accum_sh_cache[index] == NULL) {
const GPUShaderConfigData *sh_cfg_data = &GPU_shader_cfg_data[sh_cfg];
- char *defines = workbench_material_build_defines(wpd, use_textures, is_hair);
+ char *defines = workbench_material_build_defines(wpd, is_uniform_color, is_hair);
char *transparent_accum_vert = workbench_build_forward_vert(is_hair);
char *transparent_accum_frag = workbench_build_forward_transparent_accum_frag();
sh_data->transparent_accum_sh_cache[index] = GPU_shader_create_from_arrays({
@@ -258,8 +259,8 @@ void workbench_forward_choose_shaders(WORKBENCH_PrivateData *wpd, eGPUShaderConf
wpd->composite_sh = ensure_forward_composite_shaders(wpd);
wpd->transparent_accum_sh = ensure_forward_accum_shaders(wpd, false, false, sh_cfg);
wpd->transparent_accum_hair_sh = ensure_forward_accum_shaders(wpd, false, true, sh_cfg);
- wpd->transparent_accum_texture_sh = ensure_forward_accum_shaders(wpd, true, false, sh_cfg);
- wpd->transparent_accum_texture_hair_sh = ensure_forward_accum_shaders(wpd, true, true, sh_cfg);
+ wpd->transparent_accum_uniform_sh = ensure_forward_accum_shaders(wpd, true, false, sh_cfg);
+ wpd->transparent_accum_uniform_hair_sh = ensure_forward_accum_shaders(wpd, true, true, sh_cfg);
}
void workbench_forward_outline_shaders_ensure(WORKBENCH_PrivateData *wpd, eGPUShaderConfig sh_cfg)
@@ -497,13 +498,13 @@ static void workbench_forward_cache_populate_particles(WORKBENCH_Data *vedata, O
ImageUser *iuser;
int interp;
workbench_material_get_image_and_mat(ob, part->omat, &image, &iuser, &interp, &mat);
- int color_type = workbench_material_determine_color_type(wpd, image, ob);
+ int color_type = workbench_material_determine_color_type(wpd, image, ob, false);
WORKBENCH_MaterialData *material = workbench_forward_get_or_create_material_data(
- vedata, ob, mat, image, iuser, color_type, interp);
+ vedata, ob, mat, image, iuser, color_type, interp, false);
- struct GPUShader *shader = (color_type != V3D_SHADING_TEXTURE_COLOR) ?
+ struct GPUShader *shader = (wpd->shading.color_type == color_type) ?
wpd->transparent_accum_hair_sh :
- wpd->transparent_accum_texture_hair_sh;
+ wpd->transparent_accum_uniform_hair_sh;
DRWShadingGroup *shgrp = DRW_shgroup_hair_create(
ob, psys, md, psl->transparent_accum_pass, shader);
DRW_shgroup_uniform_block(shgrp, "world_block", wpd->world_ubo);
@@ -564,8 +565,7 @@ void workbench_forward_cache_populate(WORKBENCH_Data *vedata, Object *ob)
WORKBENCH_MaterialData *material;
if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL)) {
- const bool is_active = (ob == draw_ctx->obact);
- const bool is_sculpt_mode = is_active && (draw_ctx->object_mode & OB_MODE_SCULPT) != 0;
+ const bool is_sculpt_mode = (ob->sculpt != NULL);
bool is_drawn = false;
if (!is_sculpt_mode && TEXTURE_DRAWING_ENABLED(wpd) && ELEM(ob->type, OB_MESH)) {
@@ -579,9 +579,9 @@ void workbench_forward_cache_populate(WORKBENCH_Data *vedata, Object *ob)
ImageUser *iuser;
int interp;
workbench_material_get_image_and_mat(ob, i + 1, &image, &iuser, &interp, &mat);
- int color_type = workbench_material_determine_color_type(wpd, image, ob);
+ int color_type = workbench_material_determine_color_type(wpd, image, ob, is_sculpt_mode);
material = workbench_forward_get_or_create_material_data(
- vedata, ob, mat, image, iuser, color_type, interp);
+ vedata, ob, mat, image, iuser, color_type, interp, is_sculpt_mode);
DRW_shgroup_call_object_add(material->shgrp_object_outline, geom_array[i], ob);
DRW_shgroup_call_object_add(material->shgrp, geom_array[i], ob);
}
@@ -594,12 +594,21 @@ void workbench_forward_cache_populate(WORKBENCH_Data *vedata, Object *ob)
if (ELEM(wpd->shading.color_type,
V3D_SHADING_SINGLE_COLOR,
V3D_SHADING_OBJECT_COLOR,
- V3D_SHADING_RANDOM_COLOR)) {
+ V3D_SHADING_RANDOM_COLOR,
+ V3D_SHADING_VERTEX_COLOR)) {
/* No material split needed */
- struct GPUBatch *geom = DRW_cache_object_surface_get(ob);
+ int color_type = workbench_material_determine_color_type(wpd, NULL, ob, is_sculpt_mode);
+
+ struct GPUBatch *geom;
+ if (color_type == V3D_SHADING_VERTEX_COLOR) {
+ geom = DRW_cache_mesh_surface_vertpaint_get(ob);
+ }
+ else {
+ geom = DRW_cache_object_surface_get(ob);
+ }
if (geom) {
material = workbench_forward_get_or_create_material_data(
- vedata, ob, NULL, NULL, NULL, wpd->shading.color_type, 0);
+ vedata, ob, NULL, NULL, NULL, color_type, 0, is_sculpt_mode);
if (is_sculpt_mode) {
DRW_shgroup_call_sculpt_add(material->shgrp_object_outline, ob, ob->obmat);
if (!is_wire) {
@@ -631,7 +640,7 @@ void workbench_forward_cache_populate(WORKBENCH_Data *vedata, Object *ob)
Material *mat = give_current_material(ob, i + 1);
material = workbench_forward_get_or_create_material_data(
- vedata, ob, mat, NULL, NULL, V3D_SHADING_MATERIAL_COLOR, 0);
+ vedata, ob, mat, NULL, NULL, V3D_SHADING_MATERIAL_COLOR, 0, is_sculpt_mode);
if (is_sculpt_mode) {
DRW_shgroup_call_sculpt_add(material->shgrp_object_outline, ob, ob->obmat);
if (!is_wire) {
diff --git a/source/blender/draw/engines/workbench/workbench_materials.c b/source/blender/draw/engines/workbench/workbench_materials.c
index d73eee37a98..c403e358d6a 100644
--- a/source/blender/draw/engines/workbench/workbench_materials.c
+++ b/source/blender/draw/engines/workbench/workbench_materials.c
@@ -31,6 +31,7 @@
#include "BLI_hash.h"
#include "DNA_node_types.h"
+#include "DNA_mesh_types.h"
#include "ED_uvedit.h"
@@ -42,7 +43,8 @@ void workbench_material_update_data(WORKBENCH_PrivateData *wpd,
Material *mat,
WORKBENCH_MaterialData *data)
{
- /* When V3D_SHADING_TEXTURE_COLOR is active, use V3D_SHADING_MATERIAL_COLOR as fallback when no texture could be determined */
+ /* When V3D_SHADING_TEXTURE_COLOR is active, use V3D_SHADING_MATERIAL_COLOR as fallback when no
+ * texture could be determined */
int color_type = wpd->shading.color_type == V3D_SHADING_TEXTURE_COLOR ?
V3D_SHADING_MATERIAL_COLOR :
wpd->shading.color_type;
@@ -67,7 +69,7 @@ void workbench_material_update_data(WORKBENCH_PrivateData *wpd,
hsv_to_rgb_v(hsv, data->diffuse_color);
copy_v3_v3(data->base_color, data->diffuse_color);
}
- else if (color_type == V3D_SHADING_OBJECT_COLOR) {
+ else if (ELEM(color_type, V3D_SHADING_OBJECT_COLOR, V3D_SHADING_VERTEX_COLOR)) {
copy_v3_v3(data->diffuse_color, ob->color);
copy_v3_v3(data->base_color, data->diffuse_color);
}
@@ -90,9 +92,14 @@ void workbench_material_update_data(WORKBENCH_PrivateData *wpd,
}
}
-char *workbench_material_build_defines(WORKBENCH_PrivateData *wpd, bool use_textures, bool is_hair)
+char *workbench_material_build_defines(WORKBENCH_PrivateData *wpd,
+ bool is_uniform_color,
+ bool is_hair)
{
char *str = NULL;
+ bool use_textures = (wpd->shading.color_type == V3D_SHADING_TEXTURE_COLOR) && !is_uniform_color;
+ bool use_vertex_colors = (wpd->shading.color_type == V3D_SHADING_VERTEX_COLOR) &&
+ !is_uniform_color;
DynStr *ds = BLI_dynstr_new();
@@ -126,6 +133,9 @@ char *workbench_material_build_defines(WORKBENCH_PrivateData *wpd, bool use_text
if (NORMAL_VIEWPORT_PASS_ENABLED(wpd)) {
BLI_dynstr_append(ds, "#define NORMAL_VIEWPORT_PASS_ENABLED\n");
}
+ if (use_vertex_colors) {
+ BLI_dynstr_append(ds, "#define V3D_SHADING_VERTEX_COLOR\n");
+ }
if (use_textures) {
BLI_dynstr_append(ds, "#define V3D_SHADING_TEXTURE_COLOR\n");
}
@@ -160,6 +170,7 @@ uint workbench_material_get_hash(WORKBENCH_MaterialData *material_template, bool
result += BLI_ghashutil_uinthash_v4_murmur(input);
result += BLI_ghashutil_uinthash((uint)is_ghost);
+ result += BLI_ghashutil_uinthash(material_template->color_type);
/* add texture reference */
if (material_template->ima) {
@@ -184,9 +195,12 @@ int workbench_material_get_composite_shader_index(WORKBENCH_PrivateData *wpd)
}
int workbench_material_get_prepass_shader_index(WORKBENCH_PrivateData *wpd,
- bool use_textures,
+ bool is_uniform_color,
bool is_hair)
{
+ bool use_textures = (wpd->shading.color_type == V3D_SHADING_TEXTURE_COLOR) && !is_uniform_color;
+ bool use_vertex_colors = (wpd->shading.color_type == V3D_SHADING_VERTEX_COLOR) &&
+ !is_uniform_color;
/* NOTE: change MAX_PREPASS_SHADERS accordingly when modifying this function. */
int index = 0;
SET_FLAG_FROM_TEST(index, is_hair, 1 << 0);
@@ -195,32 +209,46 @@ int workbench_material_get_prepass_shader_index(WORKBENCH_PrivateData *wpd,
SET_FLAG_FROM_TEST(index, NORMAL_VIEWPORT_PASS_ENABLED(wpd), 1 << 3);
SET_FLAG_FROM_TEST(index, MATCAP_ENABLED(wpd), 1 << 4);
SET_FLAG_FROM_TEST(index, use_textures, 1 << 5);
+ SET_FLAG_FROM_TEST(index, use_vertex_colors, 1 << 6);
BLI_assert(index < MAX_PREPASS_SHADERS);
return index;
}
int workbench_material_get_accum_shader_index(WORKBENCH_PrivateData *wpd,
- bool use_textures,
+ bool is_uniform_color,
bool is_hair)
{
+ bool use_textures = (wpd->shading.color_type == V3D_SHADING_TEXTURE_COLOR) && !is_uniform_color;
+ bool use_vertex_colors = (wpd->shading.color_type == V3D_SHADING_VERTEX_COLOR) &&
+ !is_uniform_color;
/* NOTE: change MAX_ACCUM_SHADERS accordingly when modifying this function. */
int index = 0;
/* 2 bits FLAT/STUDIO/MATCAP + Specular highlight */
index = SPECULAR_HIGHLIGHT_ENABLED(wpd) ? 3 : wpd->shading.light;
SET_FLAG_FROM_TEST(index, use_textures, 1 << 2);
- SET_FLAG_FROM_TEST(index, is_hair, 1 << 3);
+ SET_FLAG_FROM_TEST(index, use_vertex_colors, 1 << 3);
+ SET_FLAG_FROM_TEST(index, is_hair, 1 << 4);
/* 1 bits SHADOWS (only facing factor) */
- SET_FLAG_FROM_TEST(index, SHADOW_ENABLED(wpd), 1 << 4);
+ SET_FLAG_FROM_TEST(index, SHADOW_ENABLED(wpd), 1 << 5);
BLI_assert(index < MAX_ACCUM_SHADERS);
return index;
}
-int workbench_material_determine_color_type(WORKBENCH_PrivateData *wpd, Image *ima, Object *ob)
+int workbench_material_determine_color_type(WORKBENCH_PrivateData *wpd,
+ Image *ima,
+ Object *ob,
+ bool is_sculpt_mode)
{
int color_type = wpd->shading.color_type;
- if ((color_type == V3D_SHADING_TEXTURE_COLOR && ima == NULL) || (ob->dt < OB_TEXTURE)) {
+ const Mesh *me = (ob->type == OB_MESH) ? ob->data : NULL;
+
+ if ((color_type == V3D_SHADING_TEXTURE_COLOR && (ima == NULL || is_sculpt_mode)) ||
+ (ob->dt < OB_TEXTURE)) {
color_type = V3D_SHADING_MATERIAL_COLOR;
}
+ if (color_type == V3D_SHADING_VERTEX_COLOR && (me == NULL || me->mloopcol == NULL)) {
+ color_type = V3D_SHADING_OBJECT_COLOR;
+ }
return color_type;
}
@@ -264,7 +292,7 @@ void workbench_material_shgroup_uniform(WORKBENCH_PrivateData *wpd,
return;
}
- if (workbench_material_determine_color_type(wpd, material->ima, ob) ==
+ if (workbench_material_determine_color_type(wpd, material->ima, ob, false) ==
V3D_SHADING_TEXTURE_COLOR) {
ImBuf *ibuf = BKE_image_acquire_ibuf(material->ima, material->iuser, NULL);
const bool do_color_correction = wpd->use_color_management &&
diff --git a/source/blender/draw/engines/workbench/workbench_private.h b/source/blender/draw/engines/workbench/workbench_private.h
index 0e2ef2f94d2..3cfb1283416 100644
--- a/source/blender/draw/engines/workbench/workbench_private.h
+++ b/source/blender/draw/engines/workbench/workbench_private.h
@@ -37,11 +37,12 @@
#define WORKBENCH_ENGINE "BLENDER_WORKBENCH"
#define M_GOLDEN_RATION_CONJUGATE 0.618033988749895
#define MAX_COMPOSITE_SHADERS (1 << 6)
-#define MAX_PREPASS_SHADERS (1 << 6)
-#define MAX_ACCUM_SHADERS (1 << 5)
+#define MAX_PREPASS_SHADERS (1 << 7)
+#define MAX_ACCUM_SHADERS (1 << 6)
#define MAX_CAVITY_SHADERS (1 << 3)
#define TEXTURE_DRAWING_ENABLED(wpd) (wpd->shading.color_type == V3D_SHADING_TEXTURE_COLOR)
+#define VERTEX_COLORS_ENABLED(wpd) (wpd->shading.color_type == V3D_SHADING_VERTEX_COLOR)
#define FLAT_ENABLED(wpd) (wpd->shading.light == V3D_LIGHTING_FLAT)
#define STUDIOLIGHT_ENABLED(wpd) (wpd->shading.light == V3D_LIGHTING_STUDIO)
#define MATCAP_ENABLED(wpd) (wpd->shading.light == V3D_LIGHTING_MATCAP)
@@ -69,7 +70,8 @@
(ELEM(wpd->shading.color_type, \
V3D_SHADING_MATERIAL_COLOR, \
V3D_SHADING_OBJECT_COLOR, \
- V3D_SHADING_TEXTURE_COLOR))
+ V3D_SHADING_TEXTURE_COLOR, \
+ V3D_SHADING_VERTEX_COLOR))
#define IS_NAVIGATING(wpd) \
((DRW_context_state_get()->rv3d) && (DRW_context_state_get()->rv3d->rflag & RV3D_NAVIGATING))
@@ -213,16 +215,16 @@ BLI_STATIC_ASSERT_ALIGN(WORKBENCH_UBO_World, 16)
typedef struct WORKBENCH_PrivateData {
struct GHash *material_hash;
struct GHash *material_transp_hash;
- struct GPUShader *prepass_solid_sh;
- struct GPUShader *prepass_solid_hair_sh;
- struct GPUShader *prepass_texture_sh;
- struct GPUShader *prepass_texture_hair_sh;
+ struct GPUShader *prepass_sh;
+ struct GPUShader *prepass_hair_sh;
+ struct GPUShader *prepass_uniform_sh;
+ struct GPUShader *prepass_uniform_hair_sh;
struct GPUShader *composite_sh;
struct GPUShader *background_sh;
struct GPUShader *transparent_accum_sh;
struct GPUShader *transparent_accum_hair_sh;
- struct GPUShader *transparent_accum_texture_sh;
- struct GPUShader *transparent_accum_texture_hair_sh;
+ struct GPUShader *transparent_accum_uniform_sh;
+ struct GPUShader *transparent_accum_uniform_hair_sh;
View3DShading shading;
StudioLight *studio_light;
const UserDef *preferences;
@@ -353,7 +355,8 @@ WORKBENCH_MaterialData *workbench_forward_get_or_create_material_data(WORKBENCH_
Image *ima,
ImageUser *iuser,
int color_type,
- int interp);
+ int interp,
+ bool is_sculpt_mode);
/* workbench_effect_aa.c */
void workbench_aa_create_pass(WORKBENCH_Data *vedata, GPUTexture **tx);
@@ -382,11 +385,14 @@ void workbench_dof_create_pass(WORKBENCH_Data *vedata,
void workbench_dof_draw_pass(WORKBENCH_Data *vedata);
/* workbench_materials.c */
-int workbench_material_determine_color_type(WORKBENCH_PrivateData *wpd, Image *ima, Object *ob);
+int workbench_material_determine_color_type(WORKBENCH_PrivateData *wpd,
+ Image *ima,
+ Object *ob,
+ bool is_sculpt_mode);
void workbench_material_get_image_and_mat(
Object *ob, int mat_nr, Image **r_image, ImageUser **r_iuser, int *r_interp, Material **r_mat);
char *workbench_material_build_defines(WORKBENCH_PrivateData *wpd,
- bool use_textures,
+ bool is_uniform_color,
bool is_hair);
void workbench_material_update_data(WORKBENCH_PrivateData *wpd,
Object *ob,
@@ -395,10 +401,10 @@ void workbench_material_update_data(WORKBENCH_PrivateData *wpd,
uint workbench_material_get_hash(WORKBENCH_MaterialData *material_template, bool is_ghost);
int workbench_material_get_composite_shader_index(WORKBENCH_PrivateData *wpd);
int workbench_material_get_prepass_shader_index(WORKBENCH_PrivateData *wpd,
- bool use_textures,
+ bool is_uniform_color,
bool is_hair);
int workbench_material_get_accum_shader_index(WORKBENCH_PrivateData *wpd,
- bool use_textures,
+ bool is_uniform_color,
bool is_hair);
void workbench_material_shgroup_uniform(WORKBENCH_PrivateData *wpd,
DRWShadingGroup *grp,
diff --git a/source/blender/draw/engines/workbench/workbench_studiolight.c b/source/blender/draw/engines/workbench/workbench_studiolight.c
index 5c95a835adc..3fc83fea7c6 100644
--- a/source/blender/draw/engines/workbench/workbench_studiolight.c
+++ b/source/blender/draw/engines/workbench/workbench_studiolight.c
@@ -78,12 +78,12 @@ void studiolight_update_world(WORKBENCH_PrivateData *wpd,
mul_v3_v3fl(wd->spherical_harmonics_coefs[0], sl->spherical_harmonics_coefs[0], M_1_PI);
/* Swizzle to make shader code simpler. */
for (int i = 0; i < 3; ++i) {
- copy_v3_fl3(
- wd->spherical_harmonics_coefs[i + 1],
- -sl->spherical_harmonics_coefs[3][i],
- sl->spherical_harmonics_coefs[2][i],
- -sl->spherical_harmonics_coefs[1][i]);
- mul_v3_fl(wd->spherical_harmonics_coefs[i + 1], M_1_PI * 1.5f); /* 1.5f is to improve the contrast a bit. */
+ copy_v3_fl3(wd->spherical_harmonics_coefs[i + 1],
+ -sl->spherical_harmonics_coefs[3][i],
+ sl->spherical_harmonics_coefs[2][i],
+ -sl->spherical_harmonics_coefs[1][i]);
+ mul_v3_fl(wd->spherical_harmonics_coefs[i + 1],
+ M_1_PI * 1.5f); /* 1.5f is to improve the contrast a bit. */
}
/* Precompute as much as we can. See shader code for derivation. */
diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h
index b0320a522f8..4d8fefbbc06 100644
--- a/source/blender/draw/intern/DRW_render.h
+++ b/source/blender/draw/intern/DRW_render.h
@@ -329,7 +329,7 @@ typedef enum {
DRW_STATE_BLEND = (1 << 15),
DRW_STATE_ADDITIVE = (1 << 16),
DRW_STATE_MULTIPLY = (1 << 17),
- /* DRW_STATE_TRANSMISSION = (1 << 18), */ /* Not used */
+ DRW_STATE_BLEND_PREMUL_UNDER = (1 << 18),
DRW_STATE_CLIP_PLANES = (1 << 19),
/** Same as DRW_STATE_ADDITIVE but let alpha accumulate without premult. */
DRW_STATE_ADDITIVE_FULL = (1 << 20),
diff --git a/source/blender/draw/intern/draw_anim_viz.c b/source/blender/draw/intern/draw_anim_viz.c
index 8ff2916b040..a6026c9da3a 100644
--- a/source/blender/draw/intern/draw_anim_viz.c
+++ b/source/blender/draw/intern/draw_anim_viz.c
@@ -184,7 +184,7 @@ static void MPATH_cache_motion_path(MPATH_PassList *psl,
struct DRWTextStore *dt = DRW_text_cache_ensure();
int txt_flag = DRW_TEXT_CACHE_GLOBALSPACE | DRW_TEXT_CACHE_ASCII;
int cfra = (int)DEG_get_ctime(draw_ctx->depsgraph);
- bool sel = (pchan) ? (pchan->bone->flag & BONE_SELECTED) : (ob->flag & SELECT);
+ bool sel = (pchan) ? (pchan->bone->flag & BONE_SELECTED) : (ob->base_flag & BASE_SELECTED);
bool show_keyframes = (avs->path_viewflag & MOTIONPATH_VIEW_KFRAS) != 0;
int sfra, efra, stepsize;
@@ -259,7 +259,8 @@ static void MPATH_cache_motion_path(MPATH_PassList *psl,
else if (avs->path_viewflag & MOTIONPATH_VIEW_FNUMS) {
bMotionPathVert *mpvP = (mpv - stepsize);
bMotionPathVert *mpvN = (mpv + stepsize);
- /* only draw framenum if several consecutive highlighted points don't occur on same point */
+ /* only draw framenum if several consecutive highlighted points don't occur on same point
+ */
if ((equals_v3v3(mpv->co, mpvP->co) == 0) || (equals_v3v3(mpv->co, mpvN->co) == 0)) {
numstr_len = sprintf(numstr, " %d", frame);
DRW_text_cache_add(dt, mpv->co, numstr, numstr_len, 0, 0, txt_flag, col);
diff --git a/source/blender/draw/intern/draw_armature.c b/source/blender/draw/intern/draw_armature.c
index 12d4ca95a39..9b52f282944 100644
--- a/source/blender/draw/intern/draw_armature.c
+++ b/source/blender/draw/intern/draw_armature.c
@@ -345,36 +345,61 @@ static void drw_shgroup_bone_custom_solid(const float (*bone_mat)[4],
const eGPUShaderConfig sh_cfg,
Object *custom)
{
- /* grr, not re-using instances! */
struct GPUBatch *surf = DRW_cache_object_surface_get(custom);
struct GPUBatch *edges = DRW_cache_object_edge_detection_get(custom, NULL);
struct GPUBatch *ledges = DRW_cache_object_loose_edges_get(custom);
float final_bonemat[4][4];
- /* XXXXXXX needs to be moved elsewhere. */
- drw_batch_cache_generate_requested(custom);
-
if (surf || edges || ledges) {
mul_m4_m4m4(final_bonemat, g_data.ob->obmat, bone_mat);
}
+ BLI_assert(g_data.passes.custom_shapes != NULL);
+
if (surf && g_data.passes.bone_solid != NULL) {
- DRWShadingGroup *shgrp_geom_solid = shgroup_instance_bone_shape_solid(
- g_data.passes.bone_solid, surf, g_data.transparent, sh_cfg);
+ DRWShadingGroup *shgrp_geom_solid = BLI_ghash_lookup(g_data.passes.custom_shapes, surf);
+
+ if (shgrp_geom_solid == NULL) {
+ /* TODO(fclem) needs to be moved elsewhere. */
+ drw_batch_cache_generate_requested(custom);
+
+ /* NOTE! g_data.transparent require a separate shading group if the
+ * object is transparent. This is done by passing a different ghash
+ * for transparent armature in pose mode. */
+ shgrp_geom_solid = shgroup_instance_bone_shape_solid(
+ g_data.passes.bone_solid, surf, g_data.transparent, sh_cfg);
+ BLI_ghash_insert(g_data.passes.custom_shapes, surf, shgrp_geom_solid);
+ }
DRW_shgroup_call_dynamic_add(shgrp_geom_solid, final_bonemat, bone_color, hint_color);
}
if (edges && outline_color[3] > 0.0f) {
- DRWShadingGroup *shgrp_geom_wire = shgroup_instance_bone_shape_outline(
- g_data.passes.bone_outline, edges, sh_cfg);
+ DRWShadingGroup *shgrp_geom_wire = BLI_ghash_lookup(g_data.passes.custom_shapes, edges);
+
+ if (shgrp_geom_wire == NULL) {
+ /* TODO(fclem) needs to be moved elsewhere. */
+ drw_batch_cache_generate_requested(custom);
+
+ shgrp_geom_wire = shgroup_instance_bone_shape_outline(
+ g_data.passes.bone_outline, edges, sh_cfg);
+
+ BLI_ghash_insert(g_data.passes.custom_shapes, edges, shgrp_geom_wire);
+ }
DRW_shgroup_call_dynamic_add(shgrp_geom_wire, final_bonemat, outline_color);
}
if (ledges) {
- DRWShadingGroup *shgrp_geom_ledges = shgroup_instance_wire(g_data.passes.bone_wire, ledges);
- float final_color[4];
- copy_v3_v3(final_color, outline_color);
- final_color[3] = 1.0f; /* hack */
+ DRWShadingGroup *shgrp_geom_ledges = BLI_ghash_lookup(g_data.passes.custom_shapes, ledges);
+
+ if (shgrp_geom_ledges == NULL) {
+ /* TODO(fclem) needs to be moved elsewhere. */
+ drw_batch_cache_generate_requested(custom);
+
+ shgrp_geom_ledges = shgroup_instance_wire(g_data.passes.bone_wire, ledges);
+
+ BLI_ghash_insert(g_data.passes.custom_shapes, ledges, shgrp_geom_ledges);
+ }
+ float final_color[4] = {outline_color[0], outline_color[1], outline_color[2], 1.0f};
DRW_shgroup_call_dynamic_add(shgrp_geom_ledges, final_bonemat, final_color);
}
}
@@ -383,18 +408,22 @@ static void drw_shgroup_bone_custom_wire(const float (*bone_mat)[4],
const float color[4],
Object *custom)
{
- /* grr, not re-using instances! */
struct GPUBatch *geom = DRW_cache_object_all_edges_get(custom);
- /* XXXXXXX needs to be moved elsewhere. */
- drw_batch_cache_generate_requested(custom);
-
if (geom) {
- DRWShadingGroup *shgrp_geom_wire = shgroup_instance_wire(g_data.passes.bone_wire, geom);
- float final_bonemat[4][4], final_color[4];
+ DRWShadingGroup *shgrp_geom_wire = BLI_ghash_lookup(g_data.passes.custom_shapes, geom);
+
+ if (shgrp_geom_wire == NULL) {
+ /* TODO(fclem) needs to be moved elsewhere. */
+ drw_batch_cache_generate_requested(custom);
+
+ shgrp_geom_wire = shgroup_instance_wire(g_data.passes.bone_wire, geom);
+
+ BLI_ghash_insert(g_data.passes.custom_shapes, geom, shgrp_geom_wire);
+ }
+ float final_color[4] = {color[0], color[1], color[2], 1.0f};
+ float final_bonemat[4][4];
mul_m4_m4m4(final_bonemat, g_data.ob->obmat, bone_mat);
- copy_v3_v3(final_color, color);
- final_color[3] = 1.0f; /* hack */
DRW_shgroup_call_dynamic_add(shgrp_geom_wire, final_bonemat, final_color);
}
}
@@ -1110,14 +1139,17 @@ static void ebone_spline_preview(EditBone *ebone, float result_array[MAX_BBONE_S
param.roll1 += prev->roll2;
}
- param.scaleIn = ebone->scaleIn;
- param.scaleOut = ebone->scaleOut;
+ param.scale_in_x = ebone->scale_in_x;
+ param.scale_in_y = ebone->scale_in_y;
+
+ param.scale_out_x = ebone->scale_out_x;
+ param.scale_out_y = ebone->scale_out_y;
- param.curveInX = ebone->curveInX;
- param.curveInY = ebone->curveInY;
+ param.curve_in_x = ebone->curve_in_x;
+ param.curve_in_y = ebone->curve_in_y;
- param.curveOutX = ebone->curveOutX;
- param.curveOutY = ebone->curveOutY;
+ param.curve_out_x = ebone->curve_out_x;
+ param.curve_out_y = ebone->curve_out_y;
ebone->segments = BKE_pchan_bbone_spline_compute(&param, false, (Mat4 *)result_array);
}
@@ -1153,8 +1185,8 @@ static void draw_bone_update_disp_matrix_bbone(EditBone *eBone, bPoseChannel *pc
size_to_mat4(s, (const float[3]){xwidth, length / bbone_segments, zwidth});
/* Compute BBones segment matrices... */
- /* Note that we need this even for one-segment bones, because box drawing need specific weirdo matrix for the box,
- * that we cannot use to draw end points & co. */
+ /* Note that we need this even for one-segment bones, because box drawing need specific weirdo
+ * matrix for the box, that we cannot use to draw end points & co. */
if (pchan) {
Mat4 *bbones_mat = (Mat4 *)pchan->draw_data->bbone_matrix;
if (bbone_segments > 1) {
@@ -1765,7 +1797,8 @@ static void draw_bone_relations(EditBone *ebone,
}
else if (pchan && pchan->parent) {
if (do_relations) {
- /* Only draw if bone or its parent is selected - reduces viewport complexity with complex rigs */
+ /* Only draw if bone or its parent is selected - reduces viewport complexity with complex
+ * rigs */
if ((boneflag & BONE_SELECTED) ||
(pchan->parent->bone && (pchan->parent->bone->flag & BONE_SELECTED))) {
if ((boneflag & BONE_CONNECTED) == 0) {
diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c
index 74c87162afd..6b4c4cef9c8 100644
--- a/source/blender/draw/intern/draw_cache.c
+++ b/source/blender/draw/intern/draw_cache.c
@@ -161,9 +161,13 @@ static void UNUSED_FUNCTION(add_fancy_edge)(GPUVertBuf *vbo,
}
#if 0 /* UNUSED */
-static void add_lat_lon_vert(
- GPUVertBuf *vbo, uint pos_id, uint nor_id,
- uint *v_idx, const float rad, const float lat, const float lon)
+static void add_lat_lon_vert(GPUVertBuf *vbo,
+ uint pos_id,
+ uint nor_id,
+ uint *v_idx,
+ const float rad,
+ const float lat,
+ const float lon)
{
float pos[3], nor[3];
nor[0] = sinf(lat) * cosf(lon);
@@ -178,8 +182,10 @@ static void add_lat_lon_vert(
static GPUVertBuf *fill_arrows_vbo(const float scale)
{
/* Position Only 3D format */
- static GPUVertFormat format = { 0 };
- static struct { uint pos; } attr_id;
+ static GPUVertFormat format = {0};
+ static struct {
+ uint pos;
+ } attr_id;
if (format.attr_len == 0) {
attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
}
@@ -476,8 +482,9 @@ GPUBatch *DRW_cache_empty_cube_get(void)
{1.0f, 1.0f, 1.0f},
};
- const GLubyte indices[24] = {0, 1, 1, 3, 3, 2, 2, 0, 0, 4, 4, 5,
- 5, 7, 7, 6, 6, 4, 1, 5, 3, 7, 2, 6};
+ const GLubyte indices[24] = {
+ 0, 1, 1, 3, 3, 2, 2, 0, 0, 4, 4, 5, 5, 7, 7, 6, 6, 4, 1, 5, 3, 7, 2, 6,
+ };
/* Position Only 3D format */
static GPUVertFormat format = {0};
@@ -653,17 +660,20 @@ GPUBatch *DRW_cache_gpencil_axes_get(void)
float v2[3] = {0.0f, 0.0f, 0.0f};
/* cube data */
- const GLfloat verts[8][3] = {{-0.25f, -0.25f, -0.25f},
- {-0.25f, -0.25f, 0.25f},
- {-0.25f, 0.25f, -0.25f},
- {-0.25f, 0.25f, 0.25f},
- {0.25f, -0.25f, -0.25f},
- {0.25f, -0.25f, 0.25f},
- {0.25f, 0.25f, -0.25f},
- {0.25f, 0.25f, 0.25f}};
-
- const GLubyte indices[24] = {0, 1, 1, 3, 3, 2, 2, 0, 0, 4, 4, 5,
- 5, 7, 7, 6, 6, 4, 1, 5, 3, 7, 2, 6};
+ const GLfloat verts[8][3] = {
+ {-0.25f, -0.25f, -0.25f},
+ {-0.25f, -0.25f, 0.25f},
+ {-0.25f, 0.25f, -0.25f},
+ {-0.25f, 0.25f, 0.25f},
+ {0.25f, -0.25f, -0.25f},
+ {0.25f, -0.25f, 0.25f},
+ {0.25f, 0.25f, -0.25f},
+ {0.25f, 0.25f, 0.25f},
+ };
+
+ const GLubyte indices[24] = {
+ 0, 1, 1, 3, 3, 2, 2, 0, 0, 4, 4, 5, 5, 7, 7, 6, 6, 4, 1, 5, 3, 7, 2, 6,
+ };
/* Position Only 3D format */
static GPUVertFormat format = {0};
@@ -1740,11 +1750,13 @@ GPUBatch *DRW_cache_light_spot_volume_get(void)
GPUBatch *DRW_cache_light_spot_square_get(void)
{
if (!SHC.drw_light_spot_square) {
- float p[5][3] = {{0.0f, 0.0f, 0.0f},
- {1.0f, 1.0f, -1.0f},
- {1.0f, -1.0f, -1.0f},
- {-1.0f, -1.0f, -1.0f},
- {-1.0f, 1.0f, -1.0f}};
+ float p[5][3] = {
+ {0.0f, 0.0f, 0.0f},
+ {1.0f, 1.0f, -1.0f},
+ {1.0f, -1.0f, -1.0f},
+ {-1.0f, -1.0f, -1.0f},
+ {-1.0f, 1.0f, -1.0f},
+ };
uint v_idx = 0;
@@ -1777,11 +1789,13 @@ GPUBatch *DRW_cache_light_spot_square_get(void)
GPUBatch *DRW_cache_light_spot_square_volume_get(void)
{
if (!SHC.drw_light_spot_square_volume) {
- float p[5][3] = {{0.0f, 0.0f, 0.0f},
- {1.0f, 1.0f, -1.0f},
- {1.0f, -1.0f, -1.0f},
- {-1.0f, -1.0f, -1.0f},
- {-1.0f, 1.0f, -1.0f}};
+ float p[5][3] = {
+ {0.0f, 0.0f, 0.0f},
+ {1.0f, 1.0f, -1.0f},
+ {1.0f, -1.0f, -1.0f},
+ {-1.0f, -1.0f, -1.0f},
+ {-1.0f, 1.0f, -1.0f},
+ };
uint v_idx = 0;
@@ -2039,10 +2053,10 @@ static const float bone_octahedral_verts[6][3] = {
static const float bone_octahedral_smooth_normals[6][3] = {
{0.0f, -1.0f, 0.0f},
#if 0 /* creates problems for outlines when scaled */
- { 0.943608f * M_SQRT1_2, -0.331048f, 0.943608f * M_SQRT1_2},
- { 0.943608f * M_SQRT1_2, -0.331048f, -0.943608f * M_SQRT1_2},
- {-0.943608f * M_SQRT1_2, -0.331048f, -0.943608f * M_SQRT1_2},
- {-0.943608f * M_SQRT1_2, -0.331048f, 0.943608f * M_SQRT1_2},
+ {0.943608f * M_SQRT1_2, -0.331048f, 0.943608f * M_SQRT1_2},
+ {0.943608f * M_SQRT1_2, -0.331048f, -0.943608f * M_SQRT1_2},
+ {-0.943608f * M_SQRT1_2, -0.331048f, -0.943608f * M_SQRT1_2},
+ {-0.943608f * M_SQRT1_2, -0.331048f, 0.943608f * M_SQRT1_2},
#else
{M_SQRT1_2, 0.0f, M_SQRT1_2},
{M_SQRT1_2, 0.0f, -M_SQRT1_2},
@@ -2055,17 +2069,13 @@ static const float bone_octahedral_smooth_normals[6][3] = {
#if 0 /* UNUSED */
static const uint bone_octahedral_wire[24] = {
- 0, 1, 1, 5, 5, 3, 3, 0,
- 0, 4, 4, 5, 5, 2, 2, 0,
- 1, 2, 2, 3, 3, 4, 4, 1,
+ 0, 1, 1, 5, 5, 3, 3, 0, 0, 4, 4, 5, 5, 2, 2, 0, 1, 2, 2, 3, 3, 4, 4, 1,
};
/* aligned with bone_octahedral_wire
* Contains adjacent normal index */
static const uint bone_octahedral_wire_adjacent_face[24] = {
- 0, 3, 4, 7, 5, 6, 1, 2,
- 2, 3, 6, 7, 4, 5, 0, 1,
- 0, 4, 1, 5, 2, 6, 3, 7,
+ 0, 3, 4, 7, 5, 6, 1, 2, 2, 3, 6, 7, 4, 5, 0, 1, 0, 4, 1, 5, 2, 6, 3, 7,
};
#endif
@@ -2109,15 +2119,15 @@ static const uint bone_octahedral_wire_lines_adjacency[12][4] = {
#if 0 /* UNUSED */
static const uint bone_octahedral_solid_tris_adjacency[8][6] = {
- { 0, 12, 1, 10, 2, 3},
- { 3, 15, 4, 1, 5, 6},
- { 6, 18, 7, 4, 8, 9},
- { 9, 21, 10, 7, 11, 0},
-
- {12, 22, 13, 2, 14, 17},
- {15, 13, 16, 5, 17, 20},
- {18, 16, 19, 8, 20, 23},
- {21, 19, 22, 11, 23, 14},
+ {0, 12, 1, 10, 2, 3},
+ {3, 15, 4, 1, 5, 6},
+ {6, 18, 7, 4, 8, 9},
+ {9, 21, 10, 7, 11, 0},
+
+ {12, 22, 13, 2, 14, 17},
+ {15, 13, 16, 5, 17, 20},
+ {18, 16, 19, 8, 20, 23},
+ {21, 19, 22, 11, 23, 14},
};
#endif
@@ -2219,17 +2229,13 @@ static const float bone_box_smooth_normals[8][3] = {
#if 0 /* UNUSED */
static const uint bone_box_wire[24] = {
- 0, 1, 1, 2, 2, 3, 3, 0,
- 4, 5, 5, 6, 6, 7, 7, 4,
- 0, 4, 1, 5, 2, 6, 3, 7,
+ 0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7,
};
/* aligned with bone_octahedral_wire
* Contains adjacent normal index */
static const uint bone_box_wire_adjacent_face[24] = {
- 0, 2, 0, 4, 1, 6, 1, 8,
- 3, 10, 5, 10, 7, 11, 9, 11,
- 3, 8, 2, 5, 4, 7, 6, 9,
+ 0, 2, 0, 4, 1, 6, 1, 8, 3, 10, 5, 10, 7, 11, 9, 11, 3, 8, 2, 5, 4, 7, 6, 9,
};
#endif
@@ -2274,23 +2280,23 @@ static const uint bone_box_wire_lines_adjacency[12][4] = {
#if 0 /* UNUSED */
static const uint bone_box_solid_tris_adjacency[12][6] = {
- { 0, 5, 1, 14, 2, 8},
- { 3, 26, 4, 20, 5, 1},
+ {0, 5, 1, 14, 2, 8},
+ {3, 26, 4, 20, 5, 1},
- { 6, 2, 7, 16, 8, 11},
- { 9, 7, 10, 32, 11, 24},
+ {6, 2, 7, 16, 8, 11},
+ {9, 7, 10, 32, 11, 24},
- {12, 0, 13, 22, 14, 17},
- {15, 13, 16, 30, 17, 6},
+ {12, 0, 13, 22, 14, 17},
+ {15, 13, 16, 30, 17, 6},
- {18, 3, 19, 28, 20, 23},
- {21, 19, 22, 33, 23, 12},
+ {18, 3, 19, 28, 20, 23},
+ {21, 19, 22, 33, 23, 12},
- {24, 4, 25, 10, 26, 29},
- {27, 25, 28, 34, 29, 18},
+ {24, 4, 25, 10, 26, 29},
+ {27, 25, 28, 34, 29, 18},
- {30, 9, 31, 15, 32, 35},
- {33, 31, 34, 21, 35, 27},
+ {30, 9, 31, 15, 32, 35},
+ {33, 31, 34, 21, 35, 27},
};
#endif
@@ -2499,8 +2505,10 @@ GPUBatch *DRW_cache_bone_point_get(void)
const float lat_inc = M_PI / lat_res;
uint v_idx = 0;
- static GPUVertFormat format = { 0 };
- static struct { uint pos, nor; } attr_id;
+ static GPUVertFormat format = {0};
+ static struct {
+ uint pos, nor;
+ } attr_id;
if (format.attr_len == 0) {
attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
attr_id.nor = GPU_vertformat_attr_add(&format, "nor", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
@@ -2515,15 +2523,17 @@ GPUBatch *DRW_cache_bone_point_get(void)
float lat = 0.0f;
for (int j = 0; j < lat_res; j++, lat += lat_inc) {
if (j != lat_res - 1) { /* Pole */
- add_lat_lon_vert(vbo, attr_id.pos, attr_id.nor, &v_idx, rad, lat + lat_inc, lon + lon_inc);
+ add_lat_lon_vert(
+ vbo, attr_id.pos, attr_id.nor, &v_idx, rad, lat + lat_inc, lon + lon_inc);
add_lat_lon_vert(vbo, attr_id.pos, attr_id.nor, &v_idx, rad, lat + lat_inc, lon);
- add_lat_lon_vert(vbo, attr_id.pos, attr_id.nor, &v_idx, rad, lat, lon);
+ add_lat_lon_vert(vbo, attr_id.pos, attr_id.nor, &v_idx, rad, lat, lon);
}
if (j != 0) { /* Pole */
- add_lat_lon_vert(vbo, attr_id.pos, attr_id.nor, &v_idx, rad, lat, lon + lon_inc);
- add_lat_lon_vert(vbo, attr_id.pos, attr_id.nor, &v_idx, rad, lat + lat_inc, lon + lon_inc);
- add_lat_lon_vert(vbo, attr_id.pos, attr_id.nor, &v_idx, rad, lat, lon);
+ add_lat_lon_vert(vbo, attr_id.pos, attr_id.nor, &v_idx, rad, lat, lon + lon_inc);
+ add_lat_lon_vert(
+ vbo, attr_id.pos, attr_id.nor, &v_idx, rad, lat + lat_inc, lon + lon_inc);
+ add_lat_lon_vert(vbo, attr_id.pos, attr_id.nor, &v_idx, rad, lat, lon);
}
}
}
@@ -2755,10 +2765,14 @@ static float z_axis_name[10][2] = {
#define S_Y 0.007f
static float axis_marker[8][2] = {
#if 0 /* square */
- {-1.0f * S_X, 1.0f * S_Y}, { 1.0f * S_X, 1.0f * S_Y},
- { 1.0f * S_X, 1.0f * S_Y}, { 1.0f * S_X, -1.0f * S_Y},
- { 1.0f * S_X, -1.0f * S_Y}, {-1.0f * S_X, -1.0f * S_Y},
- {-1.0f * S_X, -1.0f * S_Y}, {-1.0f * S_X, 1.0f * S_Y}
+ {-1.0f * S_X, 1.0f * S_Y},
+ {1.0f * S_X, 1.0f * S_Y},
+ {1.0f * S_X, 1.0f * S_Y},
+ {1.0f * S_X, -1.0f * S_Y},
+ {1.0f * S_X, -1.0f * S_Y},
+ {-1.0f * S_X, -1.0f * S_Y},
+ {-1.0f * S_X, -1.0f * S_Y},
+ {-1.0f * S_X, 1.0f * S_Y}
#else /* diamond */
{-S_X, 0.f},
{0.f, S_Y},
@@ -3003,7 +3017,8 @@ GPUBatch *DRW_cache_bone_dof_lines_get(void)
* We could make these more generic functions.
* although filling 1d lines is not common.
*
- * \note Use x coordinate to identify the vertex the vertex shader take care to place it appropriately.
+ * \note Use x coordinate to identify the vertex the vertex shader take care to place it
+ * appropriately.
*/
static const float camera_coords_frame_bounds[5] = {
@@ -3269,6 +3284,12 @@ GPUBatch *DRW_cache_mesh_face_wireframe_get(Object *ob)
return DRW_mesh_batch_cache_get_wireframes_face(ob->data);
}
+GPUBatch *DRW_cache_mesh_surface_mesh_analysis_get(Object *ob)
+{
+ BLI_assert(ob->type == OB_MESH);
+ return DRW_mesh_batch_cache_get_edit_mesh_analysis(ob->data);
+}
+
void DRW_cache_mesh_sculpt_coords_ensure(Object *ob)
{
BLI_assert(ob->type == OB_MESH);
@@ -3288,7 +3309,13 @@ GPUBatch *DRW_cache_curve_edge_wire_get(Object *ob)
BLI_assert(ob->type == OB_CURVE);
struct Curve *cu = ob->data;
- return DRW_curve_batch_cache_get_wire_edge(cu);
+ struct Mesh *mesh_eval = ob->runtime.mesh_eval;
+ if (mesh_eval != NULL) {
+ return DRW_mesh_batch_cache_get_loose_edges(mesh_eval);
+ }
+ else {
+ return DRW_curve_batch_cache_get_wire_edge(cu);
+ }
}
GPUBatch *DRW_cache_curve_edge_normal_get(Object *ob)
@@ -3434,7 +3461,13 @@ GPUBatch *DRW_cache_text_edge_wire_get(Object *ob)
BLI_assert(ob->type == OB_FONT);
struct Curve *cu = ob->data;
- return DRW_curve_batch_cache_get_wire_edge(cu);
+ struct Mesh *mesh_eval = ob->runtime.mesh_eval;
+ if (mesh_eval != NULL) {
+ return DRW_mesh_batch_cache_get_loose_edges(mesh_eval);
+ }
+ else {
+ return DRW_curve_batch_cache_get_wire_edge(cu);
+ }
}
GPUBatch *DRW_cache_text_surface_get(Object *ob)
@@ -3546,7 +3579,13 @@ GPUBatch *DRW_cache_surf_edge_wire_get(Object *ob)
BLI_assert(ob->type == OB_SURF);
struct Curve *cu = ob->data;
- return DRW_curve_batch_cache_get_wire_edge(cu);
+ struct Mesh *mesh_eval = ob->runtime.mesh_eval;
+ if (mesh_eval != NULL) {
+ return DRW_mesh_batch_cache_get_loose_edges(mesh_eval);
+ }
+ else {
+ return DRW_curve_batch_cache_get_wire_edge(cu);
+ }
}
GPUBatch *DRW_cache_surf_face_wireframe_get(Object *ob)
@@ -4017,4 +4056,25 @@ void drw_batch_cache_generate_requested(Object *ob)
}
}
+void DRW_batch_cache_free_old(Object *ob, int ctime)
+{
+ struct Mesh *mesh_eval = ob->runtime.mesh_eval;
+
+ switch (ob->type) {
+ case OB_MESH:
+ DRW_mesh_batch_cache_free_old((Mesh *)ob->data, ctime);
+ break;
+ case OB_CURVE:
+ case OB_FONT:
+ case OB_SURF:
+ if (mesh_eval) {
+ DRW_mesh_batch_cache_free_old(mesh_eval, ctime);
+ }
+ break;
+ /* TODO all cases */
+ default:
+ break;
+ }
+}
+
/** \} */
diff --git a/source/blender/draw/intern/draw_cache.h b/source/blender/draw/intern/draw_cache.h
index c9ae0a01cb9..129b180957a 100644
--- a/source/blender/draw/intern/draw_cache.h
+++ b/source/blender/draw/intern/draw_cache.h
@@ -140,6 +140,7 @@ struct GPUBatch **DRW_cache_mesh_surface_texpaint_get(struct Object *ob);
struct GPUBatch *DRW_cache_mesh_surface_texpaint_single_get(struct Object *ob);
struct GPUBatch *DRW_cache_mesh_surface_vertpaint_get(struct Object *ob);
struct GPUBatch *DRW_cache_mesh_surface_weights_get(struct Object *ob);
+struct GPUBatch *DRW_cache_mesh_surface_mesh_analysis_get(struct Object *ob);
struct GPUBatch *DRW_cache_mesh_face_wireframe_get(struct Object *ob);
void DRW_cache_mesh_sculpt_coords_ensure(struct Object *ob);
diff --git a/source/blender/draw/intern/draw_cache_impl.h b/source/blender/draw/intern/draw_cache_impl.h
index 94d8a82f2e4..4ef8f5a9326 100644
--- a/source/blender/draw/intern/draw_cache_impl.h
+++ b/source/blender/draw/intern/draw_cache_impl.h
@@ -61,6 +61,11 @@ void DRW_particle_batch_cache_free(struct ParticleSystem *psys);
void DRW_gpencil_batch_cache_dirty_tag(struct bGPdata *gpd);
void DRW_gpencil_batch_cache_free(struct bGPdata *gpd);
+/* Garbage collection */
+void DRW_batch_cache_free_old(struct Object *ob, int ctime);
+
+void DRW_mesh_batch_cache_free_old(struct Mesh *me, int ctime);
+
/* Curve */
void DRW_curve_batch_cache_create_requested(struct Object *ob);
@@ -152,6 +157,7 @@ struct GPUBatch *DRW_mesh_batch_cache_get_edituv_verts(struct Mesh *me);
struct GPUBatch *DRW_mesh_batch_cache_get_edituv_facedots(struct Mesh *me);
/* For Image UV editor. */
struct GPUBatch *DRW_mesh_batch_cache_get_uv_edges(struct Mesh *me);
+struct GPUBatch *DRW_mesh_batch_cache_get_edit_mesh_analysis(struct Mesh *me);
void DRW_mesh_cache_sculpt_coords_ensure(struct Mesh *me);
@@ -199,10 +205,19 @@ struct GPUBatch *DRW_particles_batch_cache_get_edit_tip_points(struct Object *ob
struct PTCacheEdit *edit);
/* Common */
-#define DRW_ADD_FLAG_FROM_VBO_REQUEST(flag, vbo, value) \
- (flag |= DRW_vbo_requested(vbo) ? (value) : 0)
-#define DRW_ADD_FLAG_FROM_IBO_REQUEST(flag, ibo, value) \
- (flag |= DRW_ibo_requested(ibo) ? (value) : 0)
+// #define DRW_DEBUG_MESH_CACHE_REQUEST
+
+#ifdef DRW_DEBUG_MESH_CACHE_REQUEST
+# define DRW_ADD_FLAG_FROM_VBO_REQUEST(flag, vbo, value) \
+ (flag |= DRW_vbo_requested(vbo) ? (printf(" VBO requested " #vbo "\n") ? value : value) : 0)
+# define DRW_ADD_FLAG_FROM_IBO_REQUEST(flag, ibo, value) \
+ (flag |= DRW_ibo_requested(ibo) ? (printf(" IBO requested " #ibo "\n") ? value : value) : 0)
+#else
+# define DRW_ADD_FLAG_FROM_VBO_REQUEST(flag, vbo, value) \
+ (flag |= DRW_vbo_requested(vbo) ? (value) : 0)
+# define DRW_ADD_FLAG_FROM_IBO_REQUEST(flag, ibo, value) \
+ (flag |= DRW_ibo_requested(ibo) ? (value) : 0)
+#endif
/* Test and assign NULL if test fails */
#define DRW_TEST_ASSIGN_VBO(v) (v = (DRW_vbo_requested(v) ? (v) : NULL))
diff --git a/source/blender/draw/intern/draw_cache_impl_curve.c b/source/blender/draw/intern/draw_cache_impl_curve.c
index 8e7a2253e21..33b872109a5 100644
--- a/source/blender/draw/intern/draw_cache_impl_curve.c
+++ b/source/blender/draw/intern/draw_cache_impl_curve.c
@@ -988,6 +988,10 @@ void DRW_curve_batch_cache_create_requested(Object *ob)
}
}
+#ifdef DRW_DEBUG_MESH_CACHE_REQUEST
+ printf("-- %s %s --\n", __func__, ob->id.name + 2);
+#endif
+
/* Generate MeshRenderData flags */
int mr_flag = 0;
DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag, cache->ordered.pos_nor, CU_DATATYPE_SURFACE);
@@ -1011,6 +1015,10 @@ void DRW_curve_batch_cache_create_requested(Object *ob)
DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_flag, cache->surf_per_mat_tris[i], CU_DATATYPE_SURFACE);
}
+#ifdef DRW_DEBUG_MESH_CACHE_REQUEST
+ printf(" mr_flag %d\n\n", mr_flag);
+#endif
+
CurveRenderData *rdata = curve_render_data_create(cu, ob->runtime.curve_cache, mr_flag);
/* DispLists */
diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c
index ded9d0963b7..1d8c7f0e5a7 100644
--- a/source/blender/draw/intern/draw_cache_impl_mesh.c
+++ b/source/blender/draw/intern/draw_cache_impl_mesh.c
@@ -304,7 +304,7 @@ typedef struct MeshRenderData {
bool *edge_visible_bool;
} MeshRenderData;
-enum {
+typedef enum eMRDataType {
MR_DATATYPE_VERT = 1 << 0,
MR_DATATYPE_EDGE = 1 << 1,
MR_DATATYPE_LOOPTRI = 1 << 2,
@@ -317,11 +317,16 @@ enum {
MR_DATATYPE_LOOPUV = 1 << 9,
MR_DATATYPE_LOOSE_VERT = 1 << 10,
MR_DATATYPE_LOOSE_EDGE = 1 << 11,
-};
+ MR_DATATYPE_LOOP_NORMALS = 1 << 12,
+} eMRDataType;
+
+#define MR_DATATYPE_VERT_LOOP_POLY (MR_DATATYPE_VERT | MR_DATATYPE_POLY | MR_DATATYPE_LOOP)
+#define MR_DATATYPE_VERT_LOOP_TRI_POLY (MR_DATATYPE_VERT_LOOP_POLY | MR_DATATYPE_LOOPTRI)
+#define MR_DATATYPE_LOOSE_VERT_EGDE (MR_DATATYPE_LOOSE_VERT | MR_DATATYPE_LOOSE_EDGE)
/**
- * These functions look like they would be slow but they will typically return true on the first iteration.
- * Only false when all attached elements are hidden.
+ * These functions look like they would be slow but they will typically return true on the first
+ * iteration. Only false when all attached elements are hidden.
*/
static bool bm_vert_has_visible_edge(const BMVert *v)
{
@@ -364,6 +369,11 @@ BLI_INLINE bool mesh_cd_layers_type_overlap(DRW_MeshCDMask a, DRW_MeshCDMask b)
return (*((uint32_t *)&a) & *((uint32_t *)&b)) == *((uint32_t *)&b);
}
+BLI_INLINE bool mesh_cd_layers_type_equal(DRW_MeshCDMask a, DRW_MeshCDMask b)
+{
+ return *((uint32_t *)&a) == *((uint32_t *)&b);
+}
+
BLI_INLINE void mesh_cd_layers_type_merge(DRW_MeshCDMask *a, DRW_MeshCDMask b)
{
atomic_fetch_and_or_uint32((uint32_t *)a, *(uint32_t *)&b);
@@ -670,9 +680,17 @@ static MeshRenderData *mesh_render_data_create_ex(Mesh *me,
bm_ensure_types |= BM_LOOP;
}
if (types & MR_DATATYPE_LOOP) {
- int totloop = bm->totloop;
+ rdata->loop_len = bm->totloop;
+ bm_ensure_types |= BM_LOOP;
+ }
+ if (types & MR_DATATYPE_POLY) {
+ rdata->poly_len = bm->totface;
+ bm_ensure_types |= BM_FACE;
+ }
+ if (types & MR_DATATYPE_LOOP_NORMALS) {
+ BLI_assert(types & MR_DATATYPE_LOOP);
if (is_auto_smooth) {
- rdata->loop_normals = MEM_mallocN(sizeof(*rdata->loop_normals) * totloop, __func__);
+ rdata->loop_normals = MEM_mallocN(sizeof(*rdata->loop_normals) * bm->totloop, __func__);
int cd_loop_clnors_offset = CustomData_get_offset(&bm->ldata, CD_CUSTOMLOOPNORMAL);
BM_loops_calc_normal_vcos(bm,
NULL,
@@ -686,12 +704,6 @@ static MeshRenderData *mesh_render_data_create_ex(Mesh *me,
cd_loop_clnors_offset,
false);
}
- rdata->loop_len = totloop;
- bm_ensure_types |= BM_LOOP;
- }
- if (types & MR_DATATYPE_POLY) {
- rdata->poly_len = bm->totface;
- bm_ensure_types |= BM_FACE;
}
if (types & MR_DATATYPE_OVERLAY) {
rdata->efa_act_uv = EDBM_uv_active_face_get(embm, false, false);
@@ -828,7 +840,9 @@ static MeshRenderData *mesh_render_data_create_ex(Mesh *me,
if (types & MR_DATATYPE_LOOP) {
rdata->loop_len = me->totloop;
rdata->mloop = CustomData_get_layer(&me->ldata, CD_MLOOP);
-
+ }
+ if (types & MR_DATATYPE_LOOP_NORMALS) {
+ BLI_assert(types & MR_DATATYPE_LOOP);
if (is_auto_smooth) {
mesh_render_calc_normals_loop_and_poly(me, split_angle, rdata);
}
@@ -1145,7 +1159,8 @@ static MeshRenderData *mesh_render_data_create_ex(Mesh *me,
/* note: BKE_editmesh_loop_tangent_calc calculates 'CD_TANGENT',
* not 'CD_MLOOPTANGENT' (as done below). It's OK, they're compatible. */
- /* note: normally we'd use 'i_src' here, but 'i_dst' is in sync with 'rdata->cd.output' */
+ /* note: normally we'd use 'i_src' here, but 'i_dst' is in sync with 'rdata->cd.output'
+ */
rdata->cd.layers.tangent[i_dst] = CustomData_get_layer_n(
&rdata->cd.output.ldata, CD_TANGENT, i_dst);
if (rdata->tri_len != 0) {
@@ -1344,10 +1359,6 @@ static int mesh_render_data_polys_len_get_maybe_mapped(const MeshRenderData *rda
/* ---------------------------------------------------------------------- */
-/* TODO remove prototype. */
-static void mesh_create_edit_facedots(MeshRenderData *rdata,
- GPUVertBuf *vbo_facedots_pos_nor_data);
-
/** \name Internal Cache (Lazy Initialization)
* \{ */
@@ -1645,7 +1656,7 @@ static void mesh_render_data_edge_flag(const MeshRenderData *rdata,
* specular highlights make it hard to see T55456#510873.
*
* This isn't ideal since it can't be used when mixing edge/face modes
- * but it's still better then not being able to see the active face. */
+ * but it's still better then not being able to see the active face. */
if (is_face_only_select_mode) {
if (rdata->efa_act != NULL) {
if (BM_edge_in_face(eed, rdata->efa_act)) {
@@ -1906,6 +1917,7 @@ typedef struct MeshBatchCache {
GPUVertBuf *loop_data;
GPUVertBuf *loop_lnor;
GPUVertBuf *facedots_pos_nor_data;
+ GPUVertBuf *loop_mesh_analysis;
/* UV data without modifier applied.
* Vertex count is always the one of the cage. */
GPUVertBuf *loop_uv;
@@ -1953,6 +1965,7 @@ typedef struct MeshBatchCache {
GPUBatch *edit_edges;
GPUBatch *edit_lnor;
GPUBatch *edit_facedots;
+ GPUBatch *edit_mesh_analysis;
/* Edit UVs */
GPUBatch *edituv_faces_strech_area;
GPUBatch *edituv_faces_strech_angle;
@@ -1997,7 +2010,9 @@ typedef struct MeshBatchCache {
struct DRW_MeshWeightState weight_state;
- DRW_MeshCDMask cd_used, cd_needed;
+ DRW_MeshCDMask cd_used, cd_needed, cd_used_over_time;
+
+ int lastmatch;
/* XXX, only keep for as long as sculpt mode uses shaded drawing. */
bool is_sculpt_points_tag;
@@ -2121,6 +2136,8 @@ static void mesh_batch_cache_discard_shaded_tri(MeshBatchCache *cache)
MEM_SAFE_FREE(cache->auto_layer_names);
MEM_SAFE_FREE(cache->auto_layer_is_srgb);
+ mesh_cd_layers_type_clear(&cache->cd_used);
+
cache->mat_len = 0;
}
@@ -2160,8 +2177,13 @@ void DRW_mesh_batch_cache_dirty_tag(Mesh *me, int mode)
GPU_BATCH_DISCARD_SAFE(cache->batch.edit_vertices);
GPU_BATCH_DISCARD_SAFE(cache->batch.edit_edges);
GPU_BATCH_DISCARD_SAFE(cache->batch.edit_facedots);
- /* Paint mode selection */
- /* TODO only do that in paint mode. */
+ GPU_BATCH_DISCARD_SAFE(cache->batch.edit_mesh_analysis);
+ /* Because visible UVs depends on edit mode selection, discard everything. */
+ mesh_batch_cache_discard_uvedit(cache);
+ break;
+ case BKE_MESH_BATCH_DIRTY_SELECT_PAINT:
+ /* Paint mode selection flag is packed inside the nor attrib.
+ * Note that it can be slow if auto smooth is enabled. (see T63946) */
GPU_VERTBUF_DISCARD_SAFE(cache->ordered.loop_pos_nor);
GPU_BATCH_DISCARD_SAFE(cache->batch.surface);
GPU_BATCH_DISCARD_SAFE(cache->batch.wire_loops);
@@ -2170,8 +2192,6 @@ void DRW_mesh_batch_cache_dirty_tag(Mesh *me, int mode)
GPU_BATCH_DISCARD_SAFE(cache->surf_per_mat[i]);
}
}
- /* Because visible UVs depends on edit mode selection, discard everything. */
- mesh_batch_cache_discard_uvedit(cache);
break;
case BKE_MESH_BATCH_DIRTY_ALL:
cache->is_dirty = true;
@@ -3128,7 +3148,8 @@ static void mesh_create_loop_uv_and_tan(MeshRenderData *rdata, GPUVertBuf *vbo)
for (uint i = 0; i < uv_len; i++) {
const char *attr_name = mesh_render_data_uv_layer_uuid_get(rdata, i);
#if 0 /* these are clamped. Maybe use them as an option in the future */
- uv_id[i] = GPU_vertformat_attr_add(&format, attr_name, GPU_COMP_I16, 2, GPU_FETCH_INT_TO_FLOAT_UNIT);
+ uv_id[i] = GPU_vertformat_attr_add(
+ &format, attr_name, GPU_COMP_I16, 2, GPU_FETCH_INT_TO_FLOAT_UNIT);
#else
uv_id[i] = GPU_vertformat_attr_add(&format, attr_name, GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
#endif
@@ -3373,6 +3394,71 @@ static void mesh_create_edit_facedots(MeshRenderData *rdata, GPUVertBuf *vbo_fac
}
}
+static void mesh_create_edit_mesh_analysis(MeshRenderData *rdata, GPUVertBuf *vbo_mesh_analysis)
+{
+ const MeshStatVis *mesh_stat_vis = &rdata->toolsettings->statvis;
+
+ int mesh_analysis_len_used = 0;
+
+ const uint loops_len = mesh_render_data_loops_len_get(rdata);
+ BMesh *bm = rdata->edit_bmesh->bm;
+ BMIter iter_efa, iter_loop;
+ BMFace *efa;
+ BMLoop *loop;
+
+ static struct {
+ uint weight;
+ } attr_id;
+ static GPUVertFormat mesh_analysis_format = {0};
+ if (mesh_analysis_format.attr_len == 0) {
+ attr_id.weight = GPU_vertformat_attr_add(
+ &mesh_analysis_format, "weight_color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
+ }
+
+ /* TODO(jbakker): Maybe move data generation to mesh_render_data_create() */
+ BKE_editmesh_statvis_calc(rdata->edit_bmesh, rdata->edit_data, mesh_stat_vis);
+
+ if (DRW_TEST_ASSIGN_VBO(vbo_mesh_analysis)) {
+ GPU_vertbuf_init_with_format(vbo_mesh_analysis, &mesh_analysis_format);
+ GPU_vertbuf_data_alloc(vbo_mesh_analysis, loops_len);
+ }
+
+ const bool is_vertex_data = mesh_stat_vis->type == SCE_STATVIS_SHARP;
+ if (is_vertex_data) {
+ BM_ITER_MESH (efa, &iter_efa, bm, BM_FACES_OF_MESH) {
+ BM_ITER_ELEM (loop, &iter_loop, efa, BM_LOOPS_OF_FACE) {
+ uint vertex_index = BM_elem_index_get(loop->v);
+ GPU_vertbuf_attr_set(vbo_mesh_analysis,
+ attr_id.weight,
+ mesh_analysis_len_used,
+ &rdata->edit_bmesh->derivedVertColor[vertex_index]);
+ mesh_analysis_len_used += 1;
+ }
+ }
+ }
+ else {
+ uint face_index;
+ BM_ITER_MESH_INDEX (efa, &iter_efa, bm, BM_FACES_OF_MESH, face_index) {
+ BM_ITER_ELEM (loop, &iter_loop, efa, BM_LOOPS_OF_FACE) {
+ GPU_vertbuf_attr_set(vbo_mesh_analysis,
+ attr_id.weight,
+ mesh_analysis_len_used,
+ &rdata->edit_bmesh->derivedFaceColor[face_index]);
+ mesh_analysis_len_used += 1;
+ }
+ }
+ }
+
+ // Free temp data in edit bmesh
+ BKE_editmesh_color_free(rdata->edit_bmesh);
+
+ /* Resize & Finish */
+ if (mesh_analysis_len_used != loops_len) {
+ if (vbo_mesh_analysis != NULL) {
+ GPU_vertbuf_data_resize(vbo_mesh_analysis, mesh_analysis_len_used);
+ }
+ }
+}
/* Indices */
#define NO_EDGE INT_MAX
@@ -4185,6 +4271,12 @@ GPUBatch *DRW_mesh_batch_cache_get_wireframes_face(Mesh *me)
return DRW_batch_request(&cache->batch.wire_edges);
}
+GPUBatch *DRW_mesh_batch_cache_get_edit_mesh_analysis(Mesh *me)
+{
+ MeshBatchCache *cache = mesh_batch_cache_get(me);
+ return DRW_batch_request(&cache->batch.edit_mesh_analysis);
+}
+
GPUBatch **DRW_mesh_batch_cache_get_surface_shaded(Mesh *me,
struct GPUMaterial **gpumat_array,
uint gpumat_array_len,
@@ -4197,16 +4289,16 @@ GPUBatch **DRW_mesh_batch_cache_get_surface_shaded(Mesh *me,
BLI_assert(gpumat_array_len == cache->mat_len);
- bool cd_overlap = mesh_cd_layers_type_overlap(cache->cd_used, cd_needed);
- if (!cd_overlap) {
- mesh_cd_layers_type_merge(&cache->cd_needed, cd_needed);
+ mesh_cd_layers_type_merge(&cache->cd_needed, cd_needed);
+ if (!mesh_cd_layers_type_overlap(cache->cd_used, cd_needed)) {
mesh_cd_extract_auto_layers_names_and_srgb(me,
cache->cd_needed,
&cache->auto_layer_names,
&cache->auto_layer_is_srgb,
&cache->auto_layer_len);
}
+
if (auto_layer_names) {
*auto_layer_names = cache->auto_layer_names;
*auto_layer_is_srgb = cache->auto_layer_is_srgb;
@@ -4419,8 +4511,7 @@ BLI_INLINE void edit_uv_preprocess_stretch_angle(float (*auv)[2],
BMLoop *l;
BMIter liter;
int i;
- BM_ITER_ELEM_INDEX(l, &liter, efa, BM_LOOPS_OF_FACE, i)
- {
+ BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
MLoopUV *luv_prev = BM_ELEM_CD_GET_VOID_P(l->prev, cd_loop_uv_offset);
@@ -4433,8 +4524,10 @@ BLI_INLINE void edit_uv_preprocess_stretch_angle(float (*auv)[2],
}
#if 0 /* here for reference, this is done in shader now. */
-BLI_INLINE float edit_uv_get_loop_stretch_angle(
- const float auv0[2], const float auv1[2], const float av0[3], const float av1[3])
+BLI_INLINE float edit_uv_get_loop_stretch_angle(const float auv0[2],
+ const float auv1[2],
+ const float av0[3],
+ const float av1[3])
{
float uvang = angle_normalized_v2v2(auv0, auv1);
float ang = angle_normalized_v3v3(av0, av1);
@@ -4509,16 +4602,25 @@ static void uvedit_fill_buffer_data(MeshRenderData *rdata,
}
/* Skip hidden faces. */
- if (elb_face && face_visible) {
- for (i = 0; i < efa->len; ++i) {
- GPU_indexbuf_add_generic_vert(elb_face, vidx + i);
- GPU_indexbuf_add_generic_vert(elb_vert, vidx + i);
- GPU_indexbuf_add_line_verts(elb_edge, vidx + i, vidx + (i + 1) % efa->len);
+ if (face_visible) {
+ if (elb_face) {
+ for (i = 0; i < efa->len; ++i) {
+ GPU_indexbuf_add_generic_vert(elb_face, vidx + i);
+ }
+ }
+ if (elb_vert) {
+ for (i = 0; i < efa->len; ++i) {
+ GPU_indexbuf_add_generic_vert(elb_vert, vidx + i);
+ }
+ }
+ if (elb_edge) {
+ for (i = 0; i < efa->len; ++i) {
+ GPU_indexbuf_add_line_verts(elb_edge, vidx + i, vidx + (i + 1) % efa->len);
+ }
}
}
- BM_ITER_ELEM_INDEX(l, &liter, efa, BM_LOOPS_OF_FACE, i)
- {
+ BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
if (vbo_area) {
GPU_vertbuf_attr_set(vbo_area, uv_attr_id.area, vidx, &area_stretch);
@@ -4578,18 +4680,24 @@ static void uvedit_fill_buffer_data(MeshRenderData *rdata,
GPU_vertbuf_attr_set(vbo_fdots_data, uv_attr_id.fdots_flag, fdot_idx, &face_flag);
}
/* Skip hidden faces. */
- if (elb_face && face_visible) {
- for (i = 0; i < mpoly->totloop; ++i) {
- GPU_indexbuf_add_generic_vert(elb_face, vidx + i);
- if (e_origindex[l[i].e] != ORIGINDEX_NONE) {
+ if (face_visible) {
+ if (elb_face) {
+ for (i = 0; i < mpoly->totloop; ++i) {
+ GPU_indexbuf_add_generic_vert(elb_face, vidx + i);
+ }
+ GPU_indexbuf_add_generic_vert(elb_face, vidx);
+ GPU_indexbuf_add_primitive_restart(elb_face);
+ }
+ if (elb_edge && e_origindex[l[i].e] != ORIGINDEX_NONE) {
+ for (i = 0; i < mpoly->totloop; ++i) {
GPU_indexbuf_add_line_verts(elb_edge, vidx + i, vidx + (i + 1) % mpoly->totloop);
}
- if (v_origindex[l[i].v] != ORIGINDEX_NONE) {
+ }
+ if (elb_vert && v_origindex[l[i].v] != ORIGINDEX_NONE) {
+ for (i = 0; i < mpoly->totloop; ++i) {
GPU_indexbuf_add_generic_vert(elb_vert, vidx + i);
}
}
- GPU_indexbuf_add_generic_vert(elb_face, vidx);
- GPU_indexbuf_add_primitive_restart(elb_face);
}
for (i = 0; i < mpoly->totloop; i++, l++) {
/* TODO support stretch. */
@@ -4714,6 +4822,28 @@ static void mesh_create_uvedit_buffers(MeshRenderData *rdata,
/** \name Grouped batch generation
* \{ */
+/* Thread safety need to be assured by caller. Don't call this during drawing.
+ * Note: For now this only free the shading batches / vbo if any cd layers is
+ * not needed anymore. */
+void DRW_mesh_batch_cache_free_old(Mesh *me, int ctime)
+{
+ MeshBatchCache *cache = me->runtime.batch_cache;
+
+ if (cache == NULL) {
+ return;
+ }
+
+ if (mesh_cd_layers_type_equal(cache->cd_used_over_time, cache->cd_used)) {
+ cache->lastmatch = ctime;
+ }
+
+ if (ctime - cache->lastmatch > U.vbotimeout) {
+ mesh_batch_cache_discard_shaded_tri(cache);
+ }
+
+ mesh_cd_layers_type_clear(&cache->cd_used_over_time);
+}
+
/* Can be called for any surface type. Mesh *me is the final mesh. */
void DRW_mesh_batch_cache_create_requested(
Object *ob, Mesh *me, const ToolSettings *ts, const bool is_paint_mode, const bool use_hide)
@@ -4730,6 +4860,18 @@ void DRW_mesh_batch_cache_create_requested(
drw_mesh_weight_state_clear(&wstate);
}
+ /* Optimization : Only create orco layer if mesh is deformed. */
+ if (cache->cd_needed.orco != 0) {
+ CustomData *cd_vdata = (me->edit_mesh) ? &me->edit_mesh->bm->vdata : &me->vdata;
+ if (CustomData_get_layer(cd_vdata, CD_ORCO) != NULL && ob->modifiers.first != NULL) {
+ /* Orco layer is needed. */
+ }
+ else if (cache->cd_needed.tan_orco == 0) {
+ /* Skip orco calculation if not needed by tangent generation. */
+ cache->cd_needed.orco = 0;
+ }
+ }
+
/* Verify that all surface batches have needed attribute layers. */
/* TODO(fclem): We could be a bit smarter here and only do it per material. */
bool cd_overlap = mesh_cd_layers_type_overlap(cache->cd_used, cache->cd_needed);
@@ -4754,6 +4896,7 @@ void DRW_mesh_batch_cache_create_requested(
mesh_cd_layers_type_merge(&cache->cd_used, cache->cd_needed);
}
+ mesh_cd_layers_type_merge(&cache->cd_used_over_time, cache->cd_needed);
mesh_cd_layers_type_clear(&cache->cd_needed);
/* Discard UV batches if sync_selection changes */
@@ -4779,8 +4922,10 @@ void DRW_mesh_batch_cache_create_requested(
}
}
+ bool has_request = false;
/* Init batches and request VBOs & IBOs */
if (DRW_batch_requested(cache->batch.surface, GPU_PRIM_TRIS)) {
+ has_request = true;
DRW_ibo_request(cache->batch.surface, &cache->ibo.loops_tris);
DRW_vbo_request(cache->batch.surface, &cache->ordered.loop_pos_nor);
/* For paint overlay. Active layer should have been queried. */
@@ -4792,35 +4937,43 @@ void DRW_mesh_batch_cache_create_requested(
}
}
if (DRW_batch_requested(cache->batch.all_verts, GPU_PRIM_POINTS)) {
+ has_request = true;
DRW_vbo_request(cache->batch.all_verts, &cache->ordered.pos_nor);
}
if (DRW_batch_requested(cache->batch.all_edges, GPU_PRIM_LINES)) {
+ has_request = true;
DRW_ibo_request(cache->batch.all_edges, &cache->ibo.edges_lines);
DRW_vbo_request(cache->batch.all_edges, &cache->ordered.pos_nor);
}
if (DRW_batch_requested(cache->batch.loose_edges, GPU_PRIM_LINES)) {
+ has_request = true;
DRW_ibo_request(cache->batch.loose_edges, &cache->ibo.loose_edges_lines);
DRW_vbo_request(cache->batch.loose_edges, &cache->ordered.pos_nor);
}
if (DRW_batch_requested(cache->batch.edge_detection, GPU_PRIM_LINES_ADJ)) {
+ has_request = true;
DRW_ibo_request(cache->batch.edge_detection, &cache->ibo.edges_adj_lines);
DRW_vbo_request(cache->batch.edge_detection, &cache->ordered.pos_nor);
}
if (DRW_batch_requested(cache->batch.surface_weights, GPU_PRIM_TRIS)) {
+ has_request = true;
DRW_ibo_request(cache->batch.surface_weights, &cache->ibo.surf_tris);
DRW_vbo_request(cache->batch.surface_weights, &cache->ordered.pos_nor);
DRW_vbo_request(cache->batch.surface_weights, &cache->ordered.weights);
}
if (DRW_batch_requested(cache->batch.wire_loops, GPU_PRIM_LINE_STRIP)) {
+ has_request = true;
DRW_ibo_request(cache->batch.wire_loops, &cache->ibo.loops_line_strips);
DRW_vbo_request(cache->batch.wire_loops, &cache->ordered.loop_pos_nor);
}
if (DRW_batch_requested(cache->batch.wire_edges, GPU_PRIM_LINES)) {
+ has_request = true;
DRW_ibo_request(cache->batch.wire_edges, &cache->ibo.loops_lines);
DRW_vbo_request(cache->batch.wire_edges, &cache->ordered.loop_pos_nor);
DRW_vbo_request(cache->batch.wire_edges, &cache->ordered.loop_edge_fac);
}
if (DRW_batch_requested(cache->batch.wire_loops_uvs, GPU_PRIM_LINE_STRIP)) {
+ has_request = true;
DRW_ibo_request(cache->batch.wire_loops_uvs, &cache->ibo.loops_line_strips);
/* For paint overlay. Active layer should have been queried. */
if (cache->cd_used.uv != 0) {
@@ -4830,58 +4983,77 @@ void DRW_mesh_batch_cache_create_requested(
/* Edit Mesh */
if (DRW_batch_requested(cache->batch.edit_triangles, GPU_PRIM_TRIS)) {
+ has_request = true;
DRW_ibo_request(cache->batch.edit_triangles, &cache->ibo.edit_loops_tris);
DRW_vbo_request(cache->batch.edit_triangles, &cache->edit.loop_pos_nor);
DRW_vbo_request(cache->batch.edit_triangles, &cache->edit.loop_data);
}
if (DRW_batch_requested(cache->batch.edit_vertices, GPU_PRIM_POINTS)) {
+ has_request = true;
DRW_ibo_request(cache->batch.edit_vertices, &cache->ibo.edit_loops_points);
DRW_vbo_request(cache->batch.edit_vertices, &cache->edit.loop_pos_nor);
DRW_vbo_request(cache->batch.edit_vertices, &cache->edit.loop_data);
}
if (DRW_batch_requested(cache->batch.edit_edges, GPU_PRIM_LINES)) {
+ has_request = true;
DRW_ibo_request(cache->batch.edit_edges, &cache->ibo.edit_loops_lines);
DRW_vbo_request(cache->batch.edit_edges, &cache->edit.loop_pos_nor);
DRW_vbo_request(cache->batch.edit_edges, &cache->edit.loop_data);
}
if (DRW_batch_requested(cache->batch.edit_lnor, GPU_PRIM_POINTS)) {
+ has_request = true;
DRW_ibo_request(cache->batch.edit_lnor, &cache->ibo.edit_loops_tris);
DRW_vbo_request(cache->batch.edit_lnor, &cache->edit.loop_pos_nor);
DRW_vbo_request(cache->batch.edit_lnor, &cache->edit.loop_lnor);
}
if (DRW_batch_requested(cache->batch.edit_facedots, GPU_PRIM_POINTS)) {
+ has_request = true;
DRW_vbo_request(cache->batch.edit_facedots, &cache->edit.facedots_pos_nor_data);
}
+ /* Mesh Analysis */
+ if (DRW_batch_requested(cache->batch.edit_mesh_analysis, GPU_PRIM_TRIS)) {
+ has_request = true;
+ DRW_ibo_request(cache->batch.edit_mesh_analysis, &cache->ibo.edit_loops_tris);
+ DRW_vbo_request(cache->batch.edit_mesh_analysis, &cache->edit.loop_pos_nor);
+ DRW_vbo_request(cache->batch.edit_mesh_analysis, &cache->edit.loop_mesh_analysis);
+ }
+
/* Edit UV */
if (DRW_batch_requested(cache->batch.edituv_faces, GPU_PRIM_TRI_FAN)) {
+ has_request = true;
DRW_ibo_request(cache->batch.edituv_faces, &cache->ibo.edituv_loops_tri_fans);
DRW_vbo_request(cache->batch.edituv_faces, &cache->edit.loop_uv);
DRW_vbo_request(cache->batch.edituv_faces, &cache->edit.loop_uv_data);
}
if (DRW_batch_requested(cache->batch.edituv_faces_strech_area, GPU_PRIM_TRI_FAN)) {
+ has_request = true;
DRW_ibo_request(cache->batch.edituv_faces_strech_area, &cache->ibo.edituv_loops_tri_fans);
DRW_vbo_request(cache->batch.edituv_faces_strech_area, &cache->edit.loop_uv);
DRW_vbo_request(cache->batch.edituv_faces_strech_area, &cache->edit.loop_uv_data);
DRW_vbo_request(cache->batch.edituv_faces_strech_area, &cache->edit.loop_stretch_area);
}
if (DRW_batch_requested(cache->batch.edituv_faces_strech_angle, GPU_PRIM_TRI_FAN)) {
+ has_request = true;
DRW_ibo_request(cache->batch.edituv_faces_strech_angle, &cache->ibo.edituv_loops_tri_fans);
DRW_vbo_request(cache->batch.edituv_faces_strech_angle, &cache->edit.loop_uv);
DRW_vbo_request(cache->batch.edituv_faces_strech_angle, &cache->edit.loop_uv_data);
DRW_vbo_request(cache->batch.edituv_faces_strech_angle, &cache->edit.loop_stretch_angle);
}
if (DRW_batch_requested(cache->batch.edituv_edges, GPU_PRIM_LINES)) {
+ has_request = true;
DRW_ibo_request(cache->batch.edituv_edges, &cache->ibo.edituv_loops_line_strips);
DRW_vbo_request(cache->batch.edituv_edges, &cache->edit.loop_uv);
DRW_vbo_request(cache->batch.edituv_edges, &cache->edit.loop_uv_data);
}
if (DRW_batch_requested(cache->batch.edituv_verts, GPU_PRIM_POINTS)) {
+ has_request = true;
DRW_ibo_request(cache->batch.edituv_verts, &cache->ibo.edituv_loops_points);
DRW_vbo_request(cache->batch.edituv_verts, &cache->edit.loop_uv);
DRW_vbo_request(cache->batch.edituv_verts, &cache->edit.loop_uv_data);
}
if (DRW_batch_requested(cache->batch.edituv_facedots, GPU_PRIM_POINTS)) {
+ has_request = true;
DRW_vbo_request(cache->batch.edituv_facedots, &cache->edit.facedots_uv);
DRW_vbo_request(cache->batch.edituv_facedots, &cache->edit.facedots_uv_data);
}
@@ -4889,21 +5061,25 @@ void DRW_mesh_batch_cache_create_requested(
/* Selection */
/* TODO reuse ordered.loop_pos_nor if possible. */
if (DRW_batch_requested(cache->batch.edit_selection_verts, GPU_PRIM_POINTS)) {
+ has_request = true;
DRW_ibo_request(cache->batch.edit_selection_verts, &cache->ibo.edit_loops_points);
DRW_vbo_request(cache->batch.edit_selection_verts, &cache->edit.loop_pos_nor);
DRW_vbo_request(cache->batch.edit_selection_verts, &cache->edit.loop_vert_idx);
}
if (DRW_batch_requested(cache->batch.edit_selection_edges, GPU_PRIM_LINES)) {
+ has_request = true;
DRW_ibo_request(cache->batch.edit_selection_edges, &cache->ibo.edit_loops_lines);
DRW_vbo_request(cache->batch.edit_selection_edges, &cache->edit.loop_pos_nor);
DRW_vbo_request(cache->batch.edit_selection_edges, &cache->edit.loop_edge_idx);
}
if (DRW_batch_requested(cache->batch.edit_selection_faces, GPU_PRIM_TRIS)) {
+ has_request = true;
DRW_ibo_request(cache->batch.edit_selection_faces, &cache->ibo.edit_loops_tris);
DRW_vbo_request(cache->batch.edit_selection_faces, &cache->edit.loop_pos_nor);
DRW_vbo_request(cache->batch.edit_selection_faces, &cache->edit.loop_face_idx);
}
if (DRW_batch_requested(cache->batch.edit_selection_facedots, GPU_PRIM_POINTS)) {
+ has_request = true;
DRW_vbo_request(cache->batch.edit_selection_facedots, &cache->edit.facedots_pos_nor_data);
DRW_vbo_request(cache->batch.edit_selection_facedots, &cache->edit.facedots_idx);
}
@@ -4911,6 +5087,7 @@ void DRW_mesh_batch_cache_create_requested(
/* Per Material */
for (int i = 0; i < cache->mat_len; ++i) {
if (DRW_batch_requested(cache->surf_per_mat[i], GPU_PRIM_TRIS)) {
+ has_request = true;
if (cache->mat_len > 1) {
DRW_ibo_request(cache->surf_per_mat[i], &cache->surf_per_mat_tris[i]);
}
@@ -4926,47 +5103,39 @@ void DRW_mesh_batch_cache_create_requested(
DRW_vbo_request(cache->surf_per_mat[i], &cache->ordered.loop_vcol);
}
if (cache->cd_used.orco != 0) {
- /* OPTI : Only do that if there is modifiers that modify orcos. */
- CustomData *cd_vdata = (me->edit_mesh) ? &me->edit_mesh->bm->vdata : &me->vdata;
- if (CustomData_get_layer(cd_vdata, CD_ORCO) != NULL && ob->modifiers.first != NULL) {
- DRW_vbo_request(cache->surf_per_mat[i], &cache->ordered.loop_orco);
- }
- else if (cache->cd_used.tan_orco == 0) {
- /* Skip orco calculation if not needed by tangent generation. */
- cache->cd_used.orco = 0;
- }
+ DRW_vbo_request(cache->surf_per_mat[i], &cache->ordered.loop_orco);
}
}
}
+ /* Early out if no request. */
+ if (!has_request) {
+ return;
+ }
+
+#ifdef DRW_DEBUG_MESH_CACHE_REQUEST
+ printf("-- %s %s --\n", __func__, ob->id.name + 2);
+#endif
+
/* Generate MeshRenderData flags */
- int mr_flag = 0, mr_edit_flag = 0;
- DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag, cache->ordered.pos_nor, MR_DATATYPE_VERT);
+ eMRDataType mr_flag = 0, mr_edit_flag = 0;
+ DRW_ADD_FLAG_FROM_VBO_REQUEST(
+ mr_flag, cache->ordered.pos_nor, MR_DATATYPE_VERT /* A comment to wrap the line ;) */);
DRW_ADD_FLAG_FROM_VBO_REQUEST(
mr_flag, cache->ordered.weights, MR_DATATYPE_VERT | MR_DATATYPE_DVERT);
- DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag,
- cache->ordered.loop_pos_nor,
- MR_DATATYPE_VERT | MR_DATATYPE_POLY | MR_DATATYPE_LOOP);
- DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag,
- cache->ordered.loop_uv_tan,
- MR_DATATYPE_VERT | MR_DATATYPE_POLY | MR_DATATYPE_LOOP |
- MR_DATATYPE_SHADING | MR_DATATYPE_LOOPTRI);
- DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag,
- cache->ordered.loop_orco,
- MR_DATATYPE_VERT | MR_DATATYPE_POLY | MR_DATATYPE_LOOP |
- MR_DATATYPE_SHADING);
- DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag,
- cache->ordered.loop_vcol,
- MR_DATATYPE_VERT | MR_DATATYPE_POLY | MR_DATATYPE_LOOP |
- MR_DATATYPE_SHADING);
- DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag,
- cache->ordered.loop_edge_fac,
- MR_DATATYPE_VERT | MR_DATATYPE_POLY | MR_DATATYPE_EDGE |
- MR_DATATYPE_LOOP);
- DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_flag,
- cache->ibo.surf_tris,
- MR_DATATYPE_VERT | MR_DATATYPE_LOOP | MR_DATATYPE_POLY |
- MR_DATATYPE_LOOPTRI);
+ DRW_ADD_FLAG_FROM_VBO_REQUEST(
+ mr_flag, cache->ordered.loop_pos_nor, MR_DATATYPE_VERT_LOOP_POLY | MR_DATATYPE_LOOP_NORMALS);
+ DRW_ADD_FLAG_FROM_VBO_REQUEST(
+ mr_flag, cache->ordered.loop_uv_tan, MR_DATATYPE_VERT_LOOP_TRI_POLY | MR_DATATYPE_SHADING);
+ DRW_ADD_FLAG_FROM_VBO_REQUEST(
+ mr_flag, cache->ordered.loop_orco, MR_DATATYPE_VERT_LOOP_POLY | MR_DATATYPE_SHADING);
+ DRW_ADD_FLAG_FROM_VBO_REQUEST(
+ mr_flag, cache->ordered.loop_vcol, MR_DATATYPE_VERT_LOOP_POLY | MR_DATATYPE_SHADING);
+ DRW_ADD_FLAG_FROM_VBO_REQUEST(
+ mr_flag, cache->ordered.loop_edge_fac, MR_DATATYPE_VERT_LOOP_POLY | MR_DATATYPE_EDGE);
+
+ DRW_ADD_FLAG_FROM_IBO_REQUEST(
+ mr_flag, cache->ibo.surf_tris, MR_DATATYPE_VERT_LOOP_POLY | MR_DATATYPE_LOOPTRI);
DRW_ADD_FLAG_FROM_IBO_REQUEST(
mr_flag, cache->ibo.loops_tris, MR_DATATYPE_LOOP | MR_DATATYPE_POLY | MR_DATATYPE_LOOPTRI);
DRW_ADD_FLAG_FROM_IBO_REQUEST(
@@ -4975,74 +5144,69 @@ void DRW_mesh_batch_cache_create_requested(
mr_flag, cache->ibo.loops_line_strips, MR_DATATYPE_LOOP | MR_DATATYPE_POLY);
DRW_ADD_FLAG_FROM_IBO_REQUEST(
mr_flag, cache->ibo.edges_lines, MR_DATATYPE_VERT | MR_DATATYPE_EDGE);
- DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_flag,
- cache->ibo.edges_adj_lines,
- MR_DATATYPE_VERT | MR_DATATYPE_LOOP | MR_DATATYPE_POLY |
- MR_DATATYPE_LOOPTRI);
+ DRW_ADD_FLAG_FROM_IBO_REQUEST(
+ mr_flag, cache->ibo.edges_adj_lines, MR_DATATYPE_VERT_LOOP_POLY | MR_DATATYPE_LOOPTRI);
DRW_ADD_FLAG_FROM_IBO_REQUEST(
mr_flag, cache->ibo.loose_edges_lines, MR_DATATYPE_VERT | MR_DATATYPE_EDGE);
for (int i = 0; i < cache->mat_len; ++i) {
- DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_flag,
- cache->surf_per_mat_tris[i],
- MR_DATATYPE_LOOP | MR_DATATYPE_POLY | MR_DATATYPE_LOOPTRI);
- }
-
- int combined_edit_flag = MR_DATATYPE_VERT | MR_DATATYPE_EDGE | MR_DATATYPE_LOOP |
- MR_DATATYPE_POLY | MR_DATATYPE_LOOSE_VERT | MR_DATATYPE_LOOSE_EDGE |
- MR_DATATYPE_OVERLAY;
- DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_edit_flag, cache->edit.loop_pos_nor, combined_edit_flag);
- DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_edit_flag, cache->edit.loop_lnor, combined_edit_flag);
- DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_edit_flag, cache->edit.loop_data, combined_edit_flag);
- DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_edit_flag, cache->edit.loop_uv_data, combined_edit_flag);
+ int combined_flag = MR_DATATYPE_LOOP | MR_DATATYPE_POLY | MR_DATATYPE_LOOPTRI;
+ DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_flag, cache->surf_per_mat_tris[i], combined_flag);
+ }
+
+ int combined_edit_flag = MR_DATATYPE_VERT_LOOP_POLY | MR_DATATYPE_EDGE |
+ MR_DATATYPE_LOOSE_VERT_EGDE;
+ int combined_edit_with_lnor_flag = combined_edit_flag | MR_DATATYPE_LOOP_NORMALS;
+ int combined_edituv_flag = combined_edit_flag | MR_DATATYPE_LOOPUV;
+ DRW_ADD_FLAG_FROM_VBO_REQUEST(
+ mr_edit_flag, cache->edit.loop_pos_nor, combined_edit_flag | MR_DATATYPE_OVERLAY);
+ DRW_ADD_FLAG_FROM_VBO_REQUEST(
+ mr_edit_flag, cache->edit.loop_lnor, combined_edit_with_lnor_flag | MR_DATATYPE_OVERLAY);
+ DRW_ADD_FLAG_FROM_VBO_REQUEST(
+ mr_edit_flag, cache->edit.loop_data, combined_edit_flag | MR_DATATYPE_OVERLAY);
DRW_ADD_FLAG_FROM_VBO_REQUEST(
- mr_edit_flag, cache->edit.loop_uv, combined_edit_flag | MR_DATATYPE_LOOPUV);
- DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_edit_flag,
- cache->edit.loop_vert_idx,
- MR_DATATYPE_VERT | MR_DATATYPE_EDGE | MR_DATATYPE_LOOSE_VERT |
- MR_DATATYPE_LOOSE_EDGE | MR_DATATYPE_POLY | MR_DATATYPE_LOOP);
- DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_edit_flag,
- cache->edit.loop_edge_idx,
- MR_DATATYPE_VERT | MR_DATATYPE_EDGE | MR_DATATYPE_LOOSE_VERT |
- MR_DATATYPE_LOOSE_EDGE | MR_DATATYPE_POLY | MR_DATATYPE_LOOP);
- DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_edit_flag,
- cache->edit.loop_face_idx,
- MR_DATATYPE_VERT | MR_DATATYPE_EDGE | MR_DATATYPE_LOOSE_VERT |
- MR_DATATYPE_LOOSE_EDGE | MR_DATATYPE_POLY | MR_DATATYPE_LOOP);
+ mr_edit_flag, cache->edit.loop_uv_data, combined_edit_flag | MR_DATATYPE_OVERLAY);
+ DRW_ADD_FLAG_FROM_VBO_REQUEST(
+ mr_edit_flag, cache->edit.loop_uv, combined_edituv_flag | MR_DATATYPE_OVERLAY);
+ DRW_ADD_FLAG_FROM_VBO_REQUEST(
+ mr_edit_flag, cache->edit.loop_stretch_angle, combined_edit_flag | MR_DATATYPE_OVERLAY);
+ DRW_ADD_FLAG_FROM_VBO_REQUEST(
+ mr_edit_flag, cache->edit.loop_stretch_area, combined_edit_flag | MR_DATATYPE_OVERLAY);
+ DRW_ADD_FLAG_FROM_VBO_REQUEST(
+ mr_edit_flag, cache->edit.loop_mesh_analysis, MR_DATATYPE_VERT_LOOP_POLY);
+
+ DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_edit_flag, cache->edit.loop_vert_idx, combined_edit_flag);
+ DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_edit_flag, cache->edit.loop_edge_idx, combined_edit_flag);
+ DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_edit_flag, cache->edit.loop_face_idx, combined_edit_flag);
DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_edit_flag, cache->edit.facedots_idx, MR_DATATYPE_POLY);
- DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_edit_flag,
- cache->edit.facedots_pos_nor_data,
- MR_DATATYPE_VERT | MR_DATATYPE_LOOP | MR_DATATYPE_POLY |
- MR_DATATYPE_OVERLAY);
- DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_edit_flag, cache->edit.loop_stretch_angle, combined_edit_flag);
- DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_edit_flag, cache->edit.loop_stretch_area, combined_edit_flag);
+
+ DRW_ADD_FLAG_FROM_VBO_REQUEST(
+ mr_edit_flag, cache->edit.facedots_pos_nor_data, MR_DATATYPE_POLY | MR_DATATYPE_OVERLAY);
DRW_ADD_FLAG_FROM_VBO_REQUEST(
- mr_edit_flag, cache->edit.facedots_uv, combined_edit_flag | MR_DATATYPE_LOOPUV);
- DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_edit_flag, cache->edit.facedots_uv_data, combined_edit_flag);
- DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_edit_flag, cache->ibo.edituv_loops_points, combined_edit_flag);
+ mr_edit_flag, cache->edit.facedots_uv, combined_edituv_flag | MR_DATATYPE_OVERLAY);
+ DRW_ADD_FLAG_FROM_VBO_REQUEST(
+ mr_edit_flag, cache->edit.facedots_uv_data, combined_edit_flag | MR_DATATYPE_OVERLAY);
+
DRW_ADD_FLAG_FROM_IBO_REQUEST(
- mr_edit_flag, cache->ibo.edituv_loops_line_strips, combined_edit_flag);
+ mr_edit_flag, cache->ibo.edituv_loops_points, combined_edit_flag | MR_DATATYPE_OVERLAY);
DRW_ADD_FLAG_FROM_IBO_REQUEST(
- mr_edit_flag, cache->ibo.edituv_loops_tri_fans, combined_edit_flag);
- /* TODO: Some of the flags here may not be needed. */
- DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_edit_flag,
- cache->ibo.edit_loops_points,
- MR_DATATYPE_VERT | MR_DATATYPE_EDGE | MR_DATATYPE_LOOSE_VERT |
- MR_DATATYPE_LOOSE_EDGE | MR_DATATYPE_POLY | MR_DATATYPE_LOOP |
- MR_DATATYPE_LOOPTRI);
- DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_edit_flag,
- cache->ibo.edit_loops_lines,
- MR_DATATYPE_VERT | MR_DATATYPE_EDGE | MR_DATATYPE_LOOSE_VERT |
- MR_DATATYPE_LOOSE_EDGE | MR_DATATYPE_POLY | MR_DATATYPE_LOOP |
- MR_DATATYPE_LOOPTRI);
- DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_edit_flag,
- cache->ibo.edit_loops_tris,
- MR_DATATYPE_VERT | MR_DATATYPE_EDGE | MR_DATATYPE_LOOSE_VERT |
- MR_DATATYPE_LOOSE_EDGE | MR_DATATYPE_POLY | MR_DATATYPE_LOOP |
- MR_DATATYPE_LOOPTRI);
+ mr_edit_flag, cache->ibo.edituv_loops_line_strips, combined_edit_flag | MR_DATATYPE_OVERLAY);
+ DRW_ADD_FLAG_FROM_IBO_REQUEST(
+ mr_edit_flag, cache->ibo.edituv_loops_tri_fans, combined_edit_flag | MR_DATATYPE_OVERLAY);
+
+ DRW_ADD_FLAG_FROM_IBO_REQUEST(
+ mr_edit_flag, cache->ibo.edit_loops_points, combined_edit_flag | MR_DATATYPE_LOOPTRI);
+ DRW_ADD_FLAG_FROM_IBO_REQUEST(
+ mr_edit_flag, cache->ibo.edit_loops_lines, combined_edit_flag | MR_DATATYPE_LOOPTRI);
+ DRW_ADD_FLAG_FROM_IBO_REQUEST(
+ mr_edit_flag, cache->ibo.edit_loops_tris, combined_edit_flag | MR_DATATYPE_LOOPTRI);
Mesh *me_original = me;
MBC_GET_FINAL_MESH(me);
+#ifdef DRW_DEBUG_MESH_CACHE_REQUEST
+ printf(" mr_flag %u, mr_edit_flag %u\n\n", mr_flag, mr_edit_flag);
+#endif
+
if (me_original == me) {
mr_flag |= mr_edit_flag;
}
@@ -5140,6 +5304,9 @@ void DRW_mesh_batch_cache_create_requested(
if (DRW_ibo_requested(cache->ibo.edit_loops_tris)) {
mesh_create_edit_loops_tris(rdata, cache->ibo.edit_loops_tris);
}
+ if (DRW_vbo_requested(cache->edit.loop_mesh_analysis)) {
+ mesh_create_edit_mesh_analysis(rdata, cache->edit.loop_mesh_analysis);
+ }
/* UV editor */
/**
diff --git a/source/blender/draw/intern/draw_cache_impl_metaball.c b/source/blender/draw/intern/draw_cache_impl_metaball.c
index 2c06d536f3d..432c5092274 100644
--- a/source/blender/draw/intern/draw_cache_impl_metaball.c
+++ b/source/blender/draw/intern/draw_cache_impl_metaball.c
@@ -265,4 +265,4 @@ struct GPUBatch *DRW_metaball_batch_cache_get_edge_detection(struct Object *ob,
}
return cache->edge_detection;
-} \ No newline at end of file
+}
diff --git a/source/blender/draw/intern/draw_cache_impl_particles.c b/source/blender/draw/intern/draw_cache_impl_particles.c
index e998b17a44f..9a15c51598f 100644
--- a/source/blender/draw/intern/draw_cache_impl_particles.c
+++ b/source/blender/draw/intern/draw_cache_impl_particles.c
@@ -99,7 +99,7 @@ typedef struct HairAttributeID {
typedef struct EditStrandData {
float pos[3];
- uchar color;
+ float color;
} EditStrandData;
static GPUVertFormat *edit_points_vert_format_get(uint *r_pos_id, uint *r_color_id)
@@ -110,7 +110,7 @@ static GPUVertFormat *edit_points_vert_format_get(uint *r_pos_id, uint *r_color_
/* Keep in sync with EditStrandData */
pos_id = GPU_vertformat_attr_add(&edit_point_format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
color_id = GPU_vertformat_attr_add(
- &edit_point_format, "color", GPU_COMP_U8, 1, GPU_FETCH_INT_TO_FLOAT_UNIT);
+ &edit_point_format, "color", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
}
*r_pos_id = pos_id;
*r_color_id = color_id;
@@ -693,12 +693,12 @@ static int particle_batch_cache_fill_segments_edit(
float strand_t = (float)(j) / path->segments;
if (particle) {
float weight = particle_key_weight(particle, i, strand_t);
- /* NaN or unclamped become 0xFF */
- seg_data->color = (uchar)((weight <= 1.0f) ? 0xFE * weight : 0xFF);
+ /* NaN or unclamped become 1.0f */
+ seg_data->color = (weight < 1.0f) ? weight : 1.0f;
}
else {
float selected = particle_key_select_ratio(edit, i, strand_t);
- seg_data->color = (uchar)(0xFF * selected);
+ seg_data->color = selected;
}
GPU_indexbuf_add_generic_vert(elb, curr_point);
curr_point++;
@@ -1565,7 +1565,7 @@ static void particle_batch_cache_ensure_edit_inner_pos(PTCacheEdit *edit,
const PTCacheEditPoint *point = &edit->points[point_index];
for (int key_index = 0; key_index < point->totkey - 1; key_index++) {
PTCacheEditKey *key = &point->keys[key_index];
- uchar color = (key->flag & PEK_SELECT) ? 0xFF : 0x00;
+ float color = (key->flag & PEK_SELECT) ? 1.0f : 0.0f;
GPU_vertbuf_attr_set(cache->edit_inner_pos, pos_id, global_key_index, key->world_co);
GPU_vertbuf_attr_set(cache->edit_inner_pos, color_id, global_key_index, &color);
global_key_index++;
@@ -1611,7 +1611,8 @@ static void particle_batch_cache_ensure_edit_tip_pos(PTCacheEdit *edit, Particle
for (int point_index = 0; point_index < edit->totpoint; point_index++) {
const PTCacheEditPoint *point = &edit->points[point_index];
PTCacheEditKey *key = &point->keys[point->totkey - 1];
- uchar color = (key->flag & PEK_SELECT) ? 0xFF : 0x00;
+ float color = (key->flag & PEK_SELECT) ? 1.0f : 0.0f;
+
GPU_vertbuf_attr_set(cache->edit_tip_pos, pos_id, point_index, key->world_co);
GPU_vertbuf_attr_set(cache->edit_tip_pos, color_id, point_index, &color);
}
diff --git a/source/blender/draw/intern/draw_common.c b/source/blender/draw/intern/draw_common.c
index 465a4f7a897..b4eb354ec59 100644
--- a/source/blender/draw/intern/draw_common.c
+++ b/source/blender/draw/intern/draw_common.c
@@ -90,8 +90,8 @@ void DRW_globals_update(void)
dot_v3v3(gb->colorEditMeshMiddle, (float[3]){0.3333f, 0.3333f, 0.3333f})); /* Desaturate */
interp_v4_v4v4(gb->colorDupliSelect, gb->colorBackground, gb->colorSelect, 0.5f);
- /* Was 50% in 2.7x since the background was lighter making it easier to tell the color from black,
- * with a darker background we need a more faded color. */
+ /* Was 50% in 2.7x since the background was lighter making it easier to tell the color from
+ * black, with a darker background we need a more faded color. */
interp_v4_v4v4(gb->colorDupli, gb->colorBackground, gb->colorWire, 0.3f);
#ifdef WITH_FREESTYLE
@@ -142,7 +142,7 @@ void DRW_globals_update(void)
UI_GetThemeColorShadeAlpha4fv(TH_WIRE, 0, -30, gb->colorOutline);
UI_GetThemeColorShadeAlpha4fv(TH_LIGHT, 0, 255, gb->colorLightNoAlpha);
- gb->sizeLightCenter = (U.obcenter_dia + 1.5f) * U.pixelsize;
+ gb->sizeLightCenter = (UI_GetThemeValuef(TH_OBCENTER_DIA) + 1.5f) * U.pixelsize;
gb->sizeLightCircle = U.pixelsize * 9.0f;
gb->sizeLightCircleShadow = gb->sizeLightCircle + U.pixelsize * 3.0f;
@@ -1045,7 +1045,7 @@ struct GPUShader *volume_velocity_shader_get(bool use_needle)
}
}
-/* ******************************************** COLOR UTILS *********************************************** */
+/* ******************************************** COLOR UTILS ************************************ */
/* TODO FINISH */
/**
diff --git a/source/blender/draw/intern/draw_common.h b/source/blender/draw/intern/draw_common.h
index db8f8d46e85..489bc7459df 100644
--- a/source/blender/draw/intern/draw_common.h
+++ b/source/blender/draw/intern/draw_common.h
@@ -216,6 +216,7 @@ typedef struct DRWArmaturePasses {
struct DRWPass *bone_envelope;
struct DRWPass *bone_axes;
struct DRWPass *relationship_lines;
+ struct GHash *custom_shapes;
} DRWArmaturePasses;
void DRW_shgroup_armature_object(struct Object *ob,
diff --git a/source/blender/draw/intern/draw_hair.c b/source/blender/draw/intern/draw_hair.c
index b3081a44dfb..cb83265195a 100644
--- a/source/blender/draw/intern/draw_hair.c
+++ b/source/blender/draw/intern/draw_hair.c
@@ -193,7 +193,8 @@ static DRWShadingGroup *drw_shgroup_create_hair_procedural_ex(Object *object,
DRW_shgroup_uniform_float_copy(shgrp, "hairRadTip", part->rad_tip * part->rad_scale * 0.5f);
DRW_shgroup_uniform_bool_copy(
shgrp, "hairCloseTip", (part->shape_flag & PART_SHAPE_CLOSE_TIP) != 0);
- /* TODO(fclem): Until we have a better way to cull the hair and render with orco, bypass culling test. */
+ /* TODO(fclem): Until we have a better way to cull the hair and render with orco, bypass culling
+ * test. */
DRW_shgroup_call_object_add_no_cull(
shgrp, hair_cache->final[subdiv].proc_hairs[thickness_res - 1], object);
diff --git a/source/blender/draw/intern/draw_instance_data.c b/source/blender/draw/intern/draw_instance_data.c
index 27e03a3495a..e8d91309e06 100644
--- a/source/blender/draw/intern/draw_instance_data.c
+++ b/source/blender/draw/intern/draw_instance_data.c
@@ -22,11 +22,11 @@
/**
* DRW Instance Data Manager
- * This is a special memory manager that keeps memory blocks ready to send as vbo data in one continuous allocation.
- * This way we avoid feeding gawain each instance data one by one and unnecessary memcpy.
- * Since we loose which memory block was used each #DRWShadingGroup we need to redistribute them in the same order/size
- * to avoid to realloc each frame.
- * This is why #DRWInstanceDatas are sorted in a list for each different data size.
+ * This is a special memory manager that keeps memory blocks ready to send as vbo data in one
+ * continuous allocation. This way we avoid feeding gawain each instance data one by one and
+ * unnecessary memcpy. Since we loose which memory block was used each #DRWShadingGroup we need to
+ * redistribute them in the same order/size to avoid to realloc each frame. This is why
+ * #DRWInstanceDatas are sorted in a list for each different data size.
*/
#include "draw_instance_data.h"
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index 9e078fd2774..5c88c1f93db 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -35,6 +35,7 @@
#include "BKE_global.h"
#include "BKE_gpencil.h"
#include "BKE_lattice.h"
+#include "BKE_main.h"
#include "BKE_mball.h"
#include "BKE_mesh.h"
#include "BKE_object.h"
@@ -404,7 +405,7 @@ void DRW_multisamples_resolve(GPUTexture *src_depth, GPUTexture *src_color, bool
builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_16_DEPTH_TEST;
break;
default:
- BLI_assert("Mulisample count unsupported by blit shader.");
+ BLI_assert(!"Mulisample count unsupported by blit shader.");
builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_2_DEPTH_TEST;
break;
}
@@ -424,7 +425,7 @@ void DRW_multisamples_resolve(GPUTexture *src_depth, GPUTexture *src_color, bool
builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_16;
break;
default:
- BLI_assert("Mulisample count unsupported by blit shader.");
+ BLI_assert(!"Mulisample count unsupported by blit shader.");
builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_2;
break;
}
@@ -518,11 +519,20 @@ static void drw_viewport_cache_resize(void)
GPU_viewport_cache_release(DST.viewport);
if (DST.vmempool != NULL) {
+ /* Release Image textures. */
+ BLI_mempool_iter iter;
+ GPUTexture **tex;
+ BLI_mempool_iternew(DST.vmempool->images, &iter);
+ while ((tex = BLI_mempool_iterstep(&iter))) {
+ GPU_texture_free(*tex);
+ }
+
BLI_mempool_clear_ex(DST.vmempool->calls, BLI_mempool_len(DST.vmempool->calls));
BLI_mempool_clear_ex(DST.vmempool->states, BLI_mempool_len(DST.vmempool->states));
BLI_mempool_clear_ex(DST.vmempool->shgroups, BLI_mempool_len(DST.vmempool->shgroups));
BLI_mempool_clear_ex(DST.vmempool->uniforms, BLI_mempool_len(DST.vmempool->uniforms));
BLI_mempool_clear_ex(DST.vmempool->passes, BLI_mempool_len(DST.vmempool->passes));
+ BLI_mempool_clear_ex(DST.vmempool->images, BLI_mempool_len(DST.vmempool->images));
}
DRW_instance_data_list_free_unused(DST.idatalist);
@@ -602,6 +612,10 @@ static void drw_viewport_var_init(void)
if (DST.vmempool->passes == NULL) {
DST.vmempool->passes = BLI_mempool_create(sizeof(DRWPass), 0, 64, 0);
}
+ if (DST.vmempool->images == NULL) {
+ DST.vmempool->images = BLI_mempool_create(
+ sizeof(GPUTexture *), 0, 512, BLI_MEMPOOL_ALLOW_ITER);
+ }
DST.idatalist = GPU_viewport_instance_data_list_get(DST.viewport);
DRW_instance_data_list_reset(DST.idatalist);
@@ -966,6 +980,45 @@ static void drw_drawdata_unlink_dupli(ID *id)
/** \} */
/* -------------------------------------------------------------------- */
+/** \name Garbage Collection
+ * \{ */
+
+void DRW_cache_free_old_batches(Main *bmain)
+{
+ Scene *scene;
+ ViewLayer *view_layer;
+ static int lasttime = 0;
+ int ctime = (int)PIL_check_seconds_timer();
+
+ if (U.vbotimeout == 0 || (ctime - lasttime) < U.vbocollectrate || ctime == lasttime) {
+ return;
+ }
+
+ lasttime = ctime;
+
+ for (scene = bmain->scenes.first; scene; scene = scene->id.next) {
+ for (view_layer = scene->view_layers.first; view_layer; view_layer = view_layer->next) {
+ Depsgraph *depsgraph = BKE_scene_get_depsgraph(scene, view_layer, false);
+ if (depsgraph == NULL) {
+ continue;
+ }
+
+ /* TODO(fclem): This is not optimal since it iter over all dupli instances.
+ * In this case only the source object should be tagged. */
+ int iter_flags = DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY | DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET |
+ DEG_ITER_OBJECT_FLAG_VISIBLE | DEG_ITER_OBJECT_FLAG_DUPLI;
+
+ DEG_OBJECT_ITER_BEGIN (depsgraph, ob, iter_flags) {
+ DRW_batch_cache_free_old(ob, ctime);
+ }
+ DEG_OBJECT_ITER_END;
+ }
+ }
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name Rendering (DRW_engines)
* \{ */
@@ -1083,9 +1136,8 @@ static void drw_engines_draw_background(void)
}
/* No draw_background found, doing default background */
- if (DRW_state_draw_background()) {
- DRW_draw_background();
- }
+ const bool do_alpha_checker = !DRW_state_draw_background();
+ DRW_draw_background(do_alpha_checker);
}
static void drw_engines_draw_scene(void)
@@ -1434,6 +1486,7 @@ void DRW_draw_view(const bContext *C)
drw_state_prepare_clean_for_draw(&DST);
DST.options.draw_text = ((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0 &&
(v3d->overlay.flag & V3D_OVERLAY_HIDE_TEXT) != 0);
+ DST.options.draw_background = scene->r.alphamode == R_ADDSKY;
DRW_draw_render_loop_ex(depsgraph, engine_type, ar, v3d, viewport, C);
}
@@ -1500,11 +1553,10 @@ void DRW_draw_render_loop_ex(struct Depsgraph *depsgraph,
drw_engines_world_update(scene);
const int object_type_exclude_viewport = v3d->object_type_exclude_viewport;
- DEG_OBJECT_ITER_BEGIN (depsgraph,
- ob,
- DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY |
- DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET | DEG_ITER_OBJECT_FLAG_VISIBLE |
- DEG_ITER_OBJECT_FLAG_DUPLI) {
+ const int iter_flag = DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY |
+ DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET | DEG_ITER_OBJECT_FLAG_VISIBLE |
+ DEG_ITER_OBJECT_FLAG_DUPLI;
+ DEG_OBJECT_ITER_BEGIN (depsgraph, ob, iter_flag) {
if ((object_type_exclude_viewport & (1 << ob->type)) != 0) {
continue;
}
@@ -1951,11 +2003,10 @@ void DRW_render_object_iter(
const int object_type_exclude_viewport = draw_ctx->v3d ?
draw_ctx->v3d->object_type_exclude_viewport :
0;
- DEG_OBJECT_ITER_BEGIN (depsgraph,
- ob,
- DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY |
- DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET | DEG_ITER_OBJECT_FLAG_VISIBLE |
- DEG_ITER_OBJECT_FLAG_DUPLI) {
+ const int iter_flag = DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY |
+ DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET | DEG_ITER_OBJECT_FLAG_VISIBLE |
+ DEG_ITER_OBJECT_FLAG_DUPLI;
+ DEG_OBJECT_ITER_BEGIN (depsgraph, ob, iter_flag) {
if ((object_type_exclude_viewport & (1 << ob->type)) == 0) {
DST.dupli_parent = data_.dupli_parent;
DST.dupli_source = data_.dupli_object_current;
@@ -2205,14 +2256,13 @@ void DRW_draw_select_loop(struct Depsgraph *depsgraph,
# endif
}
else {
+ const int iter_flag = DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY |
+ DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET | DEG_ITER_OBJECT_FLAG_VISIBLE |
+ DEG_ITER_OBJECT_FLAG_DUPLI;
const int object_type_exclude_select = (v3d->object_type_exclude_viewport |
v3d->object_type_exclude_select);
bool filter_exclude = false;
- DEG_OBJECT_ITER_BEGIN (depsgraph,
- ob,
- DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY |
- DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET |
- DEG_ITER_OBJECT_FLAG_VISIBLE | DEG_ITER_OBJECT_FLAG_DUPLI) {
+ DEG_OBJECT_ITER_BEGIN (depsgraph, ob, iter_flag) {
if (v3d->localvd && ((v3d->local_view_uuid & ob->base_local_view_bits) == 0)) {
continue;
}
@@ -2294,42 +2344,6 @@ void DRW_draw_select_loop(struct Depsgraph *depsgraph,
#endif /* USE_GPU_SELECT */
}
-static void draw_depth_texture_to_screen(GPUTexture *texture)
-{
- const float w = (float)GPU_texture_width(texture);
- const float h = (float)GPU_texture_height(texture);
-
- GPUVertFormat *format = immVertexFormat();
- uint texcoord = GPU_vertformat_attr_add(format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
-
- immBindBuiltinProgram(GPU_SHADER_3D_IMAGE_DEPTH_COPY);
-
- GPU_texture_bind(texture, 0);
-
- immUniform1i("image", 0); /* default GL_TEXTURE0 unit */
-
- immBegin(GPU_PRIM_TRI_STRIP, 4);
-
- immAttr2f(texcoord, 0.0f, 0.0f);
- immVertex2f(pos, 0.0f, 0.0f);
-
- immAttr2f(texcoord, 1.0f, 0.0f);
- immVertex2f(pos, w, 0.0f);
-
- immAttr2f(texcoord, 0.0f, 1.0f);
- immVertex2f(pos, 0.0f, h);
-
- immAttr2f(texcoord, 1.0f, 1.0f);
- immVertex2f(pos, w, h);
-
- immEnd();
-
- GPU_texture_unbind(texture);
-
- immUnbindProgram();
-}
-
/**
* object mode select-loop, see: ED_view3d_draw_depth_loop (legacy drawing).
*/
@@ -2360,11 +2374,10 @@ static void drw_draw_depth_loop_imp(void)
View3D *v3d = DST.draw_ctx.v3d;
const int object_type_exclude_viewport = v3d->object_type_exclude_viewport;
- DEG_OBJECT_ITER_BEGIN (DST.draw_ctx.depsgraph,
- ob,
- DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY |
- DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET | DEG_ITER_OBJECT_FLAG_VISIBLE |
- DEG_ITER_OBJECT_FLAG_DUPLI) {
+ const int iter_flag = DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY |
+ DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET | DEG_ITER_OBJECT_FLAG_VISIBLE |
+ DEG_ITER_OBJECT_FLAG_DUPLI;
+ DEG_OBJECT_ITER_BEGIN (DST.draw_ctx.depsgraph, ob, iter_flag) {
if ((object_type_exclude_viewport & (1 << ob->type)) != 0) {
continue;
}
@@ -2446,21 +2459,6 @@ void DRW_draw_depth_loop(struct Depsgraph *depsgraph,
drw_engines_disable();
- /* XXX Drawing the resulting buffer to the BACK_BUFFER */
- GPU_matrix_push();
- GPU_matrix_push_projection();
- wmOrtho2_region_pixelspace(DST.draw_ctx.ar);
- GPU_matrix_identity_set();
-
- glEnable(GL_DEPTH_TEST); /* Cannot write to depth buffer without testing */
- glDepthFunc(GL_ALWAYS);
- DefaultTextureList *dtxl = (DefaultTextureList *)GPU_viewport_texture_list_get(DST.viewport);
- draw_depth_texture_to_screen(dtxl->depth);
- glDepthFunc(GL_LEQUAL);
-
- GPU_matrix_pop();
- GPU_matrix_pop_projection();
-
#ifdef DEBUG
/* Avoid accidental reuse. */
drw_state_ensure_not_reused(&DST);
@@ -2506,6 +2504,69 @@ void DRW_draw_depth_loop_gpencil(struct Depsgraph *depsgraph,
#endif
}
+/**
+ * Clears the Depth Buffer and draws only the specified object.
+ */
+void DRW_draw_depth_object(ARegion *ar, GPUViewport *viewport, Object *object)
+{
+ RegionView3D *rv3d = ar->regiondata;
+
+ DRW_opengl_context_enable();
+
+ /* Setup framebuffer */
+ DefaultFramebufferList *fbl = GPU_viewport_framebuffer_list_get(viewport);
+
+ GPU_framebuffer_bind(fbl->depth_only_fb);
+ GPU_framebuffer_clear_depth(fbl->depth_only_fb, 1.0f);
+ GPU_depth_test(true);
+ GPU_matrix_mul(object->obmat);
+
+ const float(*world_clip_planes)[4] = NULL;
+ if (rv3d->rflag & RV3D_CLIPPING) {
+ ED_view3d_clipping_set(rv3d);
+ ED_view3d_clipping_local(rv3d, object->obmat);
+ world_clip_planes = rv3d->clip_local;
+ }
+
+ switch (object->type) {
+ case OB_MESH: {
+ GPUBatch *batch;
+
+ Mesh *me = object->data;
+
+ if (object->mode & OB_MODE_EDIT) {
+ batch = DRW_mesh_batch_cache_get_edit_triangles(me);
+ }
+ else {
+ batch = DRW_mesh_batch_cache_get_surface(me);
+ }
+
+ DRW_mesh_batch_cache_create_requested(object, me, NULL, false, true);
+
+ const eGPUShaderConfig sh_cfg = world_clip_planes ? GPU_SHADER_CFG_CLIPPED :
+ GPU_SHADER_CFG_DEFAULT;
+ GPU_batch_program_set_builtin_with_config(batch, GPU_SHADER_3D_DEPTH_ONLY, sh_cfg);
+ if (world_clip_planes != NULL) {
+ GPU_batch_uniform_4fv_array(batch, "WorldClipPlanes", 6, world_clip_planes[0]);
+ }
+
+ GPU_batch_draw(batch);
+ } break;
+ case OB_CURVE:
+ case OB_SURF:
+ break;
+ }
+
+ if (rv3d->rflag & RV3D_CLIPPING) {
+ ED_view3d_clipping_disable();
+ }
+
+ GPU_matrix_set(rv3d->viewmat);
+ GPU_depth_test(false);
+ GPU_framebuffer_restore();
+ DRW_opengl_context_disable();
+}
+
/* Set an opengl context to be used with shaders that draw on U32 colors. */
void DRW_framebuffer_select_id_setup(ARegion *ar, const bool clear)
{
@@ -2669,9 +2730,6 @@ bool DRW_state_draw_support(void)
*/
bool DRW_state_draw_background(void)
{
- if (DRW_state_is_image_render() == false) {
- return true;
- }
return DST.options.draw_background;
}
diff --git a/source/blender/draw/intern/draw_manager.h b/source/blender/draw/intern/draw_manager.h
index 35e2ab86a80..a70438a2d37 100644
--- a/source/blender/draw/intern/draw_manager.h
+++ b/source/blender/draw/intern/draw_manager.h
@@ -56,7 +56,9 @@
# define PROFILE_TIMER_FALLOFF 0.04
-# define PROFILE_START(time_start) double time_start = PIL_check_seconds_timer();
+# define PROFILE_START(time_start) \
+ double time_start = PIL_check_seconds_timer(); \
+ ((void)0)
# define PROFILE_END_ACCUM(time_accum, time_start) \
{ \
@@ -251,10 +253,12 @@ struct DRWShadingGroup {
};
};
- DRWState state_extra; /* State changes for this batch only (or'd with the pass's state) */
- DRWState
- state_extra_disable; /* State changes for this batch only (and'd with the pass's state) */
- uint stencil_mask; /* Stencil mask to use for stencil test / write operations */
+ /** State changes for this batch only (or'd with the pass's state) */
+ DRWState state_extra;
+ /** State changes for this batch only (and'd with the pass's state) */
+ DRWState state_extra_disable;
+ /** Stencil mask to use for stencil test / write operations */
+ uint stencil_mask;
DRWShadingGroupType type;
/* Builtin matrices locations */
@@ -393,10 +397,11 @@ typedef struct DRWManager {
/* gl_context serves as the offset for clearing only
* the top portion of the struct so DO NOT MOVE IT! */
- void *gl_context; /* Unique ghost context used by the draw manager. */
+ /** Unique ghost context used by the draw manager. */
+ void *gl_context;
GPUContext *gpu_context;
- TicketMutex
- *gl_context_mutex; /* Mutex to lock the drw manager and avoid concurrent context usage. */
+ /** Mutex to lock the drw manager and avoid concurrent context usage. */
+ TicketMutex *gl_context_mutex;
/** GPU Resource State: Memory storage between drawing. */
struct {
diff --git a/source/blender/draw/intern/draw_manager_data.c b/source/blender/draw/intern/draw_manager_data.c
index 4a9f4fe910b..65ef2fa66fa 100644
--- a/source/blender/draw/intern/draw_manager_data.c
+++ b/source/blender/draw/intern/draw_manager_data.c
@@ -161,7 +161,8 @@ void DRW_shgroup_uniform_texture(DRWShadingGroup *shgroup, const char *name, con
drw_shgroup_uniform(shgroup, name, DRW_UNIFORM_TEXTURE, tex, 0, 1);
}
-/* Same as DRW_shgroup_uniform_texture but is guaranteed to be bound if shader does not change between shgrp. */
+/* Same as DRW_shgroup_uniform_texture but is guaranteed to be bound if shader does not change
+ * between shgrp. */
void DRW_shgroup_uniform_texture_persistent(DRWShadingGroup *shgroup,
const char *name,
const GPUTexture *tex)
@@ -178,7 +179,8 @@ void DRW_shgroup_uniform_block(DRWShadingGroup *shgroup,
drw_shgroup_uniform(shgroup, name, DRW_UNIFORM_BLOCK, ubo, 0, 1);
}
-/* Same as DRW_shgroup_uniform_block but is guaranteed to be bound if shader does not change between shgrp. */
+/* Same as DRW_shgroup_uniform_block but is guaranteed to be bound if shader does not change
+ * between shgrp. */
void DRW_shgroup_uniform_block_persistent(DRWShadingGroup *shgroup,
const char *name,
const GPUUniformBuffer *ubo)
@@ -634,6 +636,17 @@ void DRW_shgroup_call_generate_add(DRWShadingGroup *shgroup,
BLI_LINKS_APPEND(&shgroup->calls, call);
}
+/* This function tests if the current draw engine draws the vertex colors
+ * It is used when drawing sculpts
+ *
+ * XXX: should we use a callback to a the draw engine to retrieve this
+ * setting, this makes the draw manager more clean? */
+static bool DRW_draw_vertex_color_active(const DRWContextState *draw_ctx)
+{
+ View3D *v3d = draw_ctx->v3d;
+ return v3d->shading.type == OB_SOLID && v3d->shading.color_type == V3D_SHADING_VERTEX_COLOR;
+}
+
static void sculpt_draw_cb(DRWShadingGroup *shgroup,
void (*draw_fn)(DRWShadingGroup *shgroup, GPUBatch *geom),
void *user_data)
@@ -654,8 +667,16 @@ static void sculpt_draw_cb(DRWShadingGroup *shgroup,
}
if (pbvh) {
- BKE_pbvh_draw_cb(
- pbvh, NULL, NULL, fast_mode, false, false, (void (*)(void *, GPUBatch *))draw_fn, shgroup);
+ const bool show_vcol = DRW_draw_vertex_color_active(drwctx);
+ BKE_pbvh_draw_cb(pbvh,
+ NULL,
+ NULL,
+ fast_mode,
+ false,
+ false,
+ show_vcol,
+ (void (*)(void *, GPUBatch *))draw_fn,
+ shgroup);
}
}
@@ -679,8 +700,15 @@ static void sculpt_draw_wires_cb(DRWShadingGroup *shgroup,
}
if (pbvh) {
- BKE_pbvh_draw_cb(
- pbvh, NULL, NULL, fast_mode, true, false, (void (*)(void *, GPUBatch *))draw_fn, shgroup);
+ BKE_pbvh_draw_cb(pbvh,
+ NULL,
+ NULL,
+ fast_mode,
+ true,
+ false,
+ false,
+ (void (*)(void *, GPUBatch *))draw_fn,
+ shgroup);
}
}
@@ -955,8 +983,12 @@ static DRWShadingGroup *drw_shgroup_material_inputs(DRWShadingGroup *grp,
GPUTexture *tex = NULL;
if (input->ima) {
- tex = GPU_texture_from_blender(
+ GPUTexture **tex_ref = BLI_mempool_alloc(DST.vmempool->images);
+
+ *tex_ref = tex = GPU_texture_from_blender(
input->ima, input->iuser, GL_TEXTURE_2D, input->image_isdata);
+
+ GPU_texture_ref(tex);
}
else {
/* Color Ramps */
@@ -1148,7 +1180,7 @@ void DRW_shgroup_instance_batch(DRWShadingGroup *shgroup, struct GPUBatch *batch
/* PERF : This destroys the vaos cache so better check if it's necessary. */
/* Note: This WILL break if batch->verts[0] is destroyed and reallocated
* at the same address. Bindings/VAOs would remain obsolete. */
- //if (shgroup->instancing_geom->inst != batch->verts[0])
+ // if (shgroup->instancing_geom->inst != batch->verts[0])
GPU_batch_instbuf_set(shgroup->instance_geom, batch->verts[0], false);
#ifdef USE_GPU_SELECT
diff --git a/source/blender/draw/intern/draw_manager_exec.c b/source/blender/draw/intern/draw_manager_exec.c
index db675ee0210..8e23a616ff5 100644
--- a/source/blender/draw/intern/draw_manager_exec.c
+++ b/source/blender/draw/intern/draw_manager_exec.c
@@ -205,7 +205,7 @@ void drw_state_set(DRWState state)
int test;
if (CHANGED_ANY_STORE_VAR(DRW_STATE_BLEND | DRW_STATE_BLEND_PREMUL | DRW_STATE_ADDITIVE |
DRW_STATE_MULTIPLY | DRW_STATE_ADDITIVE_FULL |
- DRW_STATE_BLEND_OIT,
+ DRW_STATE_BLEND_OIT | DRW_STATE_BLEND_PREMUL_UNDER,
test)) {
if (test) {
glEnable(GL_BLEND);
@@ -216,6 +216,9 @@ void drw_state_set(DRWState state)
GL_ONE,
GL_ONE_MINUS_SRC_ALPHA); /* Alpha */
}
+ else if ((state & DRW_STATE_BLEND_PREMUL_UNDER) != 0) {
+ glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_ONE);
+ }
else if ((state & DRW_STATE_BLEND_PREMUL) != 0) {
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
}
@@ -445,8 +448,9 @@ void DRW_state_clip_planes_set_from_rv3d(RegionView3D *rv3d)
/* 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(projinv, bbox.vec[i]);}
+ * 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(projinv,
+ * bbox.vec[i]);}
*/
static void draw_frustum_boundbox_calc(const float (*projmat)[4], BoundBox *r_bbox)
{
@@ -498,7 +502,8 @@ static void draw_clipping_setup_from_view(void)
/* Extract Clipping Planes */
BoundBox bbox;
#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});
+ 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(projinv, bbox.vec[i]);
}
@@ -616,9 +621,9 @@ static void draw_clipping_setup_from_view(void)
float F = -1.0f, N; /* square distance of far and near point to origin */
float f, n; /* distance of far and near point to z axis. f is always > 0 but n can be < 0 */
float e, s; /* far and near clipping distance (<0) */
- float
- c; /* slope of center line = distance of far clipping center to z axis / far clipping distance */
- float z; /* projection of sphere center on z axis (<0) */
+ float c; /* slope of center line = distance of far clipping center
+ * to z axis / far clipping distance. */
+ float z; /* projection of sphere center on z axis (<0) */
/* Find farthest corner and center of far clip plane. */
float corner[3] = {1.0f, 1.0f, 1.0f}; /* in clip space */
@@ -1230,12 +1235,13 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state)
# define GPU_SELECT_LOAD_IF_PICKSEL_LIST_END(_start, _count) \
_start += _count; \
- }
+ } \
+ ((void)0)
#else
# define GPU_SELECT_LOAD_IF_PICKSEL(select_id)
# define GPU_SELECT_LOAD_IF_PICKSEL_CALL(call)
-# define GPU_SELECT_LOAD_IF_PICKSEL_LIST_END(start, count)
+# define GPU_SELECT_LOAD_IF_PICKSEL_LIST_END(start, count) ((void)0)
# define GPU_SELECT_LOAD_IF_PICKSEL_LIST(_shgroup, _start, _count) \
_start = 0; \
_count = _shgroup->instance_count;
@@ -1259,11 +1265,10 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state)
if (shgroup->instance_count > 0) {
uint count, start;
draw_geometry_prepare(shgroup, NULL);
- GPU_SELECT_LOAD_IF_PICKSEL_LIST(shgroup, start, count)
- {
+ GPU_SELECT_LOAD_IF_PICKSEL_LIST (shgroup, start, count) {
draw_geometry_execute_ex(shgroup, shgroup->instance_geom, start, count, true);
}
- GPU_SELECT_LOAD_IF_PICKSEL_LIST_END(start, count)
+ GPU_SELECT_LOAD_IF_PICKSEL_LIST_END(start, count);
}
}
}
@@ -1272,11 +1277,10 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state)
if (shgroup->instance_count > 0) {
uint count, start;
draw_geometry_prepare(shgroup, NULL);
- GPU_SELECT_LOAD_IF_PICKSEL_LIST(shgroup, start, count)
- {
+ GPU_SELECT_LOAD_IF_PICKSEL_LIST (shgroup, start, count) {
draw_geometry_execute_ex(shgroup, shgroup->batch_geom, start, count, false);
}
- GPU_SELECT_LOAD_IF_PICKSEL_LIST_END(start, count)
+ GPU_SELECT_LOAD_IF_PICKSEL_LIST_END(start, count);
}
}
}
diff --git a/source/blender/draw/intern/draw_manager_shader.c b/source/blender/draw/intern/draw_manager_shader.c
index 9cb3c1bf226..b60a41ab0c9 100644
--- a/source/blender/draw/intern/draw_manager_shader.c
+++ b/source/blender/draw/intern/draw_manager_shader.c
@@ -161,8 +161,10 @@ static void drw_deferred_shader_compilation_free(void *custom_data)
static void drw_deferred_shader_add(GPUMaterial *mat, bool deferred)
{
- /* Do not deferre the compilation if we are rendering for image. */
- if (DRW_state_is_image_render() || !USE_DEFERRED_COMPILATION || !deferred) {
+ /* Do not deferre the compilation if we are rendering for image.
+ * deferred rendering is only possible when `evil_C` is available */
+ if (DST.draw_ctx.evil_C == NULL || DRW_state_is_image_render() || !USE_DEFERRED_COMPILATION ||
+ !deferred) {
/* Double checking that this GPUMaterial is not going to be
* compiled by another thread. */
DRW_deferred_shader_remove(mat);
@@ -181,7 +183,8 @@ static void drw_deferred_shader_add(GPUMaterial *mat, bool deferred)
/* Use original scene ID since this is what the jobs template tests for. */
Scene *scene = (Scene *)DEG_get_original_id(&DST.draw_ctx.scene->id);
- /* Get the running job or a new one if none is running. Can only have one job per type & owner. */
+ /* Get the running job or a new one if none is running. Can only have one job per type & owner.
+ */
wmJob *wm_job = WM_jobs_get(wm,
win,
scene,
diff --git a/source/blender/draw/intern/draw_view.c b/source/blender/draw/intern/draw_view.c
index 1543e381d8c..7aa2e007f79 100644
--- a/source/blender/draw/intern/draw_view.c
+++ b/source/blender/draw/intern/draw_view.c
@@ -61,19 +61,35 @@ void DRW_draw_region_info(void)
/* ************************* Background ************************** */
-void DRW_draw_background(void)
+void DRW_draw_background(bool do_alpha_checker)
{
/* Just to make sure */
glDepthMask(GL_TRUE);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glStencilMask(0xFF);
- if (UI_GetThemeValue(TH_SHOW_BACK_GRAD)) {
+ if (do_alpha_checker) {
+ /* Transparent render, do alpha checker. */
+ GPU_depth_test(false);
+
+ GPU_matrix_push();
+ GPU_matrix_identity_set();
+ GPU_matrix_identity_projection_set();
+
+ imm_draw_box_checker_2d(-1.0f, -1.0f, 1.0f, 1.0f);
+
+ GPU_matrix_pop();
+
+ GPU_clear(GPU_DEPTH_BIT | GPU_STENCIL_BIT);
+
+ GPU_depth_test(true);
+ }
+ else if (UI_GetThemeValue(TH_SHOW_BACK_GRAD)) {
float m[4][4];
unit_m4(m);
/* Gradient background Color */
- glDisable(GL_DEPTH_TEST);
+ GPU_depth_test(false);
GPUVertFormat *format = immVertexFormat();
uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
@@ -104,14 +120,15 @@ void DRW_draw_background(void)
GPU_matrix_pop();
- glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+ GPU_clear(GPU_DEPTH_BIT | GPU_STENCIL_BIT);
- glEnable(GL_DEPTH_TEST);
+ GPU_depth_test(true);
}
else {
/* Solid background Color */
UI_ThemeClearColorAlpha(TH_BACK, 1.0f);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+
+ GPU_clear(GPU_COLOR_BIT | GPU_DEPTH_BIT | GPU_STENCIL_BIT);
}
}
diff --git a/source/blender/draw/intern/draw_view.h b/source/blender/draw/intern/draw_view.h
index 08a8e984c87..715c3c0d40c 100644
--- a/source/blender/draw/intern/draw_view.h
+++ b/source/blender/draw/intern/draw_view.h
@@ -24,7 +24,7 @@
#define __DRAW_VIEW_H__
void DRW_draw_region_info(void);
-void DRW_draw_background(void);
+void DRW_draw_background(bool do_alpha_checker);
void DRW_draw_cursor(void);
void DRW_draw_gizmo_3d(void);
void DRW_draw_gizmo_2d(void);
diff --git a/source/blender/draw/modes/edit_armature_mode.c b/source/blender/draw/modes/edit_armature_mode.c
index 12bf4982ffb..d1ef0d0e104 100644
--- a/source/blender/draw/modes/edit_armature_mode.c
+++ b/source/blender/draw/modes/edit_armature_mode.c
@@ -126,6 +126,7 @@ static void EDIT_ARMATURE_cache_populate(void *vedata, Object *ob)
.bone_envelope = psl->bone_envelope[ghost],
.bone_axes = psl->bone_axes,
.relationship_lines = psl->relationship[ghost],
+ .custom_shapes = NULL, /* Not needed in edit mode. */
};
DRW_shgroup_armature_edit(ob, passes, transp);
}
diff --git a/source/blender/draw/modes/edit_mesh_mode.c b/source/blender/draw/modes/edit_mesh_mode.c
index b3b6acf9b7d..ffe7fe5845c 100644
--- a/source/blender/draw/modes/edit_mesh_mode.c
+++ b/source/blender/draw/modes/edit_mesh_mode.c
@@ -55,6 +55,8 @@ extern char datatoc_edit_mesh_overlay_geom_glsl[];
extern char datatoc_edit_mesh_overlay_mix_frag_glsl[];
extern char datatoc_edit_mesh_overlay_facefill_vert_glsl[];
extern char datatoc_edit_mesh_overlay_facefill_frag_glsl[];
+extern char datatoc_edit_mesh_overlay_mesh_analysis_frag_glsl[];
+extern char datatoc_edit_mesh_overlay_mesh_analysis_vert_glsl[];
extern char datatoc_edit_normals_vert_glsl[];
extern char datatoc_edit_normals_geom_glsl[];
extern char datatoc_common_globals_lib_glsl[];
@@ -75,6 +77,7 @@ typedef struct EDIT_MESH_PassList {
struct DRWPass *edit_face_occluded;
struct DRWPass *mix_occlude;
struct DRWPass *facefill_occlude;
+ struct DRWPass *mesh_analysis_pass;
struct DRWPass *normals;
} EDIT_MESH_PassList;
@@ -115,6 +118,10 @@ typedef struct EDIT_MESH_Shaders {
GPUShader *normals_loop;
GPUShader *normals;
GPUShader *depth;
+
+ /* Mesh analysis shader */
+ GPUShader *mesh_analysis_face;
+ GPUShader *mesh_analysis_vertex;
} EDIT_MESH_Shaders;
/* *********** STATIC *********** */
@@ -149,6 +156,7 @@ typedef struct EDIT_MESH_PrivateData {
DRWShadingGroup *facedot_shgrp_in_front;
DRWShadingGroup *facefill_occluded_shgrp;
+ DRWShadingGroup *mesh_analysis_shgrp;
int data_mask[4];
int ghost_ob;
@@ -278,6 +286,22 @@ static void EDIT_MESH_engine_init(void *vedata)
.defs = (const char *[]){sh_cfg_data->def, NULL},
});
+ /* Mesh Analysis */
+ sh_data->mesh_analysis_face = GPU_shader_create_from_arrays({
+ .vert = (const char *[]){sh_cfg_data->lib,
+ datatoc_edit_mesh_overlay_mesh_analysis_vert_glsl,
+ NULL},
+ .frag = (const char *[]){datatoc_edit_mesh_overlay_mesh_analysis_frag_glsl, NULL},
+ .defs = (const char *[]){sh_cfg_data->def, "#define FACE_COLOR\n", NULL},
+ });
+ sh_data->mesh_analysis_vertex = GPU_shader_create_from_arrays({
+ .vert = (const char *[]){sh_cfg_data->lib,
+ datatoc_edit_mesh_overlay_mesh_analysis_vert_glsl,
+ NULL},
+ .frag = (const char *[]){datatoc_edit_mesh_overlay_mesh_analysis_frag_glsl, NULL},
+ .defs = (const char *[]){sh_cfg_data->def, "#define VERTEX_COLOR\n", NULL},
+ });
+
sh_data->depth = DRW_shader_create_3d_depth_only(draw_ctx->sh_cfg);
}
}
@@ -300,8 +324,6 @@ static DRWPass *edit_mesh_create_overlay_pass(float *face_alpha,
const bool select_vert = (tsettings->selectmode & SCE_SELECT_VERTEX) != 0;
const bool select_face = (tsettings->selectmode & SCE_SELECT_FACE) != 0;
const bool select_edge = (tsettings->selectmode & SCE_SELECT_EDGE) != 0;
- const bool show_wide_edge = select_edge &&
- !(draw_ctx->v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_FACE_DOT);
float winmat[4][4];
float viewdist = rv3d->dist;
@@ -336,8 +358,8 @@ static DRWPass *edit_mesh_create_overlay_pass(float *face_alpha,
DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
DRW_shgroup_uniform_float(grp, "faceAlphaMod", face_alpha, 1);
DRW_shgroup_uniform_ivec4(grp, "dataMask", data_mask, 1);
- DRW_shgroup_uniform_bool_copy(grp, "doEdges", do_edges);
DRW_shgroup_uniform_float_copy(grp, "ofs", 0.0f);
+ DRW_shgroup_uniform_bool_copy(grp, "selectFaces", select_face);
if (rv3d->rflag & RV3D_CLIPPING) {
DRW_shgroup_world_clip_planes_from_rv3d(grp, rv3d);
}
@@ -354,7 +376,8 @@ static DRWPass *edit_mesh_create_overlay_pass(float *face_alpha,
DRW_shgroup_uniform_ivec4(grp, "dataMask", data_mask, 1);
DRW_shgroup_uniform_bool_copy(grp, "doEdges", do_edges);
DRW_shgroup_uniform_float_copy(grp, "ofs", depth_ofs);
- DRW_shgroup_uniform_float_copy(grp, "edgeScale", show_wide_edge ? 1.75f : 1.0f);
+ DRW_shgroup_uniform_bool_copy(grp, "selectEdges", select_edge);
+
DRW_shgroup_state_enable(grp, DRW_STATE_OFFSET_NEGATIVE);
/* To match blender loop structure. */
DRW_shgroup_state_enable(grp, DRW_STATE_FIRST_VERTEX_CONVENTION);
@@ -422,9 +445,6 @@ static void EDIT_MESH_cache_init(void *vedata)
stl->g_data->do_faces = false;
stl->g_data->do_zbufclip = false;
}
- if ((tsettings->selectmode & SCE_SELECT_FACE) == 0) {
- stl->g_data->data_mask[0] &= ~VFLAG_FACE_ACTIVE;
- }
if ((v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_SEAMS) == 0) {
stl->g_data->data_mask[1] &= ~VFLAG_EDGE_SEAM;
}
@@ -513,6 +533,18 @@ static void EDIT_MESH_cache_init(void *vedata)
}
}
+ {
+ /* Mesh Analysis Pass */
+ DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND;
+ psl->mesh_analysis_pass = DRW_pass_create("Mesh Analysis", state);
+ const bool is_vertex_color = scene->toolsettings->statvis.type == SCE_STATVIS_SHARP;
+ stl->g_data->mesh_analysis_shgrp = DRW_shgroup_create(
+ is_vertex_color ? sh_data->mesh_analysis_vertex : sh_data->mesh_analysis_face,
+ psl->mesh_analysis_pass);
+ if (rv3d->rflag & RV3D_CLIPPING) {
+ DRW_shgroup_world_clip_planes_from_rv3d(stl->g_data->mesh_analysis_shgrp, rv3d);
+ }
+ }
/* For in front option */
psl->edit_face_overlay_in_front = edit_mesh_create_overlay_pass(
&face_mod,
@@ -538,7 +570,8 @@ static void EDIT_MESH_cache_init(void *vedata)
&stl->g_data->vert_shgrp);
}
else {
- /* We render all wires with depth and opaque to a new fbo and blend the result based on depth values */
+ /* We render all wires with depth and opaque to a new fbo and blend the result based on depth
+ * values */
psl->edit_face_occluded = edit_mesh_create_overlay_pass(&zero,
stl->g_data->data_mask,
stl->g_data->do_edges,
@@ -632,6 +665,7 @@ static void EDIT_MESH_cache_populate(void *vedata, Object *ob)
bool do_in_front = (ob->dtx & OB_DRAWXRAY) != 0;
bool do_occlude_wire = (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_OCCLUDE_WIRE) != 0;
bool do_show_weight = (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_WEIGHT) != 0;
+ bool do_show_mesh_analysis = (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_STATVIS) != 0;
bool fnormals_do = (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_FACE_NORMALS) != 0;
bool vnormals_do = (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_VERT_NORMALS) != 0;
bool lnormals_do = (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_LOOP_NORMALS) != 0;
@@ -660,6 +694,19 @@ static void EDIT_MESH_cache_populate(void *vedata, Object *ob)
DRW_shgroup_call_add(g_data->fweights_shgrp, geom, ob->obmat);
}
+ if (do_show_mesh_analysis) {
+ Mesh *me = (Mesh *)ob->data;
+ BMEditMesh *embm = me->edit_mesh;
+ const bool is_original = embm->mesh_eval_final &&
+ (embm->mesh_eval_final->runtime.is_original == true);
+ if (is_original) {
+ geom = DRW_cache_mesh_surface_mesh_analysis_get(ob);
+ if (geom) {
+ DRW_shgroup_call_add(g_data->mesh_analysis_shgrp, geom, ob->obmat);
+ }
+ }
+ }
+
if (do_occlude_wire || do_in_front) {
geom = DRW_cache_mesh_surface_get(ob);
DRW_shgroup_call_add(do_in_front ? g_data->depth_shgrp_hidden_wire_in_front :
@@ -735,6 +782,7 @@ static void EDIT_MESH_draw_scene(void *vedata)
DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
DRW_draw_pass(psl->weight_faces);
+ DRW_draw_pass(psl->mesh_analysis_pass);
DRW_draw_pass(psl->depth_hidden_wire);
diff --git a/source/blender/draw/modes/edit_mesh_mode_text.c b/source/blender/draw/modes/edit_mesh_mode_text.c
index 90396785eb3..f3630a77e9a 100644
--- a/source/blender/draw/modes/edit_mesh_mode_text.c
+++ b/source/blender/draw/modes/edit_mesh_mode_text.c
@@ -47,8 +47,8 @@ void DRW_edit_mesh_mode_text_measure_stats(ARegion *ar,
Object *ob,
const UnitSettings *unit)
{
- /* Do not use ascii when using non-default unit system, some unit chars are utf8 (micro, square, etc.).
- * See bug #36090.
+ /* Do not use ascii when using non-default unit system, some unit chars are utf8 (micro, square,
+ * etc.). See bug #36090.
*/
struct DRWTextStore *dt = DRW_text_cache_ensure();
const short txt_flag = DRW_TEXT_CACHE_GLOBALSPACE | (unit->system ? 0 : DRW_TEXT_CACHE_ASCII);
@@ -157,12 +157,12 @@ void DRW_edit_mesh_mode_text_measure_stats(ARegion *ar,
BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
BMLoop *l_a, *l_b;
if (BM_edge_loop_pair(eed, &l_a, &l_b)) {
- /* draw selected edges, or edges next to selected verts while dragging */
+ /* Draw selected edges, or edges next to selected verts while dragging. */
if (BM_elem_flag_test(eed, BM_ELEM_SELECT) ||
(do_moving && (BM_elem_flag_test(eed->v1, BM_ELEM_SELECT) ||
BM_elem_flag_test(eed->v2, BM_ELEM_SELECT) ||
- /* special case, this is useful to show when verts connected to
- * this edge via a face are being transformed */
+ /* Special case, this is useful to show when verts connected
+ * to this edge via a face are being transformed. */
BM_elem_flag_test(l_a->next->next->v, BM_ELEM_SELECT) ||
BM_elem_flag_test(l_a->prev->v, BM_ELEM_SELECT) ||
BM_elem_flag_test(l_b->next->next->v, BM_ELEM_SELECT) ||
@@ -319,7 +319,8 @@ void DRW_edit_mesh_mode_text_measure_stats(ARegion *ar,
}
}
- /* This option is for mesh ops and addons debugging; only available in UI if Blender starts with --debug */
+ /* This option is for mesh ops and addons debugging; only available in UI if Blender starts with
+ * --debug */
if (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_INDICES) {
int i;
diff --git a/source/blender/draw/modes/edit_metaball_mode.c b/source/blender/draw/modes/edit_metaball_mode.c
index 90c5676727f..aa7c6863423 100644
--- a/source/blender/draw/modes/edit_metaball_mode.c
+++ b/source/blender/draw/modes/edit_metaball_mode.c
@@ -126,7 +126,7 @@ static void EDIT_METABALL_cache_init(void *vedata)
/* Add geometry to shadingGroups. Execute for each objects */
static void EDIT_METABALL_cache_populate(void *vedata, Object *ob)
{
- //EDIT_METABALL_PassList *psl = ((EDIT_METABALL_Data *)vedata)->psl;
+ // EDIT_METABALL_PassList *psl = ((EDIT_METABALL_Data *)vedata)->psl;
EDIT_METABALL_StorageList *stl = ((EDIT_METABALL_Data *)vedata)->stl;
if (ob->type == OB_MBALL) {
diff --git a/source/blender/draw/modes/object_mode.c b/source/blender/draw/modes/object_mode.c
index ec49b4dbe51..ee2c660ca06 100644
--- a/source/blender/draw/modes/object_mode.c
+++ b/source/blender/draw/modes/object_mode.c
@@ -53,6 +53,8 @@
#include "BKE_particle.h"
#include "BKE_tracking.h"
+#include "BLI_ghash.h"
+
#include "ED_view3d.h"
#include "GPU_batch.h"
@@ -273,6 +275,8 @@ typedef struct OBJECT_PrivateData {
OBJECT_ShadingGroupList sgl;
OBJECT_ShadingGroupList sgl_ghost;
+ GHash *custom_shapes;
+
/* Outlines */
DRWShadingGroup *outlines_active;
DRWShadingGroup *outlines_select;
@@ -511,6 +515,7 @@ static void OBJECT_engine_init(void *vedata)
const bool show_axis_y = (v3d->gridflag & V3D_SHOW_Y) != 0;
const bool show_axis_z = (v3d->gridflag & V3D_SHOW_Z) != 0;
const bool show_floor = (v3d->gridflag & V3D_SHOW_FLOOR) != 0;
+ const bool show_ortho_grid = (v3d->gridflag & V3D_SHOW_ORTHO_GRID) != 0;
e_data.draw_grid = show_axis_x || show_axis_y || show_axis_z || show_floor;
DRW_viewport_matrix_get(winmat, DRW_MAT_WIN);
@@ -559,15 +564,15 @@ static void OBJECT_engine_init(void *vedata)
grid_res = viewdist / grid_scale;
if (ELEM(rv3d->view, RV3D_VIEW_RIGHT, RV3D_VIEW_LEFT)) {
- e_data.draw_grid = true;
+ e_data.draw_grid = show_ortho_grid;
e_data.grid_flag = PLANE_YZ | SHOW_AXIS_Y | SHOW_AXIS_Z | SHOW_GRID | GRID_BACK;
}
else if (ELEM(rv3d->view, RV3D_VIEW_TOP, RV3D_VIEW_BOTTOM)) {
- e_data.draw_grid = true;
+ e_data.draw_grid = show_ortho_grid;
e_data.grid_flag = PLANE_XY | SHOW_AXIS_X | SHOW_AXIS_Y | SHOW_GRID | GRID_BACK;
}
else if (ELEM(rv3d->view, RV3D_VIEW_FRONT, RV3D_VIEW_BACK)) {
- e_data.draw_grid = true;
+ e_data.draw_grid = show_ortho_grid;
e_data.grid_flag = PLANE_XZ | SHOW_AXIS_X | SHOW_AXIS_Z | SHOW_GRID | GRID_BACK;
}
else { /* RV3D_VIEW_USER */
@@ -948,7 +953,8 @@ static void DRW_shgroup_empty_image(OBJECT_Shaders *sh_data,
return;
}
- /* Calling 'BKE_image_get_size' may free the texture. Get the size from 'tex' instead, see: T59347 */
+ /* Calling 'BKE_image_get_size' may free the texture. Get the size from 'tex' instead,
+ * see: T59347 */
int size[2] = {0};
const bool use_alpha_blend = (ob->empty_image_flag & OB_EMPTY_IMAGE_USE_ALPHA_BLEND) != 0;
@@ -1039,6 +1045,8 @@ static void OBJECT_cache_init(void *vedata)
g_data->xray_enabled_and_not_wire = g_data->xray_enabled &&
draw_ctx->v3d->shading.type > OB_WIRE;
+ g_data->custom_shapes = BLI_ghash_ptr_new(__func__);
+
{
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL |
DRW_STATE_WIRE;
@@ -1494,7 +1502,7 @@ static void OBJECT_cache_init(void *vedata)
psl->ob_center = DRW_pass_create("Obj Center Pass", state);
outlineWidth = 1.0f * U.pixelsize;
- size = U.obcenter_dia * U.pixelsize + outlineWidth;
+ size = UI_GetThemeValuef(TH_OBCENTER_DIA) * U.pixelsize + outlineWidth;
GPUShader *sh = GPU_shader_get_builtin_shader_with_config(
GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_AA, draw_ctx->sh_cfg);
@@ -1853,8 +1861,10 @@ static void camera_view3d_stereoscopy_display_extra(OBJECT_ShadingGroupList *sgl
static float one = 1.0f;
float plane_mat[4][4], scale_mat[4][4];
float scale_factor[3] = {1.0f, 1.0f, 1.0f};
- float color_plane[2][4] = {{0.0f, 0.0f, 0.0f, v3d->stereo3d_convergence_alpha},
- {0.0f, 0.0f, 0.0f, 1.0f}};
+ float color_plane[2][4] = {
+ {0.0f, 0.0f, 0.0f, v3d->stereo3d_convergence_alpha},
+ {0.0f, 0.0f, 0.0f, 1.0f},
+ };
const float height = convergence_plane[1][1] - convergence_plane[0][1];
const float width = convergence_plane[2][0] - convergence_plane[0][0];
@@ -1877,9 +1887,11 @@ static void camera_view3d_stereoscopy_display_extra(OBJECT_ShadingGroupList *sgl
/* Draw convergence volume. */
if (is_stereo3d_volume && !is_select) {
static float one = 1.0f;
- float color_volume[3][4] = {{0.0f, 1.0f, 1.0f, v3d->stereo3d_volume_alpha},
- {1.0f, 0.0f, 0.0f, v3d->stereo3d_volume_alpha},
- {0.0f, 0.0f, 0.0f, 1.0f}};
+ float color_volume[3][4] = {
+ {0.0f, 1.0f, 1.0f, v3d->stereo3d_volume_alpha},
+ {1.0f, 0.0f, 0.0f, v3d->stereo3d_volume_alpha},
+ {0.0f, 0.0f, 0.0f, 1.0f},
+ };
for (int eye = 0; eye < 2; eye++) {
float winmat[4][4], viewinv[4][4], viewmat[4][4], persmat[4][4], persinv[4][4];
@@ -3115,11 +3127,10 @@ static void OBJECT_cache_populate(void *vedata, Object *ob)
((DRW_object_is_renderable(ob) && (ob->dt > OB_WIRE)) ||
(ob->dt == OB_WIRE)));
const bool show_relations = ((draw_ctx->v3d->flag & V3D_HIDE_HELPLINES) == 0);
- const bool hide_object_extra = ((v3d->overlay.flag & V3D_OVERLAY_HIDE_OBJECT_XTRAS) != 0 &&
- /* Show if this is the camera we're looking through
- * since it's useful for moving the camera. */
- (((rv3d->persp == RV3D_CAMOB) &&
- ((ID *)v3d->camera == ob->id.orig_id)) == 0));
+ const bool hide_object_extra =
+ ((v3d->overlay.flag & V3D_OVERLAY_HIDE_OBJECT_XTRAS) != 0 &&
+ /* Show if this is the camera we're looking through since it's useful for selecting. */
+ (((rv3d->persp == RV3D_CAMOB) && ((ID *)v3d->camera == ob->id.orig_id)) == 0));
if (do_outlines) {
if (!BKE_object_is_in_editmode(ob) &&
@@ -3284,6 +3295,7 @@ static void OBJECT_cache_populate(void *vedata, Object *ob)
.bone_envelope = sgl->bone_envelope,
.bone_axes = sgl->bone_axes,
.relationship_lines = NULL, /* Don't draw relationship lines */
+ .custom_shapes = stl->g_data->custom_shapes,
};
DRW_shgroup_armature_object(ob, view_layer, passes, is_wire);
}
@@ -3391,6 +3403,11 @@ static void OBJECT_cache_finish(void *vedata)
DRW_pass_sort_shgroup_z(stl->g_data->sgl.image_empties);
DRW_pass_sort_shgroup_z(stl->g_data->sgl_ghost.image_empties);
+
+ if (stl->g_data->custom_shapes) {
+ /* TODO(fclem): Do not free it for each frame but reuse it. Avoiding alloc cost. */
+ BLI_ghash_free(stl->g_data->custom_shapes, NULL, NULL);
+ }
}
static void OBJECT_draw_scene(void *vedata)
diff --git a/source/blender/draw/modes/overlay_mode.c b/source/blender/draw/modes/overlay_mode.c
index 4d583066f44..ed96b2a05bc 100644
--- a/source/blender/draw/modes/overlay_mode.c
+++ b/source/blender/draw/modes/overlay_mode.c
@@ -359,8 +359,7 @@ static void overlay_cache_populate(void *vedata, Object *ob)
if ((!pd->show_overlays) ||
(((ob != draw_ctx->object_edit) && !is_edit_mode) || has_edit_mesh_cage) ||
ob->type != OB_MESH) {
- const bool is_active = (ob == draw_ctx->obact);
- const bool is_sculpt_mode = is_active && (draw_ctx->object_mode & OB_MODE_SCULPT) != 0;
+ const bool is_sculpt_mode = (ob->sculpt != NULL);
const bool all_wires = (ob->dtx & OB_DRAW_ALL_EDGES);
const bool is_wire = (ob->dt < OB_SOLID);
const bool use_coloring = (pd->show_overlays && !is_edit_mode && !is_sculpt_mode &&
diff --git a/source/blender/draw/modes/paint_texture_mode.c b/source/blender/draw/modes/paint_texture_mode.c
index 84852ff7ab3..3e292f4e4bc 100644
--- a/source/blender/draw/modes/paint_texture_mode.c
+++ b/source/blender/draw/modes/paint_texture_mode.c
@@ -294,7 +294,7 @@ static void PAINT_TEXTURE_cache_populate(void *vedata, Object *ob)
const Mesh *me_orig = DEG_get_original_object(ob)->data;
Scene *scene = draw_ctx->scene;
const bool use_surface = draw_ctx->v3d->overlay.texture_paint_mode_opacity !=
- 0.0; //DRW_object_is_mode_shade(ob) == true;
+ 0.0; // DRW_object_is_mode_shade(ob) == true;
const bool use_material_slots = (scene->toolsettings->imapaint.mode ==
IMAGEPAINT_MODE_MATERIAL);
const bool use_face_sel = (me_orig->editflag & ME_EDIT_PAINT_FACE_SEL) != 0;
diff --git a/source/blender/draw/modes/pose_mode.c b/source/blender/draw/modes/pose_mode.c
index 5e3353414f5..a37901a1fa9 100644
--- a/source/blender/draw/modes/pose_mode.c
+++ b/source/blender/draw/modes/pose_mode.c
@@ -72,6 +72,7 @@ typedef struct POSE_Data {
typedef struct POSE_PrivateData {
DRWShadingGroup *bone_selection_shgrp;
DRWShadingGroup *bone_selection_invert_shgrp;
+ GHash *custom_shapes[2];
float blend_color[4];
float blend_color_invert[4];
bool transparent_bones;
@@ -139,6 +140,8 @@ static void POSE_cache_init(void *vedata)
state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL |
DRW_STATE_BLEND | DRW_STATE_WIRE;
psl->relationship[i] = DRW_pass_create("Bone Relationship Pass", state);
+
+ ppd->custom_shapes[i] = BLI_ghash_ptr_new(__func__);
}
{
@@ -213,6 +216,7 @@ static void POSE_cache_populate(void *vedata, Object *ob)
.bone_envelope = psl->bone_envelope[ghost],
.bone_axes = psl->bone_axes,
.relationship_lines = psl->relationship[ghost],
+ .custom_shapes = ppd->custom_shapes[transp],
};
DRW_shgroup_armature_pose(ob, passes, transp);
}
@@ -231,6 +235,16 @@ static void POSE_cache_populate(void *vedata, Object *ob)
}
}
+static void POSE_cache_finish(void *vedata)
+{
+ POSE_PrivateData *ppd = ((POSE_Data *)vedata)->stl->g_data;
+
+ /* TODO(fclem): Do not free it for each frame but reuse it. Avoiding alloc cost. */
+ for (int i = 0; i < 2; i++) {
+ BLI_ghash_free(ppd->custom_shapes[i], NULL, NULL);
+ }
+}
+
/**
* Return true if armature should be handled by the pose mode engine.
*/
@@ -323,7 +337,7 @@ DrawEngineType draw_engine_pose_type = {
&POSE_engine_free,
&POSE_cache_init,
&POSE_cache_populate,
- NULL,
+ &POSE_cache_finish,
NULL,
&POSE_draw_scene,
NULL,
diff --git a/source/blender/draw/modes/sculpt_mode.c b/source/blender/draw/modes/sculpt_mode.c
index b25a8af795b..8adae0a4238 100644
--- a/source/blender/draw/modes/sculpt_mode.c
+++ b/source/blender/draw/modes/sculpt_mode.c
@@ -135,9 +135,15 @@ static void SCULPT_cache_init(void *vedata)
}
{
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ View3D *v3d = draw_ctx->v3d;
+
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL | DRW_STATE_MULTIPLY;
psl->pass = DRW_pass_create("Sculpt Pass", state);
- stl->g_data->group_smooth = DRW_shgroup_create(e_data.shader_smooth, psl->pass);
+
+ DRWShadingGroup *shgrp = DRW_shgroup_create(e_data.shader_smooth, psl->pass);
+ DRW_shgroup_uniform_float(shgrp, "maskOpacity", &v3d->overlay.sculpt_mode_mask_opacity, 1);
+ stl->g_data->group_smooth = shgrp;
}
}
@@ -155,6 +161,7 @@ static void sculpt_draw_mask_cb(DRWShadingGroup *shgroup,
false,
false,
true,
+ false,
(void (*)(void *, struct GPUBatch *))draw_fn,
shgroup);
}
@@ -193,7 +200,8 @@ static void SCULPT_cache_populate(void *vedata, Object *ob)
sculpt_update_pbvh_normals(ob);
/* XXX, needed for dyntopo-undo (which clears).
- * probably depsgraph should handlle? in 2.7x getting derived-mesh does this (mesh_build_data) */
+ * probably depsgraph should handlle? in 2.7x
+ * getting derived-mesh does this (mesh_build_data). */
if (ob->sculpt->pbvh == NULL) {
/* create PBVH immediately (would be created on the fly too,
* but this avoids waiting on first stroke) */
diff --git a/source/blender/draw/modes/shaders/common_fxaa_lib.glsl b/source/blender/draw/modes/shaders/common_fxaa_lib.glsl
index dcb7c0ba7f2..d9e78855dc9 100644
--- a/source/blender/draw/modes/shaders/common_fxaa_lib.glsl
+++ b/source/blender/draw/modes/shaders/common_fxaa_lib.glsl
@@ -674,7 +674,7 @@ vec4 FxaaPixelShader(
posP.x += offNP.x * FXAA_QUALITY__P10;
if (!doneP)
posP.y += offNP.y * FXAA_QUALITY__P10;
- /*--------------------------------------------------------------------------*/
+ /*-------------------------------------------------------------------------*/
# if (FXAA_QUALITY__PS > 11)
if (doneNP) {
if (!doneN)
@@ -696,7 +696,7 @@ vec4 FxaaPixelShader(
posP.x += offNP.x * FXAA_QUALITY__P11;
if (!doneP)
posP.y += offNP.y * FXAA_QUALITY__P11;
- /*--------------------------------------------------------------------------*/
+ /*-----------------------------------------------------------------------*/
# if (FXAA_QUALITY__PS > 12)
if (doneNP) {
if (!doneN)
@@ -718,10 +718,10 @@ vec4 FxaaPixelShader(
posP.x += offNP.x * FXAA_QUALITY__P12;
if (!doneP)
posP.y += offNP.y * FXAA_QUALITY__P12;
- /*--------------------------------------------------------------------------*/
+ /*-----------------------------------------------------------------------*/
}
# endif
- /*--------------------------------------------------------------------------*/
+ /*-------------------------------------------------------------------------*/
}
# endif
/*--------------------------------------------------------------------------*/
diff --git a/source/blender/draw/modes/shaders/common_hair_lib.glsl b/source/blender/draw/modes/shaders/common_hair_lib.glsl
index 02254908232..1c0a31c59fd 100644
--- a/source/blender/draw/modes/shaders/common_hair_lib.glsl
+++ b/source/blender/draw/modes/shaders/common_hair_lib.glsl
@@ -38,8 +38,8 @@ uniform usamplerBuffer hairStrandBuffer; /* R32UI */
uniform usamplerBuffer hairStrandSegBuffer; /* R16UI */
/* Not used, use one buffer per uv layer */
-//uniform samplerBuffer hairUVBuffer; /* RG32F */
-//uniform samplerBuffer hairColBuffer; /* RGBA16 linear color */
+// uniform samplerBuffer hairUVBuffer; /* RG32F */
+// uniform samplerBuffer hairColBuffer; /* RGBA16 linear color */
/* -- Subdivision stage -- */
/**
diff --git a/source/blender/draw/modes/shaders/edit_mesh_overlay_common_lib.glsl b/source/blender/draw/modes/shaders/edit_mesh_overlay_common_lib.glsl
index ffabfd3fcee..7d4cba66933 100644
--- a/source/blender/draw/modes/shaders/edit_mesh_overlay_common_lib.glsl
+++ b/source/blender/draw/modes/shaders/edit_mesh_overlay_common_lib.glsl
@@ -1,5 +1,7 @@
uniform bool doEdges = true;
+uniform bool selectFaces = true;
+uniform bool selectEdges = true;
vec4 EDIT_MESH_edge_color_outer(int edge_flag, int face_flag, float crease, float bweight)
{
@@ -15,16 +17,21 @@ vec4 EDIT_MESH_edge_color_outer(int edge_flag, int face_flag, float crease, floa
vec4 EDIT_MESH_edge_color_inner(int edge_flag)
{
vec4 color = colorWireEdit;
- color = ((edge_flag & EDGE_SELECTED) != 0) ? colorEdgeSelect : color;
- color = ((edge_flag & EDGE_ACTIVE) != 0) ? colorEditMeshActive : color;
+ vec4 color_select = (selectEdges) ? colorEdgeSelect : colorFaceSelect;
+ color = (doEdges && ((edge_flag & EDGE_SELECTED) != 0)) ? color_select : color;
+ color = (doEdges && ((edge_flag & EDGE_ACTIVE) != 0)) ? colorEditMeshActive : color;
+
+ float non_edge_select_alpha = (selectFaces && (edge_flag & EDGE_SELECTED) != 0) ? 0.75 : 0.4;
+ color.a = (selectEdges) ? 1.0 : non_edge_select_alpha;
return color;
}
vec4 EDIT_MESH_edge_vertex_color(int vertex_flag)
{
vec4 color = colorWireEdit;
- color = (doEdges && (vertex_flag & (VERT_ACTIVE | VERT_SELECTED)) != 0) ? colorEdgeSelect :
- color;
+ vec4 color_select = (selectEdges) ? colorEdgeSelect : colorFaceSelect;
+ color = (doEdges && (vertex_flag & (VERT_ACTIVE | VERT_SELECTED)) != 0) ? color_select : color;
+ color.a = (selectEdges) ? 1.0 : 0.4;
return color;
}
@@ -43,18 +50,15 @@ vec4 EDIT_MESH_vertex_color(int vertex_flag)
vec4 EDIT_MESH_face_color(int face_flag)
{
- if ((face_flag & FACE_ACTIVE) != 0) {
- return mix(colorFaceSelect, colorEditMeshActive, 0.5);
- }
- else if ((face_flag & FACE_SELECTED) != 0) {
- return colorFaceSelect;
- }
- else if ((face_flag & FACE_FREESTYLE) != 0) {
- return colorFaceFreestyle;
- }
- else {
- return colorFace;
- }
+ vec4 color = colorFace;
+ vec4 color_active = mix(colorFaceSelect, colorEditMeshActive, 0.5);
+ color = ((face_flag & FACE_FREESTYLE) != 0) ? colorFaceFreestyle : color;
+ color = ((face_flag & FACE_SELECTED) != 0) ? colorFaceSelect : color;
+ color = ((face_flag & FACE_ACTIVE) != 0) ? color_active : color;
+ color.a *= ((face_flag & (FACE_FREESTYLE | FACE_SELECTED | FACE_ACTIVE)) == 0 || selectFaces) ?
+ 1.0 :
+ 0.5;
+ return color;
}
vec4 EDIT_MESH_facedot_color(float facedot_flag)
diff --git a/source/blender/draw/modes/shaders/edit_mesh_overlay_frag.glsl b/source/blender/draw/modes/shaders/edit_mesh_overlay_frag.glsl
index 3418732afc2..7fe3cea8a42 100644
--- a/source/blender/draw/modes/shaders/edit_mesh_overlay_frag.glsl
+++ b/source/blender/draw/modes/shaders/edit_mesh_overlay_frag.glsl
@@ -5,15 +5,13 @@
* 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.
+ * 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.
*/
#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)
-uniform float edgeScale;
-
flat in vec4 finalColorOuter_f;
in vec4 finalColor_f;
noperspective in float edgeCoord_f;
@@ -22,8 +20,8 @@ out vec4 FragColor;
void main()
{
- float dist = abs(edgeCoord_f) - max(sizeEdge * edgeScale - 0.5, 0.0);
- float dist_outer = dist - max(sizeEdge * edgeScale, 1.0);
+ float dist = abs(edgeCoord_f) - max(sizeEdge - 0.5, 0.0);
+ float dist_outer = dist - max(sizeEdge, 1.0);
#ifdef USE_SMOOTH_WIRE
float mix_w = smoothstep(GRID_LINE_SMOOTH_START, GRID_LINE_SMOOTH_END, dist);
float mix_w_outer = smoothstep(GRID_LINE_SMOOTH_START, GRID_LINE_SMOOTH_END, dist_outer);
@@ -31,6 +29,8 @@ void main()
float mix_w = step(0.5, dist);
float mix_w_outer = step(0.5, dist_outer);
#endif
+ /* Line color & alpha. */
FragColor = mix(finalColorOuter_f, finalColor_f, 1.0 - mix_w * finalColorOuter_f.a);
+ /* Line edges shape. */
FragColor.a *= 1.0 - (finalColorOuter_f.a > 0.0 ? mix_w_outer : mix_w);
}
diff --git a/source/blender/draw/modes/shaders/edit_mesh_overlay_geom.glsl b/source/blender/draw/modes/shaders/edit_mesh_overlay_geom.glsl
index 6e59de12260..047bd1dccc6 100644
--- a/source/blender/draw/modes/shaders/edit_mesh_overlay_geom.glsl
+++ b/source/blender/draw/modes/shaders/edit_mesh_overlay_geom.glsl
@@ -4,7 +4,6 @@ layout(triangle_strip, max_vertices = 4) out;
uniform vec2 viewportSize;
uniform vec2 viewportSizeInv;
-uniform float edgeScale;
in vec4 finalColor[2];
in vec4 finalColorOuter[2];
@@ -14,14 +13,16 @@ flat out vec4 finalColorOuter_f;
out vec4 finalColor_f;
noperspective out float edgeCoord_f;
-void do_vertex(const int i, vec4 pos, float coord, vec2 offset)
+void do_vertex(vec4 color, vec4 pos, float coord, vec2 offset)
{
- finalColor_f = (selectOveride[0] == 0) ? finalColor[i] : finalColor[0];
+ finalColor_f = color;
edgeCoord_f = coord;
gl_Position = pos;
/* Multiply offset by 2 because gl_Position range is [-1..1]. */
gl_Position.xy += offset * 2.0 * pos.w;
-#ifdef USE_WORLD_CLIP_PLANES
+ /* Correct but fails due to an AMD compiler bug, see: T62792.
+ * Do inline instead. */
+#if 0
world_clip_planes_set_clip_distance(gl_in[i].gl_ClipDistance);
#endif
EmitVertex();
@@ -57,9 +58,9 @@ void main()
line = abs(line) * viewportSize;
finalColorOuter_f = finalColorOuter[0];
- float half_size = sizeEdge * edgeScale;
+ float half_size = sizeEdge;
/* Enlarge edge for flag display. */
- half_size += (finalColorOuter_f.a > 0.0) ? max(sizeEdge * edgeScale, 1.0) : 0.0;
+ half_size += (finalColorOuter_f.a > 0.0) ? max(sizeEdge, 1.0) : 0.0;
#ifdef USE_SMOOTH_WIRE
/* Add 1 px for AA */
@@ -71,10 +72,20 @@ void main()
bool horizontal = line.x > line.y;
edge_ofs = (horizontal) ? edge_ofs.zyz : edge_ofs.xzz;
- do_vertex(0, pos0, half_size, edge_ofs.xy);
- do_vertex(0, pos0, -half_size, -edge_ofs.xy);
- do_vertex(1, pos1, half_size, edge_ofs.xy);
- do_vertex(1, pos1, -half_size, -edge_ofs.xy);
+#ifdef USE_WORLD_CLIP_PLANES
+ /* Due to an AMD glitch, this line was moved out of the `do_vertex`
+ * function (see T62792). */
+ world_clip_planes_set_clip_distance(gl_in[0].gl_ClipDistance);
+#endif
+ do_vertex(finalColor[0], pos0, half_size, edge_ofs.xy);
+ do_vertex(finalColor[0], pos0, -half_size, -edge_ofs.xy);
+
+#ifdef USE_WORLD_CLIP_PLANES
+ world_clip_planes_set_clip_distance(gl_in[1].gl_ClipDistance);
+#endif
+ vec4 final_color = (selectOveride[0] == 0) ? finalColor[1] : finalColor[0];
+ do_vertex(final_color, pos1, half_size, edge_ofs.xy);
+ do_vertex(final_color, pos1, -half_size, -edge_ofs.xy);
EndPrimitive();
}
diff --git a/source/blender/draw/modes/shaders/edit_mesh_overlay_mesh_analysis_frag.glsl b/source/blender/draw/modes/shaders/edit_mesh_overlay_mesh_analysis_frag.glsl
new file mode 100644
index 00000000000..8581453e810
--- /dev/null
+++ b/source/blender/draw/modes/shaders/edit_mesh_overlay_mesh_analysis_frag.glsl
@@ -0,0 +1,14 @@
+out vec4 fragColor;
+
+#ifdef FACE_COLOR
+flat in vec4 weightColor;
+#endif
+
+#ifdef VERTEX_COLOR
+in vec4 weightColor;
+#endif
+
+void main()
+{
+ fragColor = weightColor;
+}
diff --git a/source/blender/draw/modes/shaders/edit_mesh_overlay_mesh_analysis_vert.glsl b/source/blender/draw/modes/shaders/edit_mesh_overlay_mesh_analysis_vert.glsl
new file mode 100644
index 00000000000..94d8d2e701c
--- /dev/null
+++ b/source/blender/draw/modes/shaders/edit_mesh_overlay_mesh_analysis_vert.glsl
@@ -0,0 +1,23 @@
+uniform mat4 ModelViewProjectionMatrix;
+uniform mat4 ModelMatrix;
+
+in vec3 pos;
+in vec4 weight_color;
+
+#ifdef FACE_COLOR
+flat out vec4 weightColor;
+#endif
+
+#ifdef VERTEX_COLOR
+out vec4 weightColor;
+#endif
+
+void main()
+{
+ gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
+ weightColor = vec4(weight_color.rgb, 1.0);
+
+#ifdef USE_WORLD_CLIP_PLANES
+ world_clip_planes_calc_clip_distance((ModelMatrix * vec4(pos, 1.0)).xyz);
+#endif
+}
diff --git a/source/blender/draw/modes/shaders/edit_mesh_overlay_vert.glsl b/source/blender/draw/modes/shaders/edit_mesh_overlay_vert.glsl
index 8c54470cd5a..d700e69fb57 100644
--- a/source/blender/draw/modes/shaders/edit_mesh_overlay_vert.glsl
+++ b/source/blender/draw/modes/shaders/edit_mesh_overlay_vert.glsl
@@ -74,21 +74,15 @@ void main()
#endif
-#if !defined(FACE) && !defined(EDGE_DECORATION)
+#if !defined(FACE)
/* Facing based color blend */
vec4 vpos = ModelViewMatrix * vec4(pos, 1.0);
vec3 view_normal = normalize(NormalMatrix * vnor + 1e-4);
vec3 view_vec = (ProjectionMatrix[3][3] == 0.0) ? normalize(vpos.xyz) : vec3(0.0, 0.0, 1.0);
float facing = dot(view_vec, view_normal);
- facing = 1.0 - abs(facing) * 0.3;
-
- finalColor = mix(colorEditMeshMiddle, finalColor, facing);
- finalColor.a = 1.0;
+ facing = 1.0 - abs(facing) * 0.2;
-# if defined(EDGE) && !defined(FLAT)
- /* Hack to blend color in pixel shader in case of overide. */
- finalColor.a = facing;
-# endif
+ finalColor.rgb = mix(colorEditMeshMiddle.rgb, finalColor.rgb, facing);
#endif
diff --git a/source/blender/draw/modes/shaders/object_grid_frag.glsl b/source/blender/draw/modes/shaders/object_grid_frag.glsl
index 841b4a95b21..df2cfe7be82 100644
--- a/source/blender/draw/modes/shaders/object_grid_frag.glsl
+++ b/source/blender/draw/modes/shaders/object_grid_frag.glsl
@@ -40,8 +40,8 @@ uniform int gridFlag;
* 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.
+ * 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.
*/
#define DISC_RADIUS (M_1_SQRTPI * 1.05)
#define GRID_LINE_SMOOTH_START (0.5 - DISC_RADIUS)
diff --git a/source/blender/draw/modes/shaders/particle_strand_vert.glsl b/source/blender/draw/modes/shaders/particle_strand_vert.glsl
index 745499800e5..6dac6d6b980 100644
--- a/source/blender/draw/modes/shaders/particle_strand_vert.glsl
+++ b/source/blender/draw/modes/shaders/particle_strand_vert.glsl
@@ -45,14 +45,12 @@ vec3 weight_to_rgb(float weight)
return r_rgb;
}
-#define DECOMPRESS_RANGE 1.0039
-
void main()
{
gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
#ifdef USE_WEIGHT
- finalColor = vec4(weight_to_rgb(color * DECOMPRESS_RANGE), 1.0);
+ finalColor = vec4(weight_to_rgb(color), 1.0);
#else
finalColor = mix(colorWire, colorEdgeSelect, color);
#endif
diff --git a/source/blender/draw/modes/shaders/sculpt_mask_vert.glsl b/source/blender/draw/modes/shaders/sculpt_mask_vert.glsl
index 5ae97ec5cb9..e5e34fee57e 100644
--- a/source/blender/draw/modes/shaders/sculpt_mask_vert.glsl
+++ b/source/blender/draw/modes/shaders/sculpt_mask_vert.glsl
@@ -1,5 +1,6 @@
uniform mat4 ModelViewProjectionMatrix;
+uniform float maskOpacity;
in vec3 pos;
in float msk;
@@ -10,6 +11,6 @@ void main()
{
gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
- float mask = 1.0 - msk * 0.75;
+ float mask = 1.0 - (msk * maskOpacity);
finalColor = vec4(mask, mask, mask, 1.0);
}