Texture Paint: Add filtering option for texture paint overlay

The overlay should now use the texture interpolation setting in material
mode.

In image mode, there is now a new button to let the user choose the texture
filter. The option is located in the Texture Slots popover and only shows
in Image mode.
This commit is contained in:
Clément Foucault 2018-12-23 16:26:21 +01:00
parent 9177bb33f6
commit b98e6743dc
Notes: blender-bot 2023-02-14 08:38:14 +01:00
Referenced by issue #69106, White outline around alpha in texture paint (when using multiple layers)
7 changed files with 45 additions and 6 deletions

View File

@ -511,6 +511,8 @@ class VIEW3D_PT_slots_projectpaint(View3DPanel, Panel):
layout.menu("VIEW3D_MT_tools_projectpaint_uvlayer", text=uv_text, translate=False)
have_image = settings.canvas is not None
layout.prop(settings, "interpolation", text="")
if settings.missing_uvs:
layout.separator()
split = layout.split()

View File

@ -1063,7 +1063,9 @@ static void fill_texpaint_slots_recursive(bNodeTree *nodetree, bNode *active_nod
if (active_node == node) {
ma->paint_active_slot = *index;
}
ma->texpaintslot[*index].ima = (Image *)node->id;
ma->texpaintslot[*index].interp = ((NodeTexImage *)node->storage)->interpolation;
/* for new renderer, we need to traverse the treeback in search of a UV node */
bNode *uvnode = nodetree_uv_node_recursive(node);

View File

@ -28,6 +28,8 @@
#include "BIF_gl.h"
#include "BKE_node.h"
/* If builtin shaders are needed */
#include "GPU_shader.h"
#include "GPU_texture.h"
@ -139,8 +141,6 @@ static void PAINT_TEXTURE_engine_init(void *UNUSED(vedata))
if (!e_data.fallback_sh) {
e_data.fallback_sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR);
e_data.image_sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR);
e_data.image_sh = DRW_shader_create_with_lib(
datatoc_paint_texture_vert_glsl, NULL,
datatoc_paint_texture_frag_glsl,
@ -189,7 +189,8 @@ static void PAINT_TEXTURE_cache_init(void *vedata)
Object *ob = draw_ctx->obact;
if (ob && ob->type == OB_MESH) {
Scene *scene = draw_ctx->scene;
const bool use_material_slots = (scene->toolsettings->imapaint.mode == IMAGEPAINT_MODE_MATERIAL);
const ImagePaintSettings *imapaint = &scene->toolsettings->imapaint;
const bool use_material_slots = (imapaint->mode == IMAGEPAINT_MODE_MATERIAL);
const Mesh *me = ob->data;
const int mat_nr = max_ii(1, me->totcol);
@ -200,6 +201,7 @@ static void PAINT_TEXTURE_cache_init(void *vedata)
for (int i = 0; i < mat_nr; i++) {
Material *ma = give_current_material(ob, i + 1);
Image *ima = (ma && ma->texpaintslot) ? ma->texpaintslot[ma->paint_active_slot].ima : NULL;
int interp = (ma && ma->texpaintslot) ? ma->texpaintslot[ma->paint_active_slot].interp : 0;
GPUTexture *tex = ima ?
GPU_texture_from_blender(ima, NULL, GL_TEXTURE_2D, false, 0.0f) : NULL;
@ -208,6 +210,7 @@ static void PAINT_TEXTURE_cache_init(void *vedata)
DRW_shgroup_uniform_texture(grp, "image", tex);
DRW_shgroup_uniform_float(grp, "alpha", &draw_ctx->v3d->overlay.texture_paint_mode_opacity, 1);
DRW_shgroup_uniform_block(grp, "globalsBlock", globals_ubo);
DRW_shgroup_uniform_bool_copy(grp, "nearestInterp", interp == SHD_INTERP_CLOSEST);
stl->g_data->shgroup_image_array[i] = grp;
}
else {
@ -216,7 +219,7 @@ static void PAINT_TEXTURE_cache_init(void *vedata)
}
}
else {
Image *ima = scene->toolsettings->imapaint.canvas;
Image *ima = imapaint->canvas;
GPUTexture *tex = ima ?
GPU_texture_from_blender(ima, NULL, GL_TEXTURE_2D, false, 0.0f) : NULL;
@ -225,6 +228,7 @@ static void PAINT_TEXTURE_cache_init(void *vedata)
DRW_shgroup_uniform_texture(grp, "image", tex);
DRW_shgroup_uniform_float(grp, "alpha", &draw_ctx->v3d->overlay.texture_paint_mode_opacity, 1);
DRW_shgroup_uniform_block(grp, "globalsBlock", globals_ubo);
DRW_shgroup_uniform_bool_copy(grp, "nearestInterp", imapaint->interp == IMAGEPAINT_INTERP_CLOSEST);
stl->g_data->shgroup_image_array[0] = grp;
}
else {

View File

@ -4,8 +4,14 @@ out vec4 fragColor;
uniform sampler2D image;
uniform float alpha = 1.0;
uniform bool nearestInterp;
void main()
{
fragColor = vec4(texture(image, uv_interp).rgb, alpha);
vec2 uv = uv_interp;
if (nearestInterp) {
vec2 tex_size = vec2(textureSize(image, 0).xy);
uv = (floor(uv_interp * tex_size) + 0.5) / tex_size;
}
fragColor = vec4(texture(image, uv).rgb, alpha);
}

View File

@ -54,7 +54,8 @@ typedef struct TexPaintSlot {
char *uvname;
/** Do we have a valid image and UV map. */
int valid;
int pad;
/** Copy of node inteporlation setting. */
int interp;
} TexPaintSlot;
typedef struct MaterialGPencilStyle {

View File

@ -923,6 +923,9 @@ typedef struct ImagePaintSettings {
float stencil_col[3];
/** Dither amount used when painting on byte images. */
float dither;
/** Display texture interpolation method. */
int interp;
int pad;
} ImagePaintSettings;
/* ------------------------------------------- */
@ -2207,6 +2210,12 @@ typedef enum eImagePaintMode {
IMAGEPAINT_MODE_IMAGE, /* select texture paint image directly */
} eImagePaintMode;
/* ImagePaintSettings.interp */
enum {
IMAGEPAINT_INTERP_LINEAR = 0,
IMAGEPAINT_INTERP_CLOSEST,
};
/* ImagePaintSettings.flag */
#define IMAGEPAINT_DRAWING (1 << 0)
// #define IMAGEPAINT_DRAW_TOOL (1 << 1) // deprecated

View File

@ -872,6 +872,14 @@ static void rna_def_image_paint(BlenderRNA *brna)
{0, NULL, 0, NULL, NULL}
};
static const EnumPropertyItem paint_interp_items[] = {
{IMAGEPAINT_INTERP_LINEAR, "LINEAR", 0,
"Linear", "Linear interpolation"},
{IMAGEPAINT_INTERP_CLOSEST, "CLOSEST", 0,
"Closest", "No interpolation (sample closest texel)"},
{0, NULL, 0, NULL, NULL}
};
srna = RNA_def_struct(brna, "ImagePaint", "Paint");
RNA_def_struct_sdna(srna, "ImagePaintSettings");
RNA_def_struct_path_func(srna, "rna_ImagePaintSettings_path");
@ -964,6 +972,13 @@ static void rna_def_image_paint(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Mode", "Mode of operation for projection painting");
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, "rna_ImaPaint_mode_update");
prop = RNA_def_property(srna, "interpolation", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "interp");
RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_enum_items(prop, paint_interp_items);
RNA_def_property_ui_text(prop, "Interpolation", "Texture filtering type");
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, "rna_ImaPaint_mode_update");
/* Missing data */
prop = RNA_def_property(srna, "missing_uvs", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "missing_data", IMAGEPAINT_MISSING_UVS);