diff --git a/EvoEngine_Plugins/EcoSysLab/Internals/EcoSysLabResources/Shaders/Compute/DynamicStrandsPrecompute.comp b/EvoEngine_Plugins/EcoSysLab/Internals/EcoSysLabResources/Shaders/Compute/DynamicStrandsPrecompute.comp index 24056cc..bdd0e4d 100644 --- a/EvoEngine_Plugins/EcoSysLab/Internals/EcoSysLabResources/Shaders/Compute/DynamicStrandsPrecompute.comp +++ b/EvoEngine_Plugins/EcoSysLab/Internals/EcoSysLabResources/Shaders/Compute/DynamicStrandsPrecompute.comp @@ -25,11 +25,10 @@ struct PhysicsCommand{ vec3 position_offset; }; - -layout(std430, set = PHYSICS_COMMANDS_SET, binding = 0) readonly buffer PHYSICS_COMMAND_BLOCK { - PhysicsCommand physics_commands[]; -}; - +//#define PHYSICS_COMMANDS_SET 0 +//layout(std430, set = PHYSICS_COMMANDS_SET, binding = 0) readonly buffer PHYSICS_COMMAND_BLOCK { +// PhysicsCommand physics_commands[]; +//}; layout(push_constant) uniform STRANDS_PRECOMPUTE_CONSTANTS { uint strands_size; diff --git a/EvoEngine_Plugins/EcoSysLab/Internals/EcoSysLabResources/Shaders/Graphics/Mesh/DynamicStrandsRendering.mesh b/EvoEngine_Plugins/EcoSysLab/Internals/EcoSysLabResources/Shaders/Graphics/Mesh/DynamicStrandsRendering.mesh index 7b6888e..4347bdd 100644 --- a/EvoEngine_Plugins/EcoSysLab/Internals/EcoSysLabResources/Shaders/Graphics/Mesh/DynamicStrandsRendering.mesh +++ b/EvoEngine_Plugins/EcoSysLab/Internals/EcoSysLabResources/Shaders/Graphics/Mesh/DynamicStrandsRendering.mesh @@ -125,17 +125,12 @@ void main(){ StrandSegment strand_segment = strand_segments[strand_segment_id]; - vec3 start_position; - float start_thickness; - if(strand_segment.prev_handle != -1){ - start_position = strand_segments[strand_segment.prev_handle].end_position_thickness.xyz; - start_thickness = strand_segments[strand_segment.prev_handle].end_position_thickness.w; - }else{ - start_position = strands[strand_segment.strand_handle].start_position_thickness.xyz; - start_thickness = strands[strand_segment.strand_handle].start_position_thickness.w; - } - vec3 end_position = strand_segment.end_position_thickness.xyz; - float end_thickness = strand_segment.end_position_thickness.w; + vec3 start_position = strand_segment_particles[strand_segment.start_particle_index].position_thickness.xyz; + float start_thickness = strand_segment_particles[strand_segment.start_particle_index].position_thickness.w; + vec4 start_color = strand_segment_particles[strand_segment.start_particle_index].color; + vec3 end_position = strand_segment_particles[strand_segment.end_particle_index].position_thickness.xyz; + float end_thickness = strand_segment_particles[strand_segment.end_particle_index].position_thickness.w; + vec4 end_color = strand_segment_particles[strand_segment.end_particle_index].color; vec3 center_position = (start_position + end_position) * 0.5; float center_thickness = (start_thickness + end_thickness) * 0.5; @@ -154,7 +149,7 @@ void main(){ ms_v_out[vertex_index].frag_pos = vec4(instance_matrix * vec4(vertex_position, 1.0)).xyz; ms_v_out[vertex_index].normal = vec3(0, 1, 0); ms_v_out[vertex_index].tangent = vec3(0, 0, 1); - ms_v_out[vertex_index].color = strand_segment.end_color; + ms_v_out[vertex_index].color = end_color; gl_MeshVerticesEXT[vertex_index].gl_Position = transform * vec4(vertex_position, 1.0); } diff --git a/EvoEngine_Plugins/EcoSysLab/Internals/EcoSysLabResources/Shaders/Includes/DynamicStrands.glsl b/EvoEngine_Plugins/EcoSysLab/Internals/EcoSysLabResources/Shaders/Includes/DynamicStrands.glsl index fa7b567..4da2231 100644 --- a/EvoEngine_Plugins/EcoSysLab/Internals/EcoSysLabResources/Shaders/Includes/DynamicStrands.glsl +++ b/EvoEngine_Plugins/EcoSysLab/Internals/EcoSysLabResources/Shaders/Includes/DynamicStrands.glsl @@ -4,21 +4,23 @@ struct StrandSegment { int next_handle; int strand_handle; int index; - int neighbots[8]; - vec4 end_position_thickness; - vec4 end_color; + vec4 rotation; + + int start_particle_index; + int end_particle_index; + + int neighbors[10]; }; struct Strand { - int strand_segment_handles_offset; - int strand_segment_handles_size; int first_strand_segment_handle; int last_strand_segment_handle; +}; - vec4 start_position_thickness; - - vec4 start_color; +struct StrandSegmentParticle { + vec4 position_thickness; + vec4 color; }; layout(std430, set = DYNAMIC_STRANDS_SET, binding = 0) readonly buffer REF_STRAND_SEGMENTS_BLOCK { @@ -29,8 +31,8 @@ layout(std430, set = DYNAMIC_STRANDS_SET, binding = 1) readonly buffer REF_STRAN Strand ref_strands[]; }; -layout(std430, set = DYNAMIC_STRANDS_SET, binding = 2) readonly buffer REF_STRAND_SEGMENT_HANDLE_BLOCK { - int ref_strand_segment_handles[]; +layout(std430, set = DYNAMIC_STRANDS_SET, binding = 2) readonly buffer REF_STRAND_SEGMENT_PARTICLES_BLOCK { + StrandSegmentParticle ref_strand_segment_particles[]; }; layout(std430, set = DYNAMIC_STRANDS_SET, binding = 3) buffer STRAND_SEGMENTS_BLOCK { @@ -41,7 +43,7 @@ layout(std430, set = DYNAMIC_STRANDS_SET, binding = 4) buffer STRANDS_BLOCK { Strand strands[]; }; -layout(std430, set = DYNAMIC_STRANDS_SET, binding = 5) buffer STRAND_SEGMENT_HANDLE_BLOCK { - int strand_segment_handles[]; +layout(std430, set = DYNAMIC_STRANDS_SET, binding = 5) buffer STRAND_SEGMENT_PARTICLES_BLOCK { + StrandSegmentParticle strand_segment_particles[]; }; diff --git a/EvoEngine_Plugins/EcoSysLab/include/StrandModel/DynamicStrands.hpp b/EvoEngine_Plugins/EcoSysLab/include/StrandModel/DynamicStrands.hpp index 7d2bddd..e4a702e 100644 --- a/EvoEngine_Plugins/EcoSysLab/include/StrandModel/DynamicStrands.hpp +++ b/EvoEngine_Plugins/EcoSysLab/include/StrandModel/DynamicStrands.hpp @@ -12,11 +12,11 @@ class DynamicStrands { uint32_t device_buffer_version[2]; std::shared_ptr device_ref_strand_segments_buffer[2]; std::shared_ptr device_ref_strands_buffer[2]; - std::shared_ptr device_ref_strand_segment_handles_buffer[2]; + std::shared_ptr device_ref_strand_segment_particles_buffer[2]; std::shared_ptr device_strand_segments_buffer[2]; std::shared_ptr device_strands_buffer[2]; - std::shared_ptr device_strand_segment_handles_buffer[2]; + std::shared_ptr device_strand_segment_particles_buffer[2]; public: struct InitializeParameters { @@ -35,29 +35,29 @@ class DynamicStrands { } step_parameters{}; struct GpuStrand { - int32_t strand_segment_handles_offset = -1; - int32_t strand_segment_handles_size = -1; StrandSegmentHandle first_strand_segment_handle = -1; StrandSegmentHandle last_strand_segment_handle = -1; + }; + struct GpuStrandSegment { + int prev_handle = -1; + int next_handle = -1; + int strand_handle = -1; + int index = -1; - /** - * \brief The position of the [[[START]]] of first strand segment. - */ - glm::vec3 start_position = glm::vec3(0.0f); - /** - * \brief The thickness of the [[[START]]] current strand segment. - */ - float start_thickness = 0.0f; + glm::quat rotation; - /** - * \brief The color of the [[[START]]] current strand segment. - */ - glm::vec4 start_color = glm::vec4(1.0f); + int start_particle_index; + int end_particle_index; + int neighbors[10]; }; - - std::vector ref_strand_segments; + struct GpuStrandSegmentParticle { + glm::vec3 position; + float thickness; + glm::vec4 color; + }; + std::vector ref_strand_segments; + std::vector ref_strand_segment_particles; std::vector ref_strands; - std::vector ref_strand_segment_handles; inline static std::shared_ptr strands_layout{}; DynamicStrands(); void UpdateData(const InitializeParameters& initialize_parameters, const std::vector& target_strands, diff --git a/EvoEngine_Plugins/EcoSysLab/include/Structures/StrandGroup.hpp b/EvoEngine_Plugins/EcoSysLab/include/Structures/StrandGroup.hpp index e62c5f1..f5ad490 100644 --- a/EvoEngine_Plugins/EcoSysLab/include/Structures/StrandGroup.hpp +++ b/EvoEngine_Plugins/EcoSysLab/include/Structures/StrandGroup.hpp @@ -25,7 +25,7 @@ class StrandSegment { int index_ = -1; public: - StrandHandle neighbors[8]; + StrandSegmentHandle neighbors[8]; /** * \brief The position of the [[[END]]] of current strand segment. */ diff --git a/EvoEngine_Plugins/EcoSysLab/src/DynamicStrands.cpp b/EvoEngine_Plugins/EcoSysLab/src/DynamicStrands.cpp index b04005b..f893ee8 100644 --- a/EvoEngine_Plugins/EcoSysLab/src/DynamicStrands.cpp +++ b/EvoEngine_Plugins/EcoSysLab/src/DynamicStrands.cpp @@ -17,12 +17,12 @@ DynamicStrands::DynamicStrands() { device_ref_strand_segments_buffer[i] = std::make_shared(buffer_create_info, buffer_vma_allocation_create_info); device_ref_strands_buffer[i] = std::make_shared(buffer_create_info, buffer_vma_allocation_create_info); - device_ref_strand_segment_handles_buffer[i] = + device_ref_strand_segment_particles_buffer[i] = std::make_shared(buffer_create_info, buffer_vma_allocation_create_info); device_strand_segments_buffer[i] = std::make_shared(buffer_create_info, buffer_vma_allocation_create_info); device_strands_buffer[i] = std::make_shared(buffer_create_info, buffer_vma_allocation_create_info); - device_strand_segment_handles_buffer[i] = + device_strand_segment_particles_buffer[i] = std::make_shared(buffer_create_info, buffer_vma_allocation_create_info); device_buffer_version[i] = current_version; @@ -67,34 +67,38 @@ void DynamicStrands::UpdateData(const InitializeParameters& initialize_parameter const std::vector& target_strand_segments) { Clear(); assert(initialize_parameters.root_transform.GetScale() == glm::vec3(1.0f)); - ref_strand_segments = target_strand_segments; ref_strands.resize(target_strands.size()); - Jobs::RunParallelFor(target_strands.size(), [&](const size_t i) { - ref_strands[i].start_position = - initialize_parameters.root_transform.TransformPoint(target_strands[i].start_position); - ref_strands[i].start_thickness = target_strands[i].start_thickness; - ref_strands[i].start_color = target_strands[i].start_color; - }); + ref_strand_segments.resize(target_strand_segments.size()); + ref_strand_segment_particles.resize(ref_strands.size() + ref_strand_segments.size()); + int particle_index = 0; + for (uint32_t strand_index = 0; strand_index < target_strands.size(); strand_index++) { + auto& target_strand = target_strands[strand_index]; + auto& first_particle = ref_strand_segment_particles[particle_index]; + first_particle.position = target_strand.start_position; + first_particle.thickness = target_strand.start_thickness; + first_particle.color = target_strand.start_color; + particle_index++; + const auto& handles = target_strand.PeekStrandSegmentHandles(); + for (const auto& i : handles) { + ref_strand_segments[i].start_particle_index = particle_index - 1; + ref_strand_segments[i].end_particle_index = particle_index; + auto& particle = ref_strand_segment_particles[particle_index]; + particle.position = target_strand_segments[i].end_position; + particle.thickness = target_strand_segments[i].end_thickness; + particle.color = target_strand_segments[i].end_color; + particle_index++; + } + ref_strands[strand_index].first_strand_segment_handle = handles.front(); + ref_strands[strand_index].last_strand_segment_handle = handles.back(); + } Jobs::RunParallelFor(target_strand_segments.size(), [&](const size_t i) { - ref_strand_segments[i].end_position = - initialize_parameters.root_transform.TransformPoint(ref_strand_segments[i].end_position); + ref_strand_segments[i].prev_handle = target_strand_segments[i].GetPrevHandle(); + ref_strand_segments[i].next_handle = target_strand_segments[i].GetNextHandle(); + ref_strand_segments[i].strand_handle = target_strand_segments[i].GetStrandHandle(); + ref_strand_segments[i].index = target_strand_segments[i].GetIndex(); ref_strand_segments[i].rotation = - initialize_parameters.root_transform.GetRotation() * ref_strand_segments[i].rotation; + initialize_parameters.root_transform.GetRotation() * target_strand_segments[i].rotation; }); - for (uint32_t i = 0; i < target_strands.size(); i++) { - const auto& handles = target_strands[i].PeekStrandSegmentHandles(); - ref_strands[i].strand_segment_handles_offset = static_cast(ref_strand_segment_handles.size()); - if (handles.empty()) { - ref_strands[i].first_strand_segment_handle = -1; - ref_strands[i].last_strand_segment_handle = -1; - } else { - ref_strands[i].first_strand_segment_handle = handles.front(); - ref_strands[i].last_strand_segment_handle = handles.back(); - } - ref_strands[i].strand_segment_handles_size = static_cast(handles.size()); - ref_strand_segment_handles.insert(ref_strand_segment_handles.end(), handles.begin(), handles.end()); - } - ref_strand_segment_handles.resize(ref_strand_segment_handles.size() + ref_strand_segment_handles.size() % 4); current_version++; } @@ -138,27 +142,28 @@ void DynamicStrands::Upload() const { const auto current_frame_index = current_left ? 0 : 1; device_ref_strand_segments_buffer[current_frame_index]->UploadVector(ref_strand_segments); device_ref_strands_buffer[current_frame_index]->UploadVector(ref_strands); - device_ref_strand_segment_handles_buffer[current_frame_index]->UploadVector(ref_strand_segment_handles); + device_ref_strand_segment_particles_buffer[current_frame_index]->UploadVector(ref_strand_segment_particles); device_strand_segments_buffer[current_frame_index]->UploadVector(ref_strand_segments); device_strands_buffer[current_frame_index]->UploadVector(ref_strands); - device_strand_segment_handles_buffer[current_frame_index]->UploadVector(ref_strand_segment_handles); + device_strand_segment_particles_buffer[current_frame_index]->UploadVector(ref_strand_segment_particles); } void DynamicStrands::Clear() { ref_strand_segments.clear(); ref_strands.clear(); - ref_strand_segment_handles.clear(); + ref_strand_segment_particles.clear(); } void DynamicStrands::BindStrandsDescriptorSet(const std::shared_ptr& target_descriptor_set) const { const auto current_frame_index = current_left ? 0 : 1; target_descriptor_set->UpdateBufferDescriptorBinding(0, device_ref_strand_segments_buffer[current_frame_index], 0); target_descriptor_set->UpdateBufferDescriptorBinding(1, device_ref_strands_buffer[current_frame_index], 0); - target_descriptor_set->UpdateBufferDescriptorBinding(2, device_ref_strand_segment_handles_buffer[current_frame_index], - 0); + target_descriptor_set->UpdateBufferDescriptorBinding( + 2, device_ref_strand_segment_particles_buffer[current_frame_index], 0); target_descriptor_set->UpdateBufferDescriptorBinding(3, device_strand_segments_buffer[current_frame_index], 0); target_descriptor_set->UpdateBufferDescriptorBinding(4, device_strands_buffer[current_frame_index], 0); - target_descriptor_set->UpdateBufferDescriptorBinding(5, device_strand_segment_handles_buffer[current_frame_index], 0); + target_descriptor_set->UpdateBufferDescriptorBinding(5, device_strand_segment_particles_buffer[current_frame_index], + 0); } diff --git a/EvoEngine_Plugins/EcoSysLab/src/DynamicStrandsRender.cpp b/EvoEngine_Plugins/EcoSysLab/src/DynamicStrandsRender.cpp index 5293c47..b61e3ef 100644 --- a/EvoEngine_Plugins/EcoSysLab/src/DynamicStrandsRender.cpp +++ b/EvoEngine_Plugins/EcoSysLab/src/DynamicStrandsRender.cpp @@ -55,6 +55,7 @@ void DynamicStrands::Render(const StepParameters::RenderParameters& render_param render_pipeline->fragment_shader = frag_shader; render_pipeline->geometry_type = GeometryType::Mesh; + auto per_frame_layout = Platform::GetDescriptorSetLayout("PER_FRAME_LAYOUT"); render_pipeline->descriptor_set_layouts.emplace_back(per_frame_layout); render_pipeline->descriptor_set_layouts.emplace_back(strands_layout); @@ -81,6 +82,7 @@ void DynamicStrands::Render(const StepParameters::RenderParameters& render_param push_constant.camera_index = render_layer->GetCameraIndex(render_parameters.target_camera->GetHandle()); push_constant.strand_size = ref_strands.size(); push_constant.strand_segment_size = ref_strand_segments.size(); + Platform::RecordCommandsMainQueue([&](const VkCommandBuffer vk_command_buffer) { #pragma region Viewport and scissor VkViewport viewport; @@ -98,7 +100,7 @@ void DynamicStrands::Render(const StepParameters::RenderParameters& render_param std::vector color_attachment_infos; render_parameters.target_camera->GetRenderTexture()->AppendColorAttachmentInfos( - color_attachment_infos, VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_STORE); + color_attachment_infos, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE); render_pipeline->states.ResetAllStates(color_attachment_infos.size()); render_pipeline->states.view_port = viewport; render_pipeline->states.scissor = scissor;