From 78a9b5bde1ee644b6dbf5702fb46b4e8f9056ea5 Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Thu, 14 May 2020 21:40:54 +0200 Subject: [PATCH] Animation working Code still wip and lacking comments --- data/shaders/gltfskinning/mesh.frag | 6 +-- data/shaders/gltfskinning/mesh.frag.spv | Bin 0 -> 2024 bytes data/shaders/gltfskinning/mesh.vert | 6 +-- data/shaders/gltfskinning/mesh.vert.spv | Bin 0 -> 5156 bytes examples/gltfskinning/gltfskinning.cpp | 65 ++++++++++++++++++++++++ 5 files changed, 67 insertions(+), 10 deletions(-) create mode 100644 data/shaders/gltfskinning/mesh.frag.spv create mode 100644 data/shaders/gltfskinning/mesh.vert.spv diff --git a/data/shaders/gltfskinning/mesh.frag b/data/shaders/gltfskinning/mesh.frag index 6ff22d7b..6d5f4edc 100644 --- a/data/shaders/gltfskinning/mesh.frag +++ b/data/shaders/gltfskinning/mesh.frag @@ -8,8 +8,6 @@ layout (location = 2) in vec2 inUV; layout (location = 3) in vec3 inViewVec; layout (location = 4) in vec3 inLightVec; -layout (location = 5) in vec4 inColVis; - layout (location = 0) out vec4 outFragColor; void main() @@ -20,9 +18,7 @@ void main() vec3 L = normalize(inLightVec); vec3 V = normalize(inViewVec); vec3 R = reflect(-L, N); - vec3 diffuse = max(dot(N, L), 0.15) * inColor; + vec3 diffuse = max(dot(N, L), 0.5) * inColor; vec3 specular = pow(max(dot(R, V), 0.0), 16.0) * vec3(0.75); outFragColor = vec4(diffuse * color.rgb + specular, 1.0); - -// outFragColor = inColVis; } \ No newline at end of file diff --git a/data/shaders/gltfskinning/mesh.frag.spv b/data/shaders/gltfskinning/mesh.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..3dea62b05ef4dc08b008d218c076e2de5c25c37c GIT binary patch literal 2024 zcmZ9NSyNL%5QWEtL=!Wk5+M?2D}L@|zG$*3eJxhc6LS(gkc4xS21ORI`=f0QI6G#QV5M!ssZ-fU^l zsE>2n+m*&az1CU--l`nb);4mVnr{ce-OH+5dlHz8rBX6L1|usP>-2{XgyoY=r+v&WUMPY!s* z_XiT#Vz8M3i+Y3F$wy!ChqRLm96mNP0fT=*JABRu|Dtw$;PA1T8Q7F;xR)f(9Tnj- z8_tsC=VZgTcxIZknQ1cLtZc2K<$uw&kLxXa`)JktE8boyPOBU0u1dg6=xa?jXQDUy zz~=72=JleO4|l=>`zs`)9WHmocVw}gk?$dC7f#rdCv4t#lFu7Y+Prb>CDr3D2PE7h zHg|Pi!aaRaSMWw8aKPbk?lB2>^TB^1yr(Xv?HIcfFy?K%@qjUd_sUNGs}kbj3yZle-D2<&!;HZ#=B{+! zj>X)QZZY_XnbZz$G1Jn?^F7S$zH~72&q$}YeocXyK9G=eQvw%1dAUz~7WYUxab`c3 zPMzQ3E}lq-15R$fn>h)&IRk#)y~WQ<=PrLKo<5#Rz=)wf?+48I&!p3n+0UhOcB{WA z9S*qFUy^S1@$;RTuNZvXKRmuU>*b~NRS6t=;q8K1ZSI-=uz5=x65hzRz9i1VEWr>K zJ)|VOFZ{116-$)_TJ0ViHDD$_s-e) M8-eeiGAu~`14yZDzyJUM literal 0 HcmV?d00001 diff --git a/data/shaders/gltfskinning/mesh.vert b/data/shaders/gltfskinning/mesh.vert index 50115434..8b3fc9d5 100644 --- a/data/shaders/gltfskinning/mesh.vert +++ b/data/shaders/gltfskinning/mesh.vert @@ -28,15 +28,13 @@ layout (location = 2) out vec2 outUV; layout (location = 3) out vec3 outViewVec; layout (location = 4) out vec3 outLightVec; -layout (location = 5) out vec4 outColVis; - void main() { outNormal = inNormal; outColor = inColor; outUV = inUV; - // Calculated skinned matrix from vertice's weights and joint indices + // Calculate skinned matrix from weights and joint indices of the current vertex mat4 skinMat = inJointWeights.x * jointMatrices[int(inJointIndices.x)] + inJointWeights.y * jointMatrices[int(inJointIndices.y)] + @@ -50,6 +48,4 @@ void main() vec3 lPos = mat3(uboScene.view) * uboScene.lightPos.xyz; outLightVec = lPos - pos.xyz; outViewVec = -pos.xyz; - - outColVis = inJointWeights; } \ No newline at end of file diff --git a/data/shaders/gltfskinning/mesh.vert.spv b/data/shaders/gltfskinning/mesh.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..9a35e3318622e3bdfe89f1e873cece2c14e81ad3 GIT binary patch literal 5156 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 static_cast(animations.size()) - 1) { + std::cout << "No animation with index " << index << std::endl; + return; + } + Animation& animation = animations[index]; + + bool updated = false; + for (auto& channel : animation.channels) { + AnimationSampler& sampler = animation.samplers[channel.samplerIndex]; + if (sampler.inputs.size() > sampler.outputsVec4.size()) { + continue; + } + + for (size_t i = 0; i < sampler.inputs.size() - 1; i++) { + if ((time >= sampler.inputs[i]) && (time <= sampler.inputs[i + 1])) { + float u = std::max(0.0f, time - sampler.inputs[i]) / (sampler.inputs[i + 1] - sampler.inputs[i]); + if (u <= 1.0f) { + if (channel.path == "translation") { + glm::vec4 trans = glm::mix(sampler.outputsVec4[i], sampler.outputsVec4[i + 1], u); + channel.node->translation = glm::vec3(trans); + updated = true; + } + if (channel.path == "rotation") { + glm::quat q1; + q1.x = sampler.outputsVec4[i].x; + q1.y = sampler.outputsVec4[i].y; + q1.z = sampler.outputsVec4[i].z; + q1.w = sampler.outputsVec4[i].w; + glm::quat q2; + q2.x = sampler.outputsVec4[i + 1].x; + q2.y = sampler.outputsVec4[i + 1].y; + q2.z = sampler.outputsVec4[i + 1].z; + q2.w = sampler.outputsVec4[i + 1].w; + channel.node->rotation = glm::normalize(glm::slerp(q1, q2, u)); + updated = true; + } + if (channel.path == "scale") { + glm::vec4 trans = glm::mix(sampler.outputsVec4[i], sampler.outputsVec4[i + 1], u); + channel.node->scale = glm::vec3(trans); + updated = true; + } + } + } + } + } + if (updated) { + for (auto& node : nodes) { + updateJoints(node); + } + } + } + /* glTF rendering functions */ @@ -713,6 +767,7 @@ class VulkanExample : public VulkanExampleBase { public: bool wireframe = false; + float animationTimer = 0.0f; VulkanglTFModel glTFModel; @@ -1085,6 +1140,16 @@ public: if (camera.updated) { updateUniformBuffers(); } + // @todo: poi + if (!paused) { + if (glTFModel.animations.size() > 0) { + animationTimer += frameTimer * 0.75f; + if (animationTimer > glTFModel.animations[0].end) { + animationTimer -= glTFModel.animations[0].end; + } + glTFModel.updateAnimation(0, animationTimer); + } + } } virtual void OnUpdateUIOverlay(vks::UIOverlay *overlay)