WebGL & 3D
Activate the WEBGL renderer, draw 3D primitives, work with lights, cameras, and custom geometry.
Switching to WEBGL mode
Pass WEBGL as the third argument to createCanvas():
function setup() {
createCanvas(700, 500, WEBGL);
}
In WEBGL mode, the coordinate origin moves to the centre of the canvas. x goes right, y goes down, z comes toward you (out of the screen).
3D primitives
function draw() {
background(20);
lights(); // default lighting
// box(w, h, d) — default cube if no args
push();
translate(-150, 0, 0);
rotateX(frameCount * 0.01);
rotateY(frameCount * 0.015);
fill(100, 180, 255);
box(80);
pop();
// sphere(radius, detailX, detailY)
push();
translate(0, 0, 0);
fill(255, 150, 50);
sphere(60, 32, 32);
pop();
// cylinder(radius, height, detailX, detailY)
push();
translate(150, 0, 0);
fill(100, 220, 140);
cylinder(30, 100, 24, 1);
pop();
// cone, torus, plane, ellipsoid
push();
translate(0, 150, 0);
fill(200, 100, 255);
torus(60, 20, 24, 16);
pop();
}
Lighting
// Ambient light — fills everything uniformly
ambientLight(50);
// Directional light — parallel rays from a direction
directionalLight(255, 200, 100, 0.5, 1, -1);
// args: r, g, b, directionX, directionY, directionZ
// Point light — emits in all directions from a position
pointLight(255, 255, 255, 0, -100, 200);
// args: r, g, b, x, y, z
// Specular highlight
specularMaterial(200); // shininess
shininess(50);
Camera control
// orbitControl() — drag to rotate, scroll to zoom
function draw() {
background(20);
orbitControl();
box(100);
}
// Manual camera:
// camera(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ)
camera(0, -200, 400, 0, 0, 0, 0, 1, 0);
// Perspective:
// perspective(fov, aspect, near, far)
perspective(PI / 4, width / height, 0.1, 5000);
3D text
let font;
function preload() {
font = loadFont('SpaceMono-Regular.otf');
}
function draw() {
background(20);
orbitControl();
lights();
textFont(font);
textSize(60);
textAlign(CENTER, CENTER);
fill(200, 150, 255);
text('3D TEXT', 0, 0);
}
Custom geometry with beginShape()
WEBGL supports 3D vertices in beginShape():
function draw() {
background(20);
orbitControl();
lights();
noFill();
stroke(100, 200, 255, 60);
strokeWeight(0.5);
let t = frameCount * 0.01;
beginShape(LINES);
for (let i = 0; i < 400; i++) {
let a = i * 0.2 + t;
let r = map(sin(a * 0.3), -1, 1, 50, 200);
let x = cos(a) * r;
let y = map(i, 0, 400, -200, 200);
let z = sin(a) * r;
vertex(x, y, z);
}
endShape();
}
Textures
Apply an image as a texture to a 3D shape:
let img;
function preload() {
img = loadImage('texture.jpg');
}
function setup() {
createCanvas(600, 500, WEBGL);
}
function draw() {
background(20);
orbitControl();
noStroke();
texture(img);
rotateY(frameCount * 0.01);
sphere(150, 64, 64);
}
Off-screen graphics buffers
createGraphics() creates a 2D buffer that you can texture onto 3D surfaces:
let pg;
function setup() {
createCanvas(600, 500, WEBGL);
pg = createGraphics(512, 512);
}
function draw() {
// Draw to 2D buffer
pg.background(20);
pg.fill(255);
pg.textSize(60);
pg.textAlign(CENTER, CENTER);
pg.text('SPIN', 256, 256);
pg.circle(frameCount % 512, 256, 20);
// Apply as texture
background(10);
orbitControl();
noStroke();
texture(pg);
rotateY(frameCount * 0.01);
box(200);
}
Key takeaways
- Pass
WEBGLtocreateCanvas()to enable 3D — origin moves to canvas centre - Built-in 3D shapes:
box(),sphere(),cylinder(),cone(),torus(),plane() - Lighting:
ambientLight(),directionalLight(),pointLight()— call before drawing shapes orbitControl()adds free camera rotation and zoom with mousetexture(img)applies a 2D image orcreateGraphics()buffer to any 3D shape- WEBGL
beginShape()accepts 3Dvertex(x, y, z)for custom geometry