Vertex and Fragment shaders are written in GLSL, a domain-specific mini-language for writing shaders. The syntax is C/C++-like, and basic shaders tend to look like very simple C programs, such as:
x1// some declarations here
2
3void main() {
4 // main program here
5}
The vertex shader's job is to:
gl_Position
, which is a vec4
that contains the vertex's position.varying
parameters needed for the Fragment shaderThe fragment shader's job is to:
gl_FragColor
, which is a vec4
containing the fragment's color.Here are some things about GLSL that are not C-like:
vec2
, vec3
, vec4
, mat2
, mat3
, mat4
are built-in vector and matrix types; their values are floats.Multiplication involving these types is matrix/vector multiplication
Colors are 4 channels. The first 3 are RGB, and the 4th is transparency; 0 is fully transparent, 1 is fully opaque.
varying
s are declared in both the Vertex shader and in the Fragment shader. By convention, their names are usually chosen to begin with v
, such as vColor
or vNormal
.
Vector types support some neat shorthand. For example:
In the following line Position
is a vec3
, and its entries become the first three entries of the vec4
being set to gl_Position
:
xxxxxxxxxx
11gl_Position = vec4(Position, 1.0);
Accessing elements of a vector using attribute names:
xxxxxxxxxx
51vec4 a = vec4(1, 2, 3, 4);
2float x = a.x; // x = 1.0
3float y = a.y; // x = 2.0
4float z = a.z; // x = 3.0
5float w = a.w; // x = 4.0
This works for shorter vectors too, within bounds; you can also use r,g,b,a
, and s,t,p,q
as alternative accessors.
Swizzling allows you to easily construct one vector from elements of another:
xxxxxxxxxx
51vec4 a = vec4(1, 2, 3, 4);
2
3vec3 b = a.xyz; // b = (1,2,3)
4vec2 c = a.qp; // c = (4,3)
5vec4 d = a.xxyy; // d = (1,1,2,2)
vec2
xxxxxxxxxx
111vec2 a;
2a.x = 0.0;
3a.y = 1.0; // a = (0,1)
4
5vec2 b;
6b.s = 10.0;
7b.t = 12.5; // b = (10,12.5)
8
9vec2 c;
10c[0] = 9.0;
11c[1] = 8.0; // c= (9,8)
vec3
xxxxxxxxxx
141vec3 a;
2a.x = 10.0; a.y = 20.0; a.z = 30.0; // a = (10, 20, 30)
3a.r = 0.1; a.g = 0.2; a.b = 0.3; // a = (0.1, 0.2, 0.3)
4a.s = 1.0; a.t = 2.0; a.p = 3.0; // a = (1, 2, 3)
5
6vec3 b = vec3(4.0, 5.0, 6.0);
7
8vec3 c = a + b; // c = (5, 7, 9)
9vec3 d = a - b; // d = (-3, -3, -3)
10vec3 e = a * b; // e = (4, 10, 18)
11vec3 f = a * 3; // e = (3, 6, 9)
12float g = dot(a, b); // g = 32
13vec3 h = cross(a,b); // h = (-5,6,-3)
14float i = length(a); // i = 3.742
vec4
xxxxxxxxxx
121vec4 a;
2a.x = 10.0; a.y = 20.0; a.z = 30.0; a.w = 40.0; // a = (10, 20, 30, 40)
3a.r = 0.1; a.g = 0.2; a.b = 0.3; a.a = 0.4; // a = (0.1, 0.2, 0.3, 0.4)
4a.s = 1.0; a.t = 2.0; a.p = 3.0; a.q = 4.0; // a = (1, 2, 3, 4)
5
6vec4 b = vec4(5, 6, 7, 8);
7
8vec4 c = a + b; // c = (6, 8, 10, 12)
9vec4 d = a - b; // d = (-4, -4, -4, -4)
10vec4 e = a * b; // e = (5, 12, 21, 32)
11vec4 f = a * 3; // f = (3, 6, 9, 12)
12float g = length(a); // g = 5.477
mat2
xxxxxxxxxx
71mat2 A = mat2(1.0,2.0,3.0,4.0); // in column-major order
2
3vec2 x = vec2(1.0, 0.0);
4vec2 y = vec2(0.0, 1.0);
5
6vec2 a = A * x; // a = (1,2)
7vec2 b = A * y; // b = (3,4)
mat3
xxxxxxxxxx
91mat3 A = mat3(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0); // in column-major order
2
3vec3 x = vec3(1.0, 0.0, 0.0);
4vec3 y = vec3(0.0, 1.0, 0.0);
5vec3 z = vec3(0.0, 0.0, 1.0);
6
7vec3 a = A * x; // a = (1,2,3)
8vec3 b = A * y; // b = (4,5,6)
9vec3 c = A * z; // c = (6,7,8)
mat4
xxxxxxxxxx
151mat4 A = mat4(
2 1.0, 2.0, 3.0, 4.0,
3 5.0, 6.0, 7.0, 8.0,
4 9.0, 10.0, 11.0, 12.0,
5 13.0, 14.0, 15.0, 16.0); // in column-major order
6
7vec4 x = vec4(1.0, 0.0, 0.0, 0.0);
8vec4 y = vec4(0.0, 1.0, 0.0, 0.0);
9vec4 z = vec4(0.0, 0.0, 1.0, 0.0);
10vec4 w = vec4(0.0, 0.0, 0.0, 1.0);
11
12vec4 a = A * x; // a = (1,2,3,4)
13vec4 b = A * y; // b = (5,6,7,8)
14vec4 c = A * z; // c = (9,10,11,12)
15vec4 d = A * w; // d = (13,14,15,16)
There are also integer vectors (ivec2
, ivec3
, ivec4
) and boolean vectors (bvec2
, bvec3
, bvec4
).
You can declare fixed-size arrays whose sizes are known at compile time:
xxxxxxxxxx
61float A[4];
2A[0] = 5; A[3] = 10;
3
4vec4 B[10];
5B[3] = vec4(1,2,3,4);
6B[8].y = 10.0;