GLSL compilation fails when multiplying mat4x3 vec4
I have a GLSL shader that works great until I add the following lines to it.
"vec4 coord = texture2D(Coordinates,gl_TexCoord[0].st);"
"mat4x3 theMatrix;"
"theMatrix[1][1] = 1.0;"
"vec3 CampProj = theMatrix * coord;"
when i check the error log i am told:
"ERROR: 0:2: '=' : cannot convert from '4-component vector of float' to '3-component vector of float'\n\n"
if I do CampProject a vec4 it compiles fine, but I'm very confused about how a 4-column matrix multiplied by a 4-component vector would result in a 4-component vector.
Is this a bug, or is it possible that the 4x3 matrix is really just 4x4 under the hood with the final row 0,0,0,1? if can anyone explain to me why the compiler insists on returning vec4?
I am using C ++ via VSExpress 2013, win7, Intel® 4 Series Express Chipset Family
UPDATE:
Reto's answer is what I expect. This is a compilation error. And because this is the only thing that makes sense in the Los Angeles context and because the definition of LA is that the GLSL documentation refers to matrix / matrix and matrix / vec multiplication; however, even after updating my GPU drivers, compilation shows me the same behavior. can another person confirm what Reto's behavior is describing?
@Repeat if no one has confirmed 12-05-14 I will take your answer as correct as it seems like the only real logical possibility.
source to share
It looks like a bug in your GLSL compiler. This should compile successfully:
mat4x3 mat;
vec3 res = mat * vec4(1.0);
and this should give an error:
mat4x3 mat;
vec4 res = mat * vec4(1.0);
I tested this on 3 configurations and they all confirmed this behavior:
- Windows 8.1 with Intel HD Graphics 4600.
- Windows 8.1 with NVIDIA GeForce GT 740M.
- Mac OS Yosemite with Intel Iris Pro.
This is also in line with my understanding of the specs. The GLSL 3.30 specification document mat4x3
describes how:
floating point matrix with 4 columns and 3 rows
and the multiplication is defined (emphasis added):
The operator is multiplied (*) where both operands are matrices, or one operand is a vector and the other is a matrix. The correct vector operand is treated as a column vector and the left vector operand as a row vector. In all these cases, it is required that the number of columns of the left operand is equal to the number of rows of the correct operand . The multiply operation (*) then performs linear algebraic multiplication, yielding an object that has the same number of rows as the left operand and the same number of columns as the right operand.
In this example, the "number of columns of the left operand" is 4, which means the vector must have 4 "rows", which is a 4-element column vector. Then, since the left operand has 3 rows, the resulting vector has 3 "rows", which is a 3-element column vector.
It's also the only one that makes sense based on standard linear algebra.
source to share
This is because your component count of both your vec4 and your mat4x3 is four. You cannot expect to get vec3 from this multiplication.
Why don't you just use a uniform matrix and vec4? You will get vec4, and if you really need to, you can convert it to vec3 by doing
vec3.xyz
Hope this helps, my first answer!
source to share