Home Game Development instancing – GLSL GLTF Instanced Hardware Skinning

instancing – GLSL GLTF Instanced Hardware Skinning

0
instancing – GLSL GLTF Instanced Hardware Skinning

[ad_1]

I’m beating my head on making an attempt to get {hardware} skinning moving into my engine.
We’re utilizing OZZ Animation and TinyGLTF collectively to animate fashions.

The situation appears to both stem from how OZZ maps their joint id’s vs how I seize them out of the .gltf file utilizing TinyGLTF or how the inverse bind poses are mapped when loading the .gltf file.

When loading a mannequin, we map joint names to id’s and seize the bind poses:

for (size_t i = 0; i < mannequin.skins.dimension(); i++)
{
    tinygltf::Skin _Skin = mannequin.skins[i];
    
    for (auto& JointID : _Skin.joints)
    {
        std::string NodeName = mannequin.nodes[JointID].identify;
        Infos->JointMap_[NodeName] = JointID - _Skin.skeleton;
    }

    if (_Skin.inverseBindMatrices > -1)
    {
        const tinygltf::Accessor& acc = mannequin.accessors[_Skin.inverseBindMatrices];
        const tinygltf::BufferView& bufview = mannequin.bufferViews[acc.bufferView];
        const tinygltf::Buffer& buf = mannequin.buffers[bufview.buffer];
        Infos->InverseBindMatrices.resize(acc.rely);
        memcpy(Infos->InverseBindMatrices.knowledge(), &buf.knowledge[acc.byteOffset + bufview.byteOffset], acc.rely * sizeof(glm::mat4));

        break;
    }
}

Infos is only a struct that holds our loaded mannequin knowledge.

Infos->JointMap_ is std::map<std::string, uint16_t> JointMap_ = {};

Infos->InverseBindMatrices is std::vector<glm::mat4> InverseBindMatrices = {};

We go our Infos construction off and later when rendering the item, we use the information to animate our mannequin:

auto joints = skeleton_.num_joints();
for (int i = 0; i < joints; i++)
{
    const char* OZZ_JointTitle = skeleton_.joint_names()[i];
    uint16_t GLFW_JointIndex = _GLTFJointMap[OZZ_JointName];

    glm::mat4 OZZ_Matrix = to_mat4(models_[i]);
    glm::mat4 GLFW_Matrix = InverseBindMatrices_[GLFW_JointIndex];

    if (_Mesh->bAnimated && i < 32)
    {
        _Mesh->instanceData_Animation[instanceIndex].bones[GLFW_JointIndex] = OZZ_Matrix * GLFW_Matrix;
    }
}

Iterate via all of the joints in our skeleton.

For every joint get the joint identify.

From this identify get the gltf joint index.

Take the ozz mannequin area animation matrix and multiply it with the gltf inverse bind pose, and replace every bone on our mannequin to carry the computed matrix.

The knowledge is uploaded to our vertex shader and used to show the animated mannequin:

#model 450

format(location = 0) in vec4 inPosition;
//format(location = 1) in vec3 inColor;
format(location = 2) in vec2 inTexCoord;
format(location = 3) in vec3 inNormal;
format(location = 4) in vec3 inTangent;
format(location = 5) in vec4 inBones;
format(location = 6) in vec4 inWeights;

format(std140, binding = 0) readonly buffer InstanceData {
    mat4 mannequin[];
} ssbo;

format (binding = 1) uniform UBO {
    mat4 view_proj;
} ubo;

format(std140, binding = 2) readonly buffer InstanceData_Animated {
    mat4 Matrices[32];
} Joint[];

format(location = 0) out vec3 outNormal;
format(location = 1) out vec2 outUV;
//format(location = 2) out vec3 outColor;
format(location = 3) out vec4 outWorldPos;
format(location = 4) out vec3 outTangent;

void essential() {
    outWorldPos = ssbo.mannequin[gl_InstanceIndex] * inPosition;
    outUV = inTexCoord;
    //outColor = inColor;

    mat4 skinMat =
        inWeights.x * Joint[0].Matrices[int(inBones.x)] +
        inWeights.y * Joint[0].Matrices[int(inBones.y)] +
        inWeights.z * Joint[0].Matrices[int(inBones.z)] +
        inWeights.w * Joint[0].Matrices[int(inBones.w)];

    //gl_Position = ubo.view_proj * ssbo.mannequin[gl_InstanceIndex] * inPosition;
    gl_Position = ubo.view_proj * ssbo.mannequin[gl_InstanceIndex] * skinMat * inPosition;
    
    
    mat3 mNormal = transpose(inverse(mat3(ssbo.mannequin[gl_InstanceIndex])));
    outNormal = mNormal * normalize(inNormal);
    outTangent = mNormal * normalize(inTangent);

}

Which finally ends up giving us one thing like this:

enter image description here

When it ought to seem like this:

enter image description here

(not my screenshots, used as an example the difficulty).

My shader code must be positive. If I painstakingly manually map the joint names to joint index by hand, I can get right output. This handbook mapping was positive to assist work out the place the difficulty was in my program, however must be programmatically computed when loading the mannequin for apparent causes.

Any concepts what I’m doing improper right here??

[ad_2]

LEAVE A REPLY

Please enter your comment!
Please enter your name here