2015-04-28 104 views
3

我想實現在程序GLSL供電的骨骼動畫......而非美麗的3D動畫,我創建了一個怪物:https://i.imgur.com/dmpKg6n.gif骨骼動畫在OpenGL(GLSL)與Assimp

嘗試了之後幾個不同的技術,我創建了一個不太可怕,但仍然滔天事情

Monster

該模型是穿西裝的基本人權,動畫應該是腿部擺動,而所有其他靜止不動(一個非常簡單的測試動畫)。 所有骨骼在t = 0時在其原始位置都有靜態關鍵幀,以儘量減少它們每隔幾秒跳出一個位置。

問題...應該是相當可見的。另外,我相當確定這個模型比它應該的高。

無論如何,這是我原來的頂點着色器:

#version 430 core 
layout (location = 0) in vec4 position; 
layout (location = 1) in vec3 normal; 
layout (location = 2) in vec2 texcoords; 
layout (location = 3) in vec4 color; 
layout (location = 4) in vec4 Weights; 
layout (location = 5) in vec4 BoneID; 
layout (location = 0) out vec4 f_position; 
layout (location = 1) out vec3 f_normal; 
layout (location = 2) out vec2 f_texcoord; 
const int MAX_BONES = 50; 
layout (location = 1) uniform mat4 proj_matrix; 
layout (location = 2) uniform mat4 mv_matrix; 
layout (location = 6) uniform mat4 boneTrans[MAX_BONES]; 
void main(void) 
{ 
mat4 boneTransform = (boneTrans[int(BoneID[0])] * Weights[0]) + 
(boneTrans[int(BoneID[1])] * Weights[1]) + 
(boneTrans[int(BoneID[2])] * Weights[2]) + 
(boneTrans[int(BoneID[3])] * Weights[3]); 
float rem = 1 - (Weights[0] + Weights[1] + Weights[2] + Weights[3]); 
boneTransform += mat4(1.0) * rem; 
f_texcoord = texcoords; 
f_position = mv_matrix * (boneTransform * position); 
mat4 mv_mat_simple = mv_matrix; 
mv_mat_simple[3][0] = 0.0; 
mv_mat_simple[3][1] = 0.0; 
mv_mat_simple[3][2] = 0.0; 
vec4 norm1 = boneTransform * vec4(normal, 1.0); 
vec4 nnormal = mv_mat_simple * vec4(norm1.xyz, 1.0); 
f_normal = nnormal.xyz/nnormal.w; // TODO: Normalize? 
vec4 pos1 = boneTransform * position; 
gl_Position = proj_matrix * mv_matrix * vec4(pos1.xyz, 1.0); 
} 

,這是我新的:

#version 430 core 

layout (location = 0) in vec3 position; 
layout (location = 1) in vec3 normal; 
layout (location = 2) in vec2 texcoords; 
layout (location = 3) in vec4 color; 
layout (location = 4) in vec4 Weights; 
layout (location = 5) in vec4 BoneID; 

layout (location = 0) out vec4 f_position; 
layout (location = 1) out vec3 f_normal; 
layout (location = 2) out vec2 f_texcoord; 

const int MAX_BONES = 50; 

layout (location = 1) uniform mat4 proj_matrix; 
layout (location = 2) uniform mat4 mv_matrix; 
layout (location = 6) uniform mat4 boneTrans[MAX_BONES]; 

void main(void) 
{ 
    vec4 pos1 = vec4(position, 1.0); 
    pos1 += (boneTrans[int(BoneID[0])] * vec4(position, 0.0)) * Weights[0]; 
    pos1 += (boneTrans[int(BoneID[1])] * vec4(position, 0.0)) * Weights[1]; 
    pos1 += (boneTrans[int(BoneID[2])] * vec4(position, 0.0)) * Weights[2]; 
    pos1 += (boneTrans[int(BoneID[3])] * vec4(position, 0.0)) * Weights[3]; 
    vec4 norm1 = vec4(normal, 1.0); 
    norm1 += (boneTrans[int(BoneID[0])] * vec4(normal, 0.0)) * Weights[0]; 
    norm1 += (boneTrans[int(BoneID[1])] * vec4(normal, 0.0)) * Weights[1]; 
    norm1 += (boneTrans[int(BoneID[2])] * vec4(normal, 0.0)) * Weights[2]; 
    norm1 += (boneTrans[int(BoneID[3])] * vec4(normal, 0.0)) * Weights[3]; 
    f_texcoord = texcoords; 
    f_position = mv_matrix * vec4(pos1.xyz, 1.0); 
    mat4 mv_mat_simple = mv_matrix; 
    mv_mat_simple[3][0] = 0.0; 
    mv_mat_simple[3][1] = 0.0; 
    mv_mat_simple[3][2] = 0.0; 
    //vec4 norm1 = boneTransform * vec4(normal, 1.0); 
    vec4 nnormal = mv_mat_simple * vec4(norm1.xyz, 1.0); 
    f_normal = nnormal.xyz/nnormal.w; // TODO: Normalize? 
    gl_Position = proj_matrix * mv_matrix * vec4(pos1.xyz, 1.0); 
} 

骨處理代碼既不漂亮也不短:http://pastebin.com/A8x1GdUw

那代碼和原始着色器源自http://ogldev.atspace.co.uk/www/tutorial38/tutorial38.html

新的着色器來自隨機搜索。

編輯:現在我得到這樣的:

Leg twisty twisty

有了這個代碼:http://pastebin.com/PvCWUdJn

現在...我在做什麼錯?什麼是「適當」的方法來處理這個問題?是否有更高質量的教程可以用來替代這個教程?

UPDATE:完整的源代碼爲測試APP:https://github.com/mcmonkey4eva/skeletalanimationtest

+1

確保[N64墨盒始終處於完全就位狀態](http://knowyourmeme.com/memes/get-down-geddan)。 – genpfault

+0

我已經爲測試應用程序添加了證明此問題的完整源代碼:https://github.com/mcmonkey4eva/skeletalanimationtest – mcmonkey4eva

回答

1

所以答案很簡單 - 不要乘x矩陣向量,向量多X矩陣在着色器。