As briefly seen in the introduction there is various ways to send data to your GPU. If we take the vertex shader of the introduction :
<!-- VERTEX SHADER -->
<script id="vertext_shader" type="vs_01">
attribute vec3 a_position;
void main()
{
gl_Position = vec4(a_position, 1);
}
</script>
We can see an attribute before our vec3 variable. An atribute is one of the 3 ways to send data to our vertex shader :
- attribute (data provided by the buffers )
- uniforms (data that remain the same from one call to another.)
- textures (pixels/texels data)
Attributes
Attributes are the most common way to pass data to our Vertex Shader, they are used with buffers.
Buffers are arrays of binary data. Your allowed to put anything you want in them, despite it’s mainly used to contains positions, texture coordinates, normals…
Attributes are here to gather the data out of your buffer and give them to your vertex shader. As developer you goal is to specify to an attribute his buffer, and the type of data he should pull out of the buffer…
Let’s see in code with an example :
// First of all we create our buffer and our data
var ourBuffer = gl.createBuffer();
var ourData =
[
0,0,1,
1,0,0,
0,1,0,
];
// We then bind our buffer and assign his data
gl.bindBuffer(gl.ARRAY_BUFFER, ourBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(ourData), gl.STATIC_DRAW);
// We then need to find our attribute location and allow this attribute to gather data from our buffer
var attribLocation = gl.getAttribLocation(ourShader, "a_position");
gl.enableVertexAttribArray(attribLocation);
// gl.vertexAttribPointer(position, columnNumberOfOurData, typeOfData, normalized?, offset, stride);
gl.vertexAttribPointer(attribLocation, 3, gl.FLOAT, false, 0, 0);
Uniforms
Uniform are values that stay the same for all vertices in a draw call. They are passed to the shader and doesn’t change. Uniform are used in read-only for the shader, each call get the same data and cant write on them.
They can be used for an offset, the canvas resolution, the mouse position, …
// like the attributes, we have to get the location of our uniforms
var intLoc = gl.getUniformLocation(ourProgram, "u_int");
// We then set our uniform (/!\ before drawing)
gl.uniform1i (intLoc, anExampleInt);
// the methods used above will change according to the type, here it's one int so we used
// gl.uniform1i. If we have a vector3 for example :
gl.uniform3f(vec3Loc, 0, 1, 2);