Glsl шкуры препятствие, кто может прыгнуть это? - PullRequest
2 голосов
/ 17 февраля 2012

В настоящее время я пытаюсь настроить скины графического процессора (с помощью glsl), но он работает не так, как я бы :) На самом деле он вообще не работает.Мой меш исчезнет, ​​когда я попробую этот код glsl:

layout(location = 0) in vec3    vertexPos;
layout(location = 1) in vec2    vertexUv;
layout(location = 2) in vec3    vertexNor;
layout(location = 5) in ivec4   joints_influences;
layout(location = 6) in vec4    weights_influences;

uniform mat4    ViewProj, View, Proj, Model;
out vec3        vertexPosEye;
out vec3        vertexNorEye;

const int       MAX_INFLUENCES = 4;
const int       MAX_BONES = 50;
uniform mat4    animation_matrices[MAX_BONES];
uniform mat4    inv_bind_matrices[MAX_BONES];

void main()
{
    vertexPosEye = (View * Model * vec4(vertexPos, 1)).xyz;     // Position
    vertexNorEye = (View * Model * vec4(vertexNor, 0)).xyz;     // Normal matrix

    vec4 final_v = vec4(0, 0, 0, 0);

    for (int i = 0; i < MAX_INFLUENCES; i++)
    {
        vec4 v =        vec4(vertexPos, 1)
                    *   inv_bind_matrices[joints_influences[i]]
                    *   animation_matrices[joints_influences[i]]
                    *   weights_influences[i];

        final_v += v;
    }
    gl_Position =  ViewProj * Model * final_v;
}

, когда я попробую это:

gl_Position =  ViewProj * Model * vertexPos;

Мой меш вернулся :), но больше никаких анимаций, конечно же ...

Вот код моего приложения (c ++), когда я устанавливаю атрибуты VBO:

// Vertex position
glGenBuffers(1, &buffer[0]);
glBindBuffer(GL_ARRAY_BUFFER, buffer[0]);
glBufferData(GL_ARRAY_BUFFER, vertices.pos.size() * sizeof(bVector3), &vertices.pos[0], GL_STATIC_DRAW);

// Ibid for uv, normals, tangents and bitangents.

// Skinning : joints index
glGenBuffers(1, &buffer[5]);
glBindBuffer(GL_ARRAY_BUFFER, buffer[5]);
glBufferData(GL_ARRAY_BUFFER, vertices.joints.size() * sizeof(SkinningJoints), &vertices.joints[0], GL_STATIC_DRAW);

// Skinning : weights
glGenBuffers(1, &buffer[6]);
glBindBuffer(GL_ARRAY_BUFFER, buffer[6]);
glBufferData(GL_ARRAY_BUFFER, vertices.weights.size() * sizeof(SkinningWeights), &vertices.weights[0], GL_STATIC_DRAW);

// Indices
glGenBuffers(1, &buffer[7]);
glBindBuffer(GL_ARRAY_BUFFER, buffer[7]);
glBufferData(GL_ARRAY_BUFFER, vertices.indices.size() * sizeof(bUshort), &vertices.indices[0], GL_STATIC_DRAW);

В основном цикле:

glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, m->GetBuffer(0));
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));

glEnableVertexAttribArray(for uv, normals, tangents and bitangents)...

glEnableVertexAttribArray(5);
glBindBuffer(GL_ARRAY_BUFFER, m->GetBuffer(5));
glVertexAttribPointer(5, 4, GL_INT, GL_FALSE, 0, BUFFER_OFFSET(0));

glEnableVertexAttribArray(6);
glBindBuffer(GL_ARRAY_BUFFER, m->GetBuffer(6));
glVertexAttribPointer(6, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m->GetBuffer(7));
glDrawElements(GL_TRIANGLES, m->vertices.indices.size(), GL_UNSIGNED_SHORT, BUFFER_OFFSET(0));

Вот моя структура RenderingVertices (после рекомендаций Барра):

struct RenderingVertices
{
    // std::vector<Vec3>
    vVec3                       pos, nor, tang, btan;
    vVec2                       uv;
    vUshort                     indices;

    vector<SkinningJoints>      joints;
    vector<SkinningWeights>     weights;
};

А вот моя структура SkinningJoints:

struct SkinningJoints
{
    int         j[MAX_BONES_PER_VERT];

    SkinningJoints(Vertex::Weights weights[MAX_BONES_PER_VERT])
    {
        for (bUint i = 0; i < MAX_BONES_PER_VERT; i++)
            j[i] = weights[i].jid;
    }
};

Моя структура SkinningWeights почти такая же, с массивом float вместо int.

Сейчаскогда я пытаюсь отладить индекс соединений, значения весов и конечную вершину как цвета, вот что я получаю:

// Shader
color_debug = joints_influences;

http://www.images -host.fr / view.php? img = 00021800pop.jpg

color_debug = weights_influences;

http://www.images -host.fr / view.php? img = 00021800pop2.jpg

Еще одна интересная вещь, когда я пытаюсьэто:

vec4 pop = vec4(vertexPos, 1) * animation_matrices[1] * inv_bind_matrices[1] * 1.0;
gl_Position =  ViewProj * Model * pop;

Моя вся сетка на самом деле вращается, а это значит, что мои одинаковые animation_matrices хороши.

Каждый может увидеть, что я делаю вг здесь?

Ответы [ 2 ]

4 голосов
/ 19 февраля 2012

Я наконец-то заработал.Для тех, кто может быть заинтересован, вот что я делал неправильно:

Когда я отправляю массив индексов соединений в Glsl, вместо этого:

glEnableVertexAttribArray(5);
glBindBuffer(GL_ARRAY_BUFFER, m->GetBuffer(5));
glVertexAttribPointer(5, 4, GL_INT, GL_FALSE, 0, BUFFER_OFFSET(0));

Мне нужно было сделать это:

glEnableVertexAttribArray(5);
glBindBuffer(GL_ARRAY_BUFFER, m->GetBuffer(5));
glVertexAttribIPointer(5, 4, GL_INT, 0, BUFFER_OFFSET(0));

Вы должны присмотреться, чтобы найти разницу.Вместо вызова glVertexAttribPointer () мне нужно было вызвать glVertexAttribIPointer (), потому что индексы соединений равны int.

Надеюсь, это когда-нибудь кому-нибудь поможет.

2 голосов
/ 17 февраля 2012

Вы пробовали отлаживать свои атрибуты скинов?Выведите вес вершины в цветах, чтобы вы могли подтвердить, что у вас есть значимые значения?Если все чёрное, вы будете знать, где искать.

Беглый взгляд на ваши RenderingVertices, я могу обнаружить первую проблему.Вы передаете Вектор указателей в GL, и я не думаю, что это то, что вы хотите сделать.

В большинстве случаев вы ограничиваете влияние скиннинга на 4 пары суставов / вес на вершину.Таким образом, вы можете использовать простой массив (например, SkinningJoints joint [4];).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...