Three.js and TypeScript | Sean Bradley | Skillshare

Playback Speed

  • 0.5x
  • 1x (Normal)
  • 1.25x
  • 1.5x
  • 2x

Three.js and TypeScript

teacher avatar Sean Bradley, Course Instructor

Watch this class and thousands more

Get unlimited access to every class
Taught by industry leaders & working professionals
Topics include illustration, design, photography, and more

Watch this class and thousands more

Get unlimited access to every class
Taught by industry leaders & working professionals
Topics include illustration, design, photography, and more

Lessons in This Class

79 Lessons (9h 25m)
    • 1. Threejs and TypeScript Introduction

    • 2. How to do this course

    • 3. Setup Development Environment

    • 4. Install TypeScript

    • 5. Begin Creating the Three.js Project

    • 6. Add the Initial Scripts

    • 7. Setting up the WebPack Dev Server

    • 8. Importing Three.js Modules

    • 9. Install the Three.js Typescript Boilerplate

    • 10. Scene, Camera and Renderer

    • 11. Animation Loop

    • 12. Stats Panel

    • 13. Dat.GUI Panel

    • 14. Object3D

    • 15. Object3D Hierarchy

    • 16. Threejs geometries

    • 17. Materials

    • 18. MeshBasicMaterial

    • 19. MeshNormalMaterial

    • 20. MeshLambertMaterial

    • 21. MeshPhongMaterial

    • 22. MeshStandardMaterial

    • 23. MeshPhysicalMaterial

    • 24. MeshMatcapMaterial

    • 25. MeshToonMaterial

    • 26. Specular Map

    • 27. Roughness and Metalness Maps

    • 28. Bumpmap

    • 29. Normalmap

    • 30. Displacement Map

    • 31. Material Repeat and Center

    • 32. Texture Mipmaps

    • 33. Custom Mipmaps

    • 34. Anistropy

    • 35. Lights

    • 36. Ambient Light

    • 37. Directional Light

    • 38. Hemisphere Light

    • 39. Point Light

    • 40. Spot Light

    • 41. Spot Light Shadow

    • 42. Directional Light Shadow

    • 43. Orbit Controls

    • 44. Trackball Controls

    • 45. Pointerlock Controls

    • 46. Drag Controls

    • 47. Transform Controls

    • 48. Using Multiple Controls in Same Scene

    • 49. OBJ Model Loader

    • 50. MTL Loader

    • 51. GLTF Loader

    • 52. DRACO Loader

    • 53. Textured GLTF

    • 54. FBX Loader

    • 55. FBX Animations

    • 56. GLTF Animations

    • 57. Custom GLTF Animations

    • 58. Raycaster

    • 59. Raycaster Collision Detection

    • 60. Raycaster Mouse Picking

    • 61. Raycaster Measurements

    • 62. Using tween.js

    • 63. Using tween.js and the THREE. AnimationMixer

    • 64. Vector3 Lerp

    • 65. Physics with Cannon.js

    • 66. The Cannon.js Debug Renderer

    • 67. Trimeshes, ConvexPolyhedrons and Compound Shapes

    • 68. Deploying to Production

    • 69. Setup a Webpack Production Configuration

    • 70. Host using GitHub Pages

    • 71. Host using GitLab Pages

    • 72. Host using an Nginx server

    • 73. Point a Domain Name

    • 74. Add SSL

    • 75. Server-Side Functionality with Nodejs and Express

    • 76. Socket.IO with Node.js, Express and Webpack

    • 77. Setup Nginx as a Reverse Proxy

    • 78. The Ballgame

    • 79. Converting JavaScript Threejs Examples to TypeScript Projects

  • --
  • Beginner level
  • Intermediate level
  • Advanced level
  • All levels
  • Beg/Int level
  • Int/Adv level

Community Generated

The level is determined by a majority opinion of students who have reviewed this class. The teacher's recommendation is shown until at least 5 student responses are collected.





About This Class

Welcome to my course on Three.js and Typescript.

Three.js is a cross-browser JavaScript library and Application Programming Interface used to create and display animated 3D computer graphics across the web in a browser.

In this course we will learn all about Three.js using demonstrations and sample code that you can download and experiment with on your own pc.

We start the course by setting up your development environment and installing TypeScript.

We then begin to create a Three.js boilerplate/template project that we can use throughout the remainder of the course, which will also give you exposure to Git, NPM, NodeJS, WebPack and is also generic enough that you will be able to use it in your own Three.js projects into the future.

We then move onto learning about the Three.js Scene, Camera and Renderer,
The Animation loop - when and how to use it,
Import the Stats and Dat.GUI panel tools, which are very useful when learning about Threejs,
We learn about,

  • Object3d base class, with its Rotation, Position and Scale transformation matrices,
  • Inbuilt Three.js geometries such as the Box, Sphere, Icosahedron, Plane, TorusKnot many more,
  • Materials such as the Basic, Normal, Lambert, Phong, Standard, Physical, Matcap, Toon, Shader and Depth,
  • Specular, Roughness and Metalness maps,
  • Bumpmaps and Displacement maps,
  • Manipulating UV coordinates to affect the appearance of the materials and displacement maps,
  • Llighting such at the Ambient, Directional, Hemisphere, Point and Spot Lights,
  • Shadows, and how to achieve perspective verses orthographic shadow affects,
  • Raycaster, and how to use it for mouse picking 3d objects in the scene,
  • The tween.js library to smoothly transition object properties such as camera lookat and object positions.
  • Physics with Cannon.js and using the cannonDebugRenderer
  • Understanding the different options for Cannon.js Physics Collisions.
  • Provisioning and Deployment to a Production Server
  • Setup Nginx Proxy, Domain Name and SSL
  • Using Module Specifiers with Webpack Versus Relative Import References
  • And many more useful examples of Three.js that you can copy and experiment with your side in order to understand Three.js at it's core much better.

At the end of the course, you will understand Three.js and also how to use TypeScript in order to write robust and type safe code much quicker. And then you can begin writing your own 3d games, applications and presentations which will be accessible from a browser and on the web.

Thanks for taking part in my course and I will see you there.

Meet Your Teacher

Teacher Profile Image

Sean Bradley

Course Instructor


Hello, I'm Sean.

For over 20 years I have been an IT professional developing and managing real time, low latency, high availability, asynchronous, multi threaded, remotely managed, fully automated, monitored solutions in the education, aeronautical, banking, drone, gaming and telecommunications industries.

I have also created and written hundreds of Open Source GitHub Repositories, Medium Articles and YouTube video tutorials.

See full profile

Class Ratings

Expectations Met?
  • Exceeded!
  • Yes
  • Somewhat
  • Not really
Reviews Archive

In October 2018, we updated our review system to improve the way we collect feedback. Below are the reviews written before that update.

Why Join Skillshare?

Take award-winning Skillshare Original Classes

Each class has short lessons, hands-on projects

Your membership supports Skillshare teachers

Learn From Anywhere

Take classes on the go with the Skillshare app. Stream or download to watch on the plane, the subway, or wherever you learn best.


1. Threejs and TypeScript Introduction: We haven't surveyed. Say hello. But to try to teach explosion electricity production. 2. How to do this course: Welcome to my course on three G in TypeScript, discourse comes in five main sections. First, we'll set up a development environment and install TypeScript will then create a three J is boilerplate project manually from the ground up. This will give you a very good understanding of the aspects involved in creating brand new three j's program from scratch or you could bypass I got under Section 3 and install the pre-built boilerplate manually. Then after that, we'll continue with many, many examples, starting from the core three js and building up until it gets more advanced examples and also involving other third-party libraries. And then the final section is about deploying to production. We have several different methods and we'll explore those. Excellent. Now, the course comes with free documentation, which is just full of code and examples that we'll discuss throughout the course. Each new lesson will come with some code that you can download. For example, spotlight shadow. And we get an example that you can look at on the website. Plus you can paste it into the boiler plate and then have it running locally on your own computer. Very good. Excellent. Okay, so let's get started. 3. Setup Development Environment: Okay, let's set up a development environment that matches what I'm using in the videos. So I'm using Visual Studio Code. You could use a different IDE if you like. But I recommend this because it's very good copy that visit that in a browser. And I'm using Windows 10. So it's going to give me the option to download stable build. The download is started. Now open and install. I'm just accepting all the defaults. Very good. Next, Git for Windows, this is optional if you download the boilerplate early on in the course, you will need to use Git because we use git clone. Anyway, we visit good for Windows to open the browser and download and open file. Yes. Install next, next, next, next, next, next, next next. I'm just accepting defaults. Okay, finish. If you're using Linux or a Mac, get is most likely already installed on your computer. It doesn't come pre-installed on Windows 10. And finally, NodeJS, because we'll be using a NodeJS server later on in the course. And also we'll use npm to set up our project. Okay, so no, I'm going to use Windows installer 64-bit MSR. You may be prompted if you want to keep that file, just select. Yes. I'm not being prompted in this browser at this moment. Okay. Next, Next. And once again, I'm just accepting all the defaults. Okay, finish. Brilliant. Now we can verify those things were installed. Open up a command prompt and you can type git version and it will tell you the good version. You can also write no hyphen v, and that will tell you that your Node.js installed if you type in npm, v, would also tell you that your MPM stored that comes with node. Okay, Very good. Next video, we'll set up TypeScript. 4. Install TypeScript: Okay, now we're gonna install TypeScript and verify it works. Okay, so this is a heavy course and we'll be writing it in TypeScript. If you've never seen TypeScript before, don't worry, it looks a lot like JavaScript, except it enforces type safety in your code. So as a result, we get advanced IntelliSense features and we can quickly see the available methods and properties in all the objects that we use. Okay, so let's install TypeScript globally using npm there. So copy that, okay, open a command prompt, CMD, right click using the mouse, enter. Very good Does installed. Now we can verify that installed by typing TSC IF-THEN the 4.3.4. Perfect, that works. Now, if you were using PowerShell, which also happens to be the default integrated terminal in VS Code. I'll show this in the next video. Writing TSC hearth and v may cause an error similar to that below. So how a shell, I've open PowerShell TSC IF and the, it says TSC, PS1 can't be loaded because running scripts is disable on this system. This is an error that you may see in PowerShell. If that happens to you, you can type TSC dot cmd, and it will run the command version of TOC for you. Perfect. In the next video, we'll start creating our three JS project. Excellent. 5. Begin Creating the Three.js Project: Okay, So now we're ready. Let's start creating a three J is project that we'll use throughout the remainder of the course. Now, note that we're building this manually from the ground up. You can bypass the section and go straight down to the three. J is tasked with boilerplate and download it if you like. But doing it manually gives you very good background knowledge and you'll be able to adapt this to your own needs in the future. So anyway, depending on your operating system, open a Command Prompt or Terminal. I'm on Windows 10, so I'm going to open a command prompt. So, and I'm going to go to a folder or drive somewhere on my system where I'm going to work. So I've got a spare drive called D. You might not have a spare drive or you may have something else. That anyway, doesn't matter. We want to do is create a new folder wherever you want to work called three J is TypeScript tutorial. So make directory three J is TypeScript tutorial. This is going to create a new folder, this command. Now, I just copied that using my mouse and then I right-clicked inside the command prompt and I pasted it for me growing up, press Enter. Okay, now cd or change directory into that folder. If you just press Tab after typing a few letters, it'll fill in the rest for you. So now press Enter. Okay, So I'm now in the folder three. J is TypeScript tutorial for DIR that there's nothing there, it's empty. If you're on a Linux or Mac, you can just type ls. And that's the same as typing DIR, but it doesn't work on Windows command prompt, okay, it works in PowerShell if you're using PowerShell, but anyway, on Windows command, just DIR and the way it's empty, 0 bytes now folder, now we need to initialize the project using npm init. So that's down there. Npm init, press Enter. It's going to use the folder name as a project name by default, that's okay. It's press Enter and just keep pressing Enter several times until we get to the end. Yes. Okay, DIR, there's one file in there called package.json, and we can look at that. We'll look at that in a moment. Okay, so now that we've established a working folder for ourselves where we're going to build our project. And we have one fallen it called package JSON. Instead of using command, we can actually start using Visual Studio Code. So Type C, O, D, space dot. And now that's open up Visual Studio code into the same folder where I typed code space dist folder. If we open that up, we can see package.json and that's the contents of package Jason. It's very simple. We'll add some packages, will start with three js. Now, instead of typing further commands into this command prompt, we can actually closer and have integrated terminal inside this code. So to do that, you can either press terminale, new terminal or you can type Control Shift and single quote. So Control Shift a single quote and that's opened up a new PowerShell terminal down the bottom there for me. So if I type DIR, that will show the current folder. And because I'm using PowerShell, Ls also works, does the same thing. Okay, so next let's install the three JS library. So copy that line there, that's copied it to clipboard and right-click again and paste it. So MPM install three and I'm saving it to my development environment configuration. We won't see that here right at the moment. But if I press Enter, it's downloading three js from the Internet. And it's created a new node called dev dependencies 3, 0, 1, 0, 0, 1. Now this course will be built using three release 130. There's a new three J is released every month. So depending on when you access this course, there'll be other versions of three J is available. I'll try to keep this course updated with all the changes that happen to three J is from now on. If you have downloaded three version 160, for example, and something doesn't work if my B and my code was based on three version 130, but all have notes in my online documentation outlining any differences that you should be aware of as the new versions come out. Js is MIT licensed, so there's no warranty of backwards compatibility. So that's our package.json. Now, next thing to do is to create some extra folders inside our project. First one, we'll call dist. Okay, so I'm going to use Control minus to make the screen slightly larger like that. Okay, so in the root folder here of my project three J is TypeScript tutorial. I'm going to press this icon. This is a new folder icon, and I'm going to call it just dist stands for distribution. So all our files that we'll see in the browser, we will come from the dist folder in that photo, credit to more folders, one called client and another called server. Okay, now we just need to reorder that server should be under dist, dist client and server. Now note that early on in the course, this server folder won't be used DC, something that all use a lot later in the course when I start using server-side functionality, you now three J is project, okay? Now in saw, a deceased client will create a new file called index.html. So distinct client, new file, That's the icon there, index.html. And in that, we'll copy this and paste. Now that's just a very basic index. Html doesn't have much other than what you can see, has one style for the body which are used to remove borders and imports one script called bundle JS, which webpack will create. And there's a tie that module. Now that index.HTML will be the same index HTML that is used through most of the course. We will come back to these fall very rarely but expects to make some changes to it. We'll add some styles, we'll add some extra HTML elements as we go through. Okay, so that's saved right now to create a new file called source SRC in the root down there. So press the new folder and call it SRC. Okay, so I have node modules and SRC. Src add a client and server folder. So if I click Source and add folder, it will already added as part of the source folder, just like so. So that's our folder structure right now. Okay, so verify that your folder structure looks like this. Client with an index.HTML and server is MD. The moment, that's something we'll use later on in the course. There is a new folder called Node module slash 3. This was created when we ran NPM install three and there's only one project in sawdust node modules folder, but this will slowly start filling up with a lot more projects as we install Webpack and TypeScript locally also to the project. Okay, So we will look at many of these things as we progress. But right now, just be aware that it exists. Now in source, client, and server, there are no files just yet. We'll get onto that also. In the early stages of the course, the server folder won't be used, but it's there anyway so that you know. Okay. And there's the package Jason with one dependency three, and I'm using version 130, okay, Now there's no point in running this yet. It won't work. We'll get onto the next lesson where we will add some initial scripts. Excellent. 6. Add the Initial Scripts: Okay, So let's add some initial scripts. Now inside the folder, source client will add a new file called client Ts. So in our project, in source client, new file, client Ts, the extension dot ts, this will be a TypeScript file, so we'll copy this code. So I'm pressing the icon there to Copy to Clipboard. Okay, that's copied. Now paste control V to paste. So that's the code and Control S to save. There we go. Okay, next, we need to create another file and that is called ts config dot JSON. So source client tears config dot Jason create data. So in the client folder, new file, ts config dot JSON and paste that. This is a very minimal tears config. And this is all we're going to need for almost the whole remainder of the course. Typescript can be used to generate JavaScript for many different environments, but we only need it to generate JavaScript suitable for Webpack, to bundle L code into a single file. And this is all we're going to need for the two options. We're using our module resolution, which describes how to find libraries, for example, wages type 3 and need knows where to go in is using a technique called node module resolution. To do that. Find out more about that by pressing this link, if you like, the TypeScript documentation is quite hard to read, but it's there for you. And strict equals true. This is something that I recommend in all of your projects. I'll use it to make sure my variables are either instantiated when they declared or in class initializers. And you can also read more about that. They're strict. And then include that saying that the TypeScript compiler will convert all files ending in dot ts inside this client folder, any subfolders to ts config, he's in the same folder, is the client there. So this t is config is related to this particular project. I'll create another ts config later on when I start looking at server-side code and a production one. Okay, so that's saved. Now, if we go back to the client, yes, we'll see it's having some corner problem. Could not find a declaration fall for module three. Since three Release 12 6 taught definitions that TypeScript users are no longer included in the three JS project. By default, we have to download those independently of three js. Now, the agreed best place to get these definitions from our now, from a project called definitely taught, you can create your own type definition false, which I do occasionally myself. But for this course, we'll get three J is definitions from definitely typed. So to do that, copy that line there, we're going to npm install at types slash three, okay, so in the terminal right-click, so it pastes npm install at types slash three, save-dev, press Enter. Okay, So the top definitions at this other repository would credit for version 300, 300, and look at package Jason at types 33 are slightly different versions. But this is going to happen quite often because they're both projects managed by different sets of people. So there may be occasions when the top definitions don't match the current version of three js and you may have to create your own additions to a type definition fall. But for now this is just fine. So we can continue with that. If we refresh our folders there in Node modules, we now have two projects. There's three. If we started off with the last video and now the AT types Definition folder, which has its own copy of three type definitions. So in there, you won't find any JavaScript code, but you'll find these d dot ts false, which describe the types of all the methods and properties use route through JS. And our IDE will use these files to help us keep our code type-safe. So there's three and the top definitions for three. Okay, so before version 12, 6, these things were in the same project and the types were often updated as three was updated, but now they are different. So you will get some occasional incompatibilities. Bob will resolve those if those things turn up throughout the course. Okay, so I don't need that fall open anymore. Yeah, forget back to client Ts down where it's telling us that it couldn't find a declaration file for three. It actually should have been able to find it by now BOC to fix that, press F1 and press Restart Ts server. Okay, and after a moment, the Node module resolution will take effect that we've set in tears configure, and each should find three, because that's found a definition for three now, that means IntelliSense works now in the IDE. So if I go three dot, it's going to show me all the different methods and properties and types that I can use inside the three module here, it's the same with camera. I can now use camera dot and all the methods and properties types of camera will appear in the IDA that I can click from or find out more information. The Renderer, renderer, or even cubed dot, dot all the methods and properties available to Q. That's the TypeScript definition. Doing that for us. Okay, so verify your folder structure looks like that. Three J is TypeScript tutorial, dist client server folders one index.HTML node modules now with types 33 source client, client ts, ts config server WR, not using Server package.json and package.json. That is something that is auto graded. We don't really need to worry about that for now. If you delete that and run npm install, it will just credit again for you. And in VS code, that's how it looks. Client server types, source client server. Excellent. Now there's still no point in running this. It's not going to work. What we'll do next is install webpack, which when we've finished configuring it, will take our client TypeScript here and create a bundle JS and hosted using the webpack development server. Excellent. 7. Setting up the WebPack Dev Server: Now we're going to set up Webpack with the webpack development server. Okay, so we'll use webpack development server to run our three JS code. We're pack development server has several features that make development and easier process such as HMO, hot module reloading is will auto refresh our browser when we make changes to the code. And it will bundle all of that code dependencies into a single JavaScript file that will be loaded into the HTML as bundle JS, as you see here in index.html. Okay, so we need to run this line here. This line is installing five things. So Webpack itself, which can science to call, that will bundle all of our code into development and production versions is the Webpack CLI, which allows us to use webpack from the command line and also via an NPM script, which I'll show you the webpack development server, which is little mini web server that will host our files so that we can view them through the browser as if we were looking at it through a real web server, the web pack merge, this is optional, but it allows me to create several different configuration files, but also have shared elements to those. We'll look at that and Ts loader, which is used because we're using TypeScript files. Now, if you weren't doing TypeScript and you just rotting away your source using JavaScript. You wouldn't need a T, a slider bar discourses about doing it using TypeScript. So we need that, okay, and then save-dev again. Once again, all of these are only going to be useful during our development server setup. Okay, so copy that line, go to the VS Code integrated terminal, right-click and press Enter. Okay, Now, if I refresh the folder, there we go. The node modules folder now has many, many more dependencies in it. Webpack has many dependencies. It uses a little bit of this and that like so. Now, looking at the output of the in-store, there were several warnings. Webpack is also a project developed by a different set of people. Depending on when you install Webpack, you can get different kinds of warnings. At the moment, there is one moderate severity vulnerability, which is because it uses a project called chocolate, are within the next month or two from creativeness video, this particular area should be fixed right now, this won't affect the ability to run the course, but you can run npm audit fixed, but right now also, that doesn't actually work. But eventually that's one of the options you, I have right now. Is it not functionality? Block us? And also, since we are using DNS load on here, one of the warning says it requires a peer of TypeScript, but none is installed. So that means it needs a local copy of TypeScript inside your project. We've installed TypeScript globally, but dispersion of Ts load or doesn't find the global version of TypeScript. So when you install it locally. So to do that, npm install TypeScript save-dev. Okay, so npm install TypeScript save div. Okay, go to package JSON. And if we look our package Jason, it has a whole lot of other things under dev dependencies, so including TypeScript as well. So that's what we've installed test loader, Webpack, CLI, div server, merge. And these are all the different versions that were available at the time of correctness video. Okay, so next thing, let's create some Webpack configurations. The first one, source client will call it and dot js. So let's create a new file. So under source client, their new file, ab.js, copy that script and paste. Now you can ignore those three dots there. It's offering to convert that to an ES6 module. I'm not going to do that in this course. I'm going to keep it just the way it is. Okay? So this is a configuration that is applicable to both our development and production versions of our webpack configurations. So it's saying this is the entry point to our application being source client, client Ts. That's what we've got there. We're describing a role that webpack should follow. And it's looking for anything with Ts or TSX. And if it finds anything like that, it will use the Ts loader to process those falls. And it's going to exclude the node modules folder if it finds one. So it's going to resolve all extensions TSX, Ts, and JS. It will output a file called bundle JS. That's the name of the fall that I'm referencing in my index on NodeJS. And the path that it will save it to will be the client. If I go down one and go down another, so down one and then down another back to the root of 1 to dist then declined. So index.HTML and bundle JS will be at the same level from the perspective of the browser. So the browser will load index.HTML and equal find bundle JS next to it. Okay, so next file, webpack dev JS, it's credit that fall under Client webpack dev js. Copy that, paste that. Now it's using Webpack merge here. What it's gonna do is first load common, which is that one just there. So these are the common configurations for both of our webpack configurations for development. Production and also add a mode being development, a dev tool, email source map, and the dev server, the content base being decent client, hot equals true. That's describing the hot module reloading. If you turn that off, the white refresh the browser when you make changes to the source code. I won't add a production configuration just yet. I'll do that later on in the course when we do the section on deploying to production. But for now, let's continue onto package. Jason did add a script that will use the Webpack CLI that will allow us to start the webpack development server using the configurations that we just saved. So this line here under scripts div, webpack, config source, client, webpack dev JS comma. So that's saved, go down to Jason and under scripts here, add this new option scripts div called dev Webpack assert it will run this line and that will start up a Webpack development server using that configuration webpack dev JS, that's webpack dev JS, which is also loading WebEx CommonJS and those configurations. So let's just save package Jason. Now, after you've done that, you should be able to type npm run dev div is that script there. So npm run dev looked at, okay, it's building the bundle JS for us using the development configuration. And if I scroll up their assigned a project is hosted at localhost. I DID. If I just hold down Control and press plus, it'll open a browser with the three GIS project running it. And it's just a rotating cube. If I press F2, you will live to up the development tools inside the browser. This first era, dc cannot find a fab icon, does nothing to worry about. I haven't added a fab icon. Do like CO2, my project, but you can create one if you like. The official boiler plate has one added, but it's just a little graphic that we use as an icon in the tab there. Okay, now, if we look at the other things written in the console, so the high chair ma, live reloading is enabled. That means that if I was to make a change to client Ts down here, for example, or change the color of the material used by the cube or put in 66. Press Control is to cite it auto updates. That's not a very good color. Let me just do if if 000 and we go, It's completely red or I can comment out Wireframe, press Control site, announce a solid color as the course progresses. All discuss every line of code here so that you know what each of those does that for now, so that you know that what HMO is actually doing, It's refreshing the browser, want to make a change to the source client TS. Now other things to note about the webpack development server is that if I was to refresh the folder structure there under deceased client there there is no bundle ab.js Webpack development server is hosting that dynamically for us, looking at the development tools, if I look at network there, and now it is clear that and then just press F5 to refresh the browser, we can see that it's getting bundled ab.js there. And when you actually look at the contents, but this is being created and served dynamically through the webpack development server. And it's quite a large file. It includes Hashim, It's not good enough for production. That's why we have a different configuration for development, setup and Webpack. Ce credits assigned specific WebSocket which are uses for high GMR, which our production version one do that. But the development version credit through webpack dev server is built quite quickly. So just be aware that that file doesn't actually exist. Here. It's being served dynamically and we can actually visit it in the browser just by typing onto dot js like that. And now we can see the dynamically created bundle JS served by the webpack developments, so on. It's an enormous file and it's not suitable for production, but we'll get onto production set up later in the course. First, we'll spend a lot of time learning about three js and running it in Webpack. And back, there we go. And I'm going to put that back to grain being sewers or if, if 000, it's green. Okay, so now that we didn't create a production version of the webpack configuration just yet, but we'll look at that light up when we do the section on deploying to production. And we have many options on that. The production version of bundle JS will be a much smaller file and it won't contain the hot module reloading by EDs much slower to produce stats while we use a specific and development version during development. Excellent. In the next video, we'll expand on the current example by importing one of the three js example modules, specifically, orbit controls Excellent. 8. Importing Three.js Modules: Let's look at the basics of importing three adjacent modules. The core of three JS is focused on the most important compilers have the 3D engine. Many extra modules such as 3D model loaders and controls are part of the examples directory. If you want to use these extra modules in your project, then you need to import them separately. Okay, so looking at the node modules, and if we scroll all the way down to three, there it is, there, we get billed. So right now our project is referencing H3, which is pointing to the three dot module js file there. But in examples, GSM, more specifically, because we're using the module version of three js, all these extra folders. So modules related to animations, cameras, controls, CSM, many other things, geometries, environments, math, lights, but very common to also include one of the example modules in your projects. Probably the most common that you'll find throughout the Internet is that people will use the orbit controls. So how to get all the controls into your project? Forget about the client. If we look at the source code here and just copy that line highlighted in yellow. Import orbit controls from three examples j, same controls or controls. So that's what I was looking at. Three examples, GSM controls or the controls. And it's showing some kind of issue here. It says orbit controls is declared, but its value is never read. Okay, so let's create a new orbit controls. I'm going to credit after the renderer, because the new orbit controls uses the renderer, it also uses the camera. Now, that's all we need, press Control S. And if Webpack is running in the background because he started at using npm run dev. If you go back to the example, you can now interact with it using your mouse. So up and down, left and right, and you can zoom in and out. You can hold down the middle mouse wheel and do that. You can hold down the royal click and you can pan left and right as well. So that's the orbit controls. My tube is rotating because in my animate function on rotating the cube, but in turn that off and go back. And now it's not water rotating, but I can rotate it myself using the mouse. Then you might want to put that back like so. It's very compiled. And if I view would again, it's moving around again. Okay, so that's just the orbit controls. There are many extra modules in the examples folder, and we'll go through many of those as the course continues. But right now, that As it stands, now is the basic boilerplate that we'll use throughout the course. And we'll add more would change things, but we'll keep coming back to these basic setup. Excellent. Okay, the next video, I'll show you how to download the existing three J is boilerplate from GitHub and that's useful if you just quickly wanted something you could work with and you can quickly prototype new ideas for or if you bypassed these previous videos, okay, and then after that, we'll look at the same and the camera and the renderer. And they are the different elements that the very first example is demonstrating. Excellent. 9. Install the Three.js Typescript Boilerplate: Now installing the three J is TypeScript boilerplate. This section is optional if you completed the sections beforehand from here where we set it all up manually, you already have the boilerplate, but you may want to try this anyway, or you may have already completed the course. And you just want to boil up light because you're getting a new project. So here I'll show you how you can just use that instead. So this boilerplate is on GitHub and we can use the git clone command to download it, set it up, install it, and run it, and view it in the browser. So copy that section, complete or one line at a time, doesn't matter. Open up a command prompt, go to someplace way we'd like to work. I'm going to go to my D drive. If I right-click that whole section, data's copied in, it's now cloning the boilerplate from that address. It's also running npm install because I've copied a whole lot and now it's waiting for me to npm run dev. So I press Enter. It's good. Visit that in the browser. And that's the boilerplate running in the browser. Excellent control C to get out of that. Now looking at those commands again, okay, so I'll copy that whole section right-clicked and then it just did all those things. I could've just did one line at a time, did that density into the new folder, npm install, npm run dev if I wanted, if I wanted to edit the code, taught code space dot, and the code has opened up ready for me to edit. So source, client, client tears. Now when we started, we didn't create a folder called rage IS TypeScript boilerplate, we called it three. J is taus group tutorial. It doesn't really matter. What you can do is clone into custom folder if you like, for example, that first line git clone that you can add a different path to the end of it. So I'll just copy that. I'm gonna go back one guy back down to D, C, D, okay, now, right-clicking that It's the same as before git clone from that address. But here I'm saying example 1. So that will now put the repository into a folder called example one. Press Enter, see cloning into example 1. Now if I did C, D, Example 1, DIR or LS, if you're using Linux, mac, or even PowerShell. The falls of this, so npm install npm run dev. Is it that in the browser? There we go, That's the boilerplate running from the example one photo and Control C to N That taught code dot. And now we can edit our project from example one folder there and npm run dev. And we can visit it in a browser like so. Now I'm just not a quick one that you might come across if running multiple projects at the same time. If I leave all that running and go backwards, CD down and then cd into the three JS boilerplate folder and then run npm, run dev again. It's going to tell me the addresses in use. That's because I've got poor ADHD opened in this window down here. If I Control C that go back and start that again, that's now started. Okay, this console is using port 8080. Excellent. In the next video, we'll look at the scene camera and renderer, and we'll start learning about the core of three. J is excellent. 10. Scene, Camera and Renderer: Okay, Now we're going to look at the basics are the same, the camera and the renderer, three GIS. And it's cool is a library that allows you to add and describe data in three-dimensions, example as meshes and lights, and then convert that data into a 2D representation onto a HTML canvas. Before we can do anything with three js, we need three things seen, a camera and a renderer. So in this video, in order to understand these things better, we discuss and experiment with some of the options we have relayed to them. So there's the same as a camera and there's a renderer. So looking at the code we have so far, There it is this the same camera and to render out, okay, Another way to look at that, there's the same as a tree-like structure or meshes lot cgroups already positions and cameras optional is a camera which describes the view boundaries of the same within frustum dimensions and the renderer, which takes lead data and puts it onto the canvas. And this is a working example that they're like area is a HTML canvas. If I was to look at the output at HTML, CSS, the canvas, HTML tag, the canvas, and that was dynamically written from our code. We'll get onto that. Okay, looking at the code, Let's look at the same in more detail. If we go right down to the end where after I've added at least one mesh to the same. So I've done that day, That's console dot DIR, seem, press Save, go back to the browser. Console scene has now been logged out to the browser. These are all the objects that are inside the scene. The scene itself is a base object called object 3D, which we'll look at later on in the course. But for now an object 3D has many properties, such as its own children. In this example, that's the mesh, mesh 0 geometry, the box geometry. It has a position being 000 000. So I didn't change that default as a rotation which is continually changing. It has many properties. It has a material which I've said is why frame and green. So I'll get N This Wireframe true and color RGB. Now the scene itself also has a position which is default 000, 000, even a rotation and a scale as an APP vector that's important in three J is the up vector is why not all 3D programs are the same. Sometimes I use zetas, the up to Victor, 3 JS y is up. So anyway, so you know, you can view the properties of the same by using consult DIR or even console.log. It doesn't really matter anyway. One property of the scene we can change is the background color. And because we're using TypeScript, if I press dot, it will then give me all the available properties and methods that I can use. So if I start typing B, it says Background equals a new three dot color. Now I can pass in a string or a number, or another I'm going to pass in a number being our way, X FF 000, 000, That's RGB in hex if f is like saying 255, but that will be converted to a three dot collarbone and saints, which will be RGB floods between 01. But that is a really easy way of saying, OK, save that. Looking back at the example, the background color is now red. We can experiment with those colors IV morphine like so what FF eight zeros or does that color or 448800 or 4488 Ff or even 0000, 0000 fifth completely blew. Its RGB, or black is all zeros, or white is all F's, 66. And I go, and I'm not going to use that for now. Put it back to the way it was. Next thing we'll look at is the renderer just here. There are several different render isn't three gi is that you can use, but most of the time you'll use a WebGL rendering That's the fastest and the most supported. That's the default renderer that you'll find in almost every example on three js. So it comes with a lot of defaults, but one thing you have to sit is the size. And I'm setting the size of the window in a width and a height. That means that when I refresh screen or loads, it fills up all the available space of a document. Here I have the Development Tools open so I can just close that and it'll resources after the available space. But that re-sizing doesn't happen automatically. That happens because down here I have an event listener called re-size where I update the size and also update the aspect ratio of the camera. But we'll get onto that to match the new size. So that's what that function does. So if we comment that out and then I refresh and I resize the window, it doesn't re-size the 3D view on the canvas. So I'll put that back and it updates and now it resizes to fit the canvas and the aspect ratios also changing. We'll look at that in a moment. Okay, So that's a very common function that you'll also see throughout many examples of three JS. Okay, so what happens if we change the size? It's not being in a width and a height, but using numbers directly such as 200 by 200. When I refresh that, the canvas is now 200 by 200, but the aspect ratio looks wrong, but that's because it's being set in the camera there. So in order to match that aspect ratio out of stuff to update it in the camera as well. But there, which you can do to avoid to a 100 divided by height, which actually 200 Boyd to a 100 actually equals one. So if I precise refresher, that's fixed now, but also because I have the window resize event, it's changing if I change the window size. So I can now comment that out. And you asked That's very quickly what you're seeing there with the renderer. So it's quite important to understand the considerations to if you're singing the song is directly as numbers, or whether you're taking the window in a width and height. And also I've done the camera aspect ratio as well. And whether you have a resize event, also updating the camera aspect ratio and render a set size. And you either it's back to the why it was at the beginning. And let's look at what this law and is doing this append child, you can dynamically add. Elements to a HTML document. And here we're appending the renderer DOM element. Now render a DOM element as the render there. It has a DOM element property, which actually is a HTML canvas element. It creates his own internal Canvas element when you create the renderer and we're dynamically adding it to the document body. So when we look at pricing, if 12 open Developer Tools, and if we look at the elements down here, the Canvas, I haven't written this Canvas in my HTML code. So index.HTML, I've written script module bundle JS by haven't written Canvas script module bundle JS. But there's a canvas tag that was dynamically added, that was dynamically added by this line here, we don't use that line. We won't have a Canvas. Nothing's being drawn, but the render is still exists in the background and is still being used in the render function down here. So sometimes people would rather hard code the Canvas into the HTML. You can do that. So index HTML there, I'm just going to put it here. Canvas ID equals C1. For example. I go is a HTML canvas. I'm also going to give it its own style hash for IDs C1 width to 100 and 200 px, like so in the code, we need to create a canvas object of our HTML element there, const Canvas calls document dot getElementByID C1. And when we create our renderer, we tell it which canvas to use. Canvas colon equals does canvas element here. Now because we're using TypeScript, it's indicating that HTML element or null is not assignable to type HTML canvas. So the idea here doesn't know what is being returned by document getElementByID dot C1. It could be anything. It's considering it by default to be something of my HTML element or null because that's what that actual function returns. You can see that there, but we can cast it by saying as HTML canvas element. And now that is considered legal from the perspective of TypeScript because we're passing in a hasty well canvas elements. So we've just casted whatever that's going to return explicitly as a HTML canvas element. So that should work is a hard-coded Canvas, but it has overridden the width and the height and our style, because we're setting the size of the window in a width and a height. So it's just update that to be 200, a 100. I'll also update the camera aspect at the same time being one to a 100 divided by 200 equals one. And I'll turn off this resize event as well. I go, that is our hard-coded canvas width, height 200 with a style matching assignment. Okay, so that's another way of using the render where you're more explicit about the size and you're using existing canvas element that exists on the document. And here I'm using an ID C1. So we can have two renderers if we like. So I'll do that very quickly. Render 0, 1 and renderer to. And because we're using TypeScript, it's telling us all the things that no longer makes sense. So Renderer, renderer to render one, I'll attach the Oba controls render a 1s DOM element. Here, render, render a one, render, render it to render. Now, let's create a second canvas because L second renderer is still using the first Canvas, which is not really useful. So I brought in the first one. So Canvas, one canvas to Canvas, one canvas to C2. That's great. Does canvas in the HTML is a second canvas, C2, and I'll give it a style also being width and height. Okay, now let's refresh that because I've changed HTML. We have two Canvas is now the deck of the same also, since I'm using Oba controls and I've attached all the controls to the canvas one here, or to render the ones DOM element that has an effect, but it doesn't have an effect on random or two's DOM element. If I go back to the controls that you can say attached to render a 2s DOM element. Okay, so now that has the effect and that doesn't. So when we use the other controls, which we'll talk a lot more about lighter, it's using mouse events on the canvas that you have attached it to. Render it to stop element there and put that back to one for now. Okay, Let's create some more canvases because we can have as many canvases as l computer will allow. Okay, So index Canvas 3 Canvas for. And instead of using IDs, I'm going to convert that to a class, B, class C. So I'm giving them all the same class. And now we'll use width and height to 100. Gone back to there, it's quite yellow canvases, 3, 4, 3 4 3 4, 3 4, 1 2, 3 4. Render a 1, 2, 3, 4. And down here in my render function, it's also update the renders 34. Remember go refresh. We have four canvases, or 200 or 200 will doing the same thing. Okay, and of course, you don't have to update the renderer at all. And now one of them isn't showing, okay, so there were four render is now and there were shown the same thing. Now, looking down here in the render is render function, we're telling you which seem to use and which camera we can have several different cameras. I'm going to add a second camera and attach it to render a two. So the second camera, it's going to be a different kind of camera. Camera equals a new three dot orthographic camera. Now an orthographic camera has different properties than a perspective camera will look at these in a moment. I'll just quickly fill in some numbers. We have something to work with. Minus two for Lyft, two for Rod top being two and minus two for bottom, I'm going to call it camera to camera one. Camera one's position is okay. Oba controls camera one that we use camera one. Now, down here Camera 1, 1, 1, and renderer 2 is going to use camera too. And I'm not seeing any errors in a tall script here, so that looks okay to go. There we go. Now render to use using Camera 2, which has different settings and we're getting some clipping. So I'm just going to position camera to, to also be in the same position. There we go. Now I can see it now you can see the perspective camera there has some perspective and the orthographic looks flat, so okay, looking at the documentation down here, our camera, this is called a perspective frustum. So the shape looks like a truncated pyramid. You've got a near plane, and you've got a file plane, and you got a width and a height. And width and height is used to describe the aspect ratio. Okay, so looking at the code perspective camera, if I hover over there, it tells me the different properties on aid. So its field of view aspects near and far. So aspect we can see we're using boxes here which have the same height and width. So aspect of one makes sense. If I change that back to a 100 by 100 and side that we can see that it looks squashed or say 100 to a 100 flat. That's the aspect ratio that we're looking at there, which is really describing that box. But I'm going to keep it to onboard 200, which actually is the same as one. So to square this number here is the new plane and the far plane. So the renderer is going to draw everything within this frustum dimensions here. So if that's 0.1, anything before 0.1 white beetle, so that'll be clipped. So let's just increase that to being two. And if we look, everything that's exist before too is being clipped, were also clipping everything after the far plane. So if I might define applying to and I'll put that back to point 1. We're only seeing the stuff that's close to the camera that is less than two. Okay, so I wanted to reposition those windows. So let's put that 2.1, Let's increase it slightly to 0.2 to 0.32.4. And you can see just the extremities getting chopped. Little bit, 2.52.6 and we go Anyway, I've been using 100 by default, which is little bit over-engineering. But you know, you can make that better if you like by using a smaller number. Just remember when things stock disappear in the same, you'll need to consider your near plane and you'll fall plane anyway. Now let's look at field of view 75. I've got here the default field of view is 50, but I've done 75. So let's put that down to 50 and see what that looks like. So the perspective looks almost flat law the orthographic plus might get even smaller like 10, but it's kind of zooming everybody. I'm going to have to move the camera out, a little camera out. Ten. There we go. And it's still clipping because I've moved the camera back so far, so I'm going to increase that to a 100. There we go. So it looks flat. But if I go backwards and I use a large number, like a 160, for example, Let's move the camera a bit closer for number one. Okay, Let's try Perhaps going to make my knee applying smaller so it doesn't clip the close. So that's like extreme perspective. Let's put that down to maybe a 120 and move that back out. Well, that's playing with the perspective and the field of view. So those four properties, they are on the perspective camera. You can see more about that day if you hover over the top that will show you the basic documentation of it. They affect the frustum of what will be converted to 2D and drawn onto the HTML canvas by the render on. Okay, so let's put that back to the way it was before. That's good enough. So before at 1 110 camera, one position at two on the z axis, which actually results in a camera a big move backwards a little bit from the zeros 0000 because this cube as being positioned at default zeros 0000. Okay, anyway, let's now look at the properties of the orthographic camera. I'm just going to turn off default view there. Now I've used minus two to two and minus two. And orthographic camera is like a cube in space. There's no perspective to what? There's no field of view option. So the far plane dimensions will be exactly the same as a new plane dimensions. So it'll always look flat. And that's what we're seeing here in this second window. There's no perspective, it just looks flat. What do you describe the orthographic camera? You don't have to describe the aspect ratio. You just describe where the lift to the top and the right and the bottom is and that's what I've described here. My left is my honest to my rod is two units across, the top is two, my bottom is minus two. If I change that to 111 site, that is going to look a little larger in the view, which is good. Now I haven't described near and far plane there, but I can do that. My near plane will be 0.1 and my far plane will be 10. For example, if we go, Let's chop the box off a little bit. I've got camera position two, so I will do I'll try to there we go. I've chopped off the front side of the box. Let's jump off the backside of the box and we go anyway, so near plane, far plane of the orthographic camera. Now, what I'm gonna do is cry more cameras and these other views will also use orthographic cameras. And we talked down from the left and from the front camera, three camera for now, just copy those. Right now. I'm just going to copy camera two's position, which is just z. It will come back to that here, the renderer, camera three and camera for k. So if I like that small test case are looking at it and it'll different. After realizing the windows, we can see that those orthographic cameras are identical. I'm just controlling the perspective using the orbit camera. Now, let's change the camera positions of the orthographic cameras. So camera position two, I want it to be top-down. So instead, I'm going to use the y-axis. I'm going to lift the camera up to now because the camera will be lifting up. I know also need to pointed downwards to look back at 000 000. So camera to look at, I've got to say look at 000, 000, or I can say look at a new three dot vector 3 and a default being 000, 000, like that. Now, Camera 2 is looking top down onto the queue. Camera three, I'm going to look at it from the lift. So camera three, x equals minus 2. And also I'm gonna make it look at 000, 0, 3, and we get a camera, 3, 000, 000, 000, 000, 000, 000, 000, 000 as well. And us looking at it from a different angle and sine with camera for, I'm already moving back down the z-axis. So I'm looking at the cube from front on there. So we have one perspective camera and we have three orthographic cameras top-down from the left and from the front. I have an example of that code there on the website that you can use as it stands now? Yeah, my dad look a little more obvious that we're looking at that from different perspectives. I'm just going to change that object because a cube is pretty much the same no matter which way you look at it. Close that. And we saw is that using a box geometry, I'll use a three dot or a snot geometry like so. And I'll scale cube half Soyuz cube dot scale dot x equals 0.5. Let's do the sign for x, y, and z it, okay, so I've made it a little smaller and we can see we've got different things going on there, different perspectives. Now one final thing, if we look at the renderer, again, we're rendering the same scene every time we can render different saints. So I'm going to create a different thing called S2 and render a three will render S2. So up here, S2 is also a new same. I don't have any objects in my saying. So I'm gonna do that down here where I've added cube to the same. It's important to note that we'll get onto these further. And when we look at the object three day but an object or mesh cannot be a member of one scene. So I couldn't say S2 also add Qp because cube is now part of S2. So instead button Credit new cube, called cubed as a new 3D mesh. And I'm going to use the existing geometry and material. There we go. That's different. I'm not actually rotating. Q2, say not seeing it rotate, but I could to two, I'm going to just rotate one axis and we go anyway. You can say it's a different thing. Anyway, this starts to get a little more complicated now the scope of this particular lesson, so we'll look more about the details of what's actually happening here as we progress further. But now, the point of this lesson was to demonstrate the relationships between the same, the renderer and the camera. And the fact that you can have lots of renderers if you wanted to, loss of Sainz, lots of different cameras. You can have perspective orthographic cameras. You can all either hard-code canvases to the document and give them your own styles, or have a dynamically added, which is very common way of doing it. In the next video, we'll look at what's going on here in the animate function, okay, Excellent. 11. Animation Loop: Okay, let's look at the animation loop now. Now before starting this, make sure your scripts or back to the way they were and we finished grading the boilerplate. So that's index.html. Put that in, I've just pasted that in. And client Ts just copied that and select all paste client, yes. Okay. And that's what should be running in your browser. Okay, the animation loop, we're looking at the concept behind this function, okay? So in most three GIS examples, the function is called animate, but another 3D environments or games you may find it called the game loop. Intimate is good enough, That makes sense now and you animate loop. Everything that you want updated as your program is running can be triggered here. Inside D animation loop, there's these request animation frame function which calls itself again, which actually ends up that dysfunction just keeps looping and looping and looping all the time. Now it's using request animation frame. Request animation frame is a method that tells the browser that you wish to perform an animation and requests that the browser course specific function to update an animation for the next 3. So it takes a callback as an argument to be invoked before the next break point. So that's what we're seeing here. Request animation frame enemies. So it's just going to loop around in circles. Now, it happens about 60 times a second, but will generally match the display refresh, right? In most browsers as per the W3C Recommendation. So depending on your browser, which version request animation frame may be paused if it's running in a background tab or in an iframe that's hidden. And this is to improve performance or battery life, okay, on the MDM website,, we've got some information about window request animation frame. And just be aware that the animation will run faster on higher refresh rate screens. For example, if you're using an Oculus Rift, the refresh rate on that will be about 90 frames per seconds. So the animation loop or warm much faster. Anyway, let's look at example. The animation loop here is calling the render function. Now, if you have a 3D scene and you want it to be continually redrawing like that. And there's always something happening then having a render function be called inside animate is a good idea. So let's just turn that off. So what happens? Okay, renders no longer being called, but the animation loop is actually still running behind the scenes and about 60 frames a second. Okay, So let's put now the animate loop doesn't run automatically on this. I've called it. Okay, So animate down there, save that. Now nothing's happening. Animate actually isn't happening at all. Now, this cube rotation is done on the being updated. So if I want the cube rotation, for example, and I didn't want render, I can still call animate. And the cube rotation will be updating behind the saints. But if I wanted the screen to be redrawn, the native be calling the render function, which is actually just calling the renderer Render function. So once again, that's back. Now if you want updating. So the properties of a mesh like that, n d cubed, for example, just stays static like that. There's no need to call render all the time, 60 times a second. You actually just call it once. I'm just going to comment that out and just did a down here and actually not even call animate at all. And we'll refresh. And it's good already surrendered once computers no longer working hard. But I also have orbit controls and the Oba controls is still working behind the scenes. And if I press the mouse button down and move it around, the properties of the saner actually changing, but there's no render call happening, so we're not seeing the update. So that's one good reason to run render in an animate function, but you still don't have to do that. Orbit controls has his own vent. So in order to use, I wanted to put all the controls into its own variable. So const controls equals a new Oba controls, controls, dot, add event listener, change, render like so. Okay, controls add event listener, That's the onchange event. And every time that all the controls changes, we'll call the render function, which is down here. It's just updating the renderer. So save that. Now we've only called render once. So far. We have no animation loop, so I'm not starting it, but the Oba controls has change event registered, so now it's re-rendering every time there's a change to deal with controls. But the animation loop isn't continually re-rendering. So this is one way to improve performance when you throw a GIS applications if you need to, if you had a very heavy same, which was continually redrawing a lot of objects. So the examples that you'll see throughout the course will be a combination of either updating the renderer in the animation loop or all render only when there was a change, such as when the controls was changed or even when the window was resized. For example, here I'm still calling render in the window resize events. So far I changed that, it's re-rendering. But if I commented out that render function there and save, the canvas is not actually being redrawn here, but it's just being stretched because of the style bond the scenes. But if I rotate using Oba controls, it goes back to normal once again. And I go so only on update is render being called and that is actually just stretching the canvas. So, okay, so I often call render in the window, resize events regardless of whether I have an animation loop or not. But you don't have to do that. Let's just not call in their re-size event, re-enable animate. Turn off the first render and naval render and the animate function again. Now if I resize the window, it's still correct regardless of whether I call render inside the event listener or not. That's because render is being continually updated in the animate function which is being triggered about 60 frames a second. Okay, So now I will just put the changes of rotation back so that we see a moving. Okay? Now, if you're running an enter my loop, it's not absolutely necessary to run render in the re-size that event as well, depending on how big your scene, as you may see, a slight delay when resizing the window. It might not be a problem for you, but it's just a very small detail that I've noticed on older browsers that I prefer to actually call render and saw the resize event as well, even if I have an animate loop. And it's also since I'm now running the animation loop again, identity call render. It would tell me all the controls changes because the enemy loop is already calling render, so that it works already. Okay, So just one example where I didn't use the animation loop. I only called render on the first call and render whenever the orbit changes and also render whenever the window changes. Like so is in this program, there'll be a link at the bottom of the documentation, but it's quite a complex model. And when the screen is sitting still like that, There's no need to keep rendering all the time in an animation loop. So I only update the render when I used the Oba controls like I'm using right now. And also, if the screen changes size like that, then the item render is actually being called. And also with anything else changes such as you drag an object into the same. I need to render. There's not one. Okay, I re-rendered. Excellent. So there you go. Beware that that's an option you have. Okay, so anyway, how the code sits now is on the documentation page, faunal scripts, client here, client tiers. So we'll continue the next lesson from these scripts. So next lesson will be stats panel. And we'll look at this little panel here on the top left, which shows us our frames per second. And this is continually being updated in the animation loop in this particular example that's running here. Anyway, Excellent. 12. Stats Panel: Okay. The stats panel, that's this little thing on the left here, top-left shows statistics about L3 JS performance.