3

プログラムに GLSL を利用した骨格アニメーションを実装しようとしています...美しい 3D アニメーションではなく、モンスターを作成しました: https://i.imgur.com/dmpKg6n.gif

いくつかの異なる手法を試した後、恐ろしくはありませんが、それでも巨大なものを作成しました。

モンスター

モデルはスーツを着た基本的な人間で、アニメーションは脚が揺れるのに対し、他のすべては静止したままです (非常に単純なテスト アニメーション)。すべてのボーンには、元の場所の t=0 に静的なキーフレームがあり、数秒ごとに位置がずれることを最小限に抑えようとしています。

問題は...かなり目に見えるはずです。また、モデルの身長が想定よりも高いことは確かです。

とにかく、これは私のオリジナルの Vertex Shader です。

#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から派生したものです。

新しいシェーダーは、ランダムにグーグル検索することで得られました。

編集:私は今これを取得します:

足ツイスティツイスティ

このコードで: http://pastebin.com/PvCWUdJn

今...私は何を間違っていますか?! これを処理する「適切な」方法は何ですか? このチュートリアルの代わりに使用すべき高品質のチュートリアルはありますか?

更新: テスト アプリの完全なソース コード: https://github.com/mcmonkey4eva/skeletalanimationtest

4

1 に答える 1

1

したがって、答えは簡単です。シェーダーで行列 x ベクトル、複数のベクトル x 行列を乗算しないでください。

于 2015-05-04T03:43:04.237 に答える