diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index 4870c67254b..5e48316dade 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -49,6 +49,7 @@ set(SRC intern/mesh_extractors/extract_mesh_vbo_mesh_analysis.cc intern/mesh_extractors/extract_mesh_vbo_orco.cc intern/mesh_extractors/extract_mesh_vbo_pos.cc + intern/mesh_extractors/extract_mesh_vbo_paint_overlay_flag.cc intern/mesh_extractors/extract_mesh_vbo_sculpt_data.cc intern/mesh_extractors/extract_mesh_vbo_select_idx.cc intern/mesh_extractors/extract_mesh_vbo_skin_roots.cc @@ -541,12 +542,12 @@ set(GLSL_SRC intern/shaders/subdiv_ibo_tris_comp.glsl intern/shaders/subdiv_lib.glsl intern/shaders/subdiv_normals_accumulate_comp.glsl - intern/shaders/subdiv_normals_finalize_comp.glsl intern/shaders/subdiv_patch_evaluation_comp.glsl intern/shaders/subdiv_vbo_edge_fac_comp.glsl intern/shaders/subdiv_vbo_edituv_strech_angle_comp.glsl intern/shaders/subdiv_vbo_edituv_strech_area_comp.glsl intern/shaders/subdiv_vbo_lnor_comp.glsl + intern/shaders/subdiv_vbo_paint_overlay_flag_comp.glsl intern/shaders/subdiv_vbo_sculpt_data_comp.glsl intern/shaders/draw_aabb_lib.glsl intern/shaders/draw_colormanagement_lib.glsl diff --git a/source/blender/draw/engines/overlay/overlay_paint.hh b/source/blender/draw/engines/overlay/overlay_paint.hh index a2377256f2e..408140f10ab 100644 --- a/source/blender/draw/engines/overlay/overlay_paint.hh +++ b/source/blender/draw/engines/overlay/overlay_paint.hh @@ -233,16 +233,16 @@ class Paints : Overlay { const bool in_texture_paint_mode = state.ctx_mode == CTX_MODE_PAINT_TEXTURE; if ((use_face_selection || show_wires_) && !in_texture_paint_mode) { - gpu::Batch *geom = DRW_cache_mesh_surface_edges_get(ob_ref.object); + gpu::Batch *geom = DRW_cache_mesh_paint_overlay_edges_get(ob_ref.object); paint_region_edge_ps_->push_constant("use_select", use_face_selection); paint_region_edge_ps_->draw(geom, manager.unique_handle(ob_ref)); } if (use_face_selection) { - gpu::Batch *geom = DRW_cache_mesh_surface_get(ob_ref.object); + gpu::Batch *geom = DRW_cache_mesh_paint_overlay_surface_get(ob_ref.object); paint_region_face_ps_->draw(geom, manager.unique_handle(ob_ref)); } if (use_vert_selection && !in_texture_paint_mode) { - gpu::Batch *geom = DRW_cache_mesh_all_verts_get(ob_ref.object); + gpu::Batch *geom = DRW_cache_mesh_paint_overlay_verts_get(ob_ref.object); paint_region_vert_ps_->draw(geom, manager.unique_handle(ob_ref)); } } diff --git a/source/blender/draw/engines/overlay/shaders/infos/overlay_paint_info.hh b/source/blender/draw/engines/overlay/shaders/infos/overlay_paint_info.hh index cb724006073..d3f7ec9a652 100644 --- a/source/blender/draw/engines/overlay/shaders/infos/overlay_paint_info.hh +++ b/source/blender/draw/engines/overlay/shaders/infos/overlay_paint_info.hh @@ -21,7 +21,7 @@ GPU_SHADER_CREATE_INFO(overlay_paint_face) DO_STATIC_COMPILATION() VERTEX_IN(0, float3, pos) -VERTEX_IN(1, float4, nor) /* Select flag on the 4th component. */ +VERTEX_IN(1, int, paint_overlay_flag) PUSH_CONSTANT(float4, ucolor) FRAGMENT_OUT(0, float4, frag_color) VERTEX_SOURCE("overlay_paint_face_vert.glsl") @@ -48,7 +48,7 @@ GPU_SHADER_INTERFACE_END() GPU_SHADER_CREATE_INFO(overlay_paint_point) DO_STATIC_COMPILATION() VERTEX_IN(0, float3, pos) -VERTEX_IN(1, float4, nor) /* Select flag on the 4th component. */ +VERTEX_IN(1, int, paint_overlay_flag) VERTEX_OUT(overlay_overlay_paint_point_iface) FRAGMENT_OUT(0, float4, frag_color) VERTEX_SOURCE("overlay_paint_point_vert.glsl") @@ -151,7 +151,7 @@ GPU_SHADER_INTERFACE_END() GPU_SHADER_CREATE_INFO(overlay_paint_wire) DO_STATIC_COMPILATION() VERTEX_IN(0, float3, pos) -VERTEX_IN(1, float4, nor) /* flag stored in w */ +VERTEX_IN(1, int, paint_overlay_flag) VERTEX_OUT(overlay_paint_wire_iface) PUSH_CONSTANT(bool, use_select) FRAGMENT_OUT(0, float4, frag_color) diff --git a/source/blender/draw/engines/overlay/shaders/overlay_paint_face_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_paint_face_vert.glsl index 6a6d4349b06..96c730e8eaf 100644 --- a/source/blender/draw/engines/overlay/shaders/overlay_paint_face_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_paint_face_vert.glsl @@ -20,8 +20,8 @@ void main() gl_Position.z -= 5e-5f; #endif - bool is_select = (nor.w > 0.0f); - bool is_hidden = (nor.w < 0.0f); + bool is_select = (paint_overlay_flag > 0); + bool is_hidden = (paint_overlay_flag < 0); /* Don't draw faces that are selected. */ if (is_hidden || is_select) { diff --git a/source/blender/draw/engines/overlay/shaders/overlay_paint_point_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_paint_point_vert.glsl index 9a3ab137bd1..92008e3bc85 100644 --- a/source/blender/draw/engines/overlay/shaders/overlay_paint_point_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_paint_point_vert.glsl @@ -12,8 +12,8 @@ VERTEX_SHADER_CREATE_INFO(overlay_paint_point) void main() { - bool is_select = (nor.w > 0.0f); - bool is_hidden = (nor.w < 0.0f); + bool is_select = (paint_overlay_flag > 0); + bool is_hidden = (paint_overlay_flag < 0); float3 world_pos = drw_point_object_to_world(pos); gl_Position = drw_point_world_to_homogenous(world_pos); @@ -26,7 +26,7 @@ void main() } final_color = (is_select) ? float4(1.0f) : theme.colors.wire; - final_color.a = nor.w; + final_color.a = float(paint_overlay_flag); gl_PointSize = theme.sizes.vert * 2.0f; diff --git a/source/blender/draw/engines/overlay/shaders/overlay_paint_wire_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_paint_wire_vert.glsl index 170c2b5dcaf..7bec1db8372 100644 --- a/source/blender/draw/engines/overlay/shaders/overlay_paint_wire_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_paint_wire_vert.glsl @@ -12,8 +12,8 @@ VERTEX_SHADER_CREATE_INFO(overlay_paint_wire) void main() { - bool is_select = (nor.w > 0.0f) && use_select; - bool is_hidden = (nor.w < 0.0f) && use_select; + bool is_select = (paint_overlay_flag > 0) && use_select; + bool is_hidden = (paint_overlay_flag < 0) && use_select; float3 world_pos = drw_point_object_to_world(pos); gl_Position = drw_point_world_to_homogenous(world_pos); diff --git a/source/blender/draw/intern/draw_cache.cc b/source/blender/draw/intern/draw_cache.cc index d772dbe5d9a..f681f901d1a 100644 --- a/source/blender/draw/intern/draw_cache.cc +++ b/source/blender/draw/intern/draw_cache.cc @@ -167,6 +167,12 @@ gpu::Batch *DRW_cache_mesh_all_verts_get(Object *ob) return DRW_mesh_batch_cache_get_all_verts(DRW_object_get_data_for_drawing(*ob)); } +gpu::Batch *DRW_cache_mesh_paint_overlay_verts_get(Object *ob) +{ + BLI_assert(ob->type == OB_MESH); + return DRW_mesh_batch_cache_get_paint_overlay_verts(DRW_object_get_data_for_drawing(*ob)); +} + gpu::Batch *DRW_cache_mesh_all_edges_get(Object *ob) { BLI_assert(ob->type == OB_MESH); @@ -192,10 +198,17 @@ gpu::Batch *DRW_cache_mesh_surface_get(Object *ob) return DRW_mesh_batch_cache_get_surface(DRW_object_get_data_for_drawing(*ob)); } -gpu::Batch *DRW_cache_mesh_surface_edges_get(Object *ob) +gpu::Batch *DRW_cache_mesh_paint_overlay_surface_get(Object *ob) { BLI_assert(ob->type == OB_MESH); - return DRW_mesh_batch_cache_get_surface_edges(DRW_object_get_data_for_drawing(*ob)); + return DRW_mesh_batch_cache_get_paint_overlay_surface( + DRW_object_get_data_for_drawing(*ob)); +} + +gpu::Batch *DRW_cache_mesh_paint_overlay_edges_get(Object *ob) +{ + BLI_assert(ob->type == OB_MESH); + return DRW_mesh_batch_cache_get_paint_overlay_edges(DRW_object_get_data_for_drawing(*ob)); } Span DRW_cache_mesh_surface_shaded_get(Object *ob, diff --git a/source/blender/draw/intern/draw_cache.hh b/source/blender/draw/intern/draw_cache.hh index 32e78769723..38f1d80d482 100644 --- a/source/blender/draw/intern/draw_cache.hh +++ b/source/blender/draw/intern/draw_cache.hh @@ -52,11 +52,13 @@ gpu::Batch *DRW_cache_object_face_wireframe_get(const Scene *scene, Object *ob); /* Meshes */ gpu::Batch *DRW_cache_mesh_all_verts_get(Object *ob); +gpu::Batch *DRW_cache_mesh_paint_overlay_verts_get(Object *ob); gpu::Batch *DRW_cache_mesh_all_edges_get(Object *ob); gpu::Batch *DRW_cache_mesh_loose_edges_get(Object *ob); gpu::Batch *DRW_cache_mesh_edge_detection_get(Object *ob, bool *r_is_manifold); gpu::Batch *DRW_cache_mesh_surface_get(Object *ob); -gpu::Batch *DRW_cache_mesh_surface_edges_get(Object *ob); +gpu::Batch *DRW_cache_mesh_paint_overlay_surface_get(Object *ob); +gpu::Batch *DRW_cache_mesh_paint_overlay_edges_get(Object *ob); /** * Return list of batches with length equal to `max(1, totcol)`. */ diff --git a/source/blender/draw/intern/draw_cache_extract.hh b/source/blender/draw/intern/draw_cache_extract.hh index 5d34b5cb7d8..5d3df2bbdaa 100644 --- a/source/blender/draw/intern/draw_cache_extract.hh +++ b/source/blender/draw/intern/draw_cache_extract.hh @@ -109,6 +109,7 @@ enum class VBOType : int8_t { Attr15, AttrViewer, VertexNormal, + PaintOverlayFlag, }; /** @@ -177,12 +178,13 @@ struct MeshBatchList { /* Individual edges with face normals. */ gpu::Batch *wire_edges; /* Loops around faces. no edges between selected faces */ - gpu::Batch *wire_loops; - /* Same as wire_loops but only has uvs. */ + gpu::Batch *paint_overlay_wire_loops; gpu::Batch *wire_loops_uvs; gpu::Batch *wire_loops_edituvs; gpu::Batch *sculpt_overlays; gpu::Batch *surface_viewer_attribute; + gpu::Batch *paint_overlay_verts; + gpu::Batch *paint_overlay_surface; }; #define MBC_BATCH_LEN (sizeof(MeshBatchList) / sizeof(void *)) @@ -216,12 +218,14 @@ enum DRWBatchFlag : uint64_t { MBC_LOOSE_EDGES = (1u << MBC_BATCH_INDEX(loose_edges)), MBC_EDGE_DETECTION = (1u << MBC_BATCH_INDEX(edge_detection)), MBC_WIRE_EDGES = (1u << MBC_BATCH_INDEX(wire_edges)), - MBC_WIRE_LOOPS = (1u << MBC_BATCH_INDEX(wire_loops)), + MBC_PAINT_OVERLAY_WIRE_LOOPS = (1u << MBC_BATCH_INDEX(paint_overlay_wire_loops)), MBC_WIRE_LOOPS_UVS = (1u << MBC_BATCH_INDEX(wire_loops_uvs)), MBC_WIRE_LOOPS_EDITUVS = (1u << MBC_BATCH_INDEX(wire_loops_edituvs)), MBC_SCULPT_OVERLAYS = (1u << MBC_BATCH_INDEX(sculpt_overlays)), MBC_VIEWER_ATTRIBUTE_OVERLAY = (1u << MBC_BATCH_INDEX(surface_viewer_attribute)), - MBC_SURFACE_PER_MAT = (1u << MBC_BATCH_LEN), + MBC_PAINT_OVERLAY_VERTS = (1u << MBC_BATCH_INDEX(paint_overlay_verts)), + MBC_PAINT_OVERLAY_SURFACE = (uint64_t(1u) << MBC_BATCH_INDEX(paint_overlay_surface)), + MBC_SURFACE_PER_MAT = (uint64_t(1u) << MBC_BATCH_LEN), }; ENUM_OPERATORS(DRWBatchFlag, MBC_SURFACE_PER_MAT); diff --git a/source/blender/draw/intern/draw_cache_extract_mesh.cc b/source/blender/draw/intern/draw_cache_extract_mesh.cc index ade567d2a5b..20c0b5f1c99 100644 --- a/source/blender/draw/intern/draw_cache_extract_mesh.cc +++ b/source/blender/draw/intern/draw_cache_extract_mesh.cc @@ -275,6 +275,9 @@ void mesh_buffer_cache_create_requested(TaskGraph & /*task_graph*/, case VBOType::VertexNormal: created_vbos[i] = extract_vert_normals(mr); break; + case VBOType::PaintOverlayFlag: + created_vbos[i] = extract_paint_overlay_flags(mr); + break; } }); @@ -411,6 +414,10 @@ void mesh_buffer_cache_create_requested_subdiv(MeshBatchCache &cache, buffers.ibos.add_new(IBOType::FaceDots, std::move(face_dot_ibo)); } } + if (vbos_to_create.contains(VBOType::PaintOverlayFlag)) { + buffers.vbos.add_new(VBOType::PaintOverlayFlag, + extract_paint_overlay_flags_subdiv(mr, subdiv_cache)); + } if (ibos_to_create.contains(IBOType::LinesPaintMask)) { buffers.ibos.add_new(IBOType::LinesPaintMask, extract_lines_paint_mask_subdiv(mr, subdiv_cache)); diff --git a/source/blender/draw/intern/draw_cache_impl.hh b/source/blender/draw/intern/draw_cache_impl.hh index 8029b415ae4..4423aadfba6 100644 --- a/source/blender/draw/intern/draw_cache_impl.hh +++ b/source/blender/draw/intern/draw_cache_impl.hh @@ -189,11 +189,13 @@ void DRW_mesh_batch_cache_create_requested(TaskGraph &task_graph, bool use_hide); blender::gpu::Batch *DRW_mesh_batch_cache_get_all_verts(Mesh &mesh); +blender::gpu::Batch *DRW_mesh_batch_cache_get_paint_overlay_verts(Mesh &mesh); blender::gpu::Batch *DRW_mesh_batch_cache_get_all_edges(Mesh &mesh); blender::gpu::Batch *DRW_mesh_batch_cache_get_loose_edges(Mesh &mesh); blender::gpu::Batch *DRW_mesh_batch_cache_get_edge_detection(Mesh &mesh, bool *r_is_manifold); blender::gpu::Batch *DRW_mesh_batch_cache_get_surface(Mesh &mesh); -blender::gpu::Batch *DRW_mesh_batch_cache_get_surface_edges(Mesh &mesh); +blender::gpu::Batch *DRW_mesh_batch_cache_get_paint_overlay_surface(Mesh &mesh); +blender::gpu::Batch *DRW_mesh_batch_cache_get_paint_overlay_edges(Mesh &mesh); Span DRW_mesh_batch_cache_get_surface_shaded(Object &object, Mesh &mesh, Span materials); diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.cc b/source/blender/draw/intern/draw_cache_impl_mesh.cc index dc483d3e809..f362b5610ce 100644 --- a/source/blender/draw/intern/draw_cache_impl_mesh.cc +++ b/source/blender/draw/intern/draw_cache_impl_mesh.cc @@ -595,9 +595,7 @@ void DRW_mesh_batch_cache_dirty_tag(Mesh *mesh, eMeshBatchDirtyMode mode) mesh_batch_cache_discard_uvedit_select(cache); break; case BKE_MESH_BATCH_DIRTY_SELECT_PAINT: - /* Paint mode selection flag is packed inside the nor attribute. - * Note that it can be slow if auto smooth is enabled. (see #63946) */ - discard_buffers(cache, {VBOType::CornerNormal}, {IBOType::LinesPaintMask}); + discard_buffers(cache, {VBOType::PaintOverlayFlag}, {IBOType::LinesPaintMask}); break; case BKE_MESH_BATCH_DIRTY_ALL: cache.is_dirty = true; @@ -720,6 +718,13 @@ gpu::Batch *DRW_mesh_batch_cache_get_all_verts(Mesh &mesh) return DRW_batch_request(&cache.batch.all_verts); } +gpu::Batch *DRW_mesh_batch_cache_get_paint_overlay_verts(Mesh &mesh) +{ + MeshBatchCache &cache = *mesh_batch_cache_get(mesh); + cache.batch_requested |= MBC_PAINT_OVERLAY_VERTS; + return DRW_batch_request(&cache.batch.paint_overlay_verts); +} + gpu::Batch *DRW_mesh_batch_cache_get_all_edges(Mesh &mesh) { MeshBatchCache &cache = *mesh_batch_cache_get(mesh); @@ -735,6 +740,13 @@ gpu::Batch *DRW_mesh_batch_cache_get_surface(Mesh &mesh) return cache.batch.surface; } +gpu::Batch *DRW_mesh_batch_cache_get_paint_overlay_surface(Mesh &mesh) +{ + MeshBatchCache &cache = *mesh_batch_cache_get(mesh); + cache.batch_requested |= MBC_PAINT_OVERLAY_SURFACE; + return DRW_batch_request(&cache.batch.paint_overlay_surface); +} + gpu::Batch *DRW_mesh_batch_cache_get_loose_edges(Mesh &mesh) { MeshBatchCache &cache = *mesh_batch_cache_get(mesh); @@ -1065,11 +1077,11 @@ gpu::Batch *DRW_mesh_batch_cache_get_edituv_wireframe(Object &object, Mesh &mesh return DRW_batch_request(&cache.batch.wire_loops_edituvs); } -gpu::Batch *DRW_mesh_batch_cache_get_surface_edges(Mesh &mesh) +gpu::Batch *DRW_mesh_batch_cache_get_paint_overlay_edges(Mesh &mesh) { MeshBatchCache &cache = *mesh_batch_cache_get(mesh); - cache.batch_requested |= MBC_WIRE_LOOPS; - return DRW_batch_request(&cache.batch.wire_loops); + cache.batch_requested |= MBC_PAINT_OVERLAY_WIRE_LOOPS; + return DRW_batch_request(&cache.batch.paint_overlay_wire_loops); } /** \} */ @@ -1321,6 +1333,14 @@ void DRW_mesh_batch_cache_create_requested(TaskGraph &task_graph, } batch_info.append(std::move(batch)); } + if (batches_to_create & MBC_PAINT_OVERLAY_SURFACE) { + BatchCreateData batch{*cache.batch.paint_overlay_surface, + GPU_PRIM_TRIS, + list, + IBOType::Tris, + {VBOType::Position, VBOType::PaintOverlayFlag}}; + batch_info.append(std::move(batch)); + } if (batches_to_create & MBC_VIEWER_ATTRIBUTE_OVERLAY) { batch_info.append({*cache.batch.surface_viewer_attribute, GPU_PRIM_TRIS, @@ -1329,11 +1349,15 @@ void DRW_mesh_batch_cache_create_requested(TaskGraph &task_graph, {VBOType::Position, VBOType::AttrViewer}}); } if (batches_to_create & MBC_ALL_VERTS) { - batch_info.append({*cache.batch.all_verts, + batch_info.append( + {*cache.batch.all_verts, GPU_PRIM_POINTS, list, std::nullopt, {VBOType::Position}}); + } + if (batches_to_create & MBC_PAINT_OVERLAY_VERTS) { + batch_info.append({*cache.batch.paint_overlay_verts, GPU_PRIM_POINTS, list, std::nullopt, - {VBOType::Position, VBOType::CornerNormal}}); + {VBOType::Position, VBOType::PaintOverlayFlag}}); } if (batches_to_create & MBC_SCULPT_OVERLAYS) { batch_info.append({*cache.batch.sculpt_overlays, @@ -1367,12 +1391,12 @@ void DRW_mesh_batch_cache_create_requested(TaskGraph &task_graph, IBOType::Tris, {VBOType::Position, VBOType::CornerNormal, VBOType::VertexGroupWeight}}); } - if (batches_to_create & MBC_WIRE_LOOPS) { - batch_info.append({*cache.batch.wire_loops, + if (batches_to_create & MBC_PAINT_OVERLAY_WIRE_LOOPS) { + batch_info.append({*cache.batch.paint_overlay_wire_loops, GPU_PRIM_LINES, list, IBOType::LinesPaintMask, - {VBOType::Position, VBOType::CornerNormal}}); + {VBOType::Position, VBOType::PaintOverlayFlag}}); } if (batches_to_create & MBC_WIRE_EDGES) { batch_info.append({*cache.batch.wire_edges, diff --git a/source/blender/draw/intern/draw_cache_impl_subdivision.cc b/source/blender/draw/intern/draw_cache_impl_subdivision.cc index 1d431241135..8aa03a0f456 100644 --- a/source/blender/draw/intern/draw_cache_impl_subdivision.cc +++ b/source/blender/draw/intern/draw_cache_impl_subdivision.cc @@ -1372,7 +1372,6 @@ void draw_subdiv_build_lnor_buffer(const DRWSubdivCache &cache, GPU_vertbuf_bind_as_ssbo(pos, LOOP_NORMALS_POS_SLOT); GPU_vertbuf_bind_as_ssbo(cache.extra_coarse_face_data, LOOP_NORMALS_EXTRA_COARSE_FACE_DATA_BUF_SLOT); - GPU_vertbuf_bind_as_ssbo(cache.verts_orig_index, LOOP_NORMALS_INPUT_VERT_ORIG_INDEX_BUF_SLOT); GPU_vertbuf_bind_as_ssbo(vert_normals, LOOP_NORMALS_VERT_NORMALS_BUF_SLOT); GPU_vertbuf_bind_as_ssbo(subdiv_corner_verts, LOOP_NORMALS_VERTEX_LOOP_MAP_BUF_SLOT); @@ -1388,28 +1387,27 @@ void draw_subdiv_build_lnor_buffer(const DRWSubdivCache &cache, GPU_shader_unbind(); } -void draw_subdiv_build_lnor_buffer_from_custom_normals(const DRWSubdivCache &cache, - gpu::VertBuf &interpolated_custom_normals, - gpu::VertBuf &lnor) +void draw_subdiv_build_paint_overlay_flag_buffer(const DRWSubdivCache &cache, + gpu::VertBuf &subdiv_corner_verts, + gpu::VertBuf &flags) { if (!draw_subdiv_cache_need_face_data(cache)) { /* Happens on meshes with only loose geometry. */ return; } - GPUShader *shader = DRW_shader_subdiv_get(SubdivShaderType::BUFFER_LNOR); + GPUShader *shader = DRW_shader_subdiv_get(SubdivShaderType::BUFFER_PAINT_OVERLAY_FLAG); GPU_shader_bind(shader); /* Inputs */ GPU_vertbuf_bind_as_ssbo(cache.subdiv_face_offset_buffer, SUBDIV_FACE_OFFSET_BUF_SLOT); GPU_vertbuf_bind_as_ssbo(cache.extra_coarse_face_data, - NORMALS_FINALIZE_EXTRA_COARSE_FACE_DATA_BUF_SLOT); - GPU_vertbuf_bind_as_ssbo(&interpolated_custom_normals, NORMALS_FINALIZE_CUSTOM_NORMALS_BUF_SLOT); - GPU_vertbuf_bind_as_ssbo(cache.verts_orig_index, - NORMALS_FINALIZE_INPUT_VERT_ORIG_INDEX_BUF_SLOT); + PAINT_OVERLAY_EXTRA_COARSE_FACE_DATA_BUF_SLOT); + GPU_vertbuf_bind_as_ssbo(cache.verts_orig_index, PAINT_OVERLAY_EXTRA_INPUT_VERT_ORIG_INDEX_SLOT); + GPU_vertbuf_bind_as_ssbo(&subdiv_corner_verts, PAINT_OVERLAY_FLAG_VERTEX_LOOP_MAP_BUF_SLOT); /* Outputs */ - GPU_vertbuf_bind_as_ssbo(&lnor, NORMALS_FINALIZE_OUTPUT_LNOR_BUF_SLOT); + GPU_vertbuf_bind_as_ssbo(&flags, PAINT_OVERLAY_OUTPUT_FLAG_SLOT); drw_subdiv_compute_dispatch(cache, shader, 0, 0, cache.num_subdiv_quads); diff --git a/source/blender/draw/intern/draw_shader.cc b/source/blender/draw/intern/draw_shader.cc index 0dba92c4e24..14325d0dcf6 100644 --- a/source/blender/draw/intern/draw_shader.cc +++ b/source/blender/draw/intern/draw_shader.cc @@ -63,8 +63,8 @@ static blender::StringRefNull get_subdiv_shader_info_name(SubdivShaderType shade case SubdivShaderType::BUFFER_NORMALS_ACCUMULATE: return "subdiv_normals_accumulate"; - case SubdivShaderType::BUFFER_CUSTOM_NORMALS_FINALIZE: - return "subdiv_custom_normals_finalize"; + case SubdivShaderType::BUFFER_PAINT_OVERLAY_FLAG: + return "subdiv_paint_overlay_flag"; case SubdivShaderType::BUFFER_LNOR: return "subdiv_loop_normals"; diff --git a/source/blender/draw/intern/draw_shader.hh b/source/blender/draw/intern/draw_shader.hh index 9e61b174ef3..6eb76505ab3 100644 --- a/source/blender/draw/intern/draw_shader.hh +++ b/source/blender/draw/intern/draw_shader.hh @@ -34,7 +34,7 @@ enum class SubdivShaderType { BUFFER_TRIS = 4, BUFFER_TRIS_MULTIPLE_MATERIALS = 5, BUFFER_NORMALS_ACCUMULATE = 6, - BUFFER_CUSTOM_NORMALS_FINALIZE = 7, + BUFFER_PAINT_OVERLAY_FLAG = 7, PATCH_EVALUATION = 8, PATCH_EVALUATION_FVAR = 9, PATCH_EVALUATION_FACE_DOTS = 10, diff --git a/source/blender/draw/intern/draw_subdiv_defines.hh b/source/blender/draw/intern/draw_subdiv_defines.hh index ddda4733d8e..ca7dffe611c 100644 --- a/source/blender/draw/intern/draw_subdiv_defines.hh +++ b/source/blender/draw/intern/draw_subdiv_defines.hh @@ -72,14 +72,13 @@ #define NORMALS_ACCUMULATE_VERTEX_LOOP_MAP_BUF_SLOT 3 #define NORMALS_ACCUMULATE_NORMALS_BUF_SLOT 4 -#define NORMALS_FINALIZE_CUSTOM_NORMALS_BUF_SLOT 1 -#define NORMALS_FINALIZE_INPUT_VERT_ORIG_INDEX_BUF_SLOT 2 -#define NORMALS_FINALIZE_EXTRA_COARSE_FACE_DATA_BUF_SLOT 3 -#define NORMALS_FINALIZE_OUTPUT_LNOR_BUF_SLOT 4 +#define PAINT_OVERLAY_EXTRA_COARSE_FACE_DATA_BUF_SLOT 1 +#define PAINT_OVERLAY_EXTRA_INPUT_VERT_ORIG_INDEX_SLOT 2 +#define PAINT_OVERLAY_FLAG_VERTEX_LOOP_MAP_BUF_SLOT 3 +#define PAINT_OVERLAY_OUTPUT_FLAG_SLOT 4 #define LOOP_NORMALS_POS_SLOT 1 #define LOOP_NORMALS_EXTRA_COARSE_FACE_DATA_BUF_SLOT 2 -#define LOOP_NORMALS_INPUT_VERT_ORIG_INDEX_BUF_SLOT 3 -#define LOOP_NORMALS_VERT_NORMALS_BUF_SLOT 4 -#define LOOP_NORMALS_VERTEX_LOOP_MAP_BUF_SLOT 5 -#define LOOP_NORMALS_OUTPUT_LNOR_BUF_SLOT 6 +#define LOOP_NORMALS_VERT_NORMALS_BUF_SLOT 3 +#define LOOP_NORMALS_VERTEX_LOOP_MAP_BUF_SLOT 4 +#define LOOP_NORMALS_OUTPUT_LNOR_BUF_SLOT 5 diff --git a/source/blender/draw/intern/draw_subdiv_shader_shared.hh b/source/blender/draw/intern/draw_subdiv_shader_shared.hh index dba79474d50..ac856a38f99 100644 --- a/source/blender/draw/intern/draw_subdiv_shader_shared.hh +++ b/source/blender/draw/intern/draw_subdiv_shader_shared.hh @@ -73,11 +73,6 @@ struct Position { float z; }; -struct LoopNormal { - float nx, ny, nz; - float flag; -}; - struct Normal { float x; float y; diff --git a/source/blender/draw/intern/draw_subdivision.hh b/source/blender/draw/intern/draw_subdivision.hh index 235c5a3bc26..db337a68179 100644 --- a/source/blender/draw/intern/draw_subdivision.hh +++ b/source/blender/draw/intern/draw_subdivision.hh @@ -236,9 +236,9 @@ void draw_subdiv_build_lnor_buffer(const DRWSubdivCache &cache, gpu::VertBuf *subdiv_corner_verts, gpu::VertBuf *lnor); -void draw_subdiv_build_lnor_buffer_from_custom_normals(const DRWSubdivCache &cache, - gpu::VertBuf &interpolated_custom_normals, - gpu::VertBuf &lnor); +void draw_subdiv_build_paint_overlay_flag_buffer(const DRWSubdivCache &cache, + gpu::VertBuf &subdiv_corner_verts, + gpu::VertBuf &flags); void draw_subdiv_build_edituv_stretch_area_buffer(const DRWSubdivCache &cache, gpu::VertBuf *coarse_data, diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh.hh b/source/blender/draw/intern/mesh_extractors/extract_mesh.hh index 4a2ec5ae398..cbb0e2acbaa 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh.hh +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh.hh @@ -377,4 +377,8 @@ gpu::VertBufPtr extract_attribute_subdiv(const MeshRenderData &mr, StringRef name); gpu::VertBufPtr extract_attr_viewer(const MeshRenderData &mr); +gpu::VertBufPtr extract_paint_overlay_flags(const MeshRenderData &mr); +gpu::VertBufPtr extract_paint_overlay_flags_subdiv(const MeshRenderData &mr, + const DRWSubdivCache &subdiv_cache); + } // namespace blender::draw diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_lnor.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_lnor.cc index eb77d1efb7c..4ec257460cf 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_lnor.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_lnor.cc @@ -74,67 +74,6 @@ static void extract_normals_mesh(const MeshRenderData &mr, MutableSpan } } -template -static void extract_paint_overlay_flags(const MeshRenderData &mr, MutableSpan normals) -{ - const bool use_face_select = (mr.mesh->editflag & ME_EDIT_PAINT_FACE_SEL) != 0; - Span selection; - if (mr.mesh->editflag & ME_EDIT_PAINT_FACE_SEL) { - selection = mr.select_poly; - } - else if (mr.mesh->editflag & ME_EDIT_PAINT_VERT_SEL) { - selection = mr.select_vert; - } - if (selection.is_empty() && mr.hide_poly.is_empty() && (!mr.edit_bmesh || !mr.orig_index_vert)) { - return; - } - const OffsetIndices faces = mr.faces; - threading::parallel_for(faces.index_range(), 1024, [&](const IndexRange range) { - if (!selection.is_empty()) { - if (use_face_select) { - for (const int face : range) { - if (selection[face]) { - for (const int corner : faces[face]) { - normals[corner].w = 1; - } - } - } - } - else { - const Span corner_verts = mr.corner_verts; - for (const int face : range) { - for (const int corner : faces[face]) { - if (selection[corner_verts[corner]]) { - normals[corner].w = 1; - } - } - } - } - } - if (!mr.hide_poly.is_empty()) { - const Span hide_poly = mr.hide_poly; - for (const int face : range) { - if (hide_poly[face]) { - for (const int corner : faces[face]) { - normals[corner].w = -1; - } - } - } - } - if (mr.edit_bmesh && mr.orig_index_vert) { - const Span corner_verts = mr.corner_verts; - const Span orig_indices(mr.orig_index_vert, mr.verts_num); - for (const int face : range) { - for (const int corner : faces[face]) { - if (orig_indices[corner_verts[corner]] == ORIGINDEX_NONE) { - normals[corner].w = -1; - } - } - } - } - }); -} - template static void extract_vert_normals_bm(const MeshRenderData &mr, MutableSpan normals) { @@ -219,24 +158,6 @@ static void extract_face_normals_bm(const MeshRenderData &mr, MutableSpan -static void extract_edit_flags_bm(const MeshRenderData &mr, MutableSpan normals) -{ - /* TODO: Return early if there are no hidden faces. */ - const BMesh &bm = *mr.bm; - threading::parallel_for(IndexRange(bm.totface), 2048, [&](const IndexRange range) { - for (const int face_index : range) { - const BMFace &face = *BM_face_at_index(&const_cast(bm), face_index); - if (BM_elem_flag_test(&face, BM_ELEM_HIDDEN)) { - const IndexRange face_range(BM_elem_index_get(BM_FACE_FIRST_LOOP(&face)), face.len); - for (GPUType &value : normals.slice(face_range)) { - value.w = -1; - } - } - } - }); -} - template static void extract_normals_bm(const MeshRenderData &mr, MutableSpan normals) { @@ -319,11 +240,9 @@ gpu::VertBufPtr extract_normals(const MeshRenderData &mr, const bool use_hq) if (mr.extract_type == MeshExtractType::Mesh) { extract_normals_mesh(mr, corners_data); - extract_paint_overlay_flags(mr, corners_data); } else { extract_normals_bm(mr, corners_data); - extract_edit_flags_bm(mr, corners_data); } loose_data.fill(short4(0)); @@ -344,11 +263,9 @@ gpu::VertBufPtr extract_normals(const MeshRenderData &mr, const bool use_hq) if (mr.extract_type == MeshExtractType::Mesh) { extract_normals_mesh(mr, corners_data); - extract_paint_overlay_flags(mr, corners_data); } else { extract_normals_bm(mr, corners_data); - extract_edit_flags_bm(mr, corners_data); } loose_data.fill(gpu::PackedNormal{}); @@ -359,7 +276,7 @@ static const GPUVertFormat &get_normals_format() { static const GPUVertFormat format = []() { GPUVertFormat format{}; - GPU_vertformat_attr_add(&format, "nor", gpu::VertAttrType::SFLOAT_32_32_32_32); + GPU_vertformat_attr_add(&format, "nor", gpu::VertAttrType::SFLOAT_32_32_32); GPU_vertformat_alias_add(&format, "lnor"); GPU_vertformat_alias_add(&format, "vnor"); return format; @@ -403,11 +320,7 @@ gpu::VertBufPtr extract_normals_subdiv(const MeshRenderData &mr, gpu::VertBufPtr src = gpu::VertBufPtr(GPU_vertbuf_create_with_format(src_normals_format)); GPU_vertbuf_data_alloc(*src, coarse_mesh->corners_num); src->data().copy_from(coarse_mesh->corner_normals()); - gpu::VertBufPtr dst = gpu::VertBufPtr( - GPU_vertbuf_create_on_device(src_normals_format, vbo_size)); - draw_subdiv_interp_corner_normals(subdiv_cache, *src, *dst); - - draw_subdiv_build_lnor_buffer_from_custom_normals(subdiv_cache, *dst, *lnor); + draw_subdiv_interp_corner_normals(subdiv_cache, *src, *lnor); update_loose_normals(mr, subdiv_cache, *lnor); return lnor; diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_paint_overlay_flag.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_paint_overlay_flag.cc new file mode 100644 index 00000000000..6074814f543 --- /dev/null +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_paint_overlay_flag.cc @@ -0,0 +1,143 @@ +/* SPDX-FileCopyrightText: 2025 Blender Authors + * + * SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "extract_mesh.hh" + +#include "draw_subdivision.hh" + +namespace blender::draw { + +static void extract_paint_overlay_flags(const MeshRenderData &mr, MutableSpan flags) +{ + const bool use_face_select = (mr.mesh->editflag & ME_EDIT_PAINT_FACE_SEL) != 0; + Span selection; + if (mr.mesh->editflag & ME_EDIT_PAINT_FACE_SEL) { + selection = mr.select_poly; + } + else if (mr.mesh->editflag & ME_EDIT_PAINT_VERT_SEL) { + selection = mr.select_vert; + } + if (selection.is_empty() && mr.hide_poly.is_empty() && (!mr.edit_bmesh || !mr.orig_index_vert)) { + return; + } + const OffsetIndices faces = mr.faces; + threading::parallel_for(faces.index_range(), 1024, [&](const IndexRange range) { + if (selection.is_empty()) { + flags.fill(0); + } + else { + if (use_face_select) { + for (const int face : range) { + flags.slice(faces[face]).fill(selection[face] ? 1 : 0); + } + } + else { + const Span corner_verts = mr.corner_verts; + for (const int face : range) { + for (const int corner : faces[face]) { + flags[corner] = selection[corner_verts[corner]] ? 1 : 0; + } + } + } + } + if (!mr.hide_poly.is_empty()) { + const Span hide_poly = mr.hide_poly; + for (const int face : range) { + if (hide_poly[face]) { + flags.slice(faces[face]).fill(-1); + } + } + } + if (mr.edit_bmesh && mr.orig_index_vert) { + const Span corner_verts = mr.corner_verts; + const Span orig_indices(mr.orig_index_vert, mr.verts_num); + for (const int face : range) { + for (const int corner : faces[face]) { + if (orig_indices[corner_verts[corner]] == ORIGINDEX_NONE) { + flags[corner] = -1; + } + } + } + } + }); +} + +static void extract_edit_flags_bm(const MeshRenderData &mr, MutableSpan flags) +{ + /* TODO: Return early if there are no hidden faces. */ + const BMesh &bm = *mr.bm; + threading::parallel_for(IndexRange(bm.totface), 2048, [&](const IndexRange range) { + for (const int face_index : range) { + const BMFace &face = *BM_face_at_index(&const_cast(bm), face_index); + if (BM_elem_flag_test(&face, BM_ELEM_HIDDEN)) { + const IndexRange face_range(BM_elem_index_get(BM_FACE_FIRST_LOOP(&face)), face.len); + flags.slice(face_range).fill(-1); + } + } + }); +} + +static const GPUVertFormat &get_paint_overlay_flag_format() +{ + static const GPUVertFormat format = GPU_vertformat_from_attribute("paint_overlay_flag", + gpu::VertAttrType::SINT_32); + return format; +} + +gpu::VertBufPtr extract_paint_overlay_flags(const MeshRenderData &mr) +{ + const int size = mr.corners_num + mr.loose_indices_num; + gpu::VertBufPtr vbo = gpu::VertBufPtr( + GPU_vertbuf_create_with_format(get_paint_overlay_flag_format())); + GPU_vertbuf_data_alloc(*vbo, size); + MutableSpan vbo_data = vbo->data(); + MutableSpan corners_data = vbo_data.take_front(mr.corners_num); + MutableSpan loose_data = vbo_data.take_back(mr.loose_indices_num); + + if (mr.extract_type == MeshExtractType::Mesh) { + extract_paint_overlay_flags(mr, corners_data); + } + else { + extract_edit_flags_bm(mr, corners_data); + } + + loose_data.fill(0); + return vbo; +} + +static void update_loose_flags(const MeshRenderData &mr, + const DRWSubdivCache &subdiv_cache, + gpu::VertBuf &flags) +{ + const int vbo_size = subdiv_full_vbo_size(mr, subdiv_cache); + const int loose_geom_start = subdiv_cache.num_subdiv_loops; + + /* Push VBO content to the GPU and bind the VBO so that #GPU_vertbuf_update_sub can work. */ + GPU_vertbuf_use(&flags); + + /* Default to zeroed attribute. The overlay shader should expect this and render engines should + * never draw loose geometry. */ + const int default_value = 0; + for (const int i : IndexRange::from_begin_end(loose_geom_start, vbo_size)) { + /* TODO(fclem): This has HORRENDOUS performance. Prefer clearing the buffer on device with + * something like glClearBufferSubData. */ + GPU_vertbuf_update_sub(&flags, i * sizeof(int), sizeof(int), &default_value); + } +} + +gpu::VertBufPtr extract_paint_overlay_flags_subdiv(const MeshRenderData &mr, + const DRWSubdivCache &subdiv_cache) +{ + gpu::VertBufPtr flags = gpu::VertBufPtr(GPU_vertbuf_create_on_device( + get_paint_overlay_flag_format(), subdiv_full_vbo_size(mr, subdiv_cache))); + gpu::VertBufPtr subdiv_corner_verts = gpu::VertBufPtr(draw_subdiv_build_origindex_buffer( + subdiv_cache.subdiv_loop_subdiv_vert_index, subdiv_cache.num_subdiv_loops)); + + draw_subdiv_build_paint_overlay_flag_buffer(subdiv_cache, *subdiv_corner_verts, *flags); + + update_loose_flags(mr, subdiv_cache, *flags); + return flags; +} + +} // namespace blender::draw diff --git a/source/blender/draw/intern/shaders/CMakeLists.txt b/source/blender/draw/intern/shaders/CMakeLists.txt index 77140e6e348..2169ab00614 100644 --- a/source/blender/draw/intern/shaders/CMakeLists.txt +++ b/source/blender/draw/intern/shaders/CMakeLists.txt @@ -39,8 +39,8 @@ set(SRC_GLSL_COMP subdiv_vbo_edituv_strech_angle_comp.glsl subdiv_vbo_edituv_strech_area_comp.glsl subdiv_vbo_lnor_comp.glsl + subdiv_vbo_paint_overlay_flag_comp.glsl subdiv_normals_accumulate_comp.glsl - subdiv_normals_finalize_comp.glsl ) # Compile shaders with shader code. diff --git a/source/blender/draw/intern/shaders/subdiv_info.hh b/source/blender/draw/intern/shaders/subdiv_info.hh index f3699bf1f7a..37a1171da63 100644 --- a/source/blender/draw/intern/shaders/subdiv_info.hh +++ b/source/blender/draw/intern/shaders/subdiv_info.hh @@ -111,10 +111,9 @@ GPU_SHADER_CREATE_INFO(subdiv_loop_normals) DO_STATIC_COMPILATION() STORAGE_BUF(LOOP_NORMALS_POS_SLOT, read, Position, positions[]) STORAGE_BUF(LOOP_NORMALS_EXTRA_COARSE_FACE_DATA_BUF_SLOT, read, uint, extra_coarse_face_data[]) -STORAGE_BUF(LOOP_NORMALS_INPUT_VERT_ORIG_INDEX_BUF_SLOT, read, int, input_vert_origindex[]) STORAGE_BUF(LOOP_NORMALS_VERT_NORMALS_BUF_SLOT, read, Normal, vert_normals[]) STORAGE_BUF(LOOP_NORMALS_VERTEX_LOOP_MAP_BUF_SLOT, read, uint, vert_loop_map[]) -STORAGE_BUF(LOOP_NORMALS_OUTPUT_LNOR_BUF_SLOT, write, LoopNormal, output_lnor[]) +STORAGE_BUF(LOOP_NORMALS_OUTPUT_LNOR_BUF_SLOT, write, Normal, output_lnor[]) COMPUTE_SOURCE("subdiv_vbo_lnor_comp.glsl") ADDITIONAL_INFO(subdiv_polygon_offset_base) GPU_SHADER_CREATE_END() @@ -285,13 +284,19 @@ COMPUTE_SOURCE("subdiv_normals_accumulate_comp.glsl") ADDITIONAL_INFO(subdiv_base) GPU_SHADER_CREATE_END() -GPU_SHADER_CREATE_INFO(subdiv_custom_normals_finalize) +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Paint Overlay Flag + * \{ */ + +GPU_SHADER_CREATE_INFO(subdiv_paint_overlay_flag) DO_STATIC_COMPILATION() -STORAGE_BUF(NORMALS_FINALIZE_CUSTOM_NORMALS_BUF_SLOT, read, Normal, custom_normals[]) -STORAGE_BUF(NORMALS_FINALIZE_INPUT_VERT_ORIG_INDEX_BUF_SLOT, read, int, input_vert_origindex[]) -STORAGE_BUF(NORMALS_FINALIZE_EXTRA_COARSE_FACE_DATA_BUF_SLOT, read, uint, extra_coarse_face_data[]) -STORAGE_BUF(NORMALS_FINALIZE_OUTPUT_LNOR_BUF_SLOT, write, LoopNormal, output_lnor[]) -COMPUTE_SOURCE("subdiv_normals_finalize_comp.glsl") +STORAGE_BUF(PAINT_OVERLAY_EXTRA_COARSE_FACE_DATA_BUF_SLOT, read, uint, extra_coarse_face_data[]) +STORAGE_BUF(PAINT_OVERLAY_EXTRA_INPUT_VERT_ORIG_INDEX_SLOT, read, int, input_vert_origindex[]) +STORAGE_BUF(PAINT_OVERLAY_FLAG_VERTEX_LOOP_MAP_BUF_SLOT, read, uint, vert_loop_map[]) +STORAGE_BUF(PAINT_OVERLAY_OUTPUT_FLAG_SLOT, write, int, flags[]) +COMPUTE_SOURCE("subdiv_vbo_paint_overlay_flag_comp.glsl") ADDITIONAL_INFO(subdiv_polygon_offset_base) GPU_SHADER_CREATE_END() diff --git a/source/blender/draw/intern/shaders/subdiv_vbo_lnor_comp.glsl b/source/blender/draw/intern/shaders/subdiv_vbo_lnor_comp.glsl index 8363894f2d0..b2cf44ec79d 100644 --- a/source/blender/draw/intern/shaders/subdiv_vbo_lnor_comp.glsl +++ b/source/blender/draw/intern/shaders/subdiv_vbo_lnor_comp.glsl @@ -6,28 +6,6 @@ COMPUTE_SHADER_CREATE_INFO(subdiv_loop_normals) -bool is_face_selected(uint coarse_quad_index) -{ - return (extra_coarse_face_data[coarse_quad_index] & shader_data.coarse_face_select_mask) != 0; -} - -bool is_face_hidden(uint coarse_quad_index) -{ - return (extra_coarse_face_data[coarse_quad_index] & shader_data.coarse_face_hidden_mask) != 0; -} - -/* Flag for paint mode overlay and normals drawing in edit-mode. */ -float get_loop_flag(uint coarse_quad_index, int vert_origindex) -{ - if (is_face_hidden(coarse_quad_index) || (shader_data.is_edit_mode && vert_origindex == -1)) { - return -1.0f; - } - if (is_face_selected(coarse_quad_index)) { - return 1.0f; - } - return 0.0f; -} - void main() { /* We execute for each quad. */ @@ -48,16 +26,12 @@ void main() uint subdiv_vert_index = vert_loop_map[start_loop_index + i]; Normal vert_normal = vert_normals[subdiv_vert_index]; - int origindex = input_vert_origindex[start_loop_index + i]; - float flag = get_loop_flag(coarse_quad_index, origindex); + Normal normal; + normal.x = vert_normal.x; + normal.y = vert_normal.y; + normal.z = vert_normal.z; - LoopNormal loop_normal; - loop_normal.nx = vert_normal.x; - loop_normal.ny = vert_normal.y; - loop_normal.nz = vert_normal.z; - loop_normal.flag = flag; - - output_lnor[start_loop_index + i] = loop_normal; + output_lnor[start_loop_index + i] = normal; } } else { @@ -78,16 +52,13 @@ void main() face_normal = normalize(face_normal); - LoopNormal loop_normal; - loop_normal.nx = face_normal.x; - loop_normal.ny = face_normal.y; - loop_normal.nz = face_normal.z; + Normal normal; + normal.x = face_normal.x; + normal.y = face_normal.y; + normal.z = face_normal.z; for (int i = 0; i < 4; i++) { - int origindex = input_vert_origindex[start_loop_index + i]; - loop_normal.flag = get_loop_flag(coarse_quad_index, origindex); - - output_lnor[start_loop_index + i] = loop_normal; + output_lnor[start_loop_index + i] = normal; } } } diff --git a/source/blender/draw/intern/shaders/subdiv_normals_finalize_comp.glsl b/source/blender/draw/intern/shaders/subdiv_vbo_paint_overlay_flag_comp.glsl similarity index 52% rename from source/blender/draw/intern/shaders/subdiv_normals_finalize_comp.glsl rename to source/blender/draw/intern/shaders/subdiv_vbo_paint_overlay_flag_comp.glsl index 29af22c717a..c6b8aaf7d4b 100644 --- a/source/blender/draw/intern/shaders/subdiv_normals_finalize_comp.glsl +++ b/source/blender/draw/intern/shaders/subdiv_vbo_paint_overlay_flag_comp.glsl @@ -1,19 +1,10 @@ -/* SPDX-FileCopyrightText: 2021-2022 Blender Authors +/* SPDX-FileCopyrightText: 2021-2023 Blender Authors * * SPDX-License-Identifier: GPL-2.0-or-later */ -/* Finalize normals after accumulating or interpolation. - * - * Custom normals are interpolated from coarse face corners to subdivided face corners - * by the generic custom data interpolation process. This shader is necessary to combine - * them with the interleaved flag in the final buffer. - * - * TODO: Move the currently interleaved flag to a separate buffer so this is unnecessary. - */ - #include "subdiv_lib.glsl" -COMPUTE_SHADER_CREATE_INFO(subdiv_custom_normals_finalize) +COMPUTE_SHADER_CREATE_INFO(subdiv_paint_overlay_flag) bool is_face_selected(uint coarse_quad_index) { @@ -26,15 +17,15 @@ bool is_face_hidden(uint coarse_quad_index) } /* Flag for paint mode overlay and normals drawing in edit-mode. */ -float get_loop_flag(uint coarse_quad_index, int vert_origindex) +int get_loop_flag(uint coarse_quad_index, int vert_origindex) { if (is_face_hidden(coarse_quad_index) || (shader_data.is_edit_mode && vert_origindex == -1)) { - return -1.0; + return -1; } if (is_face_selected(coarse_quad_index)) { - return 1.0; + return 1; } - return 0.0; + return 0; } void main() @@ -45,24 +36,17 @@ void main() return; } - uint coarse_quad_index = coarse_face_index_from_subdiv_quad_index(quad_index, - shader_data.coarse_face_count); - + /* The start index of the loop is quad_index * 4. */ uint start_loop_index = quad_index * 4; + uint coarse_quad_index = coarse_face_index_from_subdiv_quad_index(quad_index, + shader_data.coarse_face_count); for (int i = 0; i < 4; i++) { - Normal custom_normal = custom_normals[start_loop_index + i]; - float3 nor = float3(custom_normal.x, custom_normal.y, custom_normal.z); - nor = normalize(nor); - - LoopNormal lnor; - lnor.nx = nor.x; - lnor.ny = nor.y; - lnor.nz = nor.z; + uint subdiv_vert_index = vert_loop_map[start_loop_index + i]; int origindex = input_vert_origindex[start_loop_index + i]; - lnor.flag = get_loop_flag(coarse_quad_index, origindex); + int flag = get_loop_flag(coarse_quad_index, origindex); - output_lnor[start_loop_index + i] = lnor; + flags[start_loop_index + i] = flag; } }