From 74cdee4cb5b25019e9e2536b9f311bbfd013c7c3 Mon Sep 17 00:00:00 2001 From: jfons Date: Fri, 5 Aug 2022 09:19:52 +0200 Subject: Add motion vectors support for MultiMeshInstance Transparently handle changes in multimesh transforms so they get reflected in the motion vectors buffer. --- .../forward_clustered/render_forward_clustered.cpp | 16 +++++++++++++--- .../forward_clustered/render_forward_clustered.h | 5 +++-- 2 files changed, 16 insertions(+), 5 deletions(-) (limited to 'servers/rendering/renderer_rd/forward_clustered') diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp index a0f6e69fd5..0b2a6ff9fd 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp @@ -477,6 +477,10 @@ void RenderForwardClustered::_render_list_template(RenderingDevice::DrawListID p prev_material_uniform_set = material_uniform_set; } + if (surf->owner->base_flags & INSTANCE_DATA_FLAG_MULTIMESH) { + mesh_storage->_multimesh_get_motion_vectors_offsets(surf->owner->data->base, push_constant.multimesh_motion_vectors_current_offset, push_constant.multimesh_motion_vectors_previous_offset); + } + RD::get_singleton()->draw_list_set_push_constant(draw_list, &push_constant, sizeof(SceneState::PushConstant)); uint32_t instance_count = surf->owner->instance_count > 1 ? surf->owner->instance_count : element_info.repeat; @@ -924,7 +928,7 @@ _FORCE_INLINE_ static uint32_t _indices_to_primitives(RS::PrimitiveType p_primit static const uint32_t subtractor[RS::PRIMITIVE_MAX] = { 0, 0, 1, 0, 1 }; return (p_indices - subtractor[p_primitive]) / divisor[p_primitive]; } -void RenderForwardClustered::_fill_render_list(RenderListType p_render_list, const RenderDataRD *p_render_data, PassMode p_pass_mode, bool p_using_sdfgi, bool p_using_opaque_gi, bool p_append) { +void RenderForwardClustered::_fill_render_list(RenderListType p_render_list, const RenderDataRD *p_render_data, PassMode p_pass_mode, uint32_t p_color_pass_flags = 0, bool p_using_sdfgi, bool p_using_opaque_gi, bool p_append) { RendererRD::MeshStorage *mesh_storage = RendererRD::MeshStorage::get_singleton(); if (p_render_list == RENDER_LIST_OPAQUE) { @@ -1149,6 +1153,12 @@ void RenderForwardClustered::_fill_render_list(RenderListType p_render_list, con scene_state.used_depth_texture = true; } + if (p_color_pass_flags & COLOR_PASS_FLAG_MOTION_VECTORS && flags & INSTANCE_DATA_FLAG_MULTIMESH) { + if (RendererRD::MeshStorage::get_singleton()->_multimesh_enable_motion_vectors(inst->data->base)) { + inst->transforms_uniform_set = mesh_storage->multimesh_get_3d_uniform_set(inst->data->base, scene_shader.default_shader_rd, TRANSFORMS_UNIFORM_SET); + } + } + } else if (p_pass_mode == PASS_MODE_SHADOW || p_pass_mode == PASS_MODE_SHADOW_DP) { if (surf->flags & GeometryInstanceSurfaceDataCache::FLAG_PASS_SHADOW) { rl->add_element(surf); @@ -1322,7 +1332,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co _update_render_base_uniform_set(); //may have changed due to the above (light buffer enlarged, as an example) - _fill_render_list(RENDER_LIST_OPAQUE, p_render_data, PASS_MODE_COLOR, using_sdfgi, using_sdfgi || using_voxelgi); + _fill_render_list(RENDER_LIST_OPAQUE, p_render_data, PASS_MODE_COLOR, color_pass_flags, using_sdfgi, using_sdfgi || using_voxelgi); render_list[RENDER_LIST_OPAQUE].sort_by_key(); render_list[RENDER_LIST_ALPHA].sort_by_reverse_depth_and_priority(); _fill_instance_data(RENDER_LIST_OPAQUE, p_render_data->render_info ? p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_VISIBLE] : (int *)nullptr); @@ -1723,7 +1733,7 @@ void RenderForwardClustered::_render_shadow_append(RID p_framebuffer, const Page PassMode pass_mode = p_use_dp ? PASS_MODE_SHADOW_DP : PASS_MODE_SHADOW; uint32_t render_list_from = render_list[RENDER_LIST_SECONDARY].elements.size(); - _fill_render_list(RENDER_LIST_SECONDARY, &render_data, pass_mode, false, false, true); + _fill_render_list(RENDER_LIST_SECONDARY, &render_data, pass_mode, 0, false, false, true); uint32_t render_list_size = render_list[RENDER_LIST_SECONDARY].elements.size() - render_list_from; render_list[RENDER_LIST_SECONDARY].sort_by_key_range(render_list_from, render_list_size); _fill_instance_data(RENDER_LIST_SECONDARY, p_render_info ? p_render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_SHADOW] : (int *)nullptr, render_list_from, render_list_size, false); diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h index 35379cd69b..9e2586542a 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h @@ -337,7 +337,8 @@ class RenderForwardClustered : public RendererSceneRenderRD { struct PushConstant { uint32_t base_index; // uint32_t uv_offset; //packed - uint32_t pad[2]; + uint32_t multimesh_motion_vectors_current_offset; + uint32_t multimesh_motion_vectors_previous_offset; }; struct InstanceData { @@ -429,7 +430,7 @@ class RenderForwardClustered : public RendererSceneRenderRD { void _update_instance_data_buffer(RenderListType p_render_list); void _fill_instance_data(RenderListType p_render_list, int *p_render_info = nullptr, uint32_t p_offset = 0, int32_t p_max_elements = -1, bool p_update_buffer = true); - void _fill_render_list(RenderListType p_render_list, const RenderDataRD *p_render_data, PassMode p_pass_mode, bool p_using_sdfgi = false, bool p_using_opaque_gi = false, bool p_append = false); + void _fill_render_list(RenderListType p_render_list, const RenderDataRD *p_render_data, PassMode p_pass_mode, uint32_t p_color_pass_flags, bool p_using_sdfgi = false, bool p_using_opaque_gi = false, bool p_append = false); HashMap sdfgi_framebuffer_size_cache; -- cgit v1.2.3