Processing

3D Space in Processing



By default, Processing draws using the JAVA2D renderer that is very precise, but slow. A sometimes faster but lower-quality version is P2D (the Processing 2D renderer), which uses your OpenGL-compatible graphics hardware. By adding a third parameter to the size() function you can specify which renderer to use. There are two ways to draw in 3D with Processing: Processing 3D ( P3D), or OpenGL.



To use P3D, you specify the renderer as the third parameter in the size() method:
void setup(){
    size(200,200,P3D);
}

The OPENGL renderer uses your graphics card to render your sketch. Since 2.0, the OPENGL library is part of the core. This makes exported applications larger. Using OPENGL allows you to run your programs more quickly than P3D does when there is a lot of geometry. To use OPENGL you specify the third parameter in the size() function:

void setup(){
    size(200,200,OPENGL);
}

Basic methods

3D Primitives

rect() works in 2D space, but not in 3D. To create a cube, Processing provides the box() function where a box is an extruded rectangle and you specify the x,y and z parameters. A box with equal dimension on all sides is a cube. If you just provide one parameter, the same value will be assigned to all three axis.

Keep in mind that drawing in three-dimensions on a 2D screen is an illusion. The addition of lighting is a simulation of the idea of real world lighting, which is useful as some objects, like spheres, do not appear three-dimensional until they are lit.

The lights() function sets the default ambient light, directional light, falloff, and specular values. The default parameters are ambientLight(128, 128, 128) and directionalLight(128, 128, 128, 0, 0, -1), lightFalloff(1, 0, 0), and lightSpecular(0, 0, 0). This function needs to be included in the draw() method to remain persistent in a looping program. Placing lighting functions in the setup() will cause them to only have an effect the first time through the loop.

void setup() {
  size(100, 100, P3D);
}

void draw() {
  background(100);
  noStroke();
  lights();
  pushMatrix();
  translate(width/2, height/2, 0);
  rotateY(map(mouseX, 0, width, -PI, PI));
  rotateX(map(mouseY, 0, height, PI, -PI));
  box(20);
  popMatrix();
}
sphere()
A sphere is a hollow ball made from tessellated triangles.
size(100, 100, P3D);
noStroke();
lights();
translate(58, 48, 0);
sphere(28);
sphereDetail()
Controls the detail used to render a sphere by adjusting the number of vertices of the sphere mesh. The default resolution is 30, which creates a fairly detailed sphere definition with vertices every 360/30 = 12 degrees. If you're going to render a great number of spheres per frame, it is advised to reduce the level of detail using this function. The setting stays active until sphereDetail() is called again with a new parameter and so should not be called prior to every sphere() statement, unless you wish to render spheres with different settings, e.g. using less detail for smaller spheres or ones further away from the camera. To control the detail of the horizontal and vertical resolution independently, use the version of the functions with two parameters (sphereDetail(ures, vres).
void setup() {
  size(100, 100, P3D);
}

void draw() {
  background(200);
 
  fill(mouseX * 2, 0, 160);
  stroke(255,50);
  lights();
  pushMatrix();
  translate(width/2, height/2, 0);
  rotateY(map(mouseX, 0, width, -PI, PI));
  rotateX(map(mouseY, 0, height, PI, -PI));
  sphereDetail((int) map(mouseX, 0, width, 3, 30), (int) map(mouseY, 0, width, 3, 30));
  sphere(40);
  popMatrix();
}

3D transforms

rotateX()
rotateY()
rotateZ()
Rotates a shape around the x,y or z-axis the amount specified by the angle parameter. Angles should be specified in radians (values from 0 to PI*2) or converted to radians with the radians() function. Objects are always rotated around their relative position to the origin and positive numbers rotate objects in a counterclockwise direction. Transformations apply to everything that happens after and subsequent calls to the function accumulates the effect. For example, calling rotateY(PI/2) and then rotateY(PI/2) is the same as rotateY(PI). If rotateY() is called within the draw(), the transformation is reset when the loop begins again.
scale()
Increases or decreases the size of a shape by expanding and contracting vertices. Objects always scale from their relative origin to the coordinate system. Scale values are specified as decimal percentages. For example, the function call scale(2.0) increases the dimension of a shape by 200%. Transformations apply to everything that happens after and subsequent calls to the function multiply the effect. For example, calling scale(2.0) and then scale(1.5) is the same as scale(3.0). If scale() is called within draw(), the transformation is reset when the loop begins again.
translate()
Specifies an amount to displace objects within the display window. The x parameter specifies left/right translation, the y parameter specifies up/down translation, and the z parameter specifies translations toward/away from the screen. Using this function with the z parameter requires using the P3D or OPENGL parameter in combination with size. Transformations apply to everything that happens after and subsequent calls to the function accumulates the effect.
pushMatrix()
popMatrix()
The pushMatrix() function saves the current coordinate system to the stack and popMatrix() restores the prior coordinate system. pushMatrix() and popMatrix() are used in conjuction with the other transformation methods and control the scope of the transformations. If you didn't use these functions, transformations would apply to all objects, which is not always what you want to do. Using theses methods allows you to use different transformations on different objects-like in a solar system model.

Lighting

There are four types of lights in Processing:
  1. spot
  2. point
  3. directional
  4. ambient


Spot lights radiate in a cone shape. This light has a direction, location, and a color.
size(100, 100, P3D);
background(0);
noStroke();
  
//spotLight(v1, v2, v3, x, y, z, nx, ny, nz, angle, concentration)
/*Parameters  
v1  float: red or hue value (depending on current color mode)
v2  float: green or saturation value (depending on current color mode)
v3  float: blue or brightness value (depending on current color mode)
x  float: x-coordinate of the light
y  float: y-coordinate of the light
z  float: z-coordinate of the light
nx  float: direction along the x axis
ny  float: direction along the y axis
nz  float: direction along the z axis
angle  float: angle of the spotlight cone
concentration  float: exponent determining the center bias of the cone
*/
spotLight(51, 102, 126, 80, 20, 40, -1, 0, 0, PI/2, 2);
translate(20, 50, 0);
sphere(30);


Point lights radiate from a single point like a lightbulb of any color.
size(100, 100, P3D);
background(0);
noStroke();

//pointLight(v1, v2, v3, x, y, z)
/*Parameters	
v1	float: red or hue value (depending on current color mode)
v2	float: green or saturation value (depending on current color mode)
v3	float: blue or brightness value (depending on current color mode)
x	float: x-coordinate of the light
y	float: y-coordinate of the light
z	float: z-coordinate of the light*/

pointLight(51, 102, 126, 35, 40, 36);
translate(80, 50, 0);
sphere(30);


Directional lights project in one direction to create strong lights and darks.
size(100, 100, P3D);
background(0);
noStroke();

//directionalLight(v1, v2, v3, nx, ny, nz)
/*Parameters  
v1  float: red or hue value (depending on current color mode)
v2  float: green or saturation value (depending on current color mode)
v3  float: blue or brightness value (depending on current color mode)
nx  float: direction along the x-axis
ny  float: direction along the y-axis
nz  float: direction along the z-axis*/

directionalLight(51, 102, 126, -1, 0, 0);
translate(20, 50, 0);
sphere(30);


Ambient lights create an even light of any color over the entire scene and are almost always used with other lights.
size(100, 100, P3D);
background(0);
noStroke();
directionalLight(126, 126, 126, 0, 0, -1);
//ambientLight(v1, v2, v3)
//ambientLight(v1, v2, v3, x, y, z)
/*Parameters  
v1  float: red or hue value (depending on current color mode)
v2  float: green or saturation value (depending on current color mode)
v3  float: blue or brightness value (depending on current color mode)
x  float: x-coordinate of the light
y  float: y-coordinate of the light
z  float: z-coordinate of the light*/

// The spheres are white by default so
// the ambient light changes their color
ambientLight(0, 0, 255);
translate(32, 50, 0);
rotateY(PI/5);
box(40);
translate(60, 0, 0);
sphere(30);
The lights() function creates the default lighting setup with both an ambient and directional light. lights() needs to be updated so it is necessary to put the call in the draw() function and if updating the background, after the call to background().

Exercise:

Create a sphere on top of a rectangular base.