Fix T98526: broken corner attributes with GPU subdivision

Although reusing the same patch coordinate for all corner pointing the
same vertex works for interpolation vertices, it does work for
interpolation face varying attributes. So we need to keep the original
patch coordinates around for face varying interpolation. This was caused
by the previous fix (a5dcae0c64).
This commit is contained in:
Kévin Dietrich 2022-06-01 07:02:05 +02:00
parent 65e7d49939
commit 54d076b20d
Notes: blender-bot 2023-02-13 22:20:49 +01:00
Referenced by issue #98526, Regression: GPU Subdivision Surface Produces Artifacts
2 changed files with 17 additions and 3 deletions

View File

@ -563,6 +563,7 @@ static void draw_subdiv_free_edit_mode_cache(DRWSubdivCache *cache)
void draw_subdiv_cache_free(DRWSubdivCache *cache)
{
GPU_VERTBUF_DISCARD_SAFE(cache->patch_coords);
GPU_VERTBUF_DISCARD_SAFE(cache->corner_patch_coords);
GPU_VERTBUF_DISCARD_SAFE(cache->face_ptex_offset_buffer);
GPU_VERTBUF_DISCARD_SAFE(cache->subdiv_polygon_offset_buffer);
GPU_VERTBUF_DISCARD_SAFE(cache->extra_coarse_face_data);
@ -805,6 +806,11 @@ static bool draw_subdiv_topology_info_cb(const SubdivForeachContext *foreach_con
cache->patch_coords, get_blender_patch_coords_format(), GPU_USAGE_DYNAMIC);
GPU_vertbuf_data_alloc(cache->patch_coords, cache->num_subdiv_loops);
cache->corner_patch_coords = GPU_vertbuf_calloc();
GPU_vertbuf_init_with_format_ex(
cache->corner_patch_coords, get_blender_patch_coords_format(), GPU_USAGE_DYNAMIC);
GPU_vertbuf_data_alloc(cache->corner_patch_coords, cache->num_subdiv_loops);
cache->verts_orig_index = GPU_vertbuf_calloc();
GPU_vertbuf_init_with_format_ex(
cache->verts_orig_index, get_origindex_format(), GPU_USAGE_DYNAMIC);
@ -1100,6 +1106,12 @@ static bool draw_subdiv_build_cache(DRWSubdivCache *cache,
* the mesh to not be watertight, leading to shadowing artifacts (see T97877). */
blender::Vector<int> first_loop_index(cache->num_subdiv_verts, -1);
/* Save coordinates for corners, as attributes may vary for each loop connected to the same
* vertex. */
memcpy(GPU_vertbuf_get_data(cache->corner_patch_coords),
cache_building_context.patch_coords,
sizeof(CompressedPatchCoord) * cache->num_subdiv_loops);
for (int i = 0; i < cache->num_subdiv_loops; i++) {
const int vertex = cache_building_context.subdiv_loop_subdiv_vert_index[i];
if (first_loop_index[vertex] != -1) {
@ -1379,7 +1391,7 @@ void draw_subdiv_extract_uvs(const DRWSubdivCache *cache,
GPU_vertbuf_bind_as_ssbo(src_buffer, binding_point++);
GPU_vertbuf_bind_as_ssbo(cache->gpu_patch_map.patch_map_handles, binding_point++);
GPU_vertbuf_bind_as_ssbo(cache->gpu_patch_map.patch_map_quadtree, binding_point++);
GPU_vertbuf_bind_as_ssbo(cache->patch_coords, binding_point++);
GPU_vertbuf_bind_as_ssbo(cache->corner_patch_coords, binding_point++);
GPU_vertbuf_bind_as_ssbo(cache->verts_orig_index, binding_point++);
GPU_vertbuf_bind_as_ssbo(patch_arrays_buffer, binding_point++);
GPU_vertbuf_bind_as_ssbo(patch_index_buffer, binding_point++);
@ -1454,7 +1466,7 @@ void draw_subdiv_interp_custom_data(const DRWSubdivCache *cache,
GPU_vertbuf_bind_as_ssbo(cache->subdiv_polygon_offset_buffer, binding_point++);
GPU_vertbuf_bind_as_ssbo(src_data, binding_point++);
GPU_vertbuf_bind_as_ssbo(cache->face_ptex_offset_buffer, binding_point++);
GPU_vertbuf_bind_as_ssbo(cache->patch_coords, binding_point++);
GPU_vertbuf_bind_as_ssbo(cache->corner_patch_coords, binding_point++);
GPU_vertbuf_bind_as_ssbo(cache->extra_coarse_face_data, binding_point++);
GPU_vertbuf_bind_as_ssbo(dst_data, binding_point++);
BLI_assert(binding_point <= MAX_GPU_SUBDIV_SSBOS);

View File

@ -104,8 +104,10 @@ typedef struct DRWSubdivCache {
bool optimal_display;
bool use_custom_loop_normals;
/* Coordinates used to evaluate patches for UVs, positions, and normals. */
/* Coordinates used to evaluate patches for positions and normals. */
struct GPUVertBuf *patch_coords;
/* Coordinates used to evaluate patches for attributes. */
struct GPUVertBuf *corner_patch_coords;
/* Coordinates used to evaluate patches for the face centers (or face dots) in edit-mode. */
struct GPUVertBuf *fdots_patch_coords;