therealremi

01-28-2007, 06:43 AM

I know this is not OpenGL but I don't know any other 3D programming forum with so many experts ready to help. And I am desperate cause I see no further possibility to debug my application and shader.

I am trying to implement animation using vertex shader. And it ALMOST works. I mean I want my object to move smoothly with time. And I basically does this but there is some small artifact that I cannot track down. Here are the details:

Every position is described by a 3x4 matrix - every vertex of an object must be multiplied by this matrix for this object to be in this position.

I have 3 such matrices - one at each point of time.

matrixA = {1,0,0,0, 0,1,0,0, 0,0,1,0};

at point in time 0 ms

matrixB = {1,0,0,0, 0,1,0,1, 0,0,1,0};

at point in time 1000 ms

matrixC = {1,0,0,0, 0,1,0,2, 0,0,1,0};

at point in time 2000 ms

My app keeps track of current time and updates shader parameters accordingly. These 3 (uniform in Cg) parameters are: 2 matrices and a weight factor. The weight factor is used to linearly interpolate between two matrices, so it changes it's value from 0.0 to 1.0 during the flow of animation from 0 ms to 1000 ms, and again from 0.0 to 1.0 during animation from 1000 ms to 2000 ms. The 2 matrices send to a vertex shader are updated when 1000 ms have passed - so it is now blending between matrixB and matrixC.

Such interpolation between matrices in a vertex shader guarantees that the motion is smooth. And it is smooth. Except for one small problem: at the point in time when matrices are updated (1000 ms) the animated object for a fraction of second takes the position of the next matrix - that is, at time 1000 ms the object is for a fraction of second at position implied by matrixC, then instantly comes back to a position close to matrixB (which is the right position at this point in time) and continues to move smoothly towards position implied by matrixC.

Here is my shader code:

struct vertex_input

{

float4 position : POSITION;

};

struct vertex_output

{

float4 position : POSITION;

};

vertex_output vertex_program(vertex_input IN, uniform float4x4 model_view_proj, uniform float3x4 previous_matrix, uniform float3x4 next_matrix, uniform float weight)

{

vertex_output OUT;

float3 previous_position = mul( previous_matrix, IN.position );

float3 next_position = mul( next_matrix, IN.position );

float3 position = lerp(previous_position, next_position, weight);//here is the interpolation

OUT.position = mul(model_view_proj, float4(position, 1.0f));

return OUT;

} I thought I pass in parameters with wrong values so I printed them out just before sending them to the shader. Here is a fragment of the output at this problematic moment around 1000 ms.

previous_matrix : 1000 0100 0010

next_matrix : 1000 0101 0010

weight : 0.982

previous_matrix : 1000 0100 0010

next_matrix : 1000 0101 0010

weight : 0.999

previous_matrix : 1000 0101 0010

next_matrix : 1000 0102 0010

weight : 0.016

previous_matrix : 1000 0101 0010

next_matrix : 1000 0102 0010

weight : 0.034

You see it's correct!!

Please I want to hear that I did some very stupid mistake!

I am trying to implement animation using vertex shader. And it ALMOST works. I mean I want my object to move smoothly with time. And I basically does this but there is some small artifact that I cannot track down. Here are the details:

Every position is described by a 3x4 matrix - every vertex of an object must be multiplied by this matrix for this object to be in this position.

I have 3 such matrices - one at each point of time.

matrixA = {1,0,0,0, 0,1,0,0, 0,0,1,0};

at point in time 0 ms

matrixB = {1,0,0,0, 0,1,0,1, 0,0,1,0};

at point in time 1000 ms

matrixC = {1,0,0,0, 0,1,0,2, 0,0,1,0};

at point in time 2000 ms

My app keeps track of current time and updates shader parameters accordingly. These 3 (uniform in Cg) parameters are: 2 matrices and a weight factor. The weight factor is used to linearly interpolate between two matrices, so it changes it's value from 0.0 to 1.0 during the flow of animation from 0 ms to 1000 ms, and again from 0.0 to 1.0 during animation from 1000 ms to 2000 ms. The 2 matrices send to a vertex shader are updated when 1000 ms have passed - so it is now blending between matrixB and matrixC.

Such interpolation between matrices in a vertex shader guarantees that the motion is smooth. And it is smooth. Except for one small problem: at the point in time when matrices are updated (1000 ms) the animated object for a fraction of second takes the position of the next matrix - that is, at time 1000 ms the object is for a fraction of second at position implied by matrixC, then instantly comes back to a position close to matrixB (which is the right position at this point in time) and continues to move smoothly towards position implied by matrixC.

Here is my shader code:

struct vertex_input

{

float4 position : POSITION;

};

struct vertex_output

{

float4 position : POSITION;

};

vertex_output vertex_program(vertex_input IN, uniform float4x4 model_view_proj, uniform float3x4 previous_matrix, uniform float3x4 next_matrix, uniform float weight)

{

vertex_output OUT;

float3 previous_position = mul( previous_matrix, IN.position );

float3 next_position = mul( next_matrix, IN.position );

float3 position = lerp(previous_position, next_position, weight);//here is the interpolation

OUT.position = mul(model_view_proj, float4(position, 1.0f));

return OUT;

} I thought I pass in parameters with wrong values so I printed them out just before sending them to the shader. Here is a fragment of the output at this problematic moment around 1000 ms.

previous_matrix : 1000 0100 0010

next_matrix : 1000 0101 0010

weight : 0.982

previous_matrix : 1000 0100 0010

next_matrix : 1000 0101 0010

weight : 0.999

previous_matrix : 1000 0101 0010

next_matrix : 1000 0102 0010

weight : 0.016

previous_matrix : 1000 0101 0010

next_matrix : 1000 0102 0010

weight : 0.034

You see it's correct!!

Please I want to hear that I did some very stupid mistake!