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:
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)
|
@ -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()
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue