In WebGL what are the differences between an attribute, a uniform, and a varying variable?

Solution 1:

Copied directly from http://www.lighthouse3d.com/tutorials/glsl-tutorial/data-types-and-variables/. The actual site has much more detailed information and would be worthwhile to check out.

Variable Qualifiers

Qualifiers give a special meaning to the variable. The following qualifiers are available:

  • const – The declaration is of a compile time constant.
  • attribute – Global variables that may change per vertex, that are passed from the OpenGL application to vertex shaders. This qualifier can only be used in vertex shaders. For the shader this is a read-only variable. See Attribute section.
  • uniform – Global variables that may change per primitive [...], that are passed from the OpenGL application to the shaders. This qualifier can be used in both vertex and fragment shaders. For the shaders this is a read-only variable. See Uniform section.
  • varying – used for interpolated data between a vertex shader and a fragment shader. Available for writing in the vertex shader, and read-only in a fragment shader. See Varying section.

As for an analogy, const and uniform are like global variables in C/C++, one is constant and the other can be set. Attribute is a variable that accompanies a vertex, like color or texture coordinates. Varying variables can be altered by the vertex shader, but not by the fragment shader, so in essence they are passing information down the pipeline.

Solution 2:

  • uniform are per-primitive parameters (constant during an entire draw call) ;
  • attribute are per-vertex parameters (typically : positions, normals, colors, UVs, ...) ;
  • varying are per-fragment (or per-pixel) parameters : they vary from pixels to pixels.

It's important to understand how varying works to program your own shaders.
Let's say you define a varying parameter v for each vertex of a triangle inside the vertex shader. When this varying parameter is sent to the fragment shader, its value is automatically interpolated based on the position of the pixel to draw.

In the following image, the red pixel received an interpolated value of the varying parameter v. That's why we call them "varying".

varying parameter being bilinearly interpolated

For the sake of simplicity the example given above uses bilinear interpolation, which assumes that all the pixels drawn have the same distance from the camera. For accurate 3D rendering, graphic devices use perspective-correct interpolation which takes into account the depth of a pixel.