Housekeeping

Slides and links at

http://webglworkshop.com/fxdigital-webgl/

https://codesandbox.io/dashboard/recent?workspace=d6417b5b-13f7-4d88-b160-3afb0ed258a5

Prequisites

JavaScript

C, C++, type language

Maths

Agenda

  1. About
  2. Fragment Shaders
  3. Animation
  4. Image Processing
  5. Transitions
  6. Gotchas

Fragment Shaders

Animation

Image Processing

Transitions

About

WebGL

JavaScript API
Web standard
Cross-device
Cross-platform
Canvas based

WebGL

Renderer - 2D and 3D
GPU access from browser
Control via shader programs
GLSL language

How WebGL Works

JavaScript

Create Context/Canvas
Draw commands
Data control

GLSL

Shader program
Vertex shader
— transform vertices

Fragment (pixel) shader
— transform pixels

How WebGL Works

3D

No

3D

Today

:sadface:

2D

Code Time

Hands on

If you'd like

Probably best

HTML

Your page will look something this...


					<html>
						<head>
							

							

							
						</head>

						<body>
							
						</body>
					</html>
					

Obvs, the JavaScript can go in separate .js file
Shaders can be loaded with XHR or fetch, but NOT

<script src="shader"></script>

GLSL

Vertex shader


					
          


Fragment shader


					
          

JavaScript

Get a canvas and WebGL context


						let canvas = document.getElementById("glCanvas");
						let gl;

						const names = ["webgl", "experimental-webgl", "webkit-3d", "moz-webgl"];
						for (let i = 0; i < names.length; ++i) {
							try {
								gl = canvas.getContext(names[i]);
							}
							catch (e) { }
							if (gl) break;
						}
          

JavaScript

Get source and compile to shader code


						const vertexSource = document.getElementById("vertex").firstChild.nodeValue;
						const fragmentSource = document.getElementById("fragment").firstChild.nodeValue;

						const vertexShader = gl.createShader(gl.VERTEX_SHADER);
						gl.shaderSource(vertexShader, vertexSource);
						gl.compileShader(vertexShader);

						const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
						gl.shaderSource(fragmentShader, fragmentSource);
						gl.compileShader(fragmentShader);

						let shaderProgram = gl.createProgram();
						gl.attachShader(shaderProgram, vertexShader);
						gl.attachShader(shaderProgram, fragmentShader);
						gl.linkProgram(shaderProgram);
					

JavaScript

Error check


					if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS))
						console.log(gl.getShaderInfoLog(vertexShader));

					if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS))
						console.log(gl.getShaderInfoLog(fragmentShader));

					if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS))
						console.log(gl.getProgramInfoLog(shaderProgram));
          

JavaScript

Get Data Locations


					shaderProgram.uColor = gl.getUniformLocation(shaderProgram, "uColor");
					shaderProgram.aVertexPosition = gl.getAttribLocation(shaderProgram, "aVertexPosition");
					gl.enableVertexAttribArray(shaderProgram.aVertexPosition);
          

Define Geometry


					const vertices = new Float32Array([-0.5, 0.5, 0.5, -0.5, -0.5, -0.5]);
					const vertexBuffer = gl.createBuffer();
					gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
					gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
					vertexBuffer.itemSize = 2;
					vertexBuffer.numItems = vertices.length / vertexBuffer.itemSize;
					gl.vertexAttribPointer(shaderProgram.aVertexPosition, vertexBuffer.itemSize, gl.FLOAT, false, 0, 0);
          

JavaScript

Send data to GPU and draw


					gl.useProgram(shaderProgram);

					gl.uniform4fv(shaderProgram.uColor, [0.0, 1.0, 0.0, 1.0]);
					gl.vertexAttribPointer(shaderProgram.aVertexPosition, vertexBuffer.itemSize, gl.FLOAT, false, 0, 0);

					gl.clearColor(0, 0.5, 0, 1);
					gl.clear(gl.COLOR_BUFFER_BIT);

					gl.drawArrays(gl.TRIANGLE_STRIP, 0, vertexBuffer.numItems);
          

Ta da!

Notes

JavaScript

  • script tag - holds GLSL code
  • "x-shader" - not special
  • "gl" - convention
    WebGL map to OpenGL equivalents e.g. glDrawArrays = gl.DrawArrays

JavaScript

Draw options


					gl.drawArrays(gl.TRIANGLE_STRIP, 0, vertexBuffer.numItems);
          
gl.POINTS
gl.LINES
gl.LINE_STRIP
gl.LINE_LOOP
gl.TRIANGLES
gl.TRIANGLE_STRIP
gl.TRIANGLE_FAN

Hands on

Hands on

  1. Change the triangle's colour
  2. Move the triangle's corners
  3. Turn the triangle into a square

Review

Review

Pipeline

Rasterisation/Interpolation

Input, Output, Interpolation

Inputs
attributes and uniforms

Interpolation
varying

Built-In Outputs
gl_Position, gl_FragColor

GLSL

GLSL

Language Features

  • C-like
  • "Secure"
  • Strongly typed
  • Optimised for geometry
  • Native support of vectors and matrices (no quaternions)
  • Built-in geometry focused functions
     e.g. cos, sin, dot, cross, reflect

GLSL

Data types

  • float, int, bool
  • mat2, mat3, mat4
  • vec2, vec3, vec4
    vec4 color;
    	color.rgb;
    	color.xyz;
    	color[0];
    
  • Swizzle:
    vec3 v1, v2;
     v1[0] = v2.r;
     v1.xyz = v2.rgb;
     v1.zyx = v2.bbb;

Hands on

Notes

Hands on will be GLSL in the fragment shader

Fragment shader


					
          

More Note

Vertex co-ordinates vs texture co-oordinates

Tasks

Functions

  • sin, cos, tan
  • ceil, floor
  • abs, sign
  • min, max
  • mod, clamp, fract
  • step, smoothstep
  • mix
  • length, distance
  • normalize
  • dot, cross

Revisit Tasks

More Tasks

On sandbox.io

Gotchas

  • CORS
  • Fixed sized loops
  • No recursion

Some Resources

More Resources

?