<p>Because whether you use <span class="math-container">$MVP$</span> or <span class="math-container">$PVM$</span> actually depends on how you perform the multiplication: <span class="math-container">$vMVP$</span> versus <span class="math-container">$PVMv$</span>, note that you have:
<span class="math-container">$(PVMv)^T = v^TM^TV^TP^T=vM^TV^TP^T$</span>, where the last identity does not hold in math, but holds in glsl since vectors can be reinterpreted as either row or column vectors for convenience.</p>

<p>The same holds for <span class="math-container">$TRS$</span> and <span class="math-container">$SRT$</span>. In general CG code and applications have an issue with sticking to standard established conventions, so you get all kinds of funny conventions.</p>

CC BY-SA 4.0
2019-10-14T19:21:33.143Z
I understand that it depends on whether you use column or row major matrix notation, which reverse the multiplication order. However, what I've seen often is that column major format is used (this appears to be the most common from the resources I see online, literature, and in gaming engines), but it's still called MVP and TRS within the same column major matrix context. 

For instance in Unity: 
https://docs.unity3d.com/ScriptReference/Matrix4x4.TRS.html
https://docs.unity3d.com/Manual/SL-UnityShaderVariables.html
Thomas
CC BY-SA 4.0
2019-10-14T19:37:35.587Z
@Thomas I don't understand the issue? In the link you provided they are doing $TRSv$ which is $TRS$. Column and row-major conventions are unrelated: https://en.wikipedia.org/wiki/Row-_and_column-major_order
Their $MVP$ naming scheme seems to also be consistent with the description they have of it: "Current model * view * projection matrix."
lightxbulb
CC BY-SA 4.0
2019-10-14T20:03:37.060Z
That's what the documentation says, but when I create 2 test shaders it appears to be the other way around, unless I am wholly confused about how mul() maps to MVP, which is absolutely possible. MVP: `float4x4 mvp = mul(unity_ObjectToWorld, mul(UNITY_MATRIX_V, UNITY_MATRIX_P));
                o.vertex = mul(mvp, v.vertex);`, and this is the other way around: `float4x4 pvm = mul(UNITY_MATRIX_P, mul(UNITY_MATRIX_V, unity_ObjectToWorld));
                o.vertex = mul(pvm, v.vertex);` If you run it in Unity, only the latter works as expected.
Thomas
CC BY-SA 4.0
2019-10-14T20:17:12.400Z
You would obviously get wrong results if you do `mvp * vector`, as you did in the first case. You should have done: `vector * mvp`.
lightxbulb
CC BY-SA 4.0
2019-10-14T20:45:06.320Z
Tried this now: `float4x4 mvp = mul(unity_ObjectToWorld, mul(UNITY_MATRIX_V, UNITY_MATRIX_P));
                o.vertex = mul(v.vertex, mvp);` that still doesn't work though: https://imgur.com/a/t7vZpHy The green is with PVMv, the red is vMVP.

Am I still doing something wrong?
Thomas
CC BY-SA 4.0
2019-10-14T20:56:07.360Z
Also, it's `mul(UNITY_MATRIX_MVP, v.vertex)`, not the other way around. I believe that it's because Unity inserts the matrices as column major, and multiplying a row oriented vector with a column major matrix would not yield accurate results?
Thomas
CC BY-SA 4.0
2019-10-14T21:24:08.713Z
If `pvm * vec` works, then `vec * transpose(pvm)` should also work. In that case you should have used the transposed matrices: `vec * tr(m) * tr(v) * tr(p)`. The column/row-majority should not affect multiplication - only indexing.
lightxbulb
CC BY-SA 4.0
2019-10-12T20:15:22.553Z
2019-10-12T20:21:18.687Z
2019-10-12T20:21:18.687Z
lightxbulb
<p>Here's something that's been bothering me while learning graphics. We have two core concatenated matrix sets: "TRS" for transforms, and "MVP" for moving everything into the canonical view volume.</p>

<p>TRS is applied in this manner: T(R(S(p))), i.e. the scale is applied first, then the rotation, then the translation.</p>

<p>MVP is applied in this manner: P(V(M(p))), i.e. we apply the model matrix first, then the view matrix, and finally the projection matrix.</p>

<p>Why is the order in which we name these sets not consistent? I feel like I am getting something very obvious wrong, but I can't help but be confused by this.</p>

CC BY-SA 4.0
2019-10-15T09:54:10.577Z
MVP is actually not even consistent with itself - it encodes the transformation from model -> world -> view -> clip(projection) space. So to be consistent, it would be better to name it World-View-Projection.
russ
<matrix>
Why do we call it TRS and MVP, instead of SRT and MVP or TRS and PVM?
Thomas
# Why do we call it TRS and MVP, instead of SRT and MVP or TRS and PVM?

(Asked by: username_0 on 2019-10-12)

Here's something that's been bothering me while learning graphics. We have two core concatenated matrix sets: "TRS" for transforms, and "MVP" for moving everything into the canonical view volume.

TRS is applied in this manner: T(R(S(p))), i.e. the scale is applied first, then the rotation, then the translation.

MVP is applied in this manner: P(V(M(p))), i.e. we apply the model matrix first, then the view matrix, and finally the projection matrix.

Why is the order in which we name these sets not consistent? I feel like I am getting something very obvious wrong, but I can't help but be confused by this.

**Tags:** matrix

> **Comments:**
> **username_1**: MVP is actually not even consistent with itself - it encodes the transformation from model -> world -> view -> clip(projection) space. So to be consistent, it would be better to name it World-View-Projection.  

---

## 1 answers

### Answer by username_2 on 2019-10-12. Score: 1

Because whether you use $MVP$ or $PVM$ actually depends on how you perform the multiplication: $vMVP$ versus $PVMv$, note that you have:
$(PVMv)^T = v^TM^TV^TP^T=vM^TV^TP^T$, where the last identity does not hold in math, but holds in glsl since vectors can be reinterpreted as either row or column vectors for convenience.

The same holds for $TRS$ and $SRT$. In general CG code and applications have an issue with sticking to standard established conventions, so you get all kinds of funny conventions.

> **Comments:**
> **username_0**: I understand that it depends on whether you use column or row major matrix notation, which reverse the multiplication order. However, what I've seen often is that column major format is used (this appears to be the most common from the resources I see online, literature, and in gaming engines), but it's still called MVP and TRS within the same column major matrix context.   For instance in Unity:  https://docs.unity3d.com/ScriptReference/Matrix4x4.TRS.html https://docs.unity3d.com/Manual/SL-UnityShaderVariables.html  
> **username_2**: @username_0 I don't understand the issue? In the link you provided they are doing $TRSv$ which is $TRS$. Column and row-major conventions are unrelated: https://en.wikipedia.org/wiki/Row-_and_column-major_order Their $MVP$ naming scheme seems to also be consistent with the description they have of it: "Current model * view * projection matrix."  
> **username_0**: That's what the documentation says, but when I create 2 test shaders it appears to be the other way around, unless I am wholly confused about how mul() maps to MVP, which is absolutely possible. MVP: `float4x4 mvp = mul(unity_ObjectToWorld, mul(UNITY_MATRIX_V, UNITY_MATRIX_P));                 o.vertex = mul(mvp, v.vertex);`, and this is the other way around: `float4x4 pvm = mul(UNITY_MATRIX_P, mul(UNITY_MATRIX_V, unity_ObjectToWorld));                 o.vertex = mul(pvm, v.vertex);` If you run it in Unity, only the latter works as expected.  
> **username_2**: You would obviously get wrong results if you do `mvp * vector`, as you did in the first case. You should have done: `vector * mvp`.  
> **username_0**: Tried this now: `float4x4 mvp = mul(unity_ObjectToWorld, mul(UNITY_MATRIX_V, UNITY_MATRIX_P));                 o.vertex = mul(v.vertex, mvp);` that still doesn't work though: https://imgur.com/a/t7vZpHy The green is with PVMv, the red is vMVP.  Am I still doing something wrong?  
> **username_0**: Also, it's `mul(UNITY_MATRIX_MVP, v.vertex)`, not the other way around. I believe that it's because Unity inserts the matrices as column major, and multiplying a row oriented vector with a column major matrix would not yield accurate results?  
> **username_2**: If `pvm * vec` works, then `vec * transpose(pvm)` should also work. In that case you should have used the transposed matrices: `vec * tr(m) * tr(v) * tr(p)`. The column/row-majority should not affect multiplication - only indexing.  

---

