diff --git a/source/blender/draw/intern/draw_cache_impl_subdivision.cc b/source/blender/draw/intern/draw_cache_impl_subdivision.cc index dc40e15a450..76bb42dbb46 100644 --- a/source/blender/draw/intern/draw_cache_impl_subdivision.cc +++ b/source/blender/draw/intern/draw_cache_impl_subdivision.cc @@ -600,8 +600,9 @@ void draw_subdiv_cache_free(DRWSubdivCache *cache) #define SUBDIV_COARSE_FACE_FLAG_SMOOTH 1u #define SUBDIV_COARSE_FACE_FLAG_SELECT 2u #define SUBDIV_COARSE_FACE_FLAG_ACTIVE 4u +#define SUBDIV_COARSE_FACE_FLAG_HIDDEN 8u -#define SUBDIV_COARSE_FACE_FLAG_OFFSET 29u +#define SUBDIV_COARSE_FACE_FLAG_OFFSET 28u #define SUBDIV_COARSE_FACE_FLAG_SMOOTH_MASK \ (SUBDIV_COARSE_FACE_FLAG_SMOOTH << SUBDIV_COARSE_FACE_FLAG_OFFSET) @@ -609,10 +610,12 @@ void draw_subdiv_cache_free(DRWSubdivCache *cache) (SUBDIV_COARSE_FACE_FLAG_SELECT << SUBDIV_COARSE_FACE_FLAG_OFFSET) #define SUBDIV_COARSE_FACE_FLAG_ACTIVE_MASK \ (SUBDIV_COARSE_FACE_FLAG_ACTIVE << SUBDIV_COARSE_FACE_FLAG_OFFSET) +#define SUBDIV_COARSE_FACE_FLAG_HIDDEN_MASK \ + (SUBDIV_COARSE_FACE_FLAG_HIDDEN << SUBDIV_COARSE_FACE_FLAG_OFFSET) #define SUBDIV_COARSE_FACE_LOOP_START_MASK \ ~((SUBDIV_COARSE_FACE_FLAG_SMOOTH | SUBDIV_COARSE_FACE_FLAG_SELECT | \ - SUBDIV_COARSE_FACE_FLAG_ACTIVE) \ + SUBDIV_COARSE_FACE_FLAG_ACTIVE | SUBDIV_COARSE_FACE_FLAG_HIDDEN) \ << SUBDIV_COARSE_FACE_FLAG_OFFSET) static uint32_t compute_coarse_face_flag(BMFace *f, BMFace *efa_act) @@ -629,6 +632,9 @@ static uint32_t compute_coarse_face_flag(BMFace *f, BMFace *efa_act) if (BM_elem_flag_test(f, BM_ELEM_SELECT)) { flag |= SUBDIV_COARSE_FACE_FLAG_SELECT; } + if (BM_elem_flag_test(f, BM_ELEM_HIDDEN)) { + flag |= SUBDIV_COARSE_FACE_FLAG_HIDDEN; + } if (f == efa_act) { flag |= SUBDIV_COARSE_FACE_FLAG_ACTIVE; } @@ -1148,12 +1154,17 @@ struct DRWSubdivUboStorage { uint coarse_face_select_mask; uint coarse_face_smooth_mask; uint coarse_face_active_mask; + uint coarse_face_hidden_mask; uint coarse_face_loopstart_mask; /* Number of elements to process in the compute shader (can be the coarse quad count, or the * final vertex count, depending on which compute pass we do). This is used to early out in case * of out of bond accesses as compute dispatch are of fixed size. */ uint total_dispatch_size; + + int _pad0; + int _pad2; + int _pad3; }; static_assert((sizeof(DRWSubdivUboStorage) % 16) == 0, @@ -1180,6 +1191,7 @@ static void draw_subdiv_init_ubo_storage(const DRWSubdivCache *cache, ubo->coarse_face_smooth_mask = SUBDIV_COARSE_FACE_FLAG_SMOOTH_MASK; ubo->coarse_face_select_mask = SUBDIV_COARSE_FACE_FLAG_SELECT_MASK; ubo->coarse_face_active_mask = SUBDIV_COARSE_FACE_FLAG_ACTIVE_MASK; + ubo->coarse_face_hidden_mask = SUBDIV_COARSE_FACE_FLAG_HIDDEN_MASK; ubo->coarse_face_loopstart_mask = SUBDIV_COARSE_FACE_LOOP_START_MASK; ubo->total_dispatch_size = total_dispatch_size; } @@ -1597,12 +1609,11 @@ void draw_subdiv_build_tris_buffer(const DRWSubdivCache *cache, do_single_material ? SHADER_BUFFER_TRIS : SHADER_BUFFER_TRIS_MULTIPLE_MATERIALS, defines); GPU_shader_bind(shader); - if (!do_single_material) { - /* subdiv_polygon_offset is always at binding point 0 for each shader using it. */ - GPU_vertbuf_bind_as_ssbo(cache->subdiv_polygon_offset_buffer, 0); - } + int binding_point = 0; - int binding_point = 1; + /* subdiv_polygon_offset is always at binding point 0 for each shader using it. */ + GPU_vertbuf_bind_as_ssbo(cache->subdiv_polygon_offset_buffer, binding_point++); + GPU_vertbuf_bind_as_ssbo(cache->extra_coarse_face_data, binding_point++); /* Outputs */ GPU_indexbuf_bind_as_ssbo(subdiv_tris, binding_point++); diff --git a/source/blender/draw/intern/shaders/common_subdiv_ibo_tris_comp.glsl b/source/blender/draw/intern/shaders/common_subdiv_ibo_tris_comp.glsl index 3dccc82541e..f1275b36c34 100644 --- a/source/blender/draw/intern/shaders/common_subdiv_ibo_tris_comp.glsl +++ b/source/blender/draw/intern/shaders/common_subdiv_ibo_tris_comp.glsl @@ -3,18 +3,28 @@ /* Generate triangles from subdivision quads indices. */ -layout(std430, binding = 1) writeonly buffer outputTriangles +layout(std430, binding = 1) readonly restrict buffer extraCoarseFaceData +{ + uint extra_coarse_face_data[]; +}; + +layout(std430, binding = 2) writeonly buffer outputTriangles { uint output_tris[]; }; #ifndef SINGLE_MATERIAL -layout(std430, binding = 2) readonly buffer inputPolygonMatOffset +layout(std430, binding = 3) readonly buffer inputPolygonMatOffset { int polygon_mat_offset[]; }; #endif +bool is_face_hidden(uint coarse_quad_index) +{ + return (extra_coarse_face_data[coarse_quad_index] & coarse_face_hidden_mask) != 0; +} + void main() { uint quad_index = get_global_invocation_index(); @@ -24,20 +34,31 @@ void main() uint loop_index = quad_index * 4; + uint coarse_quad_index = coarse_polygon_index_from_subdiv_quad_index(quad_index, + coarse_poly_count); + #ifdef SINGLE_MATERIAL uint triangle_loop_index = quad_index * 6; #else - uint coarse_quad_index = coarse_polygon_index_from_subdiv_quad_index(quad_index, - coarse_poly_count); int mat_offset = polygon_mat_offset[coarse_quad_index]; int triangle_loop_index = (int(quad_index) + mat_offset) * 6; #endif - output_tris[triangle_loop_index + 0] = loop_index + 0; - output_tris[triangle_loop_index + 1] = loop_index + 1; - output_tris[triangle_loop_index + 2] = loop_index + 2; - output_tris[triangle_loop_index + 3] = loop_index + 0; - output_tris[triangle_loop_index + 4] = loop_index + 2; - output_tris[triangle_loop_index + 5] = loop_index + 3; + if (is_face_hidden(coarse_quad_index)) { + output_tris[triangle_loop_index + 0] = 0xffffffff; + output_tris[triangle_loop_index + 1] = 0xffffffff; + output_tris[triangle_loop_index + 2] = 0xffffffff; + output_tris[triangle_loop_index + 3] = 0xffffffff; + output_tris[triangle_loop_index + 4] = 0xffffffff; + output_tris[triangle_loop_index + 5] = 0xffffffff; + } + else { + output_tris[triangle_loop_index + 0] = loop_index + 0; + output_tris[triangle_loop_index + 1] = loop_index + 1; + output_tris[triangle_loop_index + 2] = loop_index + 2; + output_tris[triangle_loop_index + 3] = loop_index + 0; + output_tris[triangle_loop_index + 4] = loop_index + 2; + output_tris[triangle_loop_index + 5] = loop_index + 3; + } } diff --git a/source/blender/draw/intern/shaders/common_subdiv_lib.glsl b/source/blender/draw/intern/shaders/common_subdiv_lib.glsl index ce324249446..55e4ac20271 100644 --- a/source/blender/draw/intern/shaders/common_subdiv_lib.glsl +++ b/source/blender/draw/intern/shaders/common_subdiv_lib.glsl @@ -31,6 +31,7 @@ layout(std140) uniform shader_data uint coarse_face_select_mask; uint coarse_face_smooth_mask; uint coarse_face_active_mask; + uint coarse_face_hidden_mask; uint coarse_face_loopstart_mask; /* Total number of elements to process. */