neiderer
neiderer

Reputation: 59

WebGL vec4() description

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

Answers (2)

YGilk1
YGilk1

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

Rabbid76
Rabbid76

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

Related Questions