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 00000000..3dea62b0 Binary files /dev/null and b/data/shaders/gltfskinning/mesh.frag.spv differ 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 00000000..9a35e331 Binary files /dev/null and b/data/shaders/gltfskinning/mesh.vert.spv differ diff --git a/examples/gltfskinning/gltfskinning.cpp b/examples/gltfskinning/gltfskinning.cpp index 8a9d7c94..cc45f47d 100644 --- a/examples/gltfskinning/gltfskinning.cpp +++ b/examples/gltfskinning/gltfskinning.cpp @@ -655,6 +655,60 @@ public: } } + void updateAnimation(uint32_t index, float time) + { + if (index > 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)