collada + glsl

Started by
1 comment, last by bobmckenzie123 12 years, 11 months ago
Hi,

A while ago I started writing an application using C# and the tao framework that parses a collada file (generated by DAZ Studio). I put a post on here to get some help with VBO usage with GLSL and I was directed on how to use the vertex attribute functionality. I've been hammering away at it and I'm pretty close to getting the rendering to work but something is off with the way the shader is skinning the model. I'd really first like to confirm that my shader is performing correctly. Below is the link to the COLLADA specifications for 1.4. If you look at page 4-6 it describes the formula for skinning a skeleton. I believe that I've implemented my shader correctly, but I'm hoping that someone can take a look at it and see if I'm doing anything wrong. This will help me narrow down where the problem is: the shader or the C# code. I've also posted 2 screenshots. The first is of the skeleton of the model in it's initial pose. The second is of the skeleton with the skin applied. Hopefully someone may be able to tell me from looking at the second image what I might be doing wrong. Any help will be greatly appreciated.

http://www.khronos.o...da_spec_1_4.pdf

Vertex Shader Code:


#version 120

uniform mat4 BindShapeMatrix;
uniform mat4[63] InverseBindPoseMatrixArray;
uniform mat4[63] TransformMatrixArray;

attribute vec4 v_Vertex;
attribute vec3 v_Normal;
attribute vec2 v_TexCoord0;
attribute float i_NumBones;
attribute vec4 v_Weights;
attribute vec4 v_BoneIndexes;

varying vec3 N;
varying vec3 v;

void main()
{
v = vec3(gl_ModelViewMatrix * v_Vertex);
N = normalize(gl_NormalMatrix * v_Normal);

vec4 outv = vec4(0.0, 0.0, 0.0, 1.0);
vec4 inv = vec4(0.0, 0.0, 0.0, 1.0);
int i = 0;
int bi = 0;
float w = 0.0;
mat4 tmp;
float totWeight = 0.0;

vec4 v1 = vec4(0.0, 0.0, 0.0, 1.0);
vec4 v3 = vec4(0.0, 0.0, 0.0, 1.0);


inv = BindShapeMatrix * v_Vertex;

for( i = 0; i < int(i_NumBones); i++ )
{
if( i == 0 )
{
bi = int(v_BoneIndexes.x);
w = v_Weights.x;
}

if( i == 1 )
{
bi = int(v_BoneIndexes.y);
w = v_Weights.y;
}

if( i == 2 )
{
bi = int(v_BoneIndexes.z);
w = v_Weights.z;
}

if( i == 3 )
{
bi = int(v_BoneIndexes.w);
w = v_Weights.w;
}

tmp = InverseBindPoseMatrixArray[bi] * TransformMatrixArray[bi];
v3 = tmp * inv;


// animation frame...
v1.x = v3.x * w;
v1.y = v3.y * w;
v1.z = v3.z * w;

outv.x = outv.x + v1.x;
outv.y = outv.y + v1.y;
outv.z = outv.z + v1.z;

totWeight = totWeight + w;
}


gl_Position = (gl_ModelViewProjectionMatrix * outv);

}
Advertisement
sry I can't really help u with your question, but I have some optimizations for your shader

u can replace ur if statments with
bi = int(v_BoneIndexes);
w = v_Weights;



calculate the multiplication of the InverseBindPoseMatrix and TransformMatrix on the CPU

u can write some lines shorter
// animation frame...
v1.xyz = v3.xyz * w;
outv.xyz += v1.xyz; ;


u aren't using the variables totWeight and v

I think it could be possible that the for loop with a constant iteration of 4 is fast as your use of i_NumBones, just send a weight of 0.
Aha, so a vec4 can be treated as an array of four floats. Thank you for clarifying that, I hated what I was doing with those if statements.

This topic is closed to new replies.

Advertisement