PDA

View Full Version : (help please)IQM animation on gpu



MGlNewb
02-12-2016, 09:07 AM
hello im new to modern opengl and am trying to get Iqm animation to work on the gpu. I have got the fixed function version of it working no problem, but shaders are new to me. I was would appreciate it if you guys could give me a hand.
here is the code i got so far http://pastebin.com/XJsTFKeF i put it all in one file so easier for you see all the code. here is the vert shader


#version 330

uniform mat4 projectionMatrix;
uniform mat4 modelViewMatrix;
uniform mat3x4 bonemats[80];
layout (location = 0) in vec3 inPosition;
layout (location = 1) in vec3 inColor;
layout (location = 2) in vec4 vweights;
layout (location = 3) in vec4 vbones;
layout (location = 4) in vec4 vtangent;



smooth out vec3 theColor;

void main()
{
mat3x4 m = bonemats[int(vbones.x)] * vweights.x;
m += bonemats[int(vbones.y)] * vweights.y;
m += bonemats[int(vbones.z)] * vweights.z;
m += bonemats[int(vbones.w)] * vweights.w;
vec4 mpos = vec4(gl_Vertex * m, gl_Vertex.w);
gl_Position = gl_ModelViewProjectionMatrix * mpos;
gl_TexCoord[0] = gl_MultiTexCoord0;
mat3 madjtrans = mat3(cross(m[1].xyz, m[2].xyz), cross(m[2].xyz, m[0].xyz), cross(m[0].xyz, m[1].xyz));
vec3 mnormal = gl_Normal * madjtrans;
vec3 mtangent = vtangent.xyz * madjtrans; // tangent not used, just here as an example
vec3 mbitangent = cross(mnormal, mtangent) * vtangent.w; // bitangent not used, just here as an example
gl_FrontColor = gl_Color * (clamp(dot(normalize(gl_NormalMatrix * mnormal), gl_LightSource[0].position.xyz), 0.0, 1.0) * gl_LightSource[0].diffuse + gl_LightSource[0].ambient);
gl_Position = projectionMatrix*modelViewMatrix*vec4(inPosition, 1.0);
theColor = inColor;
}


and here is frag shader


#version 330
uniform sampler2D tex;
smooth in vec3 theColor;
out vec4 outputColor;

void main()
{
outputColor = vec4(theColor, 1.0);
}


any help would be greatly appreciated.

Dark Photon
02-12-2016, 01:48 PM
Please surround source code with ... or [code]...[/nocode] tags as it makes it considerably more readable.

This isn't really a debugging service. What have you tried to debug this? Do you have specific OpenGL questions to ask?

Scanning your vertex shader, I don't see how it's going to compile. Your assigning to gl_Position twice. You're also trying to use the old GLSL 1.x legacy vertex attributes (gl_Vertex) in combination with your own custom vertex attributes (e.g. inPosition). Pick one and get rid of the other.

MGlNewb
02-13-2016, 09:29 AM
thank you dark photon i understand was to broad of a question but idk how delete it.

ill ask a more direct question, here is piece of the vert shader

void main()
{
mat3x4 m = bonemats[int(vbones.x)] * vweights.x;
m += bonemats[int(vbones.y)] * vweights.y;
m += bonemats[int(vbones.z)] * vweights.z;
m += bonemats[int(vbones.w)] * vweights.w;
vec4 mpos = inPosition * m;

and here is the output from running.

mrfixit.iqm: loaded mesh: Body
mrfixit.iqm: loaded material: Body.tga
mrfixit.iqm: loaded mesh: Head
mrfixit.iqm: loaded material: Head.tga
mrfixit.iqm: loaded anim: idle
error in shader 0(20) : error C1101: ambiguous overloaded function reference
"mul(vec3, mat3x4)"
(0) : mat3x1 mul(mat3, mat3x1)
(0) : mat3x1 mul(mat3x2, mat2x1)
(0) : mat3 mul(mat3x1, mat1x3)
(0) : mat3x2 mul(mat3x1, mat1x2)
(0) : mat3x1 mul(mat3x1, mat1)
(0) : mat2x1 mul(mat2x3, mat3x1)
(0) : mat2x1 mul(mat2, mat2x1)
(0) : mat2x3 mul(mat2x1, mat1x3)
(0) : mat2 mul(mat2x1, mat1x2)
(0) : mat2x1 mul(mat2x1, mat1)
(0) : mat1 mul(mat1x3, mat3x1)
(0) : mat1 mul(mat1x2, mat2x1)
(0) : mat1x3 mul(mat1, mat1x3)
(0) : mat1x2 mul(mat1, mat1x2)
(0) : mat1 mul(mat1, mat1)
(0) : superp vec1 mul(superp mat1, superp vec1)
(0) : superp vec1 mul(superp mat1x2, superp vec2)
(0) : superp vec1 mul(superp mat1x3, superp vec3)
(0) : superp vec2 mul(superp mat2x1, superp vec1)
(0) : superp vec2 mul(superp mat2, superp vec2)
(0) : superp vec2 mul(superp mat2x3, superp vec3)
(0) : superp vec3 mul(superp mat3x1, superp vec1)
(0) : superp vec3 mul(superp mat3x2, superp vec2)
(0) : superp vec3 mul(superp mat3, superp vec3)
(0) : lowp vec1 mul(lowp mat1, lowp vec1)
(0) : lowp vec1 mul(lowp mat1x2, lowp vec2)
(0) : lowp vec1 mul(lowp mat1x3, lowp vec3)
(0) : lowp vec2 mul(lowp mat2x1, lowp vec1)
(0) : lowp vec2 mul(lowp mat2, lowp vec2)
(0) : lowp vec2 mul(lowp mat2x3, lowp vec3)
(0) : lowp vec3 mul(lowp mat3x1, lowp vec1)
(0) : lowp vec3 mul(lowp mat3x2, lowp vec2)
(0) : lowp vec3 mul(lowp mat3, lowp vec3)
(0) : mediump vec1 mul(mediump mat1, mediump vec1)
(0) : mediump vec1 mul(mediump mat1x2, mediump vec2)
(0) : mediump vec1 mul(mediump mat1x3, mediump vec3)
(0) : mediump vec2 mul(mediump mat2x1, mediump vec1)
(0) : mediump vec2 mul(mediump mat2, mediump vec2)
(0) : mediump vec2 mul(mediump mat2x3, mediump vec3)
(0) : mediump vec3 mul(mediump mat3x1, mediump vec1)
(0) : mediump vec3 mul(mediump mat3x2, mediump vec2)
(0) : mediump vec3 mul(mediump mat3, mediump vec3)
(0) : vec1 mul(mat1, vec1)
(0) : vec1 mul(mat1x2, vec2)
(0) : vec1 mul(mat1x3, vec3)
(0) : vec2 mul(mat2x1, vec1)
(0) : vec2 mul(mat2, vec2)
(0) : vec2 mul(mat2x3, vec3)
(0) : vec3 mul(mat3x1, vec1)
(0) : vec3 mul(mat3x2, vec2)
(0) : vec3 mul(mat3, vec3)
(0) : vec4 mul(mat4x3, vec3)
Shader compilation failed.
Add shader failed.
this is where shader fails
vec4 mpos = inPosition * m;

can you not mult a vector by a matrix? or is it because its 3x4?

GClements
02-13-2016, 11:06 AM
mat3x4 m = bonemats[int(vbones.x)] * vweights.x;


A mat3x4 has 3 columns and 4 rows. This differs from the usual mathematical terminology, where a "3x4" matrix has 3 rows and 4 columns.





vec4 mpos = inPosition * m;


As m is a mat3x4, inPosition must be a vec4 and mpos would need to be a vec3.

If inPosition is a vec3, use


vec4 mpos = m * inPosition;

When multiplying a matrix by a vector, the vector is treated as a column vector if it appears on the right-hand side of the multiplication, and a row vector if it appears on the left-hand side.

Also:




mat3x4 m = bonemats[int(vbones.x)] * vweights.x;
m += bonemats[int(vbones.y)] * vweights.y;
m += bonemats[int(vbones.z)] * vweights.z;
m += bonemats[int(vbones.w)] * vweights.w;


Blending matrices using linear interpolation is rarely correct. E.g. the result of blending orthonormal matrices typically won't be orthonormal. This is the main reasons that skeletal animation normally uses unit quaternions.

Dark Photon
02-13-2016, 05:44 PM
Blending matrices using linear interpolation is rarely correct. E.g. the result of blending orthonormal matrices typically won't be orthonormal. This is the main reasons that skeletal animation normally uses unit quaternions.

This (Linear Blend Skinning) is a very simple and reasonable place to start to get a skinning implementation up and running quickly. It may even be sufficient, depending on the skeletal characters and animations involved, and the desired visual quality.

Only if it's insufficient for a developer's needs does it really make sense to get more complicated. And then I think it's possibly worth skipping quaternion-translation implementations due to the blending problems and going straight to dual quaternions.