6

When I was reading this article on Projective Texturing (9.3.2) on nvidia, I came across this graph:


(source: nvidia.com)

The order in which the transformations are written confused me. This is because I learned to read matrix multiplication from left to right and also because I thought the sequence of transformations should go in this order:


(source: nvidia.com)

Now my questions are the following:

Because Matrix multiplication is not commutative, what is the order I should do the multiplications in?

And if it is indeed in the same order as the sequence of transformations of normal objects, why is it written like this?

By the same order of sequence I mean something like this hlsl code:

float4 worldPosition        = mul(input.Position, World);
float4 viewPosition         = mul(worldPosition, View);
output.Position             = mul(viewPosition, Projection);

Finally (and this is optional but might be usefull for others wondering the same), how would you write the HLSL code to do this projective texturing multiplication or how would you do the transformations if you passed the complete Matrix via XNA.

Glorfindel
  • 21,988
  • 13
  • 81
  • 109

1 Answers1

4

Your transformation can be written symbolically as

y = T P V W x

where:

x = (x0, y0, z0, w0)T: object coordinates (column vector 4x1)
y = (s, t, r, q)T: window space coordinates (column vector 4x1)
W: world modelling matrix (4x4)
V: view modelling matrix (4x4)
P: projection matrix (4x4)
T: viewport transformation matrix (4x4)

The calculation is performed as:

y = T (P (V (W x)))

i.e. from right to left. The HLSL code would be:

float4 worldPosition  = mul(World, input.Position);     // W x
float4 viewPosition   = mul(View, worldPosition);       // V (W x)
float4 projPosition   = mul(Projection, viewPosition);  // P (V (W x))
float4 vportPosition  = mul(Viewport, projPosition);    // T (P (V (W x)))
Jiri Kriz
  • 9,192
  • 3
  • 29
  • 36
  • Thank you for your answer. I assume this is the transformation for projective texturing, like the image from the article. I am still wondering two things: - Is y = T (P (V (W x))) the same as (x W) V) P) T = y? – Alexander van der Zalm Jul 03 '11 at 18:27
  • Let y = T P V W x = T (P (V (W x))). Denote by xt the transpose of x (column vectors 4x1 become row vectors 1x4, 4x4 matrices are reflected at the diagonal). Then yt = (TPVWx)t = xt Wt Vt Pt Tt = (((xt Wt) Vt) Pt) Tt. – Jiri Kriz Jul 03 '11 at 18:42
  • The other part of my comment was: (couldnt edit my post by accident) The reason I am confused is because the article mentioned: oPosition = Mul(modelViewProj, position); Which before in the HLSL code was the other way around. - If not, why is it written like this, does this geometrically mean something different than (x W) V) P) T = y? Or is it some math convention, to sometimes write/read it from right to left? Does the hlsl compiler know the difference between these two notations? – Alexander van der Zalm Jul 03 '11 at 18:43
  • I got an AHA moment when you explained the difference between the 4x1 and 1x4 (Transposed) version of the matrix transformations. So just to be perfectly clear: the transposed version of a series of matrix multiplications has to be written in the reversered order if they are to be the same as the non-transposed matrix multiplications? Thanks! – Alexander van der Zalm Jul 03 '11 at 18:50
  • My final question is, how does the hlsl compiler know if you mean x = 4x1 or 1x4 when it is a float4? – Alexander van der Zalm Jul 03 '11 at 18:54
  • (a) The operations `y = TPVWx` and `yt = xt Wt Vt Pt Tt` are equivalent. I would prefer `y = TPVWx` as is usual in mathematics. (b) HLSL compiler can deduce the correct operation, because in any `mul(A,B)` the inner dimensions of `A` and `B` must be equal. See e.g. [link](http://msdn.microsoft.com/en-us/library/bb509628(v=vs.85).aspx). – Jiri Kriz Jul 04 '11 at 08:19