3
\$\begingroup\$

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.

\$\endgroup\$

1 Answer 1

5
\$\begingroup\$

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;
}
\$\endgroup\$
1
  • \$\begingroup\$ This is exactly what I was looking for. Very nice \$\endgroup\$
    – Charlie
    Sep 3, 2016 at 16:08

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .