Skeletal animation example shaders, code cleanup, etc.

This commit is contained in:
saschawillems 2016-10-30 18:13:49 +01:00
parent 54ddca7c08
commit 1359058d24
11 changed files with 65 additions and 121 deletions

View file

@ -1,7 +1,6 @@
cd jni cd jni
call ndk-build call ndk-build
if %ERRORLEVEL% EQU 0 ( if %ERRORLEVEL% EQU 0 (
echo ndk-build has failed, build cancelled
cd.. cd..
mkdir "assets\shaders\base" mkdir "assets\shaders\base"
@ -18,7 +17,7 @@ if %ERRORLEVEL% EQU 0 (
xcopy "..\..\data\models\plane_z.obj" "assets\models" /Y xcopy "..\..\data\models\plane_z.obj" "assets\models" /Y
mkdir "assets\textures" mkdir "assets\textures"
xcopy "..\..\data\textures\pattern_35_bc3.ktx" "assets\textures" /Y xcopy "..\..\data\textures\trail_bc3.ktx" "assets\textures" /Y
xcopy "..\..\data\textures\goblin_bc3.ktx" "assets\textures" /Y xcopy "..\..\data\textures\goblin_bc3.ktx" "assets\textures" /Y
mkdir "res\drawable" mkdir "res\drawable"

View file

@ -40,14 +40,13 @@ void main()
boneTransform += ubo.bones[inBoneIDs[2]] * inBoneWeights[2]; boneTransform += ubo.bones[inBoneIDs[2]] * inBoneWeights[2];
boneTransform += ubo.bones[inBoneIDs[3]] * inBoneWeights[3]; boneTransform += ubo.bones[inBoneIDs[3]] * inBoneWeights[3];
outNormal = inNormal;
outColor = inColor; outColor = inColor;
outUV = inUV; outUV = inUV;
gl_Position = ubo.projection * ubo.view * ubo.model * boneTransform * vec4(inPos.xyz, 1.0); gl_Position = ubo.projection * ubo.view * ubo.model * boneTransform * vec4(inPos.xyz, 1.0);
vec4 pos = ubo.model * vec4(inPos, 1.0); vec4 pos = ubo.model * vec4(inPos, 1.0);
outNormal = mat3(inverse(transpose(ubo.model))) * inNormal; outNormal = mat3(inverse(transpose(ubo.model * boneTransform))) * inNormal;
outLightVec = ubo.lightPos.xyz - pos.xyz; outLightVec = ubo.lightPos.xyz - pos.xyz;
outViewVec = ubo.viewPos.xyz - pos.xyz; outViewVec = ubo.viewPos.xyz - pos.xyz;
} }

View file

@ -19,14 +19,13 @@ void main()
float distSqr = dot(inLightVec, inLightVec); float distSqr = dot(inLightVec, inLightVec);
vec3 lVec = inLightVec * inversesqrt(distSqr); vec3 lVec = inLightVec * inversesqrt(distSqr);
float invRadius = 1.0/4500.0; const float attInvRadius = 1.0/5000.0;
float atten = max(clamp(1.0 - attInvRadius * sqrt(distSqr), 0.0, 1.0), 0.0);
float atten = max(clamp(1.0 - invRadius * sqrt(distSqr), 0.0, 1.0), 0.0);
// Fake drop shadow // Fake drop shadow
invRadius = 1.0/2500.0; const float shadowInvRadius = 1.0/2500.0;
float dropshadow = max(clamp(1.0 - invRadius * sqrt(distSqr), 0.0, 1.0), 0.0); float dropshadow = max(clamp(1.0 - shadowInvRadius * sqrt(distSqr), 0.0, 1.0), 0.0);
outFragColor = vec4(color.g * (1.0 - dropshadow)); outFragColor = vec4(color.rgba * (1.0 - dropshadow));
outFragColor.rgb *= atten; outFragColor.rgb *= atten;
} }

View file

@ -29,7 +29,7 @@ out gl_PerVertex
void main() void main()
{ {
outUV = inUV * 2.0 + ubo.uvOffset; outUV = inUV + ubo.uvOffset;
vec4 pos = vec4(inPos, 1.0); vec4 pos = vec4(inPos, 1.0);
gl_Position = ubo.projection * ubo.view * ubo.model * vec4(pos); gl_Position = ubo.projection * ubo.view * ubo.model * vec4(pos);

BIN
data/textures/trail_bc3.ktx Normal file

Binary file not shown.

View file

@ -20,6 +20,7 @@
#include <vulkan/vulkan.h> #include <vulkan/vulkan.h>
#include "vulkanexamplebase.h" #include "vulkanexamplebase.h"
#include "vulkanbuffer.hpp"
#define VERTEX_BUFFER_BIND_ID 0 #define VERTEX_BUFFER_BIND_ID 0
#define ENABLE_VALIDATION false #define ENABLE_VALIDATION false
@ -351,9 +352,9 @@ public:
SkinnedMesh *skinnedMesh = nullptr; SkinnedMesh *skinnedMesh = nullptr;
struct { struct {
vkTools::UniformData vsScene; vk::Buffer mesh;
vkTools::UniformData floor; vk::Buffer floor;
} uniformData; } uniformBuffers;
struct { struct {
glm::mat4 projection; glm::mat4 projection;
@ -402,6 +403,7 @@ public:
enableTextOverlay = true; enableTextOverlay = true;
title = "Vulkan Example - Skeletal animation"; title = "Vulkan Example - Skeletal animation";
cameraPos = { 0.0f, 0.0f, 12.0f }; cameraPos = { 0.0f, 0.0f, 12.0f };
paused = true;
} }
~VulkanExample() ~VulkanExample()
@ -417,8 +419,8 @@ public:
textureLoader->destroyTexture(textures.colorMap); textureLoader->destroyTexture(textures.colorMap);
textureLoader->destroyTexture(textures.floor); textureLoader->destroyTexture(textures.floor);
vkTools::destroyUniformData(device, &uniformData.vsScene); uniformBuffers.mesh.destroy();
vkTools::destroyUniformData(device, &uniformData.floor); uniformBuffers.floor.destroy();
// Destroy and free mesh resources // Destroy and free mesh resources
vkMeshLoader::freeMeshBufferResources(device, &meshes.floor); vkMeshLoader::freeMeshBufferResources(device, &meshes.floor);
@ -536,19 +538,19 @@ public:
vertexBuffer.push_back(vertex); vertexBuffer.push_back(vertex);
} }
} }
uint32_t vertexBufferSize = vertexBuffer.size() * sizeof(Vertex); VkDeviceSize vertexBufferSize = vertexBuffer.size() * sizeof(Vertex);
// Generate index buffer from loaded mesh file // Generate index buffer from loaded mesh file
std::vector<uint32_t> indexBuffer; std::vector<uint32_t> indexBuffer;
for (uint32_t m = 0; m < skinnedMesh->meshLoader->m_Entries.size(); m++) for (uint32_t m = 0; m < skinnedMesh->meshLoader->m_Entries.size(); m++)
{ {
uint32_t indexBase = indexBuffer.size(); uint32_t indexBase = static_cast<uint32_t>(indexBuffer.size());
for (uint32_t i = 0; i < skinnedMesh->meshLoader->m_Entries[m].Indices.size(); i++) for (uint32_t i = 0; i < skinnedMesh->meshLoader->m_Entries[m].Indices.size(); i++)
{ {
indexBuffer.push_back(skinnedMesh->meshLoader->m_Entries[m].Indices[i] + indexBase); indexBuffer.push_back(skinnedMesh->meshLoader->m_Entries[m].Indices[i] + indexBase);
} }
} }
uint32_t indexBufferSize = indexBuffer.size() * sizeof(uint32_t); VkDeviceSize indexBufferSize = indexBuffer.size() * sizeof(uint32_t);
skinnedMesh->meshBuffer.indexCount = indexBuffer.size(); skinnedMesh->meshBuffer.indexCount = indexBuffer.size();
bool useStaging = true; bool useStaging = true;
@ -645,21 +647,10 @@ public:
} }
} }
void loadTextures() void loadAssets()
{
textureLoader->loadTexture(
getAssetPath() + "textures/goblin_bc3.ktx",
VK_FORMAT_BC3_UNORM_BLOCK,
&textures.colorMap);
textureLoader->loadTexture(
getAssetPath() + "textures/pattern_35_bc3.ktx",
VK_FORMAT_BC3_UNORM_BLOCK,
&textures.floor);
}
void loadMeshes()
{ {
textureLoader->loadTexture(getAssetPath() + "textures/goblin_bc3.ktx", VK_FORMAT_BC3_UNORM_BLOCK, &textures.colorMap);
textureLoader->loadTexture(getAssetPath() + "textures/trail_bc3.ktx", VK_FORMAT_BC3_UNORM_BLOCK, &textures.floor);
VulkanExampleBase::loadMesh(getAssetPath() + "models/plane_z.obj", &meshes.floor, vertexLayout, 512.0f); VulkanExampleBase::loadMesh(getAssetPath() + "models/plane_z.obj", &meshes.floor, vertexLayout, 512.0f);
} }
@ -798,7 +789,7 @@ public:
descriptorSet, descriptorSet,
VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
0, 0,
&uniformData.vsScene.descriptor), &uniformBuffers.mesh.descriptor),
// Binding 1 : Color map // Binding 1 : Color map
vkTools::initializers::writeDescriptorSet( vkTools::initializers::writeDescriptorSet(
descriptorSet, descriptorSet,
@ -823,7 +814,7 @@ public:
descriptorSets.floor, descriptorSets.floor,
VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
0, 0,
&uniformData.floor.descriptor)); &uniformBuffers.floor.descriptor));
// Binding 1 : Color map // Binding 1 : Color map
writeDescriptorSets.push_back( writeDescriptorSets.push_back(
vkTools::initializers::writeDescriptorSet( vkTools::initializers::writeDescriptorSet(
@ -917,31 +908,23 @@ public:
// Prepare and initialize uniform buffer containing shader uniforms // Prepare and initialize uniform buffer containing shader uniforms
void prepareUniformBuffers() void prepareUniformBuffers()
{ {
// Vertex shader uniform buffer block // Mesh uniform buffer block
createBuffer( vulkanDevice->createBuffer(
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
sizeof(uboVS), &uniformBuffers.mesh,
nullptr, sizeof(uboVS));
&uniformData.vsScene.buffer, // Map persistant
&uniformData.vsScene.memory, VK_CHECK_RESULT(uniformBuffers.mesh.map());
&uniformData.vsScene.descriptor);
// Map for host access // Floor uniform buffer block
VK_CHECK_RESULT(vkMapMemory(device, uniformData.vsScene.memory, 0, sizeof(uboVS), 0, (void **)&uniformData.vsScene.mapped)); vulkanDevice->createBuffer(
// Floor
createBuffer(
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
sizeof(uboFloor), &uniformBuffers.floor,
nullptr, sizeof(uboFloor));
&uniformData.floor.buffer, // Map persistant
&uniformData.floor.memory, VK_CHECK_RESULT(uniformBuffers.floor.map());
&uniformData.floor.descriptor);
// Map for host access
VK_CHECK_RESULT(vkMapMemory(device, uniformData.floor.memory, 0, sizeof(uboFloor), 0, (void **)&uniformData.floor.mapped));
updateUniformBuffers(true); updateUniformBuffers(true);
} }
@ -950,7 +933,7 @@ public:
{ {
if (viewChanged) if (viewChanged)
{ {
uboVS.projection = glm::perspective(glm::radians(60.0f), (float)width / (float)height, 0.1f, 512.0f); uboVS.projection = glm::perspective(glm::radians(60.0f), (float)width / (float)height, 0.1f, 1024.0f);
glm::mat4 viewMatrix = glm::translate(glm::mat4(), glm::vec3(0.0f, 0.0f, zoom)); glm::mat4 viewMatrix = glm::translate(glm::mat4(), glm::vec3(0.0f, 0.0f, zoom));
viewMatrix = glm::rotate(viewMatrix, glm::radians(90.0f), glm::vec3(1.0f, 0.0f, 0.0f)); viewMatrix = glm::rotate(viewMatrix, glm::radians(90.0f), glm::vec3(1.0f, 0.0f, 0.0f));
@ -980,11 +963,11 @@ public:
uboVS.bones[i] = glm::transpose(glm::make_mat4(&skinnedMesh->boneTransforms[i].a1)); uboVS.bones[i] = glm::transpose(glm::make_mat4(&skinnedMesh->boneTransforms[i].a1));
} }
memcpy(uniformData.vsScene.mapped, &uboVS, sizeof(uboVS)); uniformBuffers.mesh.copyTo(&uboVS, sizeof(uboVS));
// Update floor animation // Update floor animation
uboFloor.uvOffset.t -= 0.5f * skinnedMesh->animationSpeed * frameTimer; uboFloor.uvOffset.t -= 0.25f * skinnedMesh->animationSpeed * frameTimer;
memcpy(uniformData.floor.mapped, &uboFloor, sizeof(uboFloor)); uniformBuffers.floor.copyTo(&uboFloor, sizeof(uboFloor));
} }
void draw() void draw()
@ -1001,9 +984,8 @@ public:
void prepare() void prepare()
{ {
VulkanExampleBase::prepare(); VulkanExampleBase::prepare();
loadTextures(); loadAssets();
loadMesh(); loadMesh();
loadMeshes();
setupVertexDescriptions(); setupVertexDescriptions();
prepareUniformBuffers(); prepareUniformBuffers();
setupDescriptorSetLayout(); setupDescriptorSetLayout();
@ -1068,63 +1050,4 @@ public:
} }
}; };
VulkanExample *vulkanExample; VULKAN_EXAMPLE_MAIN()
#if defined(_WIN32)
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
if (vulkanExample != NULL)
{
vulkanExample->handleMessages(hWnd, uMsg, wParam, lParam);
}
return (DefWindowProc(hWnd, uMsg, wParam, lParam));
}
#elif defined(__linux__) && !defined(__ANDROID__)
static void handleEvent(const xcb_generic_event_t *event)
{
if (vulkanExample != NULL)
{
vulkanExample->handleEvent(event);
}
}
#endif
// Main entry point
#if defined(_WIN32)
// Windows entry point
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pCmdLine, int nCmdShow)
#elif defined(__ANDROID__)
// Android entry point
void android_main(android_app* state)
#elif defined(__linux__)
// Linux entry point
int main(const int argc, const char *argv[])
#endif
{
#if defined(__ANDROID__)
// Removing this may cause the compiler to omit the main entry point
// which would make the application crash at start
app_dummy();
#endif
vulkanExample = new VulkanExample();
#if defined(_WIN32)
vulkanExample->setupWindow(hInstance, WndProc);
#elif defined(__ANDROID__)
// Attach vulkan example to global android application state
state->userData = vulkanExample;
state->onAppCmd = VulkanExample::handleAppCommand;
state->onInputEvent = VulkanExample::handleAppInput;
vulkanExample->androidApp = state;
#elif defined(__linux__)
vulkanExample->setupWindow();
#endif
#if !defined(__ANDROID__)
vulkanExample->initSwapchain();
vulkanExample->prepare();
#endif
vulkanExample->renderLoop();
delete(vulkanExample);
#if !defined(__ANDROID__)
return 0;
#endif
}

View file

@ -21,6 +21,12 @@
<ClInclude Include="..\base\vulkanexamplebase.h" /> <ClInclude Include="..\base\vulkanexamplebase.h" />
<ClInclude Include="..\base\vulkantools.h" /> <ClInclude Include="..\base\vulkantools.h" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<None Include="..\data\shaders\skeletalanimation\mesh.frag" />
<None Include="..\data\shaders\skeletalanimation\mesh.vert" />
<None Include="..\data\shaders\skeletalanimation\texture.frag" />
<None Include="..\data\shaders\skeletalanimation\texture.vert" />
</ItemGroup>
<PropertyGroup Label="Globals"> <PropertyGroup Label="Globals">
<ProjectGuid>{469A1996-9BC5-4003-9564-C3816E3822E0}</ProjectGuid> <ProjectGuid>{469A1996-9BC5-4003-9564-C3816E3822E0}</ProjectGuid>
<RootNamespace>skelatalanimation</RootNamespace> <RootNamespace>skelatalanimation</RootNamespace>
@ -54,6 +60,7 @@
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<OpenMPSupport>true</OpenMPSupport> <OpenMPSupport>true</OpenMPSupport>
<AdditionalOptions>/FS %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/FS %(AdditionalOptions)</AdditionalOptions>
<WarningLevel>Level3</WarningLevel>
</ClCompile> </ClCompile>
<Link> <Link>
<AdditionalDependencies>..\libs\vulkan\vulkan-1.lib;..\libs\assimp\assimp.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>..\libs\vulkan\vulkan-1.lib;..\libs\assimp\assimp.lib;%(AdditionalDependencies)</AdditionalDependencies>

View file

@ -13,6 +13,9 @@
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter> </Filter>
<Filter Include="Shaders">
<UniqueIdentifier>{a7e2f71f-eff6-4f0b-9c6f-60b729319523}</UniqueIdentifier>
</Filter>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\base\vulkandebug.cpp"> <ClCompile Include="..\base\vulkandebug.cpp">
@ -39,4 +42,18 @@
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup>
<None Include="..\data\shaders\skeletalanimation\mesh.frag">
<Filter>Shaders</Filter>
</None>
<None Include="..\data\shaders\skeletalanimation\mesh.vert">
<Filter>Shaders</Filter>
</None>
<None Include="..\data\shaders\skeletalanimation\texture.frag">
<Filter>Shaders</Filter>
</None>
<None Include="..\data\shaders\skeletalanimation\texture.vert">
<Filter>Shaders</Filter>
</None>
</ItemGroup>
</Project> </Project>