npm install three
ArrayCamera
Camera
CubeCamera
OrthographicCamera
PerspectiveCamera
const camera = new THREE.PerspectiveCamera(75, sizes.width / sizes.height)
StereoCamera
const clock = new THREE.Clock(); function animation(){ const elapsed = clock.getElapsedTime(); camera.position.x = Math.sin(elapsedTime); window.requestAnimationFrame(animation); }
const clock = new THREE.Clock();
function animation(){
const elapsed = clock.getElapsedTime();
camera.position.x = Math.sin(elapsedTime);
window.requestAnimationFrame(animation);
}
gsap has its own animation function
window.devicePixelRatio
, and to update the pixel ratio of your renderer, you simply need to call the renderer.setPixelRatio(...)
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
In Three.js, geometries are composed of vertices (point coordinates in 3D spaces) and faces (triangles that join those vertices to create a surface).
We use geometries to create meshes, but you can also use geometries to form particles. Each vertex (singular of vertices) will correspond to a particle, but this is for a future lesson.
We can store more data than the position in the vertices. A good example would be to talk about the UV coordinates or the normals. As you'll see, we will learn more about those later.
Three.js has many built-in geometries. While you don't need to know precisely how to instantiate each one, it is good to know that they exist.
All the built-in geometries we are going to see inherit from the BufferGeometry class. This class has many built in methods like translate(...), rotateX(...), normalize(), etc. but we are not going to use them in this lesson.
Most of the geometries documentation pages have examples.
const geometry = new THREE.BoxGeometry(1, 1, 1, 2, 2, 2)
const material = new THREE.MeshBasicMaterial({ color: 0xff0000, wireframe: true })
Sometimes, we need to create our own geometries. If the geometry is very complex or with a precise shape, it's better to create it in a 3D software (and we will cover that in a future lesson), but if the geometry isn't too complex, we can build it ourself by using BufferGeometry.
const geometry = new THREE.BufferGeometry()
const positionsArray = new Float32Array(9) // First vertice positionsArray[0] = 0 positionsArray[1] = 0 positionsArray[2] = 0 // Second vertice positionsArray[3] = 0 positionsArray[4] = 1 positionsArray[5] = 0 // Third vertice positionsArray[6] = 1 positionsArray[7] = 0 positionsArray[8] = 0
const positionsArray = new Float32Array(9)
// First vertice
positionsArray[0] = 0
positionsArray[1] = 0
positionsArray[2] = 0
// Second vertice
positionsArray[3] = 0
positionsArray[4] = 1
positionsArray[5] = 0
// Third vertice
positionsArray[6] = 1
positionsArray[7] = 0
positionsArray[8] = 0
const positionsAttribute = new THREE.BufferAttribute(positionsArray, 3)
setAttribute(...)
method. The first parameter is the name of this attribute and the second parameter is the value:geometry.setAttribute('position', positionsAttribute)
// Create an empty BufferGeometry const geometry = new THREE.BufferGeometry() // Create 50 triangles (450 values) const count = 50 const positionsArray = new Float32Array(count * 3 * 3) for(let i = 0; i < count * 3 * 3; i++) { positionsArray[i] = (Math.random() - 0.5) * 4 } // Create the attribute and name it 'position' const positionsAttribute = new THREE.BufferAttribute(positionsArray, 3) geometry.setAttribute('position', positionsAttribute)
// Create an empty BufferGeometry
const geometry = new THREE.BufferGeometry()
// Create 50 triangles (450 values)
const count = 50
const positionsArray = new Float32Array(count * 3 * 3)
for(let i = 0; i < count * 3 * 3; i++)
{
positionsArray[i] = (Math.random() - 0.5) * 4
}
// Create the attribute and name it 'position'
const positionsAttribute = new THREE.BufferAttribute(positionsArray, 3)
geometry.setAttribute('position', positionsAttribute)
The count * 3 * 3
is quite simple to explain: We need 50 triangles. Each triangle is composed of 3 vertices and each vertex is composed of 3 values (x, y, and z).
One interesting thing with BufferGeometry is that you can mutualize vertices using the index property. Consider a cube. Multiple faces can use some vertices like the ones in the corners. And if you look closely, every vertex can be used by various neighbor triangles. That will result in a smaller attribute array and performance improvement. But we won't cover this part in that lesson.
lil-gui
npm install lil-gui