From bce7237e20a05b2067afcdc3463bf0edf2b5ff88 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Mon, 16 Jan 2023 21:02:37 +0800 Subject: [PATCH] Modified shader to support instanced bone first index and system to support runtime updating of animations --- Assets/Shaders/Anim_VS.glsl | 9 ++-- Assets/Shaders/Anim_VS.shshaderb | Bin 4341 -> 5837 bytes .../src/Application/SBApplication.cpp | 4 +- .../src/Animation/SHAnimationSystem.cpp | 22 +++++++- .../src/Animation/SHAnimationSystem.h | 17 +++++-- .../src/Animation/SHAnimatorComponent.h | 2 +- .../src/Animation/SHAnimatorComponent.hpp | 9 +++- .../Libraries/Loaders/SHModelLoader.cpp | 1 + .../Inspector/SHEditorComponentView.hpp | 2 +- .../Graphics/MiddleEnd/Batching/SHBatch.cpp | 47 ++++++++++++++++++ .../src/Graphics/MiddleEnd/Batching/SHBatch.h | 2 + .../MiddleEnd/Batching/SHSuperBatch.cpp | 1 + .../GlobalData/SHGraphicsPredefinedData.cpp | 1 + .../MiddleEnd/Interface/SHGraphicsConstants.h | 7 +++ 14 files changed, 108 insertions(+), 16 deletions(-) diff --git a/Assets/Shaders/Anim_VS.glsl b/Assets/Shaders/Anim_VS.glsl index c9aa64aa..b553fdf1 100644 --- a/Assets/Shaders/Anim_VS.glsl +++ b/Assets/Shaders/Anim_VS.glsl @@ -12,6 +12,7 @@ layout(location = 4) in mat4 worldTransform; layout(location = 8) in uvec2 integerData; layout(location = 9) in uvec4 aBoneIndices; layout(location = 10) in vec4 aBoneWeights; +layout(location = 11) in uint firstBoneIndex; layout(location = 0) out struct { @@ -65,10 +66,10 @@ void main() Out.normal.rgb = normalize (Out.normal.rgb); // Compute bone matrix - mat4 boneMatrix = BoneMatrices.data[aBoneIndices[0]] * aBoneWeights[0]; - boneMatrix += BoneMatrices.data[aBoneIndices[1]] * aBoneWeights[1]; - boneMatrix += BoneMatrices.data[aBoneIndices[2]] * aBoneWeights[2]; - boneMatrix += BoneMatrices.data[aBoneIndices[3]] * aBoneWeights[3]; + mat4 boneMatrix = BoneMatrices.data[firstBoneIndex + aBoneIndices[0]] * aBoneWeights[0]; + boneMatrix += BoneMatrices.data[firstBoneIndex + aBoneIndices[1]] * aBoneWeights[1]; + boneMatrix += BoneMatrices.data[firstBoneIndex + aBoneIndices[2]] * aBoneWeights[2]; + boneMatrix += BoneMatrices.data[firstBoneIndex + aBoneIndices[3]] * aBoneWeights[3]; // clip space for rendering gl_Position = cameraData.vpMat * worldTransform * boneMatrix * vec4 (aVertexPos, 1.0f); diff --git a/Assets/Shaders/Anim_VS.shshaderb b/Assets/Shaders/Anim_VS.shshaderb index c10bdc5a8ad53cb47aeb2f3d9b375b1e1728ae88..0c71194940a697833a5595575c1fcae14556c0bf 100644 GIT binary patch literal 5837 zcmZ9O`I{V76^3iJ4kkbdgn$aMXMzrz7`G6kNT5k@hz`tPLQqkMV!ARZ?CBnQdL{`j z1os_+`;PmD`@SQ_xbOJC_>0fu`&QMN)RW3{a=-JP<(_-ay`2o5-jWpG$ndsxNivkI zPcBIQQ&P#MWEdt%HYAN=oti#4y>ofc-nr|V=jw7{GE#WzvoX22z@z-VnC4xT^~eRt zW@HEQd}KG$LJlH}$i2vM*2hUYN`|TFxv80%sp*^M=9iY{mIo&~*<2^@ zW^?VlpUn^Q)l9$hYJPclzO&MDUZEO;)>!TdgM zy)mWDzGBhoj|NJ^l`ACy6?er`+K799ai^K_a4{vR;5QifA_S1wzFJ^UbYu5h~ zR&Da;Q}@lt8L#i9h@bvjShYp{PX@c6dhGX9u=ykY3a~L-@NBXw)-qmU`+Yh31go67 zdu?Miul!a{2xQUq4x%uyg z`^vkT<9V!}Tbnu5ePeRw*u~ncbp5XZ4{F9<50WG&uh)Ms$Xw%y`VFl5 zT7&WGEksWHK34s;+sm6+-AhjUOIhuueC+QVkNCsj()aA#?u4@kS7Pz~Pas>tzF~Fq zzMfSdIrFOfj^)(7FTP{xdaIRW^D3)qUqt*RcwZS9W#Zeb`T|;j?u=3g=m_ zAm49Un*}cK&}p!_Rk z1u=*3-yG`tM2;)L=J0(+4u9k1BgfOg=I~9MLtP*3zN=>^pQ8Gy^;(67l7r|y~8g=d@HvR-(-CeBIg&}i@|cvC%9`X&RNaUp>fuiAja#j z-8XlNyxOiq+*=>d=Nr5p@m=*t4C_)a}Iq z#G1w04plvT8CaWVv9^~Za(*-XYhhoe5qZVWJi|!D+yXX6K4NYK%PW58#>~JOW1fha zEwFm|Ma(Q`@b~04#9GX)uQT<&%X@BpUV+HPOb>zm{jv9+<#t3L`4)NoJ-P$2m)?#?Yxh2mv%V9N^9$}> zU}OCrsQlgy)>m8jy$5XUP>p*p*jTxUeIHm~Z4vu^u(886?gL+}3Dy7TlNhtEgA@-fekf{l}p zd43EW^VA-5_&8WwtGa`q06Wjf-voaWk&k(P3T&KwA*jQ&5+?T+{%Ei842J5RW{JsJKowtJim$VJRhz3dZ1|W}HT?^(UjX zY83{?K8eh8_zFIOSAv&<>q~MlCoJ~fYwf+y**VFN^M6{?&aWwxt%^JE8{?R|nKWNU z(~C}HbnC)oU)n%85Dvc&@4K^}>B(<*9&LpE2Vp-6_Y@jWPw#kGnYo1O6dBzpPVPqg zVV>bq#-42qzt?|?!jkOgd0k&qmhB=Z`P98U^9VcCv$Y89A z+!)I-EF9Ky3<*~$arkgmVNDAC$XgRLkew6AA?9@xpUC6XFdsxcC(K7#Pq-?qtH91u z%i{mD%`0YcFq`8mo)S0&oZXbsPYd=?#4W)w_`G?8@;m~ruYM#nxXl~%L z>WKO9;D{Gx2ZAHaD1ImFYk#>ktD5(Ph(H1HLBXMaDEwBT6LW)(a7x>7dkiuspBo^i z?z5~bz|oiZsNj~y!}>%mT~W!lDBi)UF7>P|U;7!MAzV=zt@&f%ZTw9Bg78f>=+6am z;BC$e`Si9qd-BPHC+8xU@KV8&a7T@rvikxY%W|*e!!fVrUKbqmZ4_V58~N0ekIq*x hQs0*BTY&?R!=Nj&DgOXB#ec+`(4Az7f3?-J@DDSpg=hc( diff --git a/SHADE_Application/src/Application/SBApplication.cpp b/SHADE_Application/src/Application/SBApplication.cpp index 80bb28ff..233ca4ed 100644 --- a/SHADE_Application/src/Application/SBApplication.cpp +++ b/SHADE_Application/src/Application/SBApplication.cpp @@ -34,6 +34,7 @@ #include "Physics/System/SHPhysicsDebugDrawSystem.h" #include "Scripting/SHScriptEngine.h" #include "UI/SHUISystem.h" +#include "Animation/SHAnimationSystem.h" // Components #include "Graphics/MiddleEnd/Interface/SHRenderable.h" @@ -96,6 +97,7 @@ namespace Sandbox // Link up SHDebugDraw SHSystemManager::CreateSystem(); SHDebugDraw::Init(SHSystemManager::GetSystem()); + SHSystemManager::CreateSystem(); #ifdef SHEDITOR SDL_Init(SDL_INIT_VIDEO); @@ -142,7 +144,7 @@ namespace Sandbox #ifdef SHEDITOR SHSystemManager::RegisterRoutine(); #endif - + SHSystemManager::RegisterRoutine(); SHSystemManager::RegisterRoutine(); SHSystemManager::RegisterRoutine(); diff --git a/SHADE_Engine/src/Animation/SHAnimationSystem.cpp b/SHADE_Engine/src/Animation/SHAnimationSystem.cpp index 8c514e7c..6f41e2aa 100644 --- a/SHADE_Engine/src/Animation/SHAnimationSystem.cpp +++ b/SHADE_Engine/src/Animation/SHAnimationSystem.cpp @@ -16,6 +16,7 @@ of DigiPen Institute of Technology is prohibited. // Project Includes #include "ECS_Base/Managers/SHComponentManager.h" #include "SHAnimatorComponent.h" +#include "ECS_Base/General/SHFamily.h" namespace SHADE { @@ -23,8 +24,11 @@ namespace SHADE /* System Routine Functions - UpdateRoutine */ /*-----------------------------------------------------------------------------------*/ SHAnimationSystem::UpdateRoutine::UpdateRoutine() - : SHSystemRoutine("Animation System Update", false) - {} + : SHSystemRoutine("Animation System Update", true) + { + SHFamilyID::GetID(); + } + void SHAnimationSystem::UpdateRoutine::Execute(double dt) noexcept { auto& animators = SHComponentManager::GetDense(); @@ -33,4 +37,18 @@ namespace SHADE animator.Update(dt); } } + + /*---------------------------------------------------------------------------------*/ + /* SHSystem Overrides */ + /*---------------------------------------------------------------------------------*/ + void SHAnimationSystem::Init(void) + { + + } + + void SHAnimationSystem::Exit(void) + { + + } + } diff --git a/SHADE_Engine/src/Animation/SHAnimationSystem.h b/SHADE_Engine/src/Animation/SHAnimationSystem.h index 96cd9a71..3d46edc2 100644 --- a/SHADE_Engine/src/Animation/SHAnimationSystem.h +++ b/SHADE_Engine/src/Animation/SHAnimationSystem.h @@ -18,10 +18,6 @@ of DigiPen Institute of Technology is prohibited. namespace SHADE { - /*-----------------------------------------------------------------------------------*/ - /* Forward Declarations */ - /*-----------------------------------------------------------------------------------*/ - /*-----------------------------------------------------------------------------------*/ /* Type Definitions */ /*-----------------------------------------------------------------------------------*/ @@ -30,7 +26,7 @@ namespace SHADE /// class SH_API SHAnimationSystem : public SHSystem { - public: + public: /*---------------------------------------------------------------------------------*/ /* Type Definitions */ /*---------------------------------------------------------------------------------*/ @@ -44,5 +40,16 @@ namespace SHADE UpdateRoutine(); void Execute(double dt) noexcept override final; }; + + /*---------------------------------------------------------------------------------*/ + /* Constructors */ + /*---------------------------------------------------------------------------------*/ + SHAnimationSystem() = default; + + /*---------------------------------------------------------------------------------*/ + /* SHSystem Overrides */ + /*---------------------------------------------------------------------------------*/ + virtual void Init(void) override final; + virtual void Exit(void) override final; }; } \ No newline at end of file diff --git a/SHADE_Engine/src/Animation/SHAnimatorComponent.h b/SHADE_Engine/src/Animation/SHAnimatorComponent.h index 6c525be2..43a9f044 100644 --- a/SHADE_Engine/src/Animation/SHAnimatorComponent.h +++ b/SHADE_Engine/src/Animation/SHAnimatorComponent.h @@ -128,7 +128,7 @@ namespace SHADE Handle currClip; // Playback Tracking float currPlaybackTime = 0.0f; - bool isPlaying = false; + bool isPlaying = true; // Useful Cached Data float secsPerTick = 0.0f; // Buffer diff --git a/SHADE_Engine/src/Animation/SHAnimatorComponent.hpp b/SHADE_Engine/src/Animation/SHAnimatorComponent.hpp index 9c70d15e..d0775711 100644 --- a/SHADE_Engine/src/Animation/SHAnimatorComponent.hpp +++ b/SHADE_Engine/src/Animation/SHAnimatorComponent.hpp @@ -55,15 +55,20 @@ namespace SHADE // No keyframes at all, means no changes if (nextKeyFrame == keyframes.end()) return T(); - // At the back, so no keyframes will follow + // Out of range, clamp to the back else - return firstKeyFrame->Data; + return nextKeyFrame->Data; } // At the front, so no prior key frames else if (nextKeyFrame != keyframes.end()) { return nextKeyFrame->Data; } + // At the back, so no keyframes will follow + else + { + return firstKeyFrame->Data; + } // Get interpolated vector const float PREV_FRAME_TIME = firstKeyFrame->FrameIndex * secsPerTick; diff --git a/SHADE_Engine/src/Assets/Libraries/Loaders/SHModelLoader.cpp b/SHADE_Engine/src/Assets/Libraries/Loaders/SHModelLoader.cpp index 230df857..6773fb28 100644 --- a/SHADE_Engine/src/Assets/Libraries/Loaders/SHModelLoader.cpp +++ b/SHADE_Engine/src/Assets/Libraries/Loaders/SHModelLoader.cpp @@ -79,6 +79,7 @@ namespace SHADE void SHModelLoader::ReadAnimNode(FileReference file, SHAnimNodeInfo const& info, SHAnimData& data) { + data.name.resize(info.charCount); file.read( data.name.data(), info.charCount diff --git a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp index d3329585..8f1cbb6d 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp @@ -607,7 +607,7 @@ namespace SHADE }, SHDragDrop::DRAG_RESOURCE); Handle const& clip = component->GetCurrentClip(); - const auto CLIP_NAME = rig ? SHResourceManager::GetAssetName(clip).value_or("") : ""; + const auto CLIP_NAME = clip ? SHResourceManager::GetAssetName(clip).value_or("") : ""; SHEditorWidgets::DragDropReadOnlyField("Clip", CLIP_NAME, [component]() { diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp index 48859040..fdbbad24 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp @@ -380,6 +380,38 @@ namespace SHADE } + void SHBatch::UpdateAnimationBuffer(uint32_t frameIndex) + { + // Frame Index check + if (frameIndex >= SHGraphicsConstants::NUM_FRAME_BUFFERS) + { + SHLOG_WARNING("[SHBatch] Attempted to update animation buffers with an invalid frame index."); + return; + } + + // Reset Animation Matrix Data + boneMatrixData.clear(); + + // Populate on the CPU + for (auto& subBatch : subBatches) + for (auto rendId : subBatch.Renderables) + { + auto animator = SHComponentManager::GetComponent_s(rendId); + if (animator) + { + const auto& MATRICES = animator->GetBoneMatrices(); + boneMatrixData.insert(boneMatrixData.end(), MATRICES.cbegin(), MATRICES.cend()); + } + } + + // Update GPU Buffers + const uint32_t BONE_MTX_DATA_BYTES = static_cast(boneMatrixData.size() * sizeof(SHMatrix)); + if (boneMatrixBuffer[frameIndex]) + { + boneMatrixBuffer[frameIndex]->WriteToMemory(boneMatrixData.data(), BONE_MTX_DATA_BYTES, 0, 0); + } + } + void SHBatch::Build(Handle _device, Handle descPool, uint32_t frameIndex) { if (frameIndex >= SHGraphicsConstants::NUM_FRAME_BUFFERS) @@ -557,6 +589,17 @@ namespace SHADE BuffUsage::eVertexBuffer, "Batch Instance Data Buffer" ); + // - Bone Matrix Indices + if (!boneMatrixIndices.empty()) + { + const uint32_t BMI_DATA_BYTES = static_cast(boneMatrixIndices.size() * sizeof(uint32_t)); + SHVkUtil::EnsureBufferAndCopyHostVisibleData + ( + device, boneMatrixFirstIndexBuffer[frameIndex], boneMatrixIndices.data(), BMI_DATA_BYTES, + BuffUsage::eVertexBuffer, + "Batch Instance Bone Matrix First Index Buffer" + ); + } // - Material and bone buffers/descriptor sets rebuildDescriptorSetBuffers(frameIndex, descPool); } @@ -590,6 +633,10 @@ namespace SHADE cmdBuffer->BindPipeline(pipeline); cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::TRANSFORM, transformDataBuffer[frameIndex], 0); cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::INTEGER_DATA, instancedIntegerBuffer[frameIndex], 0); + if (boneMatrixFirstIndexBuffer[frameIndex]) + { + cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::BONE_MATRIX_FIRST_INDEX, boneMatrixFirstIndexBuffer[frameIndex], 0); + } auto const& descMappings = SHGraphicsPredefinedData::GetMappings(SHGraphicsPredefinedData::SystemType::BATCHING); if (instanceDataDescSet[frameIndex]) diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.h b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.h index 1bdd9a59..913a7a04 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.h @@ -86,6 +86,7 @@ namespace SHADE void UpdateMaterialBuffer(uint32_t frameIndex, Handle descPool); void UpdateTransformBuffer(uint32_t frameIndex); void UpdateInstancedIntegerBuffer(uint32_t frameIndex); + void UpdateAnimationBuffer(uint32_t frameIndex); void Build(Handle device, Handle descPool, uint32_t frameIndex); void Draw(Handle cmdBuffer, uint32_t frameIndex); @@ -134,6 +135,7 @@ namespace SHADE TripleBuffer instancedIntegerBuffer; TripleBuffer matPropsBuffer; TripleBuffer boneMatrixBuffer; + TripleBuffer boneMatrixFirstIndexBuffer; // Instanced buffer, indicates where the first bone matrix is TripleDescSet instanceDataDescSet; /*-----------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp index 58993026..0129c0ba 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp @@ -94,6 +94,7 @@ namespace SHADE { batch.UpdateMaterialBuffer(frameIndex, descPool); batch.UpdateTransformBuffer(frameIndex); + batch.UpdateAnimationBuffer(frameIndex); batch.UpdateInstancedIntegerBuffer(frameIndex); } } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.cpp index 0cbd6c33..09f7d19e 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.cpp @@ -218,6 +218,7 @@ namespace SHADE defaultVertexInputState.AddBinding(true , true , { SHVertexAttribute(SHAttribFormat::UINT32_2D) }); // Instanced integer data at index 8 defaultVertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::UINT32_4D) }); // Attribute bone indices at index 9 defaultVertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_4D) }); // Attribute bone weights at index 10 + defaultVertexInputState.AddBinding(true , true , { SHVertexAttribute(SHAttribFormat::UINT32_1D) }); // Instance bone matrix first index at index 11 } void SHGraphicsPredefinedData::Init(Handle logicalDevice) noexcept diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsConstants.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsConstants.h index e967312f..99694c11 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsConstants.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsConstants.h @@ -234,6 +234,13 @@ namespace SHADE */ /***************************************************************************/ static constexpr uint32_t BONE_WEIGHTS = 7; + /***************************************************************************/ + /*! + \brief + Vertex buffer bindings for the bone matrix first index buffer. + */ + /***************************************************************************/ + static constexpr uint32_t BONE_MATRIX_FIRST_INDEX = 8; static constexpr uint32_t CALCULATED_GLYPH_POSITION = 0; static constexpr uint32_t GLYPH_INDEX = 1;