Reputation: 59
I am just learning WebGL graphics programming.
I am examining someone's code that includes the statement
// multiply the position by the matrix.
gl_Position = vec4((u_matrix * vec3(a_position,1)).xy,0,1);
I think he is multiplying a 4-component vector by a 4x4 matrix. But unsure why/what the .xy
is?
If someone could tell me what is happening here and where to go for vec4()
definition page?
Upvotes: 4
Views: 7030
Reputation: 464
What you describe is called swizzling in the shader code. It's a convenient way offered by the language to access the components of a vector. There are different accessors defined, matching with the syntax need: rgba, xyzw, stpq.
You can find more information on https://www.khronos.org/opengl/wiki/Data_Type_(GLSL)#Swizzling
vec4 aVector;
vec4 color = aVector.rgba;
vec4 coordinates = aVector.xyzw;
vec4 textures = aVector.stpq;
But you can also play the way you want with this accessors to create vectors of different dimensions, or use the components in the order you need.
vec4 point;
vec2 projected = point.xy;
vec2 orthogonal = point.yx;
vec4 aVector;
vec2 textureCoord = aVector.st;
vec4 color;
vec3 grayscale = color.rrr;
vec3 colorRGB;
vec3 colorBGR = colorRGB.bgr;
In your case gl_Position is a vec4 built-in in the vertex shader built-in that should be set with a 4 dimension clip space vector.
Your code transforms the 2D vertex attribute a_position into the 4D clip space value.
gl_Position = vec4((u_matrix * vec3(a_position,1)).xy,0,1);
Let's rewrite this code to have a better understanding
// First create a vector 3 and assign a_position xy components, and z component to 1
vec3 position = vec3(a_position, 1.0);
// Transform the point with the 3D matrix
vec3 transformed = u_matrix * position;
// Set the clip space vec4 with the transformed position x and y components
// Set z to 0 and w to 1
gl_Position = vec4(transformed.xy, 0.0, 1.0);
Upvotes: 4
Reputation: 210908
To understand .xy
you have to read about Swizzling. .xy
gets the x
and y
component of a_position
and creates a vec2
with this components.
In glsl vectors (vec2
, vec3
, vec4
) can be constructed in many different ways. See Vector constructors. Thus a vec4
can be constructed by a vec2
and 2 scalars.
gl_Position = vec4((u_matrix * vec3(a_position,1)).xy,0,1);
can be expressed as:
vec3 pos_vec3 = vec3(a_position, 1);
vec3 pos_vec3_transformed = u_matrix * pos_vec3;
vec2 pos_vec2 = pos_vec3_transformed.xy;
vec4 pos_vec4 = vec4(pos_vec2, 0, 1);
gl_Position = pos_vec4;
Explanation:
a_position
is of type vec2
and u_matrix
is of type mat3
, thus a_position
has to be expanded to vec3
to perform a multiplication of u_matrix
and a_position
:
vec3 pos_vec3 = vec3(a_position, 1);
vec3 pos_vec3_transformed = u_matrix * pos_vec3;
Furthermore, only the components x
and y
are required, thus the z
component is skipped:
vec2 pos_vec2 = pos_vec3_transformed.xy;
gl_Position
is of type vec4
, thus the transformed position has to be expanded to a vec4
:
vec4 pos_vec4 = vec4(pos_vec2, 0, 1);
gl_Position = pos_vec4;
Upvotes: 2