diff --git a/source/blender/draw/engines/workbench/shaders/infos/workbench_prepass_info.hh b/source/blender/draw/engines/workbench/shaders/infos/workbench_prepass_info.hh index 0973d5c8630..b19ab3c4b36 100644 --- a/source/blender/draw/engines/workbench/shaders/infos/workbench_prepass_info.hh +++ b/source/blender/draw/engines/workbench/shaders/infos/workbench_prepass_info.hh @@ -54,8 +54,10 @@ GPU_SHADER_CREATE_INFO(workbench_next_curves) "draw_hair_new"); GPU_SHADER_CREATE_INFO(workbench_next_pointcloud) - /* TODO Adding workbench_next_mesh to avoid shader compilation errors */ - .additional_info("workbench_next_mesh"); + .vertex_source("workbench_prepass_pointcloud_vert.glsl") + .additional_info("draw_modelmat_new_with_custom_id", + "draw_resource_handle_new", + "draw_pointcloud_new"); /** \} */ diff --git a/source/blender/draw/engines/workbench/shaders/workbench_prepass_pointcloud_vert.glsl b/source/blender/draw/engines/workbench/shaders/workbench_prepass_pointcloud_vert.glsl index 1551b1c8084..dce038aa5dd 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_prepass_pointcloud_vert.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_prepass_pointcloud_vert.glsl @@ -19,8 +19,13 @@ void main() uv_interp = vec2(0.0); +#ifdef WORKBENCH_NEXT + workbench_material_data_get( + int(drw_CustomID), vec3(1.0), color_interp, alpha_interp, _roughness, metallic); +#else workbench_material_data_get( resource_handle, vec3(1.0), color_interp, alpha_interp, _roughness, metallic); +#endif object_id = int(uint(resource_handle) & 0xFFFFu) + 1; } diff --git a/source/blender/draw/engines/workbench/workbench_engine.cc b/source/blender/draw/engines/workbench/workbench_engine.cc index e9a601ef050..88cff6d917e 100644 --- a/source/blender/draw/engines/workbench/workbench_engine.cc +++ b/source/blender/draw/engines/workbench/workbench_engine.cc @@ -163,11 +163,14 @@ class Instance { sculpt_sync(ob_ref, handle, object_state); emitter_handle = handle; } - else if (ELEM(ob->type, OB_MESH, OB_POINTCLOUD)) { + else if (ob->type == OB_MESH) { ResourceHandle handle = manager.resource_handle(ob_ref); mesh_sync(ob_ref, handle, object_state); emitter_handle = handle; } + else if (ob->type == OB_POINTCLOUD) { + point_cloud_sync(manager, ob_ref, object_state); + } else if (ob->type == OB_CURVES) { curves_sync(manager, ob_ref, object_state); } @@ -363,6 +366,22 @@ class Instance { } } + void point_cloud_sync(Manager &manager, ObjectRef &ob_ref, const ObjectState &object_state) + { + ResourceHandle handle = manager.resource_handle(ob_ref); + + Material mat = get_material(ob_ref, object_state.color_type); + resources.material_buf.append(mat); + int material_index = resources.material_buf.size() - 1; + + PassMain::Sub &pass = get_mesh_pass(ob_ref, mat.is_transparent()) + .get_subpass(eGeometryType::POINTCLOUD) + .sub("Point Cloud SubPass"); + + GPUBatch *batch = point_cloud_sub_pass_setup(pass, ob_ref.object); + pass.draw(batch, handle, material_index); + } + void hair_sync(Manager &manager, ObjectRef &ob_ref, ResourceHandle emitter_handle, diff --git a/source/blender/draw/intern/draw_common.hh b/source/blender/draw/intern/draw_common.hh index b507897d7e2..fa085000de0 100644 --- a/source/blender/draw/intern/draw_common.hh +++ b/source/blender/draw/intern/draw_common.hh @@ -36,4 +36,12 @@ GPUBatch *curves_sub_pass_setup(PassSimple::Sub &ps, Object *ob, GPUMaterial *gpu_material = nullptr); +GPUBatch *point_cloud_sub_pass_setup(PassMain::Sub &sub_ps, + Object *object, + GPUMaterial *gpu_material = nullptr); + +GPUBatch *point_cloud_sub_pass_setup(PassSimple::Sub &sub_ps, + Object *object, + GPUMaterial *gpu_material = nullptr); + } // namespace blender::draw diff --git a/source/blender/draw/intern/draw_pointcloud.cc b/source/blender/draw/intern/draw_pointcloud.cc index be8efb36de8..3f5db691201 100644 --- a/source/blender/draw/intern/draw_pointcloud.cc +++ b/source/blender/draw/intern/draw_pointcloud.cc @@ -96,3 +96,51 @@ void DRW_pointcloud_free() { GPU_VERTBUF_DISCARD_SAFE(g_dummy_vbo); } + +#include "draw_common.hh" +namespace blender::draw { + +template +GPUBatch *point_cloud_sub_pass_setup_implementation(PassT &sub_ps, + Object *object, + GPUMaterial *gpu_material) +{ + BLI_assert(object->type == OB_POINTCLOUD); + PointCloud &pointcloud = *static_cast(object->data); + + /* Fix issue with certain driver not drawing anything if there is no texture bound to + * "ac", "au", "u" or "c". */ + sub_ps.bind_texture("u", g_dummy_vbo); + sub_ps.bind_texture("au", g_dummy_vbo); + sub_ps.bind_texture("c", g_dummy_vbo); + sub_ps.bind_texture("ac", g_dummy_vbo); + + GPUVertBuf *pos_rad_buf = pointcloud_position_and_radius_get(&pointcloud); + sub_ps.bind_texture("ptcloud_pos_rad_tx", pos_rad_buf); + + if (gpu_material != nullptr) { + /* Only single material supported for now. */ + GPUBatch **geom = pointcloud_surface_shaded_get(&pointcloud, &gpu_material, 1); + return geom[0]; + } + else { + GPUBatch *geom = pointcloud_surface_get(&pointcloud); + return geom; + } +} + +GPUBatch *point_cloud_sub_pass_setup(PassMain::Sub &sub_ps, + Object *object, + GPUMaterial *gpu_material) +{ + return point_cloud_sub_pass_setup_implementation(sub_ps, object, gpu_material); +} + +GPUBatch *point_cloud_sub_pass_setup(PassSimple::Sub &sub_ps, + Object *object, + GPUMaterial *gpu_material) +{ + return point_cloud_sub_pass_setup_implementation(sub_ps, object, gpu_material); +} + +} // namespace blender::draw diff --git a/source/blender/draw/intern/shaders/draw_view_info.hh b/source/blender/draw/intern/shaders/draw_view_info.hh index 80c69cc8cbf..7d5c9f0941b 100644 --- a/source/blender/draw/intern/shaders/draw_view_info.hh +++ b/source/blender/draw/intern/shaders/draw_view_info.hh @@ -143,6 +143,14 @@ GPU_SHADER_CREATE_INFO(draw_pointcloud) .vertex_in(2, Type::VEC3, "nor") .additional_info("draw_modelmat_instanced_attr", "draw_resource_id_uniform"); +GPU_SHADER_CREATE_INFO(draw_pointcloud_new) + .sampler(0, ImageType::FLOAT_BUFFER, "ptcloud_pos_rad_tx", Frequency::BATCH) + .define("POINTCLOUD_SHADER") + .define("DRW_POINTCLOUD_INFO") + .vertex_in(0, Type::VEC4, "pos") + .vertex_in(1, Type::VEC3, "pos_inst") + .vertex_in(2, Type::VEC3, "nor"); + GPU_SHADER_CREATE_INFO(draw_volume).additional_info("draw_modelmat", "draw_resource_id_uniform"); GPU_SHADER_CREATE_INFO(draw_volume_new)