I have a basic shape that I want to render. Nothing too complex, just a tall cube. And I want to attach 2 bones to it. Not only that, but I also want one of the bones/matrices to influence the cube more than the other bone, say 60-40 ratio. Can someone show or explain how to do this? I've been trying to find an explanation for this the past few days without luck. How to calculate the weight of a bone/matrix and how (much) effect it will have on the vertex transformation.

Im just using basic c++/opengl for this, looking for an explanation about how weights are calculated in, especially if there are multiple bones.

up vote 3 down vote accepted

You need to add together all the end results of each weighted bone for the vertex. The weights should add up to 1 in total for the weights to be correct. So basically:

float weight1 = 60.0f;
float weight2 = 40.0f;
float totalWeights = weight1 + weight2;
// Make them be from 0 to 1, and 1 in total.
weight1 = weight1 / totalWeights;
weight2 = weight2 / totalWeights;

And then in the shader:

vec4 vPos = bone1matrix * vertex * weight1 + bone2matrix * vertex * weight2;

The same applies for normals and other vertex data you want to animate with the bones.

A better example copy pasted from the OpenGL Wiki:

//[Vertex Shader]
attribute vec4 Vertex;
attribute vec3 Normal;
attribute vec2 TexCoord;
attribute vec2 Index;
attribute vec2 Weight;
uniform mat4 ModelviewMatrix;
uniform mat4 ProjectionModelviewMatrix;
uniform mat4 Bone[10];  //Array of bones that you compute (animate) on the CPU and you upload to the shader
//-----------------------
varying vec2 TexCoord0;
varying vec3 EyeNormal;
//-----------------------
void main()
{
  vec4 newVertex;
  vec4 newNormal;
  int index;
  //-----------------------
  index=int(Index.x);    //Cast to int
  newVertex = (Bone[index] * Vertex) * Weight.x;
  newNormal = (Bone[index] * vec4(Normal, 0.0)) * Weight.x;
  index=int(Index.y);    //Cast to int
  newVertex = (Bone[index] * Vertex) * Weight.y + newVertex;
  newNormal = (Bone[index] * vec4(Normal, 0.0)) * Weight.y + newNormal;
  EyeNormal = vec3(ModelviewMatrix * newNormal);
  gl_Position = ProjectionModelviewMatrix * newVertex;
  TexCoord0 = TexCoord;
}
  • This is exactly what I was looking for. Very nice – Charlie Sep 3 '16 at 16:08

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.