Introduction to this article
Bringing the awkward monkey, I’m the director of the Moral Education Department
I have written several p5.js
articles before, but they have not yet touched upon 3D graphics, but in fact p5.js
provides basic 3D graphics.
This article will start with the simplest cube, and make a few small demos to help fellow workers master the usage of the cube.
Basic usage of cube
Use the box()
method in p5.js
to create a cube.
Basic Grammar Instructions
According to the instructions on the official website, the syntax of box()
is as follows:
box([width], [height], [depth], [detailX], [detailY])
I think the parameter explanation given on the official website is a bit confusing. The following is my understanding.
width
: The width of the cube (optional), the default value is 50.height
: The height of the cube (optional).depth
: The depth of the cube (optional).detailX
: A number used to specify the subdivision level of the cube in the x-axis direction. The larger the value, the smoother the surface of the cube. (optional)detailY
: A number used to specify the subdivision level of the cube in the y-axis direction. The larger the value, the smoother the surface of the cube. (optional)
First, you need to understand the three parameters width
, height
and depth
. They are all optional parameters. The following situations will occur when passing parameters. :
- When none of the three parameters are passed: their values default to 50.
- When only
width
is passed:height
anddepth
will use the value ofwidth
. - When
width
andheight
are passed:depth
will use the value ofheight
. - All three parameters are passed: each uses its own value.
Try it yourself
First try creating a base cube.
<script> function setup() { createCanvas(200, 200, WEBGL) // Create a 200 * 200 canvas background(200) //Set the canvas background color (gray) box(100) //Create a cube } </script>
In this example, the cube created using box()
does not look like a cube, but a plane. The main reason is that we are facing it directly, so we can only see one side of it.
Rotate the angle and you will see that it is a cube.
<script> function setup() { createCanvas(200, 200, WEBGL) // Create a 200 * 200 canvas background(200) //Set the canvas background color (gray) // Rotation angle rotateX(10) rotateY(10) box(100) //Create a cube } </script>
Set style
To set the style for the cube, write the style function before box()
! ! !
fill color fill
Use the fill()
method to set the fill color.
<script> function setup() { createCanvas(200, 200, WEBGL) // Create a 200 * 200 canvas background(200) //Set the canvas background color (gray) // Rotation angle rotateX(10) rotateY(10) // fill color fill(255, 0, 0) box(100) //Create a cube } </script>
Do not use fill color
The default fill color of box()
is white. If you don’t need the fill color, you can use the noFill()
method to modify it.
<script> function setup() { createCanvas(200, 200, WEBGL) // Create a 200 * 200 canvas background(200) //Set the canvas background color (gray) // Rotation angle rotateX(10) rotateY(10) // Do not use fill color noFill() box(100) //Create a cube } </script>
stroke color stroke
Use the stroke()
method to set the cube’s stroke color.
<script> function setup() { createCanvas(200, 200, WEBGL) background(200) noFill() stroke(255, 0, 0) //Set the red border color rotateX(10) rotateY(10) box(100) } </script>
Set border width
Use the strokeWeight()
method to set the cube border width, and you need to pass in a numeric data.
<script> function setup() { createCanvas(200, 200, WEBGL) background(200) noFill() stroke(255, 0, 0) //Set the red border color strokeWeight(4) //Set the border width rotateX(10) rotateY(10) box(100) } </script>
Texture
In addition to basic fill and stroke, the cube can also be textured.
Textures can be pictures or videos. Let me first use picture resources as an example.
Loading resources needs to be processed in the preload()
life cycle. I mentioned it in “Introduction to p5.js Lightspeed”. Workers who have forgotten this knowledge point can take a look.
To attach the texture to the cube, there are the following steps:
- Load texture resources (images or videos)
- Set texture
- Create cube
<script> let myTexture = null function preload() { myTexture = loadImage('texture.gif') // Load texture } function setup() { createCanvas(200, 200, WEBGL) background(200) rotateX(0.5) rotateY(0.5) texture(myTexture) //Set texture box(100) //Create a cube } </script>
In this example, I loaded a gif texture, but this texture will not move when attached to the cube, because the cube is created in setup()
, and it will move if needed. We The texture needs to be set and the cube created in the draw()
statement cycle. I will discuss this part later in the “Animation” chapter.
Lighting Effect
You read that right, p5.js
also provides lighting effects. I have not talked about lighting effects in previous articles, and I will not talk about this part in this article (I will leave it to the next article) Talk), but workers can also understand this part first.
I used ambientLight()
and directional light directionalLight()
to hit the cube.
<script> function setup() { createCanvas(200, 200, WEBGL) background(200) rotateX(10) rotateY(10) ambientLight(255) //Set ambient lighting directionalLight(255, 255, 255, 0, 0, -1) // Set directional lighting box(100) } </script>
It can be seen that the colors on different sides are slightly different.
animation
Animation is very simple, just change the properties of the cube in the draw()
life cycle.
In addition, we also need to understand frameCount
, which is a global system variable provided by p5.js
, which records p5.js
How many frames have been run. During setup()
, the value of frameCount
is 0, and then frameCount
will be given every time draw()
is executed. plus 1.
Workers who are still unclear about the life cycle of draw()
must read the “drap” chapter of “Introduction to p5.js Lightspeed”.
Rotation animation
For example, if you want to do a rotation animation, just keep changing rotateX
, rotateY
or rotateX
in draw()
Produce a good effect.
<script> function setup() { createCanvas(200, 200, WEBGL) } function draw() { // The canvas color must be refilled every time it is refreshed, otherwise the last drawn cube will be left behind. background(200) // rotate rotateX(frameCount * 0.01) rotateY(frameCount * 0.01) rotateZ(frameCount * 0.01) // Draw the cube box(100) } </script>
gif sticker
In the previous texture example, we already know how to paste the image. If you paste a gif animation and want the image to really move at runtime, you need to set it in draw()
Texture mapped.
<script> let myTexture = null function preload() { myTexture = loadImage('texture.gif') // Load gif } function setup() { createCanvas(200, 200, WEBGL) } function draw() { background(200) rotateX(frameCount * 0.01) rotateY(frameCount * 0.01) rotateZ(frameCount * 0.01) //Set texture map texture(myTexture) box(100) } </script>
Video texture
Setting video texture is actually similar to setting image texture, except that the type of resource loaded is different.
Use the createVideo()
method to load video resources, and then hide the video, otherwise it will take up space on the page.
<script> let video = null function preload() { video = createVideo('video.mp4') // Load mp4 video.hide() // Hide video element } function setup() { createCanvas(640, 480, WEBGL) video.loop() // loop playback video.volume(0) //Set the volume } function draw() { background(200) rotateX(frameCount * 0.01) rotateY(frameCount * 0.01) //Set video texture texture(video) box(200) } </script>
The above code still uses the video.loop()
and video.volume()
methods.
video.loop()
: loop playback.video.volume()
: Set the video volume, the value range is0 ~ 1
.
Small Case
p5.js
is an art-oriented canvas
library. We have mastered the basic usage of box()
to create a cube. Let’s understand it next. With a few small cases, you should be able to implement some special effects yourself. Very suitable for living in the Nuggets~
Case 1: Rotate Push Pop
The first case is called “Rotate Push Pop”, which is an example of processing. I converted his code to be written using p5.js
.
Let me first mention the relationship between processing
and p5.js
: processing
is written in Java
, and p5.js
is the JS
version of processing
.
If you want to learn about processing
, you can find “Brother from the South”, who has written articles related to Processing.
Let’s take a look at the effect and code of this example first.
<script> let a = 0 let offset = Math.PI / 24 let num = 12 function setup() { createCanvas(440, 460, WEBGL) noStroke() } function draw() { lights() background(200, 200, 200) for(let i = 0; i < num; i + + ) { // map mapping let gray = map(i, 0, num - 1, 0, 255) push() fill(gray) rotateY(a + offset * i) rotateX(a / 2 + offset * i) box(200) pop() } a + = 0.01 } </script>
This example uses the knowledge of “p5.js State Management” and “p5.js Map Mapping”. Workers can understand it by themselves first. If you don’t understand, I will leave annotations for this example in the comment area.
Case 2: Moving Cubes
<script> function setup() { createCanvas(400, 400, WEBGL) } let letter = [ [0, 0, 0], [0, 0, 50], [25, 0, 25], [0, 50, 0], [0, 50, 50], [25, 25, 25], [50, 0, 0], [50, 0, 50], [50, 50, 0], [50, 50, 50] ] function draw() { background(200) rotateX(frameCount * 0.01) rotateY(frameCount * 0.01) for (let i = 0; i < letter.length; i + + ) { push() translate(letter[i][0], letter[i][1], letter[i][2]) box(10) pop() } } </script>
In this example, I combined the knowledge mentioned in “p5.js Transformation Operation” and “p5.js State Management”.
letter
creates a bunch of coordinate points, which record the positions of the cubes. Constantly change their positions in draw()
.
In order to prevent the cubes from reflecting each other when translate()
, you need to use push()
and pop()
to “isolate them from each other” “.
Case 3: Arranging Cubes
<script> function setup() { createCanvas(400, 400, WEBGL) } function draw() { background(200); rotateX(frameCount * 0.01); rotateY(frameCount * 0.01); for (let x = -50; x <= 50; x + = 10) { for (let y = -50; y <= 50; y + = 10) { for (let z = -50; z <= 50; z + = 10) { push(); translate(x, y, z); box(5); pop(); } } } } </script>
If you understand “Case 2”, then the example “Case 3” will be relatively simple. It is a bit like the “Nine-Nine Multiplication Table” exercise we did when we first learned JS
.
Case 4: Still a cube, I don’t know how to name it
Let’s compile another cube case, I’ll try my best. . .
<script> function setup() { createCanvas(400, 400, WEBGL) } function fractalBox(size, level) { box(size) if (level > 1) { level-- push() translate(-size/2, -size/2, -size/2) fractalBox(size/2, level) pop() push() translate(-size/2, -size/2, size/2) fractalBox(size/2, level) pop() push() translate(-size/2, size/2, -size/2) fractalBox(size/2, level) pop() push() translate(-size/2, size/2, size/2) fractalBox(size/2, level) pop() push() translate(size/2, -size/2, -size/2) fractalBox(size/2, level) pop() push() translate(size/2, -size/2, size/2) fractalBox(size/2, level) pop() push() translate(size/2, size/2, -size/2) fractalBox(size/2, level) pop() push() translate(size/2, size/2, size/2) fractalBox(size/2, level) pop() } } function draw() { background(200) rotateX(frameCount * 0.01) rotateY(frameCount * 0.01) fractalBox(200, 3) } </script>
I still used the method in the previous example and modified it a bit.
I really have no sense of art
Recommended Reading
“p5.js Lightspeed Introduction”
“p5.js State Management”
《p5.js How to use p5.js after installing it with npm? 》
“p5.js map mapping”
Like + Follow + Collection = Learned Code Warehouse