WebGL Version Overview
WebGL 1.0 was released in 2011, based on OpenGL ES 2.0. WebGL 2.0 was released in 2017, based on OpenGL ES 3.0, bringing numerous new features and performance improvements.
Main Differences Comparison
| Feature | WebGL 1.0 | WebGL 2.0 |
|---|
| Base Specification | OpenGL ES 2.0 | OpenGL ES 3.0 |
| Release Year | 2011 | 2017 |
| Shader Version | GLSL ES 1.0 | GLSL ES 3.0 |
| 3D Textures | Requires extension | Native support |
| Multiple Render Targets (MRT) | Requires extension | Native support |
| Instanced Rendering | Requires extension | Native support |
| Transform Feedback | Not supported | Supported |
| Sampler Objects | Not supported | Supported |
| Vertex Array Objects (VAO) | Requires extension | Native support |
| Non-power-of-2 Textures | Limited support | Full support |
Shader Language Differences
WebGL 1.0 (GLSL ES 1.0)
// Vertex shader
attribute vec3 a_position;
attribute vec2 a_texCoord;
uniform mat4 u_mvpMatrix;
uniform sampler2D u_texture;
varying vec2 v_texCoord;
void main() {
gl_Position = u_mvpMatrix * vec4(a_position, 1.0);
v_texCoord = a_texCoord;
}
// Fragment shader
precision mediump float;
varying vec2 v_texCoord;
uniform sampler2D u_texture;
void main() {
gl_FragColor = texture2D(u_texture, v_texCoord);
}
WebGL 2.0 (GLSL ES 3.0)
#version 300 es
// Vertex shader
in vec3 a_position; // attribute → in
in vec2 a_texCoord;
uniform mat4 u_mvpMatrix;
out vec2 v_texCoord; // varying → out
void main() {
gl_Position = u_mvpMatrix * vec4(a_position, 1.0);
v_texCoord = a_texCoord;
}
// Fragment shader
#version 300 es
precision mediump float;
in vec2 v_texCoord; // varying → in
uniform sampler2D u_texture;
out vec4 fragColor; // gl_FragColor → out variable
void main() {
fragColor = texture(u_texture, v_texCoord); // texture2D → texture
}
Shader Syntax Changes
| WebGL 1.0 | WebGL 2.0 | Description |
|---|
attribute | in | Vertex input |
varying | in/out | Data transfer between vertex/fragment shaders |
gl_FragColor | out variable | Fragment shader output |
texture2D() | texture() | 2D texture sampling |
textureCube() | texture() | Cubemap texture sampling |
| - | #version 300 es | Version declaration (required) |
WebGL 2.0 New Features Explained
1. 3D Textures
// WebGL 2.0 native 3D texture support
const texture3D = gl.createTexture();
gl.bindTexture(gl.TEXTURE_3D, texture3D);
gl.texImage3D(
gl.TEXTURE_3D, // Target
0, // Level
gl.RGBA, // Internal format
width,
height,
depth, // Depth
0, // Border
gl.RGBA,
gl.UNSIGNED_BYTE,
data
);
#version 300 es
uniform sampler3D u_volumeTexture;
void main() {
vec4 color = texture(u_volumeTexture, vec3(x, y, z));
}
2. Multiple Render Targets (MRT)
// Create framebuffer with multiple color attachments
const framebuffer = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
// Attach multiple textures
const textures = [];
for (let i = 0; i < 4; i++) {
const texture = gl.createTexture();
// ... configure texture
gl.framebufferTexture2D(
gl.FRAMEBUFFER,
gl.COLOR_ATTACHMENT0 + i, // COLOR_ATTACHMENT0, COLOR_ATTACHMENT1, ...
gl.TEXTURE_2D,
texture,
0
);
textures.push(texture);
}
// Specify which attachments to draw to
gl.drawBuffers([
gl.COLOR_ATTACHMENT0,
gl.COLOR_ATTACHMENT1,
gl.COLOR_ATTACHMENT2,
gl.COLOR_ATTACHMENT3
]);
#version 300 es
layout(location = 0) out vec4 color0;
layout(location = 1) out vec4 color1;
layout(location = 2) out vec4 color2;
layout(location = 3) out vec4 color3;
void main() {
color0 = vec4(1.0, 0.0, 0.0, 1.0);
color1 = vec4(0.0, 1.0, 0.0, 1.0);
color2 = vec4(0.0, 0.0, 1.0, 1.0);
color3 = vec4(1.0, 1.0, 1.0, 1.0);
}
3. Instanced Rendering
// WebGL 2.0 native support
// Draw 1000 instances, each with different transformation
const instanceCount = 1000;
gl.drawArraysInstanced(gl.TRIANGLES, 0, vertexCount, instanceCount);
// Or with indexed drawing
gl.drawElementsInstanced(gl.TRIANGLES, indexCount, gl.UNSIGNED_SHORT, 0, instanceCount);
#version 300 es
in vec3 a_position;
in mat4 a_instanceMatrix; // Instance matrix
void main() {
gl_Position = u_projectionMatrix * u_viewMatrix * a_instanceMatrix * vec4(a_position, 1.0);
}
// Create transform feedback object
const transformFeedback = gl.createTransformFeedback();
// Set vertex shader outputs
const vertexShaderSource = `#version 300 es
in vec3 a_position;
out vec3 v_newPosition; // Transformed position
void main() {
v_newPosition = a_position * 2.0; // Some transformation
}
`;
// Configure transform feedback
const program = gl.createProgram();
// ... compile and link shaders
gl.transformFeedbackVaryings(
program,
['v_newPosition'], // Output variables to capture
gl.SEPARATE_ATTRIBS // or INTERLEAVED_ATTRIBS
);
// Execute transform feedback
gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, transformFeedback);
gl.beginTransformFeedback(gl.POINTS);
gl.drawArrays(gl.POINTS, 0, count);
gl.endTransformFeedback();
5. Sampler Objects
// Separate texture parameters from texture object
const sampler = gl.createSampler();
// Configure sampler parameters
gl.samplerParameteri(sampler, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);
gl.samplerParameteri(sampler, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
gl.samplerParameteri(sampler, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.samplerParameteri(sampler, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
// Bind sampler to texture unit
gl.bindSampler(0, sampler); // Bind to texture unit 0
6. Vertex Array Object (VAO) Native Support
// WebGL 2.0 native support, no extension needed
const vao = gl.createVertexArray();
gl.bindVertexArray(vao);
// Configure vertex attributes (stored in VAO)
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(0);
gl.bindVertexArray(null);
// When drawing, just bind VAO
gl.bindVertexArray(vao);
gl.drawArrays(gl.TRIANGLES, 0, count);
New Texture Features
Non-power-of-2 Texture Full Support
// In WebGL 2.0, non-power-of-2 textures support all features
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
gl.generateMipmap(gl.TEXTURE_2D); // Also supports mipmap
Texture Arrays
const textureArray = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D_ARRAY, textureArray);
gl.texImage3D(
gl.TEXTURE_2D_ARRAY,
0,
gl.RGBA,
width,
height,
layerCount, // Number of layers
0,
gl.RGBA,
gl.UNSIGNED_BYTE,
data
);
How to Detect WebGL 2.0 Support
function getWebGLContext(canvas) {
// Try WebGL 2.0 first
let gl = canvas.getContext('webgl2');
if (gl) {
console.log('Using WebGL 2.0');
return gl;
}
// Fallback to WebGL 1.0
gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
if (gl) {
console.log('Using WebGL 1.0');
return gl;
}
console.error('WebGL not supported');
return null;
}
Browser Support
| Browser | WebGL 1.0 | WebGL 2.0 |
|---|
| Chrome | ✓ | ✓ (56+) |
| Firefox | ✓ | ✓ (51+) |
| Safari | ✓ | ✓ (15+) |
| Edge | ✓ | ✓ (79+) |
| IE 11 | ✓ | ✗ |
Migration Recommendations
- Progressive Enhancement: Detect WebGL 2.0 support first, fallback to 1.0 if not supported
- Shader Versions: Prepare different shader code for both versions
- Feature Detection: Check if specific features are available before using them
- Performance Considerations: WebGL 2.0 is more powerful, but 1.0 has better compatibility