Converting float4x4 to float4x3

Started by
2 comments, last by ProgrammerDX 7 years, 2 months ago
Hi there,

Currently I have a working skinned shader that uses float4x4 bone matrices.

Code snippet in Vertex Shader:

float4 position = mul(float4(input.position, 1.0f), Bone);
Bone is the float4x4 matrix of the bone. input.position is the vertex position as it comes into the vertex shader.

This works perfectly fine, now I want to convert to float4x3 for the Bone matrix as an optimization, but it doesn't work:

float4 position = float4(mul(input.position, (float4x3)Bone), 1.0f)
What happens is that everything in the mesh is rendered in the origin of the model, so basicly it seems that the translation of the bone is not being applied now.

I've been trying to figure it out by swapping arguments around and trying float3x4 and such but nothing makes it right.

Anyone with a clue?
Advertisement
Always remember: Row dot column. Is your input position a float3? If so, then you need to convert it to float4 with 1.0 for w otherwise the translation will not occur. So, if I'm not mistaken, you need to do the following

float4 = float4( float4(float3,1) * float4x3, 1.0)


Your float4x3 when multiplied TO a 1x4 matrix will yield a 3x1:

1x4 * 4x3 = 1x3

In your case you are doing the following:
1x3 * 4x3 = ?
This doesn't make any sense mathematically. If it isn't giving you a compile error, it may be upcomverting it to a float4(float3,0), scaling translation by 0.

Anyone with a clue?

The last column of your matrix will be [0,0,0,1]. If you drop it, it's as if it's [0,0,0,0], which has the effect of scaling the translation component by zero...
Also, yeah, as above you're trying to do mat1x3 * mat4x3 which isn't even a mathematically defined operation.

You at least need to do mat1x4 * mat4x3, but that results in a 3d result (1x3 matrix / 3d vector), where the output of a 3D vertex shader should be a homogeneous 4d result (1x4 matrix / 4d vector) so that perspective correct interpolation works...

Instead of trying to drop the last column as an optimization, you could try hard-coding its value as [0,0,0,1], which will let the compiler know which operations it can solve at compile-time and remove from the generated code.

Thanks for the replies.

Yes fais, input was float3, so you are right that it got automatically converted into float4 with the w as 0.f in this operation.
I read that if I declare the input as float4, hlsl will automatically set w to 1.f even though verrtex decleration for it is float3, so I might do that aswell.

I tried as you said now, making it float4(input,1) and it actually worked! I can't believe it, because I felt like I tried every combination.

So this is the final line that works, if anyone is interested:
float4 position = float4(mul(float4(input.position, 1.0f), (float4x3)Bone), 1.0f);
Hodgman I think it doesn't matter that the last column will be interpreted as [0,0,0,0] if I remove it by casting to float4x3, because later I set float4 with w valued as 1 again.

I'm going to try to optimize further by sending float4x3 matrices to the vertex shader now, which was the final intent of this optimization.

This topic is closed to new replies.

Advertisement