# Why does matrix multiplication lead to different result if it's done on CPU, compared to GPU(shader)?

If I'm calculating a "camera space" on the CPU, by multiplying the view with the projection matrix on the CPU , and afterwards multiplying the world to the result my vertices do not pass to the pixel shader (probably because they are thrown of the screen space).

On the other hand if I'm multiplying the world with the view and the result with the projection, all on the GPU the result is right.

What exactly happens on the GPU that doesn't happen when multiplying on the CPU?

-
They can both be made to do the same calculation (with possibly minor precision differences). Your code isn't working because it has a bug somewhere. – Adam Mar 3 '13 at 22:09
I changed the multiplication between the GPU and the CPU and it works on the GPU, which is odd, I agree, but maybe someone can pinpoint me to common bugs maybe that have the same behaviour? – Taikand Mar 3 '13 at 22:12
Also, remember GPU will be column-order. Your software solution might be row-order. – Joey Green Mar 5 '13 at 15:42

What do you use as the W component for vertex positions in CPU-based calculations? To apply the translation part of the matrix, you have to use 1 for W. GPU adds that W=1 for you while converting less than 4-component vertex position data streams to 4-component vectors.

I assume that all of the other math is correct, though. There are many ways to mess things up with multiple non-commutative operations (like matrix-matrix/matrix-vector multiplication), it could also be possible that there might be wrong order of operands somewhere...

-

After tweaks and many, many matrix multiplications done by hand I figured it out. When passing data to shader DirectX implicitly transposes it, therefore:
A*B on CPU sent to shader becomes (A*B)t (where t denotes transposed).
(A*B)t according to formal math is Bt*At(observe the change in order of operation).

In order to premultiply your matrices (View and Projection) in my case I had to apply transpose to their product, not each one.
WRONG: At*Bt sent to GPU becomes (At*Bt)t=Btt*Att=B*A
RIGHT: (A*B)t sent to GPU becomes (A*B)tt=A*B
Check the wikipedia article on Transpose

-