Fix #103244: ghosting in Eevee with sculpt paint brush and canvas #104557

Open
Colin Marmond wants to merge 9 commits from Kdaf/blender:fix-103244-sculpt-lighting-using-paint-brush-on-image into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
5 changed files with 18 additions and 8 deletions
Showing only changes of commit 6e7e0de091 - Show all commits

View File

@ -254,7 +254,8 @@ int EEVEE_temporal_sampling_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data
const DRWContextState *draw_ctx = DRW_context_state_get();
const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
Review

This should be hidden in DRW_state_is_navigating or a similar function. Not sure yet if we need to split DRW_state_is_navigating... Best to ask direction in the eevee-viewport-module on blender.chat.

This should be hidden in `DRW_state_is_navigating` or a similar function. Not sure yet if we need to split DRW_state_is_navigating... Best to ask direction in the eevee-viewport-module on blender.chat.
if ((scene_eval->eevee.taa_samples != 1) || DRW_state_is_image_render()) {
if (((scene_eval->eevee.taa_samples != 1) || DRW_state_is_image_render()) &&
!(draw_ctx->region->do_draw & RGN_DRAW_SINGLE_SAMPLE)) {
float persmat[4][4];
if (!DRW_state_is_image_render() && (scene_eval->eevee.flag & SCE_EEVEE_TAA_REPROJECTION)) {

View File

@ -71,6 +71,7 @@ void ED_region_update_rect(struct ARegion *region);
*/
void ED_region_floating_init(struct ARegion *region);
void ED_region_tag_redraw(struct ARegion *region);
void ED_region_tag_redraw_force_single_sample(struct ARegion *region);
void ED_region_tag_redraw_partial(struct ARegion *region, const struct rcti *rct, bool rebuild);
void ED_region_tag_redraw_cursor(struct ARegion *region);
void ED_region_tag_redraw_no_rebuild(struct ARegion *region);

View File

@ -658,12 +658,21 @@ void ED_region_tag_redraw(ARegion *region)
* but python scripts can cause this to happen indirectly */
if (region && !(region->do_draw & RGN_DRAWING)) {
/* zero region means full region redraw */
region->do_draw &= ~(RGN_DRAW_PARTIAL | RGN_DRAW_NO_REBUILD | RGN_DRAW_EDITOR_OVERLAYS);
region->do_draw &= ~(RGN_DRAW_PARTIAL | RGN_DRAW_NO_REBUILD | RGN_DRAW_EDITOR_OVERLAYS |
RGN_DRAW_SINGLE_SAMPLE);
region->do_draw |= RGN_DRAW;
memset(&region->drawrct, 0, sizeof(region->drawrct));
}
}
void ED_region_tag_redraw_force_single_sample(ARegion *region)
{
if (region && !(region->do_draw & RGN_DRAWING)) {
ED_region_tag_redraw(region);
region->do_draw |= RGN_DRAW_SINGLE_SAMPLE;
}
}
void ED_region_tag_redraw_cursor(ARegion *region)
{
if (region) {
@ -674,7 +683,7 @@ void ED_region_tag_redraw_cursor(ARegion *region)
void ED_region_tag_redraw_no_rebuild(ARegion *region)
{
if (region && !(region->do_draw & (RGN_DRAWING | RGN_DRAW))) {
region->do_draw &= ~(RGN_DRAW_PARTIAL | RGN_DRAW_EDITOR_OVERLAYS);
region->do_draw &= ~(RGN_DRAW_PARTIAL | RGN_DRAW_EDITOR_OVERLAYS | RGN_DRAW_SINGLE_SAMPLE);
region->do_draw |= RGN_DRAW_NO_REBUILD;
memset(&region->drawrct, 0, sizeof(region->drawrct));
}

View File

@ -5379,12 +5379,8 @@ void SCULPT_flush_update_step(bContext *C, SculptUpdateType update_flags)
}
if ((update_flags & SCULPT_UPDATE_IMAGE) != 0) {
ED_region_tag_redraw(region);
ED_region_tag_redraw_force_single_sample(region);
if (update_flags == SCULPT_UPDATE_IMAGE) {
if (ELEM(v3d->shading.type, OB_MATERIAL, OB_TEXTURE, OB_RENDER)) {
/* When multisampling is activated, this should prevent from ghosting */
DEG_id_tag_update(&ob->id, ID_RECALC_SHADING);
}
/* Early exit when only need to update the images. We don't want to tag any geometry updates
Kdaf marked this conversation as resolved
Review

I see what you're doing and why you have chosen this solution. I did have something else in mind to fix this, what doesn't need re-evaluating materials, shaders etc.

When the user is painting (Paint model operator is active) eevee should only use a single sample.
When the user finishes the stroke the rest of the samples can be calculated.

The ghosting effect appears as previous samples might have different colors. Blending multiple samples together leads to the ghosting. By just drawing a single sample we can make sure ghosting isn't working.

Although the final result is the same, I expect it to be lighter on the painting pipeline and improves the performance when using larger textures and complexer shaders.

We should prototype the other approach and see which one would be better in terms of performance and maintencance.

I see what you're doing and why you have chosen this solution. I did have something else in mind to fix this, what doesn't need re-evaluating materials, shaders etc. When the user is painting (Paint model operator is active) eevee should only use a single sample. When the user finishes the stroke the rest of the samples can be calculated. The ghosting effect appears as previous samples might have different colors. Blending multiple samples together leads to the ghosting. By just drawing a single sample we can make sure ghosting isn't working. Although the final result is the same, I expect it to be lighter on the painting pipeline and improves the performance when using larger textures and complexer shaders. We should prototype the other approach and see which one would be better in terms of performance and maintencance.
* that would rebuilt the PBVH. */
return;

View File

@ -742,6 +742,9 @@ enum {
/* Only editor overlays (currently gizmos only!) should be redrawn. */
RGN_DRAW_EDITOR_OVERLAYS = 32,
/* Force single sample for some specific cases (sculpt paint tool stroke). */
RGN_DRAW_SINGLE_SAMPLE = 64,
};
#ifdef __cplusplus