
The course is in 5 main sections,
Set up the Development Environment
Create a Three.js boilerplate project - This section is optional, but advisable. This will give you a very good understanding of the aspects involved in creating a brand-new Three.js application from scratch.
Install the Threejs Course Boilerplate - This section is also optional, but useful in case you bypassed section 2, or you have finished the course, and you want a familiar template project that you can start from.
Learn all about the many aspects of Three.js from the core up to using it in more advanced examples and involving other third party libraries.
Deploying to Production - We will look at several options that you have for hosting your own Threejs projects on the internet.
Install VSCode IDE and Node
VSCode https://code.visualstudio.com/
Node https://nodejs.org/en/download/
We will create a course boilerplate using Vite.
Vite is a French word meaning "quick". It is pronounced "veet".
After copying the main.ts code from the last lesson, we should see an error indicating,
Cannot find module 'three' or its corresponding type declarations
We can fix this by installing the three library and its related type declarations.
Open the VSCode integrated terminal and execute these commands below.
npm install three --save-dev
npm install @types/three --save-dev
The core of Three.js is focused on the most important components of the 3D engine. For example, that is classes related to managing the scene graph, cameras, renderers, primitive geometries, textures, lighting, shadows and more.
To keep the core small and manageable to quickly download, many modules, such as 3D model loaders, controls and other utilities can be downloaded as addons from the examples/jsm folder.
If we want to use these extra modules in our projects, then we can import them separately.
The ./node_modules/three/examples/jsm/ directory, which was installed as part of Threejs library, contains many useful extra modules that we can use in our Threejs projects.
In this lesson, I will show you how to import the OrbitControls into the existing TypeScript project.
Let's add the Stats panel to our course boilerplate.
We can also use third party libraries in our Threejs applications.
The dat.GUI is another very useful tool that we can use to learn about Three.js as it allows us to quickly add a very basic user interface to interact with our 3d scene and the objects within it.
Note This section is optional. If you completed all the sections before this, then you already have the project created. This boilerplate is useful if you have chosen to bypass all the preceding sections, or you have already finished the course, and you would like to use a Three.js TypeScript project template that you are familiar with.
git clone https://github.com/Sean-Bradley/Three.js-Boilerplate-TS-Vite.git
cd Three.js-Boilerplate-TS-Vite
npm install
npm run dev
A Scene allows you to set up, in 3D coordinates, what is to be rendered by Three.js.
We need to have a scene. The scene is also sometimes referred to as the scene graph.
To introduce the scene, we will experiment with the background property.
The default colour of a scene is null. In that case it will use the default clear colour of the renderer.
There are several types of Cameras in Threejs. In this video we will experiment with the Perspective and the Orthographic cameras.
The camera properties describe a Frustum which are the dimensions inside the scene that will be rendered.
The most common Renderer used in Three.js is the WebGLRenderer.
It paints the scene and camera information onto a HTML Canvas Element.
The WebGLRenderer will use WebGL.
WebGL allows GPU-accelerated image processing and effects as the renderer creates the 2D image for the Canvas.
Object3D is the base class for many objects in Three.js.
It provides all the common methods and properties for manipulating objects in 3D space.
The most common examples of Object3Ds that you will see are Meshes, Lights, Cameras and Groups of Object3Ds.
The scene is an Object3D. You can add other Object3Ds to the scene and they become children of the scene. The scene itself is derived from the Object3D base class.
If you rotate the scene, or scale the scene, or translate its position, it will affect all if its child objects.
You make an Object3D a child of another Object3D by using the parents add method.
scene.add(cube)
You can also add Object3Ds to other Object3Ds that are already part of the scene. Any changes to the Object3D such as position, scale, rotation will affect all the children under the same parent equally.
Three.js has many classes for creating common geometries.
BoxGeometry
CircleGeometry
CylinderGeometry
ConeGeometry
EdgesGeometry
ExtrudeGeometry
ShapeGeometry
LatheGeometry
PlaneGeometry
RingGeometry
SphereGeometry
TextGeometry
TorusGeometry
TorusKnotGeometry
TubeGeometry
PolyhedronGeometry
DodecahedronGeometry
IcosahedronGeometry
OctahedronGeometry
TetrahedronGeometry
ParametricGeometry
WireframeGeometry
An introduction to the Three.js Materials.
THREE.Material
All these classes below inherit methods and properties from the Material base class.
LineBasicMaterial
LineDashedMaterial
MeshBasicMaterial
MeshDepthMaterial
MeshDistanceMaterial
MeshLambertMaterial
MeshMatcapMaterial
MeshNormalMaterial
MeshPhongMaterial
MeshStandardMaterial
MeshPhysicalMaterial
MeshToonMaterial
PointsMaterial
ShaderMaterial
RawShaderMaterial
ShadowMaterial
SpriteMaterial
In this lesson, we will introduce four of the most commonly used materials that you will see used in Three.js.
MeshBasicMaterial
MeshNormalMaterial
MeshPhongMaterial
MeshStandardMaterial
There are other materials, but we will discuss those, plus more details, about each material as we progress.
In this lesson, we will start by focusing on several important factors about materials and why you might choose one over the other.
Many Three.js projects may still use the dat.GUI, and this is because dat.GUI was the default GUI in the official Three.js examples from release 52 in 2012, up until release 135, when it was then replaced by lil-gui.
dat.GUI still works very well, but it is no longer maintained in case any libraries it depends upon also need updating.
In this lesson, we will migrate from using dat.GUI to using lil-gui.
lil-gui was designed as a drop-in replacement for dat.GUI.
Let's add a few different types of lights to the scene, and see how they affect the different materials.
In this lesson we will look at the shadows created by the SpotLight, PointLight and DirectionaLight.
In the case of PBR materials, such as MeshStandardMaterial and MeshPhysicalMaterial, we have the choice of setting the scene environment map, rather than placing multiple lights.
As our projects become more advanced, we will want to load extra assets into them, for example, images, models, sounds, animations, fonts, JSON data or more.
We have several ways of doing this.
All Three.js loaders extend from the THREE.Loader base class.
The THREE.Loader base class has a default THREE.LoadingManager object under the hood to keep track of loaded and pending objects and data.
The THREE.LoadingManager knows when a resource has started loading, has finished loading, the progress of a download (in most browsers), and if an error occurred while attempting to download the resource.
When you instantiate any Threejs loaders, e.g., GLTFLoader, OBJLoader, TextureLoader, etc..., you can pass in a callback function to use when the resource has loaded (onLoad), is downloading (onProgress) and if there was any error (onError) during the download.
A loader for loading glTF models into the Threejs scene.
glTF is a specification for the efficient transmission and loading of 3D scenes and models.
glTF minimizes both the size of 3D assets, and the runtime processing needed to unpack and use those assets.
A glTF file may contain one or more scenes, meshes, materials, textures, skins, skeletons, morph targets, animations, lights and cameras.
Assets can be provided in either JSON (.gltf) or binary (.glb) format.
We will experiment with materials, textures and lighting.
The final 3D model used in this lesson was created using Blender.
Instructions on how to make the model, are shown in the videos.
Raycasting allows you to create a vector from a 3D point in the scene, and detect which object(s) the vector intersects.
The raycasting class is mostly used for mouse picking objects in the 3D scene.
We can set up the Raycaster position and direction using the set or setFromCamera methods and then call its intersectObject or intersectObjects methods to tell us many things about the scene objects that were intersected by the ray, including,
the distance of the intersection from the Raycaster position,
the position of the intersection in the 3D scene,
the face of the object that was intersected,
the direction of the faces normal,
the UV coordinate of the intersection on the face
and a reference to the intersected object itself.
The OrbitControls allows the camera to orbit around a target.
Animating using Linear interpolation (Lerp).
There are many ways to lerp in Three.js from using the methods in the core base classes to even writing our own.
In this lesson, we will lerp an objects position, scale and material properties using various lerping options.
JEasings is a JavaScript Easing engine that can be used for animating.
It allows you to transition values of an objects properties to new values over a time duration.
You can set,
- The time duration
- The new values to ease to,
- An optional delay to start,
- An optional script to run on each update,
- An optional script to run when completed,
- An optional easing curve function to change the speed of the transition as it propgresses through the duration
- Start the Jeasing as soon as it is created, or put it into a varaible for use later
- Can chain multiple JEasings together to run in sequence or in a continuous loop.
JEasings provides a more advanced way of controlling animations verses using lerp.
In this lesson, we will use GLTF animations both stored in the GLTF and external.
We will use Blender to convert FBX models and animations from Mixamo, into GLB files.
The DRACO loader is used to load geometry compressed with the Draco library.
Draco is an open source library for compressing and decompressing 3D meshes and point clouds.
glTF files can also be compressed using the DRACO library, and they can also be loaded using the glTF loader.
We can configure the glTF loader to use the DRACOLoader to decompress the file in such cases.
In this lesson, we will compress the Eve model from the last lesson using the glTF Transform CLI tool.
Rapier is a physics engine that we can use to calculate Rigid body forces, velocities, contacts, constraints and more.
Calculating physics is useful in video games, animations, robotics and simulations.
We can use a physics engine independently of Threejs, or any rendering engine in fact, if we only wanted to calculate physics properties and events over time.
Instead, we are going to use that information, from the physics calculations, to continually update a THREE.Object3D position and quaternion between each frame render.
When trying to create Physics shapes or colliders to suit a geometry, it can be easy to make mistakes since you can't really visualize their dimensions, positions and rotations.
In this case, we can get a list of points, used by the shapes/colliders in the Rapier world and draw lines between each point.
The PointerLockControls implements the browsers inbuilt Pointer Lock API.
It provides input methods based on the movement of the mouse over time (i.e., deltas), not just the absolute position of the mouse cursor in the viewport.
It gives you access to raw mouse movement, locks the target of mouse events to a single element, eliminates limits on how far mouse movement can go in a single direction, and removes the cursor from view.
Furthermore, it's commonly used for first person view 3D games.
In this lesson we will,
Implement a follow cam to chase the car,
Setup revolute ImpulseJoint constraints to join the front wheels to steering axels, and then to the car body,
Use `configureMotorVelocity` to rotate the rear wheels of the car,
Use `configureMotorPosition` to steer the front wheels.
Use collision/interaction groups.
We will make an FPV (First Person View) game using the Rapier physics engine and Threejs.
We add some platforms, spinners, pendulums, start and finish platforms to the game example.
Each new type of game object will have a different problem to solve.
We will create the production version of our app ready for deployment.
The production version of the code, will have,
all the imported libraries concatenated and minified into a single bundle file,
unused portions of libraries will be tree-shaked, in case the imported library supports it,
the HMR functionality and Vite core scripts used while running the development version will be excluded,
all static resources, used by your app, we be copied into the `./dist` folder for easier deployment.
Note that image and model assets will still be loaded into your applications at runtime, as separate files. Asset files are usually binary files, and bundling binary files is not advisable since they need to be encoded as Base64 and this will normally increase there download size by an average 4 times.
Provided that our Three.js project works when served from the `./dist/` folder, then we can host it using GitHub pages for free.
To use GitHub pages, you will need to have a GitHub account.
You may prefer to use GitLab Pages to host your project instead of using GitHub Pages.
The process is very similar. We need to make sure our code can work from a sub path in the URL.
We can also host our applications on our own web servers.
In the next few lessons, we will provision our own internet connected server, where we will install Nginx, point a domain name and bind an SSL certificate.
We will use Nginx as the web server.
Now to upload the contents of our `./dist` folder to our server using Secure File Transfer Protocol (SFTP).
I have a domain already, and I can add subdomains to it, so I will create a new subdomain for my-project.sbcode.net.
In my domain name provider, I will create a new "A name record" called "my-project" for my main domain that will point to the IP address of the new server.
Let's make http://my-project.your-domain.tld have an SSL certificate and auto-forward all HTTP traffic to HTTPS.
Welcome to my course on Three.js and Typescript.
Three.js is a JavaScript library that allows developers to create exciting and very visual interactive 3D content on the internet.
TypeScript introduces static type checking, which means you can explicitly define the types of variables, function parameters, and return values. This catches potential errors during development, making your code more robust and reliable.
TypeScript also integrates well with modern IDEs and offers intelligent code hinting and autocompletion.
Threejs has become a hugely valuable resource on the internet and provides millions of possibilities, however many new learners struggle in their early stages while trying to de-cypher the huge amount of resources on the internet.
So this is where this course will help you. It will guide you first with the essential basics of using Threejs and its related addons library, and as the course progresses, each now concept will build on the previous, and become increasingly more sophisticated, so that you understand the problem that each new concept was designed to solve.
So, at the end, you would have covered many of the requirements to understand how to build your own Threejs projects and also understand the official examples better. This is so you can confidently continue on your own to build much more complex applications in the future.
All the code demonstrated in the videos, is provided in this accompanying documentation, that you can access for free online, so that you can easily copy and paste and participate alongside the videos.
So, if you know that you like coding, you like seeing it work for yourself, and you like to experiment, and have millions of ideas that you want to explore, then this course is for you.
There is much to learn, but in the end you would have developed the techniques required to build your own Threejs projects and participate more effectively in the 3D developer community.
Thanks for taking part in my course, and I hope to see you there.
Sean