Fix T102519: GPU Subdivision : selected vertices not visible in paint mode

Retrieve and load the vertices selected/hidden state in pos_nor extraction.

Reviewed By: fclem

Maniphest Tasks: T102519

Differential Revision: https://developer.blender.org/D16594
This commit is contained in:
Miguel Pozo 2022-11-29 21:05:14 +01:00
parent 412fdc9698
commit 6c4c09b2df
Notes: blender-bot 2023-02-14 03:21:27 +01:00
Referenced by issue #102519, GPU subdivision: vertex paintmask: vertices (or their selection status) not visible in weightpaint/vertexpaint
5 changed files with 60 additions and 6 deletions

View File

@ -1408,6 +1408,7 @@ static void drw_subdiv_compute_dispatch(const DRWSubdivCache *cache,
}
void draw_subdiv_extract_pos_nor(const DRWSubdivCache *cache,
GPUVertBuf *flags_buffer,
GPUVertBuf *pos_nor,
GPUVertBuf *orco)
{
@ -1460,6 +1461,10 @@ void draw_subdiv_extract_pos_nor(const DRWSubdivCache *cache,
GPU_vertbuf_bind_as_ssbo(patch_arrays_buffer, binding_point++);
GPU_vertbuf_bind_as_ssbo(patch_index_buffer, binding_point++);
GPU_vertbuf_bind_as_ssbo(patch_param_buffer, binding_point++);
if (flags_buffer) {
GPU_vertbuf_bind_as_ssbo(flags_buffer, binding_point);
}
binding_point++;
GPU_vertbuf_bind_as_ssbo(pos_nor, binding_point++);
if (orco) {
GPU_vertbuf_bind_as_ssbo(src_extra_buffer, binding_point++);

View File

@ -242,6 +242,7 @@ void draw_subdiv_finalize_custom_normals(const DRWSubdivCache *cache,
GPUVertBuf *pos_nor);
void draw_subdiv_extract_pos_nor(const DRWSubdivCache *cache,
GPUVertBuf *flags_buffer,
struct GPUVertBuf *pos_nor,
struct GPUVertBuf *orco);

View File

@ -236,7 +236,7 @@ static void extract_edituv_stretch_angle_init_subdiv(const DRWSubdivCache *subdi
draw_subdiv_get_pos_nor_format(),
subdiv_cache->num_subdiv_loops + loose_geom.loop_len);
draw_subdiv_extract_pos_nor(subdiv_cache, pos_nor, nullptr);
draw_subdiv_extract_pos_nor(subdiv_cache, nullptr, pos_nor, nullptr);
}
/* UVs are stored contiguously so we need to compute the offset in the UVs buffer for the active

View File

@ -200,8 +200,26 @@ static GPUVertFormat *get_custom_normals_format()
return &format;
}
static void extract_vertex_flags(const MeshRenderData *mr, char *flags)
{
for (int i = 0; i < mr->vert_len; i++) {
char *flag = &flags[i];
const bool vert_hidden = mr->hide_vert && mr->hide_vert[i];
/* Flag for paint mode overlay. */
if (vert_hidden || ((mr->v_origindex) && (mr->v_origindex[i] == ORIGINDEX_NONE))) {
*flag = -1;
}
else if (mr->select_vert && mr->select_vert[i]) {
*flag = 1;
}
else {
*flag = 0;
}
}
}
static void extract_pos_nor_init_subdiv(const DRWSubdivCache *subdiv_cache,
const MeshRenderData * /*mr*/,
const MeshRenderData *mr,
MeshBatchCache *cache,
void *buffer,
void * /*data*/)
@ -217,6 +235,17 @@ static void extract_pos_nor_init_subdiv(const DRWSubdivCache *subdiv_cache,
return;
}
GPUVertBuf *flags_buffer = GPU_vertbuf_calloc();
static GPUVertFormat flag_format = {0};
if (flag_format.attr_len == 0) {
GPU_vertformat_attr_add(&flag_format, "flag", GPU_COMP_I32, 1, GPU_FETCH_INT);
}
GPU_vertbuf_init_with_format(flags_buffer, &flag_format);
GPU_vertbuf_data_alloc(flags_buffer, divide_ceil_u(mr->vert_len, 4));
char *flags = static_cast<char *>(GPU_vertbuf_get_data(flags_buffer));
extract_vertex_flags(mr, flags);
GPU_vertbuf_tag_dirty(flags_buffer);
GPUVertBuf *orco_vbo = cache->final.buff.vbo.orco;
if (orco_vbo) {
@ -231,7 +260,7 @@ static void extract_pos_nor_init_subdiv(const DRWSubdivCache *subdiv_cache,
GPU_vertbuf_init_build_on_device(orco_vbo, &format, subdiv_cache->num_subdiv_loops);
}
draw_subdiv_extract_pos_nor(subdiv_cache, vbo, orco_vbo);
draw_subdiv_extract_pos_nor(subdiv_cache, flags_buffer, vbo, orco_vbo);
if (subdiv_cache->use_custom_loop_normals) {
Mesh *coarse_mesh = subdiv_cache->mesh;
@ -279,6 +308,8 @@ static void extract_pos_nor_init_subdiv(const DRWSubdivCache *subdiv_cache,
GPU_vertbuf_discard(vertex_normals);
GPU_vertbuf_discard(subdiv_loop_subdiv_vert_index);
}
GPU_vertbuf_discard(flags_buffer);
}
static void extract_pos_nor_loose_geom_subdiv(const DRWSubdivCache *subdiv_cache,

View File

@ -87,16 +87,30 @@ layout(std430, binding = 11) readonly buffer extraCoarseFaceData
uint extra_coarse_face_data[];
};
#else
layout(std430, binding = 8) writeonly buffer outputVertexData
layout(std430, binding = 8) readonly buffer inputFlagsBuffer
{
int flags_buffer[]; /*char*/
};
float get_flag(int vertex)
{
int char4 = flags_buffer[vertex / 4];
int flag = (char4 >> ((vertex % 4) * 8)) & 0xFF;
if (flag >= 128) {
flag = -128 + (flag - 128);
}
return float(flag);
}
layout(std430, binding = 9) writeonly buffer outputVertexData
{
PosNorLoop output_verts[];
};
# if defined(ORCO_EVALUATION)
layout(std430, binding = 9) buffer src_extra_buffer
layout(std430, binding = 10) buffer src_extra_buffer
{
float srcExtraVertexBuffer[];
};
layout(std430, binding = 10) writeonly buffer outputOrcoData
layout(std430, binding = 11) writeonly buffer outputOrcoData
{
vec4 output_orcos[];
};
@ -463,6 +477,9 @@ void main()
if (origindex == -1) {
flag = -1.0;
}
else {
flag = get_flag(origindex);
}
PosNorLoop vertex_data;
set_vertex_pos(vertex_data, pos);