Processing every pixel of a live video frame in JavaScript can make the interface sluggish. WebGL offers a way to move that graphics work to the GPU. A shader is the small program that does part of the work—but WebGL is low-level, so a Web Component can keep its setup out of the page using it. section 15.3
For a simple image effect, two shaders work together:
- A vertex shader positions the points that form a flat square the size of the canvas and passes texture coordinates onward. section 15.2
- A fragment shader samples the image and sets the color of each drawn pixel. In the radial-fade example, distance from the image center darkens pixels toward the edges. section 15.2
Listing 15.1. An example WebGL shader
attribute vec2 a_position; #1
attribute vec2 a_texCoord;
uniform vec2 u_resolution;
varying vec2 v_texCoord;
uniform vec2 offset;
void main() { #2
vec2 zeroToOne = a_position / u_resolution;
vec2 zeroToTwo = zeroToOne * 2.0;
vec2 clipSpace = zeroToTwo - 1.0 + offset;
gl_Position = vec4(clipSpace.x * 1.0, clipSpace.y * -1.0, 0.0, 1.0);
v_texCoord = a_texCoord;
}
Follow the coordinate conversions through to gl_Position; the shader also passes texture coordinates for the fragment shader to use. section 15.2
Listing 15.1. An example WebGL shader (continued)
precision mediump float;
varying vec2 v_texCoord; #1
uniform sampler2D u_image0; #2
void main(void) {
vec4 sourcePixel = #3
texture2D(u_image0, v_texCoord);
float multiply = 1.0;
vec2 center = vec2(0.5, 0.5);
float dist = distance(v_texCoord, center);
gl_FragColor = (0.6-dist) * sourcePixel; #4
}
Here texture2D reads a source pixel, and distance from the center contributes to the color written through gl_FragColor. section 15.2
Shaders on live video
A WebGL-backed video component uses a WebGL canvas context and hides much of the low-level shader handling. Its filter demo includes sepia, greyscale, and edge-detection options. For a custom effect, the demo places vertex and fragment shader code in separate script elements alongside the video component. section 15.3
Writing shaders directly is one option, not a requirement for every 3D scene. Higher-level libraries such as Three.js and Babylon.js let you work with objects and models without handling all the rendering details yourself. section 15.2
