WebGL constants - Web APIs

WebGL constants
===============

The WebGL API provides several constants that are passed into or returned by functions. All constants are of type `GLenum`.

Standard WebGL constants are installed on the `WebGLRenderingContext` and `WebGL2RenderingContext` objects, so that you use them as `gl.CONSTANT_NAME`:

```js
const canvas = document.getElementById("myCanvas");
const gl = canvas.getContext("webgl");

gl.getParameter(gl.LINE\_WIDTH);
```

Some constants are also provided by WebGL extensions. A list is provided below.

```js
const debugInfo = gl.getExtension("WEBGL\_debug\_renderer\_info");
const vendor = gl.getParameter(debugInfo.UNMASKED\_VENDOR\_WEBGL);
```

The WebGL tutorial has more information, examples, and resources on how to get started with WebGL.

Table of contents
-----------------

* Standard WebGL 1 constants
* Standard WebGL 2 constants
* WebGL extension constants
Standard WebGL 1 constants
--------------------------

These constants are defined on the `WebGLRenderingContext` interface.

### Clearing buffers

Constants passed to `WebGLRenderingContext.clear()` to clear buffer masks.

| Constant name | Value | Description |
| --- | --- | --- |
| `DEPTH_BUFFER_BIT` | 0x00000100 | Passed to `clear` to clear the current depth buffer. |
| `STENCIL_BUFFER_BIT` | 0x00000400 | Passed to `clear` to clear the current stencil buffer. |
| `COLOR_BUFFER_BIT` | 0x00004000 | Passed to `clear` to clear the current color buffer. |

### Rendering primitives

Constants passed to `WebGLRenderingContext.drawElements()` or `WebGLRenderingContext.drawArrays()` to specify what kind of primitive to render.

| Constant name | Value | Description |
| --- | --- | --- |
| `POINTS` | 0x0000 |
 Passed to `drawElements` or `drawArrays` to draw
 single points.
  |
| `LINES` | 0x0001 |
 Passed to `drawElements` or `drawArrays` to draw
 lines. Each vertex connects to the one after it.
  |
| `LINE_LOOP` | 0x0002 |
 Passed to `drawElements` or `drawArrays` to draw
 lines. Each set of two vertices is treated as a separate line segment.
  |
| `LINE_STRIP` | 0x0003 |
 Passed to `drawElements` or `drawArrays` to draw a
 connected group of line segments from the first vertex to the last.
  |
| `TRIANGLES` | 0x0004 |
 Passed to `drawElements` or `drawArrays` to draw
 triangles. Each set of three vertices creates a separate triangle.
  |
| `TRIANGLE_STRIP` | 0x0005 |
 Passed to `drawElements` or `drawArrays` to draw a
 connected group of triangles.
  |
| `TRIANGLE_FAN` | 0x0006 |
 Passed to `drawElements` or `drawArrays` to draw a
 connected group of triangles. Each vertex connects to the previous and
 the first vertex in the fan.
  |

### Blending modes

Constants passed to `WebGLRenderingContext.blendFunc()` or `WebGLRenderingContext.blendFuncSeparate()` to specify the blending mode (for both, RGB and alpha, or separately).

| Constant name | Value | Description |
| --- | --- | --- |
| `ZERO` | 0 |
 Passed to `blendFunc` or `blendFuncSeparate` to
 turn off a component.
  |
| `ONE` | 1 |
 Passed to `blendFunc` or `blendFuncSeparate` to
 turn on a component.
  |
| `SRC_COLOR` | 0x0300 |
 Passed to `blendFunc` or `blendFuncSeparate` to
 multiply a component by the source elements color.
  |
| `ONE_MINUS_SRC_COLOR` | 0x0301 |
 Passed to `blendFunc` or `blendFuncSeparate` to
 multiply a component by one minus the source elements color.
  |
| `SRC_ALPHA` | 0x0302 |
 Passed to `blendFunc` or `blendFuncSeparate` to
 multiply a component by the source's alpha.
  |
| `ONE_MINUS_SRC_ALPHA` | 0x0303 |
 Passed to `blendFunc` or `blendFuncSeparate` to
 multiply a component by one minus the source's alpha.
  |
| `DST_ALPHA` | 0x0304 |
 Passed to `blendFunc` or `blendFuncSeparate` to
 multiply a component by the destination's alpha.
  |
| `ONE_MINUS_DST_ALPHA` | 0x0305 |
 Passed to `blendFunc` or `blendFuncSeparate` to
 multiply a component by one minus the destination's alpha.
  |
| `DST_COLOR` | 0x0306 |
 Passed to `blendFunc` or `blendFuncSeparate` to
 multiply a component by the destination's color.
  |
| `ONE_MINUS_DST_COLOR` | 0x0307 |
 Passed to `blendFunc` or `blendFuncSeparate` to
 multiply a component by one minus the destination's color.
  |
| `SRC_ALPHA_SATURATE` | 0x0308 |
 Passed to `blendFunc` or `blendFuncSeparate` to
 multiply a component by the minimum of source's alpha or one minus the
 destination's alpha.
  |
| `CONSTANT_COLOR` | 0x8001 |
 Passed to `blendFunc` or `blendFuncSeparate` to
 specify a constant color blend function.
  |
| `ONE_MINUS_CONSTANT_COLOR` | 0x8002 |
 Passed to `blendFunc` or `blendFuncSeparate` to
 specify one minus a constant color blend function.
  |
| `CONSTANT_ALPHA` | 0x8003 |
 Passed to `blendFunc` or `blendFuncSeparate` to
 specify a constant alpha blend function.
  |
| `ONE_MINUS_CONSTANT_ALPHA` | 0x8004 |
 Passed to `blendFunc` or `blendFuncSeparate` to
 specify one minus a constant alpha blend function.
  |

### Blending equations

Constants passed to `WebGLRenderingContext.blendEquation()` or `WebGLRenderingContext.blendEquationSeparate()` to control how the blending is calculated (for both, RGB and alpha, or separately).

| Constant name | Value | Description |
| --- | --- | --- |
| `FUNC_ADD` | 0x8006 |
 Passed to `blendEquation` or
 `blendEquationSeparate` to set an addition blend function.
  |
| `FUNC_SUBTRACT` | 0x800A |
 Passed to `blendEquation` or
 `blendEquationSeparate` to specify a subtraction blend
 function (source - destination).
  |
| `FUNC_REVERSE_SUBTRACT` | 0x800B |
 Passed to `blendEquation` or
 `blendEquationSeparate` to specify a reverse subtraction
 blend function (destination - source).
  |

### Getting GL parameter information

Constants passed to `WebGLRenderingContext.getParameter()` to specify what information to return.

| Constant name | Value | Description |
| --- | --- | --- |
| `BLEND_EQUATION` | 0x8009 |
 Passed to `getParameter` to get the current RGB blend
 function.
  |
| `BLEND_EQUATION_RGB` | 0x8009 |
 Passed to `getParameter` to get the current RGB blend
 function. Same as BLEND\_EQUATION
  |
| `BLEND_EQUATION_ALPHA` | 0x883D |
 Passed to `getParameter` to get the current alpha blend
 function.
  |
| `BLEND_DST_RGB` | 0x80C8 |
 Passed to `getParameter` to get the current destination RGB
 blend function.
  |
| `BLEND_SRC_RGB` | 0x80C9 |
 Passed to `getParameter` to get the current destination RGB
 blend function.
  |
| `BLEND_DST_ALPHA` | 0x80CA |
 Passed to `getParameter` to get the current destination alpha
 blend function.
  |
| `BLEND_SRC_ALPHA` | 0x80CB |
 Passed to `getParameter` to get the current source alpha
 blend function.
  |
| `BLEND_COLOR` | 0x8005 | Passed to `getParameter` to return a the current blend color. |
| `ARRAY_BUFFER_BINDING` | 0x8894 | Passed to `getParameter` to get the array buffer binding. |
| `ELEMENT_ARRAY_BUFFER_BINDING` | 0x8895 |
 Passed to `getParameter` to get the current element array
 buffer.
  |
| `LINE_WIDTH` | 0x0B21 |
 Passed to `getParameter` to get the current
 `lineWidth` (set by the `lineWidth` method).
  |
| `ALIASED_POINT_SIZE_RANGE` | 0x846D |
 Passed to `getParameter` to get the current size of a point
 drawn with `gl.POINTS` |
| `ALIASED_LINE_WIDTH_RANGE` | 0x846E |
 Passed to `getParameter` to get the range of available widths
 for a line. Returns a length-2 array with the lo value at 0, and hight
 at 1.
  |
| `CULL_FACE_MODE` | 0x0B45 |
 Passed to `getParameter` to get the current value of
 `cullFace`. Should return `FRONT`,
 `BACK`, or `FRONT_AND_BACK` |
| `FRONT_FACE` | 0x0B46 |
 Passed to `getParameter` to determine the current value of
 `frontFace`. Should return `CW` or
 `CCW`.
  |
| `DEPTH_RANGE` | 0x0B70 |
 Passed to `getParameter` to return a length-2 array of floats
 giving the current depth range.
  |
| `DEPTH_WRITEMASK` | 0x0B72 |
 Passed to `getParameter` to determine if the depth write mask
 is enabled.
  |
| `DEPTH_CLEAR_VALUE` | 0x0B73 |
 Passed to `getParameter` to determine the current depth clear
 value.
  |
| `DEPTH_FUNC` | 0x0B74 |
 Passed to `getParameter` to get the current depth function.
 Returns `NEVER`, `ALWAYS`, `LESS`,
 `EQUAL`, `LEQUAL`, `GREATER`,
 `GEQUAL`, or `NOTEQUAL`.
  |
| `STENCIL_CLEAR_VALUE` | 0x0B91 |
 Passed to `getParameter` to get the value the stencil will be
 cleared to.
  |
| `STENCIL_FUNC` | 0x0B92 |
 Passed to `getParameter` to get the current stencil function.
 Returns `NEVER`, `ALWAYS`, `LESS`,
 `EQUAL`, `LEQUAL`, `GREATER`,
 `GEQUAL`, or `NOTEQUAL`.
  |
| `STENCIL_FAIL` | 0x0B94 |
 Passed to `getParameter` to get the current stencil fail
 function. Should return `KEEP`, `REPLACE`,
 `INCR`, `DECR`, `INVERT`,
 `INCR_WRAP`, or `DECR_WRAP`.
  |
| `STENCIL_PASS_DEPTH_FAIL` | 0x0B95 |
 Passed to `getParameter` to get the current stencil fail
 function should the depth buffer test fail. Should return
 `KEEP`, `REPLACE`, `INCR`,
 `DECR`, `INVERT`, `INCR_WRAP`, or
 `DECR_WRAP`.
  |
| `STENCIL_PASS_DEPTH_PASS` | 0x0B96 |
 Passed to `getParameter` to get the current stencil fail
 function should the depth buffer test pass. Should return KEEP, REPLACE,
 INCR, DECR, INVERT, INCR\_WRAP, or DECR\_WRAP.
  |
| `STENCIL_REF` | 0x0B97 |
 Passed to `getParameter` to get the reference value used for
 stencil tests.
  |
| `STENCIL_VALUE_MASK` | 0x0B93 |  |
| `STENCIL_WRITEMASK` | 0x0B98 |  |
| `STENCIL_BACK_FUNC` | 0x8800 |  |
| `STENCIL_BACK_FAIL` | 0x8801 |  |
| `STENCIL_BACK_PASS_DEPTH_FAIL` | 0x8802 |  |
| `STENCIL_BACK_PASS_DEPTH_PASS` | 0x8803 |  |
| `STENCIL_BACK_REF` | 0x8CA3 |  |
| `STENCIL_BACK_VALUE_MASK` | 0x8CA4 |  |
| `STENCIL_BACK_WRITEMASK` | 0x8CA5 |  |
| `VIEWPORT` | 0x0BA2 |
 Returns an `Int32Array` with four elements for the
 current viewport dimensions.
  |
| `SCISSOR_BOX` | 0x0C10 |
 Returns an `Int32Array` with four elements for the
 current scissor box dimensions.
  |
| `COLOR_CLEAR_VALUE` | 0x0C22 |  |
| `COLOR_WRITEMASK` | 0x0C23 |  |
| `UNPACK_ALIGNMENT` | 0x0CF5 |  |
| `PACK_ALIGNMENT` | 0x0D05 |  |
| `MAX_TEXTURE_SIZE` | 0x0D33 |  |
| `MAX_VIEWPORT_DIMS` | 0x0D3A |  |
| `SUBPIXEL_BITS` | 0x0D50 |  |
| `RED_BITS` | 0x0D52 |  |
| `GREEN_BITS` | 0x0D53 |  |
| `BLUE_BITS` | 0x0D54 |  |
| `ALPHA_BITS` | 0x0D55 |  |
| `DEPTH_BITS` | 0x0D56 |  |
| `STENCIL_BITS` | 0x0D57 |  |
| `POLYGON_OFFSET_UNITS` | 0x2A00 |  |
| `POLYGON_OFFSET_FACTOR` | 0x8038 |  |
| `TEXTURE_BINDING_2D` | 0x8069 |  |
| `SAMPLE_BUFFERS` | 0x80A8 |  |
| `SAMPLES` | 0x80A9 |  |
| `SAMPLE_COVERAGE_VALUE` | 0x80AA |  |
| `SAMPLE_COVERAGE_INVERT` | 0x80AB |  |
| `COMPRESSED_TEXTURE_FORMATS` | 0x86A3 |  |
| `VENDOR` | 0x1F00 |  |
| `RENDERER` | 0x1F01 |  |
| `VERSION` | 0x1F02 |  |
| `IMPLEMENTATION_COLOR_READ_TYPE` | 0x8B9A |  |
| `IMPLEMENTATION_COLOR_READ_FORMAT` | 0x8B9B |  |
| `BROWSER_DEFAULT_WEBGL` | 0x9244 |  |

### Buffers

Constants passed to `WebGLRenderingContext.bufferData()`, `WebGLRenderingContext.bufferSubData()`, `WebGLRenderingContext.bindBuffer()`, or `WebGLRenderingContext.getBufferParameter()`.

| Constant name | Value | Description |
| --- | --- | --- |
| `STATIC_DRAW` | 0x88E4 |
 Passed to `bufferData` as a hint about whether the contents
 of the buffer are likely to be used often and not change often.
  |
| `STREAM_DRAW` | 0x88E0 |
 Passed to `bufferData` as a hint about whether the contents
 of the buffer are likely to not be used often.
  |
| `DYNAMIC_DRAW` | 0x88E8 |
 Passed to `bufferData` as a hint about whether the contents
 of the buffer are likely to be used often and change often.
  |
| `ARRAY_BUFFER` | 0x8892 |
 Passed to `bindBuffer` or `bufferData` to specify
 the type of buffer being used.
  |
| `ELEMENT_ARRAY_BUFFER` | 0x8893 |
 Passed to `bindBuffer` or `bufferData` to specify
 the type of buffer being used.
  |
| `BUFFER_SIZE` | 0x8764 | Passed to `getBufferParameter` to get a buffer's size. |
| `BUFFER_USAGE` | 0x8765 |
 Passed to `getBufferParameter` to get the hint for the buffer
 passed in when it was created.
  |

### Vertex attributes

Constants passed to `WebGLRenderingContext.getVertexAttrib()`.

| Constant name | Value | Description |
| --- | --- | --- |
| `CURRENT_VERTEX_ATTRIB` | 0x8626 | Passed to `getVertexAttrib` to read back the current vertex attribute. |
| `VERTEX_ATTRIB_ARRAY_ENABLED` | 0x8622 |  |
| `VERTEX_ATTRIB_ARRAY_SIZE` | 0x8623 |  |
| `VERTEX_ATTRIB_ARRAY_STRIDE` | 0x8624 |  |
| `VERTEX_ATTRIB_ARRAY_TYPE` | 0x8625 |  |
| `VERTEX_ATTRIB_ARRAY_NORMALIZED` | 0x886A |  |
| `VERTEX_ATTRIB_ARRAY_POINTER` | 0x8645 |  |
| `VERTEX_ATTRIB_ARRAY_BUFFER_BINDING` | 0x889F |  |

### Culling

Constants passed to `WebGLRenderingContext.cullFace()`.

| Constant name | Value | Description |
| --- | --- | --- |
| `CULL_FACE` | 0x0B44 |
 Passed to `enable`/`disable` to turn on/off
 culling. Can also be used with `getParameter` to find the
 current culling method.
  |
| `FRONT` | 0x0404 |
 Passed to `cullFace` to specify that only front faces should
 be culled.
  |
| `BACK` | 0x0405 |
 Passed to `cullFace` to specify that only back faces should
 be culled.
  |
| `FRONT_AND_BACK` | 0x0408 |
 Passed to `cullFace` to specify that front and back faces
 should be culled.
  |

### Enabling and disabling

Constants passed to `WebGLRenderingContext.enable()` or `WebGLRenderingContext.disable()`.

| Constant name | Value | Description |
| --- | --- | --- |
| `BLEND` | 0x0BE2 |
 Passed to `enable`/`disable` to turn on/off
 blending. Can also be used with `getParameter` to find the
 current blending method.
  |
| `DEPTH_TEST` | 0x0B71 |
 Passed to `enable`/`disable` to turn on/off the
 depth test. Can also be used with `getParameter` to query the
 depth test.
  |
| `DITHER` | 0x0BD0 |
 Passed to `enable`/`disable` to turn on/off
 dithering. Can also be used with `getParameter` to find the
 current dithering method.
  |
| `POLYGON_OFFSET_FILL` | 0x8037 |
 Passed to `enable`/`disable` to turn on/off the
 polygon offset. Useful for rendering hidden-line images, decals, and or
 solids with highlighted edges. Can also be used with
 `getParameter` to query the scissor test.
  |
| `SAMPLE_ALPHA_TO_COVERAGE` | 0x809E |
 Passed to `enable`/`disable` to turn on/off the
 alpha to coverage. Used in multi-sampling alpha channels.
  |
| `SAMPLE_COVERAGE` | 0x80A0 |
 Passed to `enable`/`disable` to turn on/off the
 sample coverage. Used in multi-sampling.
  |
| `SCISSOR_TEST` | 0x0C11 |
 Passed to `enable`/`disable` to turn on/off the
 scissor test. Can also be used with `getParameter` to query
 the scissor test.
  |
| `STENCIL_TEST` | 0x0B90 |
 Passed to `enable`/`disable` to turn on/off the
 stencil test. Can also be used with `getParameter` to query
 the stencil test.
  |

### Errors

Constants returned from `WebGLRenderingContext.getError()`.

| Constant name | Value | Description |
| --- | --- | --- |
| `NO_ERROR` | 0 | Returned from `getError`. |
| `INVALID_ENUM` | 0x0500 | Returned from `getError`. |
| `INVALID_VALUE` | 0x0501 | Returned from `getError`. |
| `INVALID_OPERATION` | 0x0502 | Returned from `getError`. |
| `OUT_OF_MEMORY` | 0x0505 | Returned from `getError`. |
| `CONTEXT_LOST_WEBGL` | 0x9242 | Returned from `getError`. |

### Front face directions

Constants passed to `WebGLRenderingContext.frontFace()`.

| Constant name | Value | Description |
| --- | --- | --- |
| `CW` | 0x0900 | Passed to `frontFace` to specify the front face of a polygon is drawn in the clockwise direction |
| `CCW` | 0x0901 | Passed to `frontFace` to specify the front face of a polygon is drawn in the counter clockwise direction |

### Hints

Constants passed to `WebGLRenderingContext.hint()`

| Constant name | Value | Description |
| --- | --- | --- |
| `DONT_CARE` | 0x1100 | There is no preference for this behavior. |
| `FASTEST` | 0x1101 | The most efficient behavior should be used. |
| `NICEST` | 0x1102 | The most correct or the highest quality option should be used. |
| `GENERATE_MIPMAP_HINT` | 0x8192 |
 Hint for the quality of filtering when generating mipmap images with
 `WebGLRenderingContext.generateMipmap()`.
  |

### Data types

| Constant name | Value | Description |
| --- | --- | --- |
| `BYTE` | 0x1400 |  |
| `UNSIGNED_BYTE` | 0x1401 |  |
| `SHORT` | 0x1402 |  |
| `UNSIGNED_SHORT` | 0x1403 |  |
| `INT` | 0x1404 |  |
| `UNSIGNED_INT` | 0x1405 |  |
| `FLOAT` | 0x1406 |  |

### Pixel formats

| Constant name | Value | Description |
| --- | --- | --- |
| `DEPTH_COMPONENT` | 0x1902 |  |
| `ALPHA` | 0x1906 |  |
| `RGB` | 0x1907 |  |
| `RGBA` | 0x1908 |  |
| `LUMINANCE` | 0x1909 |  |
| `LUMINANCE_ALPHA` | 0x190A |  |

### Pixel types

| Constant name | Value | Description |
| --- | --- | --- |
| `UNSIGNED_BYTE` | 0x1401 |  |
| `UNSIGNED_SHORT_4_4_4_4` | 0x8033 |  |
| `UNSIGNED_SHORT_5_5_5_1` | 0x8034 |  |
| `UNSIGNED_SHORT_5_6_5` | 0x8363 |  |

### Shaders

Constants passed to `WebGLRenderingContext.createShader()` or `WebGLRenderingContext.getShaderParameter()`

| Constant name | Value | Description |
| --- | --- | --- |
| `FRAGMENT_SHADER` | 0x8B30 | Passed to `createShader` to define a fragment shader. |
| `VERTEX_SHADER` | 0x8B31 | Passed to `createShader` to define a vertex shader |
| `COMPILE_STATUS` | 0x8B81 |
 Passed to `getShaderParameter` to get the status of the
 compilation. Returns false if the shader was not compiled. You can then
 query `getShaderInfoLog` to find the exact error
  |
| `DELETE_STATUS` | 0x8B80 |
 Passed to `getShaderParameter` to determine if a shader was
 deleted via `deleteShader`. Returns true if it was, false
 otherwise.
  |
| `LINK_STATUS` | 0x8B82 |
 Passed to `getProgramParameter` after calling
 `linkProgram` to determine if a program was linked correctly.
 Returns false if there were errors. Use
 `getProgramInfoLog` to find the exact error.
  |
| `VALIDATE_STATUS` | 0x8B83 |
 Passed to `getProgramParameter` after calling
 `validateProgram` to determine if it is valid. Returns false
 if errors were found.
  |
| `ATTACHED_SHADERS` | 0x8B85 |
 Passed to `getProgramParameter` after calling
 `attachShader` to determine if the shader was attached
 correctly. Returns false if errors occurred.
  |
| `ACTIVE_ATTRIBUTES` | 0x8B89 |
 Passed to `getProgramParameter` to get the number of
 attributes active in a program.
  |
| `ACTIVE_UNIFORMS` | 0x8B86 |
 Passed to `getProgramParameter` to get the number of uniforms
 active in a program.
  |
| `MAX_VERTEX_ATTRIBS` | 0x8869 | The maximum number of entries possible in the vertex attribute list. |
| `MAX_VERTEX_UNIFORM_VECTORS` | 0x8DFB |  |
| `MAX_VARYING_VECTORS` | 0x8DFC |  |
| `MAX_COMBINED_TEXTURE_IMAGE_UNITS` | 0x8B4D |  |
| `MAX_VERTEX_TEXTURE_IMAGE_UNITS` | 0x8B4C |  |
| `MAX_TEXTURE_IMAGE_UNITS` | 0x8872 | Implementation dependent number of maximum texture units. At least 8. |
| `MAX_FRAGMENT_UNIFORM_VECTORS` | 0x8DFD |  |
| `SHADER_TYPE` | 0x8B4F |  |
| `SHADING_LANGUAGE_VERSION` | 0x8B8C |  |
| `CURRENT_PROGRAM` | 0x8B8D |  |

### Depth or stencil tests

Constants passed to `WebGLRenderingContext.depthFunc()` or `WebGLRenderingContext.stencilFunc()`.

| Constant name | Value | Description |
| --- | --- | --- |
| `NEVER` | 0x0200 |
 Passed to `depthFunction` or `stencilFunction` to
 specify depth or stencil tests will never pass, i.e., nothing will be
 drawn.
  |
| `LESS` | 0x0201 |
 Passed to `depthFunction` or `stencilFunction` to
 specify depth or stencil tests will pass if the new depth value is less
 than the stored value.
  |
| `EQUAL` | 0x0202 |
 Passed to `depthFunction` or `stencilFunction` to
 specify depth or stencil tests will pass if the new depth value is
 equals to the stored value.
  |
| `LEQUAL` | 0x0203 |
 Passed to `depthFunction` or `stencilFunction` to
 specify depth or stencil tests will pass if the new depth value is less
 than or equal to the stored value.
  |
| `GREATER` | 0x0204 |
 Passed to `depthFunction` or `stencilFunction` to
 specify depth or stencil tests will pass if the new depth value is
 greater than the stored value.
  |
| `NOTEQUAL` | 0x0205 |
 Passed to `depthFunction` or `stencilFunction` to
 specify depth or stencil tests will pass if the new depth value is not
 equal to the stored value.
  |
| `GEQUAL` | 0x0206 |
 Passed to `depthFunction` or `stencilFunction` to
 specify depth or stencil tests will pass if the new depth value is
 greater than or equal to the stored value.
  |
| `ALWAYS` | 0x0207 |
 Passed to `depthFunction` or `stencilFunction` to
 specify depth or stencil tests will always pass, i.e., pixels will be
 drawn in the order they are drawn.
  |

### Stencil actions

Constants passed to `WebGLRenderingContext.stencilOp()`.

| Constant name | Value | Description |
| --- | --- | --- |
| `KEEP` | 0x1E00 |  |
| `REPLACE` | 0x1E01 |  |
| `INCR` | 0x1E02 |  |
| `DECR` | 0x1E03 |  |
| `INVERT` | 0x150A |  |
| `INCR_WRAP` | 0x8507 |  |
| `DECR_WRAP` | 0x8508 |  |

### Textures

Constants passed to `WebGLRenderingContext.texParameteri()`, `WebGLRenderingContext.texParameterf()`, `WebGLRenderingContext.bindTexture()`, `WebGLRenderingContext.texImage2D()`, and others.

| Constant name | Value | Description |
| --- | --- | --- |
| `NEAREST` | 0x2600 |  |
| `LINEAR` | 0x2601 |  |
| `NEAREST_MIPMAP_NEAREST` | 0x2700 |  |
| `LINEAR_MIPMAP_NEAREST` | 0x2701 |  |
| `NEAREST_MIPMAP_LINEAR` | 0x2702 |  |
| `LINEAR_MIPMAP_LINEAR` | 0x2703 |  |
| `TEXTURE_MAG_FILTER` | 0x2800 |  |
| `TEXTURE_MIN_FILTER` | 0x2801 |  |
| `TEXTURE_WRAP_S` | 0x2802 |  |
| `TEXTURE_WRAP_T` | 0x2803 |  |
| `TEXTURE_2D` | 0x0DE1 |  |
| `TEXTURE` | 0x1702 |  |
| `TEXTURE_CUBE_MAP` | 0x8513 |  |
| `TEXTURE_BINDING_CUBE_MAP` | 0x8514 |  |
| `TEXTURE_CUBE_MAP_POSITIVE_X` | 0x8515 |  |
| `TEXTURE_CUBE_MAP_NEGATIVE_X` | 0x8516 |  |
| `TEXTURE_CUBE_MAP_POSITIVE_Y` | 0x8517 |  |
| `TEXTURE_CUBE_MAP_NEGATIVE_Y` | 0x8518 |  |
| `TEXTURE_CUBE_MAP_POSITIVE_Z` | 0x8519 |  |
| `TEXTURE_CUBE_MAP_NEGATIVE_Z` | 0x851A |  |
| `MAX_CUBE_MAP_TEXTURE_SIZE` | 0x851C |  |
| `TEXTURE0 - 31` | 0x84C0 - 0x84DF | A texture unit. |
| `ACTIVE_TEXTURE` | 0x84E0 | The current active texture unit. |
| `REPEAT` | 0x2901 |  |
| `CLAMP_TO_EDGE` | 0x812F |  |
| `MIRRORED_REPEAT` | 0x8370 |  |

### Uniform types

| Constant name | Value | Description |
| --- | --- | --- |
| `FLOAT_VEC2` | 0x8B50 |  |
| `FLOAT_VEC3` | 0x8B51 |  |
| `FLOAT_VEC4` | 0x8B52 |  |
| `INT_VEC2` | 0x8B53 |  |
| `INT_VEC3` | 0x8B54 |  |
| `INT_VEC4` | 0x8B55 |  |
| `BOOL` | 0x8B56 |  |
| `BOOL_VEC2` | 0x8B57 |  |
| `BOOL_VEC3` | 0x8B58 |  |
| `BOOL_VEC4` | 0x8B59 |  |
| `FLOAT_MAT2` | 0x8B5A |  |
| `FLOAT_MAT3` | 0x8B5B |  |
| `FLOAT_MAT4` | 0x8B5C |  |
| `SAMPLER_2D` | 0x8B5E |  |
| `SAMPLER_CUBE` | 0x8B60 |  |

### Shader precision-specified types

| Constant name | Value | Description |
| --- | --- | --- |
| `LOW_FLOAT` | 0x8DF0 |  |
| `MEDIUM_FLOAT` | 0x8DF1 |  |
| `HIGH_FLOAT` | 0x8DF2 |  |
| `LOW_INT` | 0x8DF3 |  |
| `MEDIUM_INT` | 0x8DF4 |  |
| `HIGH_INT` | 0x8DF5 |  |

### Framebuffers and renderbuffers

| Constant name | Value | Description |
| --- | --- | --- |
| `FRAMEBUFFER` | 0x8D40 |  |
| `RENDERBUFFER` | 0x8D41 |  |
| `RGBA4` | 0x8056 |  |
| `RGB5_A1` | 0x8057 |  |
| `RGB565` | 0x8D62 |  |
| `DEPTH_COMPONENT16` | 0x81A5 |  |
| `STENCIL_INDEX8` | 0x8D48 |  |
| `DEPTH_STENCIL` | 0x84F9 |  |
| `RENDERBUFFER_WIDTH` | 0x8D42 |  |
| `RENDERBUFFER_HEIGHT` | 0x8D43 |  |
| `RENDERBUFFER_INTERNAL_FORMAT` | 0x8D44 |  |
| `RENDERBUFFER_RED_SIZE` | 0x8D50 |  |
| `RENDERBUFFER_GREEN_SIZE` | 0x8D51 |  |
| `RENDERBUFFER_BLUE_SIZE` | 0x8D52 |  |
| `RENDERBUFFER_ALPHA_SIZE` | 0x8D53 |  |
| `RENDERBUFFER_DEPTH_SIZE` | 0x8D54 |  |
| `RENDERBUFFER_STENCIL_SIZE` | 0x8D55 |  |
| `FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE` | 0x8CD0 |  |
| `FRAMEBUFFER_ATTACHMENT_OBJECT_NAME` | 0x8CD1 |  |
| `FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL` | 0x8CD2 |  |
| `FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE` | 0x8CD3 |  |
| `COLOR_ATTACHMENT0` | 0x8CE0 |  |
| `DEPTH_ATTACHMENT` | 0x8D00 |  |
| `STENCIL_ATTACHMENT` | 0x8D20 |  |
| `DEPTH_STENCIL_ATTACHMENT` | 0x821A |  |
| `NONE` | 0 |  |
| `FRAMEBUFFER_COMPLETE` | 0x8CD5 |  |
| `FRAMEBUFFER_INCOMPLETE_ATTACHMENT` | 0x8CD6 |  |
| `FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT` | 0x8CD7 |  |
| `FRAMEBUFFER_INCOMPLETE_DIMENSIONS` | 0x8CD9 |  |
| `FRAMEBUFFER_UNSUPPORTED` | 0x8CDD |  |
| `FRAMEBUFFER_BINDING` | 0x8CA6 |  |
| `RENDERBUFFER_BINDING` | 0x8CA7 |  |
| `MAX_RENDERBUFFER_SIZE` | 0x84E8 |  |
| `INVALID_FRAMEBUFFER_OPERATION` | 0x0506 |  |

### Pixel storage modes

Constants passed to `WebGLRenderingContext.pixelStorei()`.

| Constant name | Value | Description |
| --- | --- | --- |
| `UNPACK_FLIP_Y_WEBGL` | 0x9240 |  |
| `UNPACK_PREMULTIPLY_ALPHA_WEBGL` | 0x9241 |  |
| `UNPACK_COLORSPACE_CONVERSION_WEBGL` | 0x9243 |  |

Additional constants defined WebGL 2
------------------------------------

These constants are defined on the `WebGL2RenderingContext` interface. All WebGL 1 constants are also available in a WebGL 2 context.

### Getting GL parameter information

Constants passed to `WebGLRenderingContext.getParameter()` to specify what information to return.

| Constant name | Value | Description |
| --- | --- | --- |
| `READ_BUFFER` | 0x0C02 |  |
| `UNPACK_ROW_LENGTH` | 0x0CF2 |  |
| `UNPACK_SKIP_ROWS` | 0x0CF3 |  |
| `UNPACK_SKIP_PIXELS` | 0x0CF4 |  |
| `PACK_ROW_LENGTH` | 0x0D02 |  |
| `PACK_SKIP_ROWS` | 0x0D03 |  |
| `PACK_SKIP_PIXELS` | 0x0D04 |  |
| `TEXTURE_BINDING_3D` | 0x806A |  |
| `UNPACK_SKIP_IMAGES` | 0x806D |  |
| `UNPACK_IMAGE_HEIGHT` | 0x806E |  |
| `MAX_3D_TEXTURE_SIZE` | 0x8073 |  |
| `MAX_ELEMENTS_VERTICES` | 0x80E8 |  |
| `MAX_ELEMENTS_INDICES` | 0x80E9 |  |
| `MAX_TEXTURE_LOD_BIAS` | 0x84FD |  |
| `MAX_FRAGMENT_UNIFORM_COMPONENTS` | 0x8B49 |  |
| `MAX_VERTEX_UNIFORM_COMPONENTS` | 0x8B4A |  |
| `MAX_ARRAY_TEXTURE_LAYERS` | 0x88FF |  |
| `MIN_PROGRAM_TEXEL_OFFSET` | 0x8904 |  |
| `MAX_PROGRAM_TEXEL_OFFSET` | 0x8905 |  |
| `MAX_VARYING_COMPONENTS` | 0x8B4B |  |
| `FRAGMENT_SHADER_DERIVATIVE_HINT` | 0x8B8B |  |
| `RASTERIZER_DISCARD` | 0x8C89 |  |
| `VERTEX_ARRAY_BINDING` | 0x85B5 |  |
| `MAX_VERTEX_OUTPUT_COMPONENTS` | 0x9122 |  |
| `MAX_FRAGMENT_INPUT_COMPONENTS` | 0x9125 |  |
| `MAX_SERVER_WAIT_TIMEOUT` | 0x9111 |  |
| `MAX_ELEMENT_INDEX` | 0x8D6B |  |

### Textures

Constants passed to `WebGLRenderingContext.texParameteri()`, `WebGLRenderingContext.texParameterf()`, `WebGLRenderingContext.bindTexture()`, `WebGLRenderingContext.texImage2D()`, and others.

| Constant name | Value | Description |
| --- | --- | --- |
| `RED` | 0x1903 |  |
| `RGB8` | 0x8051 |  |
| `RGBA8` | 0x8058 |  |
| `RGB10_A2` | 0x8059 |  |
| `TEXTURE_3D` | 0x806F |  |
| `TEXTURE_WRAP_R` | 0x8072 |  |
| `TEXTURE_MIN_LOD` | 0x813A |  |
| `TEXTURE_MAX_LOD` | 0x813B |  |
| `TEXTURE_BASE_LEVEL` | 0x813C |  |
| `TEXTURE_MAX_LEVEL` | 0x813D |  |
| `TEXTURE_COMPARE_MODE` | 0x884C |  |
| `TEXTURE_COMPARE_FUNC` | 0x884D |  |
| `SRGB` | 0x8C40 |  |
| `SRGB8` | 0x8C41 |  |
| `SRGB8_ALPHA8` | 0x8C43 |  |
| `COMPARE_REF_TO_TEXTURE` | 0x884E |  |
| `RGBA32F` | 0x8814 |  |
| `RGB32F` | 0x8815 |  |
| `RGBA16F` | 0x881A |  |
| `RGB16F` | 0x881B |  |
| `TEXTURE_2D_ARRAY` | 0x8C1A |  |
| `TEXTURE_BINDING_2D_ARRAY` | 0x8C1D |  |
| `R11F_G11F_B10F` | 0x8C3A |  |
| `RGB9_E5` | 0x8C3D |  |
| `RGBA32UI` | 0x8D70 |  |
| `RGB32UI` | 0x8D71 |  |
| `RGBA16UI` | 0x8D76 |  |
| `RGB16UI` | 0x8D77 |  |
| `RGBA8UI` | 0x8D7C |  |
| `RGB8UI` | 0x8D7D |  |
| `RGBA32I` | 0x8D82 |  |
| `RGB32I` | 0x8D83 |  |
| `RGBA16I` | 0x8D88 |  |
| `RGB16I` | 0x8D89 |  |
| `RGBA8I` | 0x8D8E |  |
| `RGB8I` | 0x8D8F |  |
| `RED_INTEGER` | 0x8D94 |  |
| `RGB_INTEGER` | 0x8D98 |  |
| `RGBA_INTEGER` | 0x8D99 |  |
| `R8` | 0x8229 |  |
| `RG8` | 0x822B |  |
| R16F | 0x822D |  |
| R32F | 0x822E |  |
| RG16F | 0x822F |  |
| RG32F | 0x8230 |  |
| R8I | 0x8231 |  |
| R8UI | 0x8232 |  |
| R16I | 0x8233 |  |
| R16UI | 0x8234 |  |
| R32I | 0x8235 |  |
| R32UI | 0x8236 |  |
| RG8I | 0x8237 |  |
| RG8UI | 0x8238 |  |
| RG16I | 0x8239 |  |
| RG16UI | 0x823A |  |
| RG32I | 0x823B |  |
| RG32UI | 0x823C |  |
| R8\_SNORM | 0x8F94 |  |
| RG8\_SNORM | 0x8F95 |  |
| RGB8\_SNORM | 0x8F96 |  |
| RGBA8\_SNORM | 0x8F97 |  |
| `RGB10_A2UI` | 0x906F |  |
| `TEXTURE_IMMUTABLE_FORMAT` | 0x912F |  |
| `TEXTURE_IMMUTABLE_LEVELS` | 0x82DF |  |

### Pixel types

| Constant name | Value | Description |
| --- | --- | --- |
| `UNSIGNED_INT_2_10_10_10_REV` | 0x8368 |  |
| `UNSIGNED_INT_10F_11F_11F_REV` | 0x8C3B |  |
| `UNSIGNED_INT_5_9_9_9_REV` | 0x8C3E |  |
| `FLOAT_32_UNSIGNED_INT_24_8_REV` | 0x8DAD |  |
| UNSIGNED\_INT\_24\_8 | 0x84FA |  |
| `HALF_FLOAT` | 0x140B |  |
| `RG` | 0x8227 |  |
| `RG_INTEGER` | 0x8228 |  |
| `INT_2_10_10_10_REV` | 0x8D9F |  |

### Queries

| Constant name | Value | Description |
| --- | --- | --- |
| `CURRENT_QUERY` | 0x8865 |  |
| `QUERY_RESULT` | 0x8866 |  |
| `QUERY_RESULT_AVAILABLE` | 0x8867 |  |
| `ANY_SAMPLES_PASSED` | 0x8C2F |  |
| `ANY_SAMPLES_PASSED_CONSERVATIVE` | 0x8D6A |  |

### Draw buffers

| Constant name | Value | Description |
| --- | --- | --- |
| `MAX_DRAW_BUFFERS` | 0x8824 |  |
| `DRAW_BUFFER0` | 0x8825 |  |
| `DRAW_BUFFER1` | 0x8826 |  |
| `DRAW_BUFFER2` | 0x8827 |  |
| `DRAW_BUFFER3` | 0x8828 |  |
| `DRAW_BUFFER4` | 0x8829 |  |
| `DRAW_BUFFER5` | 0x882A |  |
| `DRAW_BUFFER6` | 0x882B |  |
| `DRAW_BUFFER7` | 0x882C |  |
| `DRAW_BUFFER8` | 0x882D |  |
| `DRAW_BUFFER9` | 0x882E |  |
| `DRAW_BUFFER10` | 0x882F |  |
| `DRAW_BUFFER11` | 0x8830 |  |
| `DRAW_BUFFER12` | 0x8831 |  |
| `DRAW_BUFFER13` | 0x8832 |  |
| `DRAW_BUFFER14` | 0x8833 |  |
| `DRAW_BUFFER15` | 0x8834 |  |
| `MAX_COLOR_ATTACHMENTS` | 0x8CDF |  |
| `COLOR_ATTACHMENT1` | 0x8CE1 |  |
| `COLOR_ATTACHMENT2` | 0x8CE2 |  |
| `COLOR_ATTACHMENT3` | 0x8CE3 |  |
| `COLOR_ATTACHMENT4` | 0x8CE4 |  |
| `COLOR_ATTACHMENT5` | 0x8CE5 |  |
| `COLOR_ATTACHMENT6` | 0x8CE6 |  |
| `COLOR_ATTACHMENT7` | 0x8CE7 |  |
| `COLOR_ATTACHMENT8` | 0x8CE8 |  |
| `COLOR_ATTACHMENT9` | 0x8CE9 |  |
| `COLOR_ATTACHMENT10` | 0x8CEA |  |
| `COLOR_ATTACHMENT11` | 0x8CEB |  |
| `COLOR_ATTACHMENT12` | 0x8CEC |  |
| `COLOR_ATTACHMENT13` | 0x8CED |  |
| `COLOR_ATTACHMENT14` | 0x8CEE |  |
| `COLOR_ATTACHMENT15` | 0x8CEF |  |

### Samplers

| Constant name | Value | Description |
| --- | --- | --- |
| `SAMPLER_3D` | 0x8B5F |  |
| `SAMPLER_2D_SHADOW` | 0x8B62 |  |
| `SAMPLER_2D_ARRAY` | 0x8DC1 |  |
| `SAMPLER_2D_ARRAY_SHADOW` | 0x8DC4 |  |
| `SAMPLER_CUBE_SHADOW` | 0x8DC5 |  |
| `INT_SAMPLER_2D` | 0x8DCA |  |
| `INT_SAMPLER_3D` | 0x8DCB |  |
| `INT_SAMPLER_CUBE` | 0x8DCC |  |
| `INT_SAMPLER_2D_ARRAY` | 0x8DCF |  |
| `UNSIGNED_INT_SAMPLER_2D` | 0x8DD2 |  |
| `UNSIGNED_INT_SAMPLER_3D` | 0x8DD3 |  |
| `UNSIGNED_INT_SAMPLER_CUBE` | 0x8DD4 |  |
| `UNSIGNED_INT_SAMPLER_2D_ARRAY` | 0x8DD7 |  |
| `MAX_SAMPLES` | 0x8D57 |  |
| `SAMPLER_BINDING` | 0x8919 |  |

### Buffers

| Constant name | Value | Description |
| --- | --- | --- |
| `PIXEL_PACK_BUFFER` | 0x88EB |  |
| `PIXEL_UNPACK_BUFFER` | 0x88EC |  |
| `PIXEL_PACK_BUFFER_BINDING` | 0x88ED |  |
| `PIXEL_UNPACK_BUFFER_BINDING` | 0x88EF |  |
| `COPY_READ_BUFFER` | 0x8F36 |  |
| `COPY_WRITE_BUFFER` | 0x8F37 |  |
| `COPY_READ_BUFFER_BINDING` | 0x8F36 |  |
| `COPY_WRITE_BUFFER_BINDING` | 0x8F37 |  |

### Data types

| Constant name | Value | Description |
| --- | --- | --- |
| `FLOAT_MAT2x3` | 0x8B65 |  |
| `FLOAT_MAT2x4` | 0x8B66 |  |
| `FLOAT_MAT3x2` | 0x8B67 |  |
| `FLOAT_MAT3x4` | 0x8B68 |  |
| `FLOAT_MAT4x2` | 0x8B69 |  |
| `FLOAT_MAT4x3` | 0x8B6A |  |
| `UNSIGNED_INT_VEC2` | 0x8DC6 |  |
| `UNSIGNED_INT_VEC3` | 0x8DC7 |  |
| `UNSIGNED_INT_VEC4` | 0x8DC8 |  |
| `UNSIGNED_NORMALIZED` | 0x8C17 |  |
| `SIGNED_NORMALIZED` | 0x8F9C |  |

### Vertex attributes

| Constant name | Value | Description |
| --- | --- | --- |
| `VERTEX_ATTRIB_ARRAY_INTEGER` | 0x88FD |  |
| `VERTEX_ATTRIB_ARRAY_DIVISOR` | 0x88FE |  |

### Transform feedback

| Constant name | Value | Description |
| --- | --- | --- |
| `TRANSFORM_FEEDBACK_BUFFER_MODE` | 0x8C7F |  |
| `MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS` | 0x8C80 |  |
| `TRANSFORM_FEEDBACK_VARYINGS` | 0x8C83 |  |
| `TRANSFORM_FEEDBACK_BUFFER_START` | 0x8C84 |  |
| `TRANSFORM_FEEDBACK_BUFFER_SIZE` | 0x8C85 |  |
| `TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN` | 0x8C88 |  |
| `MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS` | 0x8C8A |  |
| `MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS` | 0x8C8B |  |
| `INTERLEAVED_ATTRIBS` | 0x8C8C |  |
| `SEPARATE_ATTRIBS` | 0x8C8D |  |
| `TRANSFORM_FEEDBACK_BUFFER` | 0x8C8E |  |
| `TRANSFORM_FEEDBACK_BUFFER_BINDING` | 0x8C8F |  |
| `TRANSFORM_FEEDBACK` | 0x8E22 |  |
| `TRANSFORM_FEEDBACK_PAUSED` | 0x8E23 |  |
| `TRANSFORM_FEEDBACK_ACTIVE` | 0x8E24 |  |
| `TRANSFORM_FEEDBACK_BINDING` | 0x8E25 |  |

### Framebuffers and renderbuffers

| Constant name | Value | Description |
| --- | --- | --- |
| `FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING` | 0x8210 |  |
| `FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE` | 0x8211 |  |
| `FRAMEBUFFER_ATTACHMENT_RED_SIZE` | 0x8212 |  |
| `FRAMEBUFFER_ATTACHMENT_GREEN_SIZE` | 0x8213 |  |
| `FRAMEBUFFER_ATTACHMENT_BLUE_SIZE` | 0x8214 |  |
| `FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE` | 0x8215 |  |
| `FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE` | 0x8216 |  |
| `FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE` | 0x8217 |  |
| `FRAMEBUFFER_DEFAULT` | 0x8218 |  |
| `DEPTH_STENCIL_ATTACHMENT` | 0x821A |  |
| `DEPTH_STENCIL` | 0x84F9 |  |
| `DEPTH24_STENCIL8` | 0x88F0 |  |
| `DRAW_FRAMEBUFFER_BINDING` | 0x8CA6 |  |
| `READ_FRAMEBUFFER` | 0x8CA8 |  |
| `DRAW_FRAMEBUFFER` | 0x8CA9 |  |
| `READ_FRAMEBUFFER_BINDING` | 0x8CAA |  |
| `RENDERBUFFER_SAMPLES` | 0x8CAB |  |
| `FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER` | 0x8CD4 |  |
| `FRAMEBUFFER_INCOMPLETE_MULTISAMPLE` | 0x8D56 |  |

### Uniforms

| Constant name | Value | Description |
| --- | --- | --- |
| `UNIFORM_BUFFER` | 0x8A11 |  |
| `UNIFORM_BUFFER_BINDING` | 0x8A28 |  |
| `UNIFORM_BUFFER_START` | 0x8A29 |  |
| `UNIFORM_BUFFER_SIZE` | 0x8A2A |  |
| `MAX_VERTEX_UNIFORM_BLOCKS` | 0x8A2B |  |
| `MAX_FRAGMENT_UNIFORM_BLOCKS` | 0x8A2D |  |
| `MAX_COMBINED_UNIFORM_BLOCKS` | 0x8A2E |  |
| `MAX_UNIFORM_BUFFER_BINDINGS` | 0x8A2F |  |
| `MAX_UNIFORM_BLOCK_SIZE` | 0x8A30 |  |
| `MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS` | 0x8A31 |  |
| `MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS` | 0x8A33 |  |
| `UNIFORM_BUFFER_OFFSET_ALIGNMENT` | 0x8A34 |  |
| `ACTIVE_UNIFORM_BLOCKS` | 0x8A36 |  |
| `UNIFORM_TYPE` | 0x8A37 |  |
| `UNIFORM_SIZE` | 0x8A38 |  |
| `UNIFORM_BLOCK_INDEX` | 0x8A3A |  |
| `UNIFORM_OFFSET` | 0x8A3B |  |
| `UNIFORM_ARRAY_STRIDE` | 0x8A3C |  |
| `UNIFORM_MATRIX_STRIDE` | 0x8A3D |  |
| `UNIFORM_IS_ROW_MAJOR` | 0x8A3E |  |
| `UNIFORM_BLOCK_BINDING` | 0x8A3F |  |
| `UNIFORM_BLOCK_DATA_SIZE` | 0x8A40 |  |
| `UNIFORM_BLOCK_ACTIVE_UNIFORMS` | 0x8A42 |  |
| `UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES` | 0x8A43 |  |
| `UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER` | 0x8A44 |  |
| `UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER` | 0x8A46 |  |

### Sync objects

| Constant name | Value | Description |
| --- | --- | --- |
| `OBJECT_TYPE` | 0x9112 |  |
| `SYNC_CONDITION` | 0x9113 |  |
| `SYNC_STATUS` | 0x9114 |  |
| `SYNC_FLAGS` | 0x9115 |  |
| `SYNC_FENCE` | 0x9116 |  |
| `SYNC_GPU_COMMANDS_COMPLETE` | 0x9117 |  |
| `UNSIGNALED` | 0x9118 |  |
| `SIGNALED` | 0x9119 |  |
| `ALREADY_SIGNALED` | 0x911A |  |
| `TIMEOUT_EXPIRED` | 0x911B |  |
| `CONDITION_SATISFIED` | 0x911C |  |
| `WAIT_FAILED` | 0x911D |  |
| `SYNC_FLUSH_COMMANDS_BIT` | 0x00000001 |  |

### Miscellaneous constants

| Constant name | Value | Description |
| --- | --- | --- |
| `COLOR` | 0x1800 |  |
| DEPTH | 0x1801 |  |
| `STENCIL` | 0x1802 |  |
| `MIN` | 0x8007 |  |
| MAX | 0x8008 |  |
| `DEPTH_COMPONENT24` | 0x81A6 |  |
| `STREAM_READ` | 0x88E1 |  |
| `STREAM_COPY` | 0x88E2 |  |
| `STATIC_READ` | 0x88E5 |  |
| `STATIC_COPY` | 0x88E6 |  |
| `DYNAMIC_READ` | 0x88E9 |  |
| `DYNAMIC_COPY` | 0x88EA |  |
| `DEPTH_COMPONENT32F` | 0x8CAC |  |
| `DEPTH32F_STENCIL8` | 0x8CAD |  |
| `INVALID_INDEX` | 0xFFFFFFFF |  |
| `TIMEOUT_IGNORED` | -1 |  |
| `MAX_CLIENT_WAIT_TIMEOUT_WEBGL` | 0x9247 |  |

Constants defined in WebGL extensions
-------------------------------------

### ANGLE\_instanced\_arrays

| Constant name | Value | Description |
| --- | --- | --- |
| `VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE` | 0x88FE | Describes the frequency divisor used for instanced rendering. |

For more information, see `ANGLE_instanced_arrays`.

### WEBGL\_debug\_renderer\_info

| Constant name | Value | Description |
| --- | --- | --- |
| `UNMASKED_VENDOR_WEBGL` | 0x9245 | Passed to `getParameter` to get the vendor string of the graphics driver. |
| `UNMASKED_RENDERER_WEBGL` | 0x9246 | Passed to `getParameter` to get the renderer string of the graphics driver. |

For more information, see `WEBGL_debug_renderer_info`.

### EXT\_texture\_filter\_anisotropic

| Constant name | Value | Description |
| --- | --- | --- |
| `MAX_TEXTURE_MAX_ANISOTROPY_EXT` | 0x84FF | Returns the maximum available anisotropy. |
| `TEXTURE_MAX_ANISOTROPY_EXT` | 0x84FE | Passed to `texParameter` to set the desired maximum anisotropy for a texture. |

For more information, see `EXT_texture_filter_anisotropic`.

### WEBGL\_compressed\_texture\_s3tc

| Constant name | Value | Description |
| --- | --- | --- |
| `COMPRESSED_RGB_S3TC_DXT1_EXT` | 0x83F0 | A DXT1-compressed image in an RGB image format. |
| `COMPRESSED_RGBA_S3TC_DXT1_EXT` | 0x83F1 |
 A DXT1-compressed image in an RGB image format with a simple on/off
 alpha value.
  |
| `COMPRESSED_RGBA_S3TC_DXT3_EXT` | 0x83F2 |
 A DXT3-compressed image in an RGBA image format. Compared to a 32-bit
 RGBA texture, it offers 4:1 compression.
  |
| `COMPRESSED_RGBA_S3TC_DXT5_EXT` | 0x83F3 |
 A DXT5-compressed image in an RGBA image format. It also provides a 4:1
 compression, but differs to the DXT3 compression in how the alpha
 compression is done.
  |

For more information, see `WEBGL_compressed_texture_s3tc`.

### WEBGL\_compressed\_texture\_etc

| Constant name | Value | Description |
| --- | --- | --- |
| `COMPRESSED_R11_EAC` | 0x9270 | One-channel (red) unsigned format compression. |
| `COMPRESSED_SIGNED_R11_EAC` | 0x9271 | One-channel (red) signed format compression. |
| `COMPRESSED_RG11_EAC` | 0x9272 | Two-channel (red and green) unsigned format compression. |
| `COMPRESSED_SIGNED_RG11_EAC` | 0x9273 | Two-channel (red and green) signed format compression. |
| `COMPRESSED_RGB8_ETC2` | 0x9274 | Compresses RGB8 data with no alpha channel. |
| `COMPRESSED_RGBA8_ETC2_EAC` | 0x9275 |
 Compresses RGBA8 data. The RGB part is encoded the same as
 `RGB_ETC2`, but the alpha part is encoded separately.
  |
| `COMPRESSED_SRGB8_ETC2` | 0x9276 | Compresses sRGB8 data with no alpha channel. |
| `COMPRESSED_SRGB8_ALPHA8_ETC2_EAC` | 0x9277 |
 Compresses sRGBA8 data. The sRGB part is encoded the same as
 `SRGB_ETC2`, but the alpha part is encoded separately.
  |
| `COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2` | 0x9278 |
 Similar to `RGB8_ETC`, but with ability to punch through the
 alpha channel, which means to make it completely opaque or transparent.
  |
| `COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2` | 0x9279 |
 Similar to `SRGB8_ETC`, but with ability to punch through the
 alpha channel, which means to make it completely opaque or transparent.
  |

For more information, see `WEBGL_compressed_texture_etc`.

### WEBGL\_compressed\_texture\_pvrtc

| Constant name | Value | Description |
| --- | --- | --- |
| `COMPRESSED_RGB_PVRTC_4BPPV1_IMG` | 0x8C00 | RGB compression in 4-bit mode. One block for each 4×4 pixels. |
| `COMPRESSED_RGBA_PVRTC_4BPPV1_IMG` | 0x8C02 | RGBA compression in 4-bit mode. One block for each 4×4 pixels. |
| `COMPRESSED_RGB_PVRTC_2BPPV1_IMG` | 0x8C01 | RGB compression in 2-bit mode. One block for each 8×4 pixels. |
| `COMPRESSED_RGBA_PVRTC_2BPPV1_IMG` | 0x8C03 | RGBA compression in 2-bit mode. One block for each 8×4 pixels. |

For more information, see `WEBGL_compressed_texture_pvrtc`.

### WEBGL\_compressed\_texture\_etc1

| Constant name | Value | Description |
| --- | --- | --- |
| `COMPRESSED_RGB_ETC1_WEBGL` | 0x8D64 | Compresses 24-bit RGB data with no alpha channel. |

For more information, see `WEBGL_compressed_texture_etc1`.

### WEBGL\_depth\_texture

| Constant name | Value | Description |
| --- | --- | --- |
| `UNSIGNED_INT_24_8_WEBGL` | 0x84FA | Unsigned integer type for 24-bit depth texture data. |

For more information, see `WEBGL_depth_texture`.

### OES\_texture\_half\_float

| Constant name | Value | Description |
| --- | --- | --- |
| `HALF_FLOAT_OES` | 0x8D61 | Half floating-point type (16-bit). |

For more information, see `OES_texture_half_float`.

### WEBGL\_color\_buffer\_float

| Constant name | Value | Description |
| --- | --- | --- |
| `RGBA32F_EXT` | 0x8814 | RGBA 32-bit floating-point color-renderable format. |
| `RGB32F_EXT` | 0x8815 | RGB 32-bit floating-point color-renderable format. |
| `FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT` | 0x8211 |  |
| `UNSIGNED_NORMALIZED_EXT` | 0x8C17 |  |

For more information, see `WEBGL_color_buffer_float`.

### EXT\_blend\_minmax

| Constant name | Value | Description |
| --- | --- | --- |
| `MIN_EXT` | 0x8007 | Produces the minimum color components of the source and destination colors. |
| `MAX_EXT` | 0x8008 | Produces the maximum color components of the source and destination colors. |

For more information, see `EXT_blend_minmax`.

### EXT\_sRGB

| Constant name | Value | Description |
| --- | --- | --- |
| `SRGB_EXT` | 0x8C40 | Unsized sRGB format that leaves the precision up to the driver. |
| `SRGB_ALPHA_EXT` | 0x8C42 | Unsized sRGB format with unsized alpha component. |
| `SRGB8_ALPHA8_EXT` | 0x8C43 | Sized (8-bit) sRGB and alpha formats. |
| `FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT` | 0x8210 | Returns the framebuffer color encoding. |

For more information, see `EXT_sRGB`.

### OES\_standard\_derivatives

| Constant name | Value | Description |
| --- | --- | --- |
| `FRAGMENT_SHADER_DERIVATIVE_HINT_OES` | 0x8B8B |
 Indicates the accuracy of the derivative calculation for the GLSL
 built-in functions: `dFdx`, `dFdy`, and
 `fwidth`.
  |

For more information, see `OES_standard_derivatives`.

### WEBGL\_draw\_buffers

| Constant name | Value | Description |
| --- | --- | --- |
| `COLOR_ATTACHMENT0_WEBGL` | 0x8CE0 | Framebuffer color attachment point |
| `COLOR_ATTACHMENT1_WEBGL` | 0x8CE1 | Framebuffer color attachment point |
| `COLOR_ATTACHMENT2_WEBGL` | 0x8CE2 | Framebuffer color attachment point |
| `COLOR_ATTACHMENT3_WEBGL` | 0x8CE3 | Framebuffer color attachment point |
| `COLOR_ATTACHMENT4_WEBGL` | 0x8CE4 | Framebuffer color attachment point |
| `COLOR_ATTACHMENT5_WEBGL` | 0x8CE5 | Framebuffer color attachment point |
| `COLOR_ATTACHMENT6_WEBGL` | 0x8CE6 | Framebuffer color attachment point |
| `COLOR_ATTACHMENT7_WEBGL` | 0x8CE7 | Framebuffer color attachment point |
| `COLOR_ATTACHMENT8_WEBGL` | 0x8CE8 | Framebuffer color attachment point |
| `COLOR_ATTACHMENT9_WEBGL` | 0x8CE9 | Framebuffer color attachment point |
| `COLOR_ATTACHMENT10_WEBGL` | 0x8CEA | Framebuffer color attachment point |
| `COLOR_ATTACHMENT11_WEBGL` | 0x8CEB | Framebuffer color attachment point |
| `COLOR_ATTACHMENT12_WEBGL` | 0x8CEC | Framebuffer color attachment point |
| `COLOR_ATTACHMENT13_WEBGL` | 0x8CED | Framebuffer color attachment point |
| `COLOR_ATTACHMENT14_WEBGL` | 0x8CEE | Framebuffer color attachment point |
| `COLOR_ATTACHMENT15_WEBGL` | 0x8CEF | Framebuffer color attachment point |
| `DRAW_BUFFER0_WEBGL` | 0x8825 | Draw buffer |
| `DRAW_BUFFER1_WEBGL` | 0x8826 | Draw buffer |
| `DRAW_BUFFER2_WEBGL` | 0x8827 | Draw buffer |
| `DRAW_BUFFER3_WEBGL` | 0x8828 | Draw buffer |
| `DRAW_BUFFER4_WEBGL` | 0x8829 | Draw buffer |
| `DRAW_BUFFER5_WEBGL` | 0x882A | Draw buffer |
| `DRAW_BUFFER6_WEBGL` | 0x882B | Draw buffer |
| `DRAW_BUFFER7_WEBGL` | 0x882C | Draw buffer |
| `DRAW_BUFFER8_WEBGL` | 0x882D | Draw buffer |
| `DRAW_BUFFER9_WEBGL` | 0x882E | Draw buffer |
| `DRAW_BUFFER10_WEBGL` | 0x882F | Draw buffer |
| `DRAW_BUFFER11_WEBGL` | 0x8830 | Draw buffer |
| `DRAW_BUFFER12_WEBGL` | 0x8831 | Draw buffer |
| `DRAW_BUFFER13_WEBGL` | 0x8832 | Draw buffer |
| `DRAW_BUFFER14_WEBGL` | 0x8833 | Draw buffer |
| `DRAW_BUFFER15_WEBGL` | 0x8834 | Draw buffer |
| `MAX_COLOR_ATTACHMENTS_WEBGL` | 0x8CDF | Maximum number of framebuffer color attachment points |
| `MAX_DRAW_BUFFERS_WEBGL` | 0x8824 | Maximum number of draw buffers |

For more information, see `WEBGL_draw_buffers`.

### OES\_vertex\_array\_object

| Constant name | Value | Description |
| --- | --- | --- |
| `VERTEX_ARRAY_BINDING_OES` | 0x85B5 | The bound vertex array object (VAO). |

For more information, see `OES_vertex_array_object`.

### EXT\_disjoint\_timer\_query

| Constant name | Value | Description |
| --- | --- | --- |
| `QUERY_COUNTER_BITS_EXT` | 0x8864 | The number of bits used to hold the query result for the given target. |
| `CURRENT_QUERY_EXT` | 0x8865 | The currently active query. |
| `QUERY_RESULT_EXT` | 0x8866 | The query result. |
| `QUERY_RESULT_AVAILABLE_EXT` | 0x8867 | A Boolean indicating whether or not a query result is available. |
| `TIME_ELAPSED_EXT` | 0x88BF | Elapsed time (in nanoseconds). |
| `TIMESTAMP_EXT` | 0x8E28 | The current time. |
| `GPU_DISJOINT_EXT` | 0x8FBB | A Boolean indicating whether or not the GPU performed any disjoint operation. |

For more information, see `EXT_disjoint_timer_query`.

Specifications
--------------

| Specification |
| --- |
| WebGL # 5.14 |
| WebGL2 # 3.7 |

See also
--------

* `WebGLRenderingContext`


WebGL by example - Web APIs

WebGL by example
================

* Next »

*WebGL by example* is a series of live samples with short explanations that showcase WebGL concepts and capabilities.

The examples are sorted according to topic and level of difficulty, covering the WebGL rendering context, shader programming, textures, geometry, user interaction, and more.

Examples by topic
-----------------

The examples are sorted in order of increasing difficulty. But rather than just presenting them in a single long list, they are additionally divided into topics. Sometimes we revisit a topic several times, such as when needing to discuss it initially at a basic level, and later at intermediate and advanced levels.

Instead of trying to juggle shaders, geometry, and working with GPU memory, already in the first program, the examples here explore WebGL in an incremental way. We believe that it leads to a more effective learning experience and ultimately a deeper understanding of the underlying concepts.

Explanations about the examples are found in both the main text and in comments within the code. You should read all comments, because more advanced examples could not repeat comments about parts of the code that were previously explained.

### Getting to know the rendering context

Detect WebGL

This example demonstrates how to detect a WebGL rendering context and reports the result to the user.

Clearing with colors

How to clear the rendering context with a solid color.

Clearing by clicking

How to combine user interaction with graphics operations. Clearing the rendering context with a random color when the user clicks.

Simple color animation

A very basic color animation, done by clearing the WebGL drawing buffer with a different random color every second.

Color masking

Modifying random colors by applying color masking and thus limiting the range of displayed colors to specific shades.

Basic scissoring

How to draw simple rectangles and squares with scissoring operations.

Canvas size and WebGL

The example explores the effect of setting (or not setting) the canvas size to its element size in CSS pixels, as it appears in the browser window.

Boilerplate 1

The example describes repeated pieces of code that will be hidden from now on, as well as defining a JavaScript utility function to make WebGL initialization easier.

Scissor animation

Some animation fun with scissoring and clearing operations.

Raining rectangles

A simple game that demonstrates clearing with solid colors, scissoring, animation, and user interaction.

### Shader programming basics

Hello GLSL

A very basic shader program that draws a solid color square.

Hello vertex attributes

Combining shader programming and user interaction through vertex attributes.

Textures from code

A simple demonstration of procedural texturing with fragment shaders.

### Miscellaneous advanced examples

Video textures

This example demonstrates how to use video files as textures.

* Next »


WebGL types - Web APIs

WebGL types
===========

The following types are used in WebGL interfaces.

WebGL 1
-------

These types are used within a `WebGLRenderingContext`.

| Type | Web IDL type | Description |
| --- | --- | --- |
| `GLenum` | `unsigned long` |
 Used for enums. See also the list of
 constants.
  |
| `GLboolean` | `boolean` | A boolean value. |
| `GLbitfield` | `unsigned long` |
 A bit field that stores multiple, logical bits. Used for example in
 `WebGLRenderingContext.clear()`.
  |
| `GLbyte` | `byte` | 8-bit twos complement signed integer. |
| `GLshort` | `short` | 16-bit twos complement signed integer. |
| `GLint` | `long` | 32-bit twos complement signed integer. |
| `GLsizei` | `long` | Used for sizes (e.g. width and height of the drawing buffer). |
| `GLintptr` | `long long` | Special type for pointer arithmetic. |
| `GLsizeiptr` | `long long` | Special type for pointer arithmetic. |
| `GLubyte` | `octet` | 8-bit unsigned integer. |
| `GLushort` | `unsigned short` | 16-bit unsigned integer. |
| `GLuint` | `unsigned long` | 32-bit unsigned integer. |
| `GLfloat` | `unrestricted float` | 32-bit IEEE floating point number. |
| `GLclampf` | `unrestricted float` | Clamped 32-bit IEEE floating point number. |

WebGL 2
-------

These types are used within a `WebGL2RenderingContext`. All WebGL 1 types are used as well.

| Type | Web IDL type | Description |
| --- | --- | --- |
| `GLint64` | `long long` | Signed 64-bit integer number. |

WebGL extensions
----------------

These types are used within WebGL extensions.

| Type | Web IDL type | Description |
| --- | --- | --- |
| `GLuint64EXT` | `long long` | Unsigned 64-bit integer number. |

Specifications
--------------

| Specification |
| --- |
| WebGL # 5.1 |
| WebGL2 # 3.1 |
| EXT\_disjoint\_timer\_query  |

See also
--------

* `WebGLRenderingContext`


Matrix math for the web - Web APIs

Matrix math for the web
=======================

Matrices can be used to represent transformations of objects in space, and are used for performing many key types of computation when constructing images and visualizing data on the Web. This article explores how to create matrices and how to use them with CSS transforms and the `matrix3d` transform type.

While this article uses CSS to simplify explanations, matrices are a core concept used by many different technologies including WebGL, the WebXR (VR and AR) API, and GLSL shaders. This article is also available as an MDN content kit. The live examples use a collection of utility functions available under a global object named `MDN`.

Transformation matrices
-----------------------

There are many types of matrices, but the ones we are interested in are the 3D transformation matrices. These matrices consist of a set of 16 values arranged in a 4×4 grid. In JavaScript, it is easy to represent a matrix as an array.

Let's begin by considering the **identity matrix**. This is a special transformation matrix which functions much like the number 1 does in scalar multiplication; just like n \* 1 = n, multiplying any matrix by the identity matrix gives a resulting matrix whose values match the original matrix.

The identity matrix looks like this in JavaScript:

```js
let identityMatrix = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
```

What does multiplying by the identity matrix look like? The easiest example is to multiply a single point by the identity matrix. Since a 3D point only needs three values (`x`, `y`, and `z`), and the transformation matrix is a 4×4 value matrix, we need to add a fourth dimension to the point. By convention, this dimension is called the **perspective**, and is represented by the letter `w`. For a typical position, setting `w` to 1 will make the math work out.

After adding the `w` component to the point, notice how neatly the matrix and the point line up:

```js
[1, 0, 0, 0,
 0, 1, 0, 0,
 0, 0, 1, 0,
 0, 0, 0, 1]

[4, 3, 2, 1] // Point at [x, y, z, w]
```

The `w` component has some additional uses that are out of scope for this article. Check out the WebGL model view projection article for a look into how it comes in handy.

### Multiplying a matrix and a point

In our example code we have defined a function to multiply a matrix and a point — `multiplyMatrixAndPoint()`:

```js
// point • matrix
function multiplyMatrixAndPoint(matrix, point) {
  // Give a simple variable name to each part of the matrix, a column and row number
  let c0r0 = matrix[0],
    c1r0 = matrix[1],
    c2r0 = matrix[2],
    c3r0 = matrix[3];
  let c0r1 = matrix[4],
    c1r1 = matrix[5],
    c2r1 = matrix[6],
    c3r1 = matrix[7];
  let c0r2 = matrix[8],
    c1r2 = matrix[9],
    c2r2 = matrix[10],
    c3r2 = matrix[11];
  let c0r3 = matrix[12],
    c1r3 = matrix[13],
    c2r3 = matrix[14],
    c3r3 = matrix[15];

  // Now set some simple names for the point
  let x = point[0];
  let y = point[1];
  let z = point[2];
  let w = point[3];

  // Multiply the point against each part of the 1st column, then add together
  let resultX = x \* c0r0 + y \* c0r1 + z \* c0r2 + w \* c0r3;

  // Multiply the point against each part of the 2nd column, then add together
  let resultY = x \* c1r0 + y \* c1r1 + z \* c1r2 + w \* c1r3;

  // Multiply the point against each part of the 3rd column, then add together
  let resultZ = x \* c2r0 + y \* c2r1 + z \* c2r2 + w \* c2r3;

  // Multiply the point against each part of the 4th column, then add together
  let resultW = x \* c3r0 + y \* c3r1 + z \* c3r2 + w \* c3r3;

  return [resultX, resultY, resultZ, resultW];
}
```

Now using the function above we can multiply a point by the matrix. Using the identity matrix it should return a point identical to the original, since a point (or any other matrix) multiplied by the identity matrix is always equal to itself:

```js
// sets identityResult to [4,3,2,1]
let identityResult = multiplyMatrixAndPoint(identityMatrix, [4, 3, 2, 1]);
```

Returning the same point is not very useful, but there are other types of matrices that can perform helpful operations on points. The next sections will demonstrate some of these matrices.

### Multiplying two matrices

In addition to multiplying a matrix and a point together, you can also multiply two matrices together. The function from above can be re-used to help out in this process:

```js
//matrixB • matrixA
function multiplyMatrices(matrixA, matrixB) {
  // Slice the second matrix up into rows
  let row0 = [matrixB[0], matrixB[1], matrixB[2], matrixB[3]];
  let row1 = [matrixB[4], matrixB[5], matrixB[6], matrixB[7]];
  let row2 = [matrixB[8], matrixB[9], matrixB[10], matrixB[11]];
  let row3 = [matrixB[12], matrixB[13], matrixB[14], matrixB[15]];

  // Multiply each row by matrixA
  let result0 = multiplyMatrixAndPoint(matrixA, row0);
  let result1 = multiplyMatrixAndPoint(matrixA, row1);
  let result2 = multiplyMatrixAndPoint(matrixA, row2);
  let result3 = multiplyMatrixAndPoint(matrixA, row3);

  // Turn the result rows back into a single matrix
  return [
    result0[0],
    result0[1],
    result0[2],
    result0[3],
    result1[0],
    result1[1],
    result1[2],
    result1[3],
    result2[0],
    result2[1],
    result2[2],
    result2[3],
    result3[0],
    result3[1],
    result3[2],
    result3[3],
  ];
}
```

Let's look at this function in action:

```js
let someMatrix = [4, 0, 0, 0, 0, 3, 0, 0, 0, 0, 5, 0, 4, 8, 4, 1];

let identityMatrix = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];

// Returns a new array equivalent to someMatrix
let someMatrixResult = multiplyMatrices(identityMatrix, someMatrix);
```

**Warning:** These matrix functions are written for clarity of explanation, not for speed or memory management. These functions create a lot of new arrays, which can be particularly expensive for real-time operations due to garbage collection. In real production code it would be best to use optimized functions. glMatrix is an example of a library that has a focus on speed and performance. The focus in the glMatrix library is to have target arrays that are allocated before the update loop.

Translation matrix
------------------

A **translation matrix** is based upon the identity matrix, and is used in 3D graphics to move a point or object in one or more of the three directions (`x`, `y`, and/or `z`). The easiest way to think of a translation is like picking up a coffee cup. The coffee cup must be kept upright and oriented the same way so that no coffee is spilled. It can move up in the air off the table and around the air in space.

You can't actually drink the coffee using only a translation matrix, because to drink it, you have to be able to tilt or rotate the cup to pour the coffee into your mouth. We'll look at the type of matrix (cleverly called a **rotation matrix**) you use to do this later.

```js
let x = 50;
let y = 100;
let z = 0;

let translationMatrix = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, x, y, z, 1];
```

Place the distances along the three axes in the corresponding positions in the translation matrix, then multiply it by the point or matrix you need to move through 3D space.

Manipulating the DOM with a matrix
----------------------------------

A really easy way to start using a matrix is to use the CSS `matrix3d()` `transform`. First we'll set up a simple `<div>` with some content. The style is not shown, but it's set to a fixed width and height and is centered on the page. The `<div>` has a transition set for the transform so that matrix is animated in making it easy to see what is being done.

```html
<div id="move-me" class="transformable">
  <h2>Move me with a matrix</h2>
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit…</p>
</div>
```

Finally, for each example, we will generate a 4×4 matrix, then update the `<div>`'s style to have a transform applied to it, set to a `matrix3d`. Bear in mind that even though the matrix is made up of 4 rows and 4 columns, it collapses into a single line of 16 values. Matrices are always stored in one-dimensional lists in JavaScript.

```js
// Create the matrix3d style property from a matrix array
function matrixArrayToCssMatrix(array) {
  return `matrix3d(${array.join(",")})`;
}

// Grab the DOM element
let moveMe = document.getElementById("move-me");

// Returns a result like: "matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 50, 100, 0, 1);"
let matrix3dRule = matrixArrayToCssMatrix(translationMatrix);

// Set the transform
moveMe.style.transform = matrix3dRule;
```

View on JSFiddle

![An example of matrix translation](/en-US/docs/Web/API/WebGL_API/Matrix_math_for_the_web/matrix-translation.jpg)

Scale matrix
------------

A **scale matrix** makes something larger or smaller in one or more of the three dimensions: width, height, and depth. In typical (cartesian) coordinates, this causes stretching or contracting of the object in the corresponding directions.

The amount of change to apply to each of the width, height, and depth is placed diagonally starting at the top-left corner and making their way down toward the bottom-right.

```js
let w = 1.5; // width (x)
let h = 0.7; // height (y)
let d = 1; // depth (z)

let scaleMatrix = [w, 0, 0, 0, 0, h, 0, 0, 0, 0, d, 0, 0, 0, 0, 1];
```

View on JSFiddle

![An example of matrix scaling](/en-US/docs/Web/API/WebGL_API/Matrix_math_for_the_web/matrix-scale.jpg)

Rotation matrix
---------------

A **rotation matrix** is used to rotate a point or object. Rotation matrices look a little bit more complicated than scaling and transform matrices. They use trigonometric functions to perform the rotation. While this section won't break the steps down into exhaustive detail (check out this article on Wolfram MathWorld for that), take this example for illustration.

First, here's code that rotates a point around the origin without using matrices.

```js
// Manually rotating a point about the origin without matrices
let point = [10, 2];

// Calculate the distance from the origin
let distance = Math.sqrt(point[0] \* point[0] + point[1] \* point[1]);

// The equivalent of 60 degrees, in radians
let rotationInRadians = Math.PI / 3;

let transformedPoint = [
  Math.cos(rotationInRadians) \* distance,
  Math.sin(rotationInRadians) \* distance,
];
```

It is possible to encode these type of steps into a matrix, and do it for each of the `x`, `y`, and `z` dimensions. Below is the representation of a counterclockwise rotation about the Z axis in a left-handed coordinate system:

```js
let sin = Math.sin;
let cos = Math.cos;

// NOTE: There is no perspective in these transformations, so a rotation
// at this point will only appear to only shrink the div

let a = Math.PI \* 0.3; //Rotation amount in radians

// Rotate around Z axis
let rotateZMatrix = [
  cos(a),
  -sin(a),
  0,
  0,
  sin(a),
  cos(a),
  0,
  0,
  0,
  0,
  1,
  0,
  0,
  0,
  0,
  1,
];
```

View on JSFiddle

![An example of matrix rotation.](/en-US/docs/Web/API/WebGL_API/Matrix_math_for_the_web/matrix-rotation.jpg)

Here are a set of functions that return rotation matrices for rotating around each of the three axes. One big note is that there is no perspective applied, so it might not feel very 3D yet. The flatness is equivalent to when a camera zooms in really close onto an object in the distance — the sense of perspective disappears.

```js
function rotateAroundXAxis(a) {
  return [1, 0, 0, 0, 0, cos(a), -sin(a), 0, 0, sin(a), cos(a), 0, 0, 0, 0, 1];
}

function rotateAroundYAxis(a) {
  return [cos(a), 0, sin(a), 0, 0, 1, 0, 0, -sin(a), 0, cos(a), 0, 0, 0, 0, 1];
}

function rotateAroundZAxis(a) {
  return [cos(a), -sin(a), 0, 0, sin(a), cos(a), 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
}
```

View on JSFiddle

Matrix composition
------------------

The real power of matrices comes from **matrix composition**. When matrices of a certain class are multiplied together they preserve the history of the transformations and are reversible. This means that if a translation, rotation, and scale matrix are all combined together, when the order of the matrices is reversed and re-applied, then the original points are returned.

The order that matrices are multiplied in matters. When multiplying numbers, a \* b = c, and b \* a = c are both true. For example 3 \* 4 = 12, and 4 \* 3 = 12. In math, these numbers would be described as **commutative**. Matrices are *not* guaranteed to be the same if the order is switched, so matrices are **non-commutative**.

Another mind-bender is that matrix multiplication in WebGL and CSS needs to happen in the reverse order that the operations intuitively happen. For instance, to scale something down by 80%, move it down 200 pixels, and then rotate about the origin 90 degrees would look something like the following in pseudocode.
```

transformation = rotate * translate * scale
```

### Composing multiple transformations

The function that we will be using to compose our matrices is `multiplyArrayOfMatrices()`, which is part of the set of utility functions introduced near the top of this article. It takes an array of matrices and multiplies them together, returning the result. In WebGL shader code, this is built into the language and the `*` operator can be used. Additionally this example uses `scale()` and `translate()` functions, which return matrices as defined above.

```js
let transformMatrix = MDN.multiplyArrayOfMatrices([
  rotateAroundZAxis(Math.PI \* 0.5), // Step 3: rotate around 90 degrees
  translate(0, 200, 0), // Step 2: move down 200 pixels
  scale(0.8, 0.8, 0.8), // Step 1: scale down
]);
```

View on JSFiddle

![An example of matrix composition](/en-US/docs/Web/API/WebGL_API/Matrix_math_for_the_web/matrix-composition.jpg)

Finally, a fun step to show how matrices work is to reverse the steps to bring the matrix back to the original identity matrix.

```js
let transformMatrix = MDN.multiplyArrayOfMatrices([
  scale(1.25, 1.25, 1.25), // Step 6: scale back up
  translate(0, -200, 0), // Step 5: move back up
  rotateAroundZAxis(-Math.PI \* 0.5), // Step 4: rotate back
  rotateAroundZAxis(Math.PI \* 0.5), // Step 3: rotate around 90 degrees
  translate(0, 200, 0), // Step 2: move down 200 pixels
  scale(0.8, 0.8, 0.8), // Step 1: scale down
]);
```

Why matrices are important
--------------------------

Matrices are important because they comprise a small set of numbers that can describe a wide range of transformations in space. They can easily be shared around in programs. Different coordinate spaces can be described with matrices, and some matrix multiplication will move one set of data from one coordinate space to another coordinate space. Matrices effectively remember every part of the previous transforms that were used to generate them.

For uses in WebGL, the graphics card is particularly good at multiplying a large number of points in space by matrices. Different operations like positioning points, calculating lighting, and posing animated characters all rely on this fundamental tool.


A basic 2D WebGL animation example - Web APIs

A basic 2D WebGL animation example
==================================

In this WebGL example, we create a canvas and within it render a rotating square using WebGL. The coordinate system we use to represent our scene is the same as the canvas's coordinate system. That is, (0, 0) is at the top-left corner and the bottom-right corner is at (600, 460).

A rotating square example
-------------------------

Let's follow the different steps to get our rotating square.

### Vertex shader

First, let's take a look at the vertex shader. Its job, as always, is to convert the coordinates we're using for our scene into clipspace coordinates (that is, the system by which (0, 0) is at the center of the context and each axis extends from -1.0 to 1.0 regardless of the actual size of the context).

```html
<script id="vertex-shader" type="x-shader/x-vertex">
 attribute vec2 aVertexPosition;

 uniform vec2 uScalingFactor;
 uniform vec2 uRotationVector;

 void main() {
 vec2 rotatedPosition = vec2(
 aVertexPosition.x \* uRotationVector.y +
 aVertexPosition.y \* uRotationVector.x,
 aVertexPosition.y \* uRotationVector.y -
 aVertexPosition.x \* uRotationVector.x
 );

 gl\_Position = vec4(rotatedPosition \* uScalingFactor, 0.0, 1.0);
 }
</script>
```

The main program shares with us the attribute `aVertexPosition`, which is the position of the vertex in whatever coordinate system it's using. We need to convert these values so that both components of the position are in the range -1.0 to 1.0. This can be done easily enough by multiplying by a scaling factor that's based on the context's aspect ratio. We'll see that computation shortly.

We're also rotating the shape, and we can do that here, by applying a transform. We'll do that first. The rotated position of the vertex is computed by applying the rotation vector, found in the uniform `uRotationVector`, that's been computed by the JavaScript code.

Then the final position is computed by multiplying the rotated position by the scaling vector provided by the JavaScript code in `uScalingFactor`. The values of `z` and `w` are fixed at 0.0 and 1.0, respectively, since we're drawing in 2D.

The standard WebGL global `gl_Position` is then set to the transformed and rotated vertex's position.

### Fragment shader

Next comes the fragment shader. Its role is to return the color of each pixel in the shape being rendered. Since we're drawing a solid, untextured object with no lighting applied, this is exceptionally simple:

```html
<script id="fragment-shader" type="x-shader/x-fragment">
 #ifdef GL\_ES
 precision highp float;
 #endif

 uniform vec4 uGlobalColor;

 void main() {
 gl\_FragColor = uGlobalColor;
 }
</script>
```

This starts by specifying the precision of the `float` type, as required. Then we set the global `gl_FragColor` to the value of the uniform `uGlobalColor`, which is set by the JavaScript code to the color being used to draw the square.

### HTML

The HTML consists solely of the `<canvas>` that we'll obtain a WebGL context on.

```html
<canvas id="glcanvas" width="600" height="460">
  Oh no! Your browser doesn't support canvas!
</canvas>
```

### Globals and initialization

First, the global variables. We won't discuss these here; instead, we'll talk about them as they're used in the code to come.

```js
let gl = null;
let glCanvas = null;

// Aspect ratio and coordinate system
// details

let aspectRatio;
let currentRotation = [0, 1];
let currentScale = [1.0, 1.0];

// Vertex information

let vertexArray;
let vertexBuffer;
let vertexNumComponents;
let vertexCount;

// Rendering data shared with the
// scalers.

let uScalingFactor;
let uGlobalColor;
let uRotationVector;
let aVertexPosition;

// Animation timing

let shaderProgram;
let currentAngle;
let previousTime = 0.0;
let degreesPerSecond = 90.0;
```

Initializing the program is handled through a `load` event handler called `startup()`:

```js
window.addEventListener("load", startup, false);

function startup() {
  glCanvas = document.getElementById("glcanvas");
  gl = glCanvas.getContext("webgl");

  const shaderSet = [
    {
      type: gl.VERTEX\_SHADER,
      id: "vertex-shader",
    },
    {
      type: gl.FRAGMENT\_SHADER,
      id: "fragment-shader",
    },
  ];

  shaderProgram = buildShaderProgram(shaderSet);

  aspectRatio = glCanvas.width / glCanvas.height;
  currentRotation = [0, 1];
  currentScale = [1.0, aspectRatio];

  vertexArray = new Float32Array([
    -0.5, 0.5, 0.5, 0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, -0.5, -0.5,
  ]);

  vertexBuffer = gl.createBuffer();
  gl.bindBuffer(gl.ARRAY\_BUFFER, vertexBuffer);
  gl.bufferData(gl.ARRAY\_BUFFER, vertexArray, gl.STATIC\_DRAW);

  vertexNumComponents = 2;
  vertexCount = vertexArray.length / vertexNumComponents;

  currentAngle = 0.0;

  animateScene();
}
```

After getting the WebGL context, `gl`, we need to begin by building the shader program. Here, we're using code designed to let us add multiple shaders to our program quite easily. The array `shaderSet` contains a list of objects, each describing one shader function to be compiled into the program. Each function has a type (one of `gl.VERTEX_SHADER` or `gl.FRAGMENT_SHADER`) and an ID (the ID of the `<script>` element containing the shader's code).

The shader set is passed into the function `buildShaderProgram()`, which returns the compiled and linked shader program. We'll look at how this works next.

Once the shader program is built, we compute the aspect ratio of our context by dividing its width by its height. Then we set the current rotation vector for the animation to `[0, 1]`, and the scaling vector to `[1.0, aspectRatio]`. The scaling vector, as we saw in the vertex shader, is used to scale the coordinates to fit the -1.0 to 1.0 range.

The array of vertices is created next, as a `Float32Array` with six coordinates (three 2D vertices) per triangle to be drawn, for a total of 12 values.

As you can see, we're using a coordinate system of -1.0 to 1.0 for each axis. Why, you may ask, do we need to do any adjustments at all? This is because our context is not square. We're using a context that's 600 pixels wide and 460 tall. Each of those dimensions is mapped to the range -1.0 to 1.0. Since the two axes aren't the same length, if we don't adjust the values of one of the two axes, the square will get stretched out in one direction or the other. So we need to normalize these values.

Once the vertex array has been created, we create a new GL buffer to contain them by calling `gl.createBuffer()`. We bind the standard WebGL array buffer reference to that by calling `gl.bindBuffer()` and then copy the vertex data into the buffer using `gl.bufferData()`. The usage hint `gl.STATIC_DRAW` is specified, telling WebGL that the data will be set only one time and never modified, but will be used repeatedly. This lets WebGL consider any optimizations it can apply that may improve performance based on that information.

With the vertex data now provided to WebGL, we set `vertexNumComponents` to the number of components in each vertex (2, since they're 2D vertexes) and `vertexCount` to the number of vertexes in the vertex list.

Then the current rotation angle (in degrees) is set to 0.0, since we haven't performed any rotation yet, and the rotation speed (in degrees per screen refresh period, typically 60 FPS) is set to 6.

Finally, `animateScene()` is called to render the first frame and schedule the rendering of the next frame of the animation.

### Compiling and linking the shader program

The `buildShaderProgram()` function accepts as input an array of objects describing a set of shader functions to be compiled and linked into the shader program and returns the shader program after it's been built and linked.

```js
function buildShaderProgram(shaderInfo) {
  const program = gl.createProgram();

  shaderInfo.forEach((desc) => {
    const shader = compileShader(desc.id, desc.type);

    if (shader) {
      gl.attachShader(program, shader);
    }
  });

  gl.linkProgram(program);

  if (!gl.getProgramParameter(program, gl.LINK\_STATUS)) {
    console.log("Error linking shader program:");
    console.log(gl.getProgramInfoLog(program));
  }

  return program;
}
```

First, `gl.createProgram()` is called to create a new, empty, GLSL program.

Then, for each shader in the specified list of shaders, we call a `compileShader()` function to compile it, passing into it the ID and type of the shader function to build. Each of those objects includes, as mentioned before, the ID of the `<script>` element the shader code is found in and the type of shader it is. The compiled shader is attached to the shader program by passing it into `gl.attachShader()`.

**Note:** We could go a step farther here, actually, and look at the value of the `<script>` element's `type` attribute to determine the shader type.

Once all of the shaders are compiled, the program is linked using `gl.linkProgram()`.

If an error occurs while linking the program, the error message is logged to console.

Finally, the compiled program is returned to the caller.

### Compiling an individual shader

The `compileShader()` function, below, is called by `buildShaderProgram()` to compile a single shader.

```js
function compileShader(id, type) {
  const code = document.getElementById(id).firstChild.nodeValue;
  const shader = gl.createShader(type);

  gl.shaderSource(shader, code);
  gl.compileShader(shader);

  if (!gl.getShaderParameter(shader, gl.COMPILE\_STATUS)) {
    console.log(
      `Error compiling ${
 type === gl.VERTEX\_SHADER ? "vertex" : "fragment"
 } shader:`,
    );
    console.log(gl.getShaderInfoLog(shader));
  }
  return shader;
}
```

The code is fetched from the HTML document by obtaining the value of the text node contained within the `<script>` element with the specified ID. Then a new shader of the specified type is created using `gl.createShader()`.

The source code is sent into the new shader by passing it into `gl.shaderSource()`, and then the shader is compiled using `gl.compileShader()`

Compile errors are logged to the console. Note the use of a template literal string to insert the correct shader type string into the message that gets generated. The actual error details are obtained by calling `gl.getShaderInfoLog()`.

Finally, the compiled shader is returned to the caller (which is the `buildShaderProgram()` function.

### Drawing and animating the scene

The `animateScene()` function is called to render each animation frame.

```js
function animateScene() {
  gl.viewport(0, 0, glCanvas.width, glCanvas.height);
  gl.clearColor(0.8, 0.9, 1.0, 1.0);
  gl.clear(gl.COLOR\_BUFFER\_BIT);

  const radians = (currentAngle \* Math.PI) / 180.0;
  currentRotation[0] = Math.sin(radians);
  currentRotation[1] = Math.cos(radians);

  gl.useProgram(shaderProgram);

  uScalingFactor = gl.getUniformLocation(shaderProgram, "uScalingFactor");
  uGlobalColor = gl.getUniformLocation(shaderProgram, "uGlobalColor");
  uRotationVector = gl.getUniformLocation(shaderProgram, "uRotationVector");

  gl.uniform2fv(uScalingFactor, currentScale);
  gl.uniform2fv(uRotationVector, currentRotation);
  gl.uniform4fv(uGlobalColor, [0.1, 0.7, 0.2, 1.0]);

  gl.bindBuffer(gl.ARRAY\_BUFFER, vertexBuffer);

  aVertexPosition = gl.getAttribLocation(shaderProgram, "aVertexPosition");

  gl.enableVertexAttribArray(aVertexPosition);
  gl.vertexAttribPointer(
    aVertexPosition,
    vertexNumComponents,
    gl.FLOAT,
    false,
    0,
    0,
  );

  gl.drawArrays(gl.TRIANGLES, 0, vertexCount);

  requestAnimationFrame((currentTime) => {
    const deltaAngle =
      ((currentTime - previousTime) / 1000.0) \* degreesPerSecond;

    currentAngle = (currentAngle + deltaAngle) % 360;

    previousTime = currentTime;
    animateScene();
  });
}
```

The first thing that needs to be done in order to draw a frame of the animation is to clear the background to the desired color. In this case, we set the viewport based on the size of the `<canvas>`, call `clearColor()` to set the color to use when clearing content, then we clear the buffer with `clear()`.

Next, the current rotation vector is computed by converting the current rotation in degrees (`currentAngle`) into radians, then setting the first component of the rotation vector to the sine of that value and the second component to the cosine. The `currentRotation` vector is now the location of the point on the unit circle located at the angle `currentAngle`.

`useProgram()` is called to activate the GLSL shading program we established previously. Then we obtain the locations of each of the uniforms used to share information between the JavaScript code and the shaders (with `getUniformLocation()`).

The uniform named `uScalingFactor` is set to the `currentScale` value previously computed; this, as you may recall, is the value used to adjust the coordinate system based on the aspect ratio of the context. This is done using `uniform2fv()` (since this is a 2-value floating-point vector).

`uRotationVector` is set to the current rotation vector (`currentRotation)`, also using `uniform2fv()`.

`uGlobalColor` is set using `uniform4fv()` to the color we wish to use when drawing the square. This is a 4-component floating-point vector (one component each for red, green, blue, and alpha).

Now that's all out of the way, we can set up the vertex buffer and draw our shape, first, the buffer of vertexes that will be used to draw the triangles of the shape is set by calling `bindBuffer()`. Then the vertex position attribute's index is obtained from the shader program by calling `getAttribLocation()`.

With the index of the vertex position attribute now available in `aVertexPosition`, we call `enableVertexAttribArray()` to enable the position attribute so it can be used by the shader program (in particular, by the vertex shader).

Then the vertex buffer is bound to the `aVertexPosition` attribute by calling `vertexAttribPointer()`. This step is not obvious, since this binding is almost a side effect. But as a result, accessing `aVertexPosition` now obtains data from the vertex buffer.

With the association in place between the vertex buffer for our shape and the `aVertexPosition` attribute used to deliver vertexes one by one into the vertex shader, we're ready to draw the shape by calling `drawArrays()`.

At this point, the frame has been drawn. All that's left to do is to schedule to draw the next one. That's done here by calling `requestAnimationFrame()`, which asks that a callback function be executed the next time the browser is ready to update the screen.

Our `requestAnimationFrame()` callback receives as input a single parameter, `currentTime`, which specifies the time at which the frame drawing began. We use that and the saved time at which the last frame was drawn, `previousTime`, along with the number of degrees per second the square should rotate (`degreesPerSecond`) to calculate the new value of `currentAngle`. Then the value of `previousTime` is updated and we call `animateScene()` to draw the next frame (and in turn schedule the next frame to be drawn, ad infinitum).

### Result

This is a pretty simple example, since it's just drawing one simple object, but the concepts used here extend to much more complex animations.

See also
--------

* WebGL API
* WebGL tutorial