Three.js Optimization - Best Practices and Techniques

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

this was good! will be very helpful

👍︎︎ 4 👤︎︎ u/drcmda 📅︎︎ Apr 18 2023 🗫︎ replies

Thank you sensei

👍︎︎ 2 👤︎︎ u/run_ywa 📅︎︎ Apr 18 2023 🗫︎ replies

Amazing, fantastic job!

👍︎︎ 2 👤︎︎ u/dasomen 📅︎︎ Apr 18 2023 🗫︎ replies

This really was terrific, and I hope you'll keep creating more!

👍︎︎ 2 👤︎︎ u/Jo_Cu 📅︎︎ Apr 20 2023 🗫︎ replies

could you also post some references, links and repos in the description? would like to read more about all this stuff!

👍︎︎ 1 👤︎︎ u/CROEWENS 📅︎︎ Apr 18 2023 🗫︎ replies

Awesome! Thanks a lot.

👍︎︎ 1 👤︎︎ u/pjottee 📅︎︎ Apr 22 2023 🗫︎ replies
Captions
in this video we will be discussing the importance of optimizing webgl content for performance as a developer with over five years of experience in 3GS and react 3 fiber I have came across many challenges when it comes to creating experiences that runs mostly on many devices despite how important this topic is performance optimization is often overlooked in tutorials leaving developers and 3D artists to fend for themselves that's why I have created this comprehensive guide to help you understand how to create beautiful but well optimized experiences that will run seamlessly on most devices in this video we will first talk about what's generally heavy in webgl and how to track performances then we will go over different basic concepts like draw calls materials texture shadows and post-processing finally we will analyze two websites and see what optimization techniques they used in order to optimize 3GS content we need to understand what's heavy or not is it the amount of polygons the type of material you're using the size of your textures or the number of animations 3D artists are often asking those questions to developers there is no definitive answer to these questions what's important is understanding the trade-off between visual quality and performance think of each element such as polygon count materials and textures as little sliders that you can adjust according your Project's needs for example if you want to increase the polygon count of your 3D models you might need to reduce the amount of animations or give up your fancy Shadows before starting a project it's essential to decide what's important for your project success by identifying your project priorities you can make informed decision on how to allocate your resources tracking performance metrics is crucial for optimizing your webgl content effectively by keeping an eye on memory usage the number of draw calls and the frame rate of your application you can identify any issues that may cause memory leaks or make your content too heavy to run on lower end devices one helpful tool for monitoring performance metrics is stat.js you may have seen this little panel in the top left corner of most 3DS examples when you click on it you cycle through the frame rate of your application the allocated memory in megabytes and the milliseconds needed to render one frame if you're using reactory fiber you can use r3f perf plugging which has a little more detailed information like the number of polygons texture Etc another approach to track performance metrics is to use the performance monitor of your operating system this provides a better understanding of the graphical load on the device you're testing I recommend using both method to gain a comprehensive understanding of your content's performance there is no such things as too many metrics when it comes to Performance optimization draw calls is the first metric you should be looking at they represent the number of objects the GPU has to render every frame to understand locals better let's break down how they are calculated let's start with two meshes made of a box geometry and a physical material this will create two draw calls one per box now if we add a light and enables Shadows for both boxes we have four draw calls the two we had before plus two more for the shadow of the white box and the shadow of the orange one if we make the material of The Orange Box transmissive the number of draw calls is multiplied by 2 which results in eight draw calls by adding a transmissive material to your scene it doubles the total amount of draw calls finally enabling a post-processing effect like Bloom we will end up with 16 draw calls because when enabling post-processing effects the entire scene is rendered twice in reality what you see on screen now has something like 32 draw calls because the bloom effect has a draw called base cost of 12 draw calls and there's also a background image that costs one draw call this was just an example to illustrate how draw calls are calculated for meshes as you can see depending on the setting of your scene or two simple meshes started with only two draw calls and ended up creating 16 draw calls it's important to note that things like Shadows transmissive materials or post-processing can double the number of draw calls for a mesh making them expensive in terms of performance to reduce draw calls one approach is to merge multiple objects into a single object this can be achieved by merging the meshes programmatically or in your 3D software or using instancing however there are some trade-offs to consider merging objects mean that you can only use a single material for both objects and you also won't be able to animate them separately instancing can be used to animate instanced mesh using Shadow coding but this is a more advanced technique it's also crucial to keep in mind that merging objects to reduce draw calls can cause you to lose the performance gain of fresh drum calling when many objects are merged together the renderer must render the entire object even if only a small portion of it it's visible to the camera therefore it's essential to balance the benefits of reducing draw calls with the performance cost of rendering unnecessary content next let's talk about material practices and some do and don't materials and texturing is a very wide Topic in the lesson I am only going to scratch the surface and talk about the workflow I use in most projects at the beginning of my 3GS journey I used the mesh basic materials quite often because when you are not a material expert it's an easy workflow 3D artists can back all the lighting and shadows into one texture that you can connect to the map of your basic material you don't need to deal with lighting and what you see in your 3D software will be very close to what you'll get in your 3GS scene it's a very lightweight and fast Shader but baking everything in one texture and keeping a good quality usually require larger texture files over the years I almost fully transitioned to using physically based rendering PBR for short using mesh physical material it's a heavier material but offers advantages such as an easier transition from 3D software to 3GS integration as well as being well supported by the gltf standard there's a very good guide on the blender documentation about PBR workflow and how to connect all your nodes correctly if you follow this guide you can export your models in gdltf import them in your 3DS scene and normally all the values set in blender should be well translated to 3GS transparent materials can be heavy and have weird behavior when moving the camera around or having multiple layers of transparent objects it's best to avoid them if possible if you must use them try to see if you can achieve your desired result with an atha map and the alpha test property another alternative is using mesh transmission material a better alternative with more option for transparent object recently released by The react 3 fiber team finally let's talk a little bit about UV as it will be a good Bridge onto our next topic 3GS materials can use two set of UVS the second set is used for AO and light maps and the first one for all the other Maps having two sets of UVS useful for tiling tiling is a technique to reduce your texture size by repeating a seamless image in the X and Y Direction so for example you can have a very small repeating diffuse and normal maps on uv-1 and an AO map that doesn't repeat for your shadows in my opinion textures have the most important role they are the thing that contribute the most to the overall quality but they are also the thing you have to be the most careful about when thinking about performance like I did with materials I just want to go over a few Concepts that will help you understand better how to optimize your scenes color palettes are useful optimization technique that allows you to use a single material for all your objects by simply moving the UV of the object to the corresponding color Square you created this technique offers a great compromise between quality and performance orm occlusion roughness metalness textures are commonly used in the PBO workflow by combining these three textures into a single image you can optimize the texture usage without sacrificing quality tools like substance painter allow you to export Orem textures directly making it a convenient tool for this technique the color palette system can also be used for the roughness in metalness channels however if you use the color palette you need a separate ambient occlusion map environment maps are textures that reflective materials like plastic or metal can reflect on and they can also be used to light up your objects environment Maps offer more realistic lighting options than traditional directional or ambient light sources and they are relatively cheap performance wise HDR exr or jpg images can be used for environment Maps HDR and exr will provide more realistic lighting results a common practice is using a JPEG orphan called an ldr image with a good resolution for the background and an HDR with a small resolution for the environment map Textures in 3GS should always be in power of 2 and have equal width and height for example 1024 by 1024 pixels also referred as 1K texture polygons and materials count affect CPU and GPU 3D competition power but when optimizing textures you want to keep an eye on your GPU memory or vram conception avoid using textures bigger than 2K and split your Textures in two if they are too big basis is another very light thigh format you can consider but in my experience it is currently a quite complicated workflow since traditional tools like Photoshop don't support basis format yet Shadows can be something quite expensive but also vital for the realism of your scenes Dynamic Shadows are the most expensive and should be avoided whenever possible imagine how expensive it is for the renderer to calculate and create a texture for your Shadow every frame if you absolutely need Dynamic Shadows use a small Shadow map resolution to minimize the performance impact if you're on a very tight performance budget instead of using Dynamic Shadows consider using fake generic Shadow under moving objects even for moving character having a texture based circular gradient following him is very cheap and can do the trick in a low poly style project in most cases you would use some sort of baked Shadows back Shadows can be created in a 3D software using light Maps or AO map or simply combined onto your diffuse texture you can also generate them at runtime directly in 3GS very often your scene should have a mix of static and dynamic Shadows for moving objects when it comes to rendering scenes in 3GS post-processing can significantly enhance the final output adding visual effects like depth of field motion blur and Bloom however it's important to weigh the benefits against the cost of using post-processing as it can have a significant impact on performance as mentioned earlier adding a post-processing pass to your render pipeline will double the amount of draw calls which can be taxing on low end devices in general it's a good idea to avoid using post processing unless it's absolutely necessary for the project if you find yourself with some extra room in the performance budget adding a bloom effect can add some very nice visual Flair to your scene I want to summarize what we have learned so far through two case studies a website that are in my opinion well optimized It's also two very different website with different requirements on the left we have a fairly large low poly world made by Mercy Michelle and on the right side a highly realistic car configurator made by this circle I think that reverse engineering or the website is one of the best way to learn what others do and how you can apply these techniques in your own project I believe though that the know-how of a company should be somewhat protected so I'm not gonna talk about things that was not already shared publicly by those companies if you want to investigate more you should do your own research and never copy or steal someone's as work that being said let's dive in the first project in the Colts Club project you're controlling a character in third person view in a large virtual world with a lot of objects and animations when I see a large world like this one my two main concerns will be the amount of draw call and the texture size if you read their case study you can see that merging an instancing object was one of the biggest worry if you look at the overall view of the map they ended up merging meshes into eight groups while making groups you may ask well there are two reasons they don't merge all the meshes into only one single big objects one the AO Map size for the entire map would have to be something like 8 000 pixels large and as we have seen earlier we want to avoid having very large image file because of the loading time and the vrm usage instead you better split these big 8K textures into eight smaller one like 1024 pixels splitting textures also enables the possibility to load them asynchronously for example there is no need to load the texture of a Zone if the user never visited two like I explained earlier the downside of having a single big merged mesh is that you won't be able to leverage the first term calling system of the camera meaning all the polygons will be rendered at all time no matter where we are in the scene they explained that they considered using instancing for the object that repeats a lot like the trees and the cars but given the amount of different objects they had it would be yet too many instance meshes therefore too many draw calls following your initial intuition might not always be the best solution at the end of the day you have to try several methods and the numbers will tell you what's best as you can see they are also using a color palette to give object different shades of colors even if all the meshes are merged into a single big object the last thing I thought was interesting in their case study are the shadows as we discussed earlier it's better to avoid Dynamic rendered shadows and use back Shadow texture for your static objects so you might think that of course in this big map picking your shadows will be the best method but in this case the world is too large and baking Shadows would actually create a lot of additional textures so what they did is using a directional light that followed the character and cast Shadows around him with a reasonable Shadow Map size they went the extra mile by modifying some Shadow code to make the shadow map Fade Away instead of being cut suddenly for more pleasing visual experience the second project is a very different project and has a very different workflow from the one we've seen before in a project like this one the polygon count will be an important chunk of the performance budget there is no way around it a car need a high amount of polygons a model like this exterior plus the interior is minimum three to four hundred thousand polygons so it is important to care a lot about the texturing to keep a well-optimized experience I must say it is very impressive to see how they managed to keep the texture Dimension and file size to a minimum by using a combination of colors and orm palettes with seamless repeating textures total texture file size is around 10 megabyte this experience is so well optimized that they are even using post-processing they have a bloom effect for the lights and a temporal anti-aliasing system you can see when the camera stop moving they render a few additional frames for a better quality it even appears that they use some sort of real-time ambient occlusion for the Shadows you can see when I open the doors the Shadows are rendered in real time personally I find it a bit surprising because if I had to make this project I would probably go for static AO map real-time AO is very expensive and the quality isn't always very good in this example with the static ale the only thing you'd be missing are these little Shadows when we open the door I'm not gonna lie it's a very nice touch but it's an expensive one for what it's worth reading project case study and analyzing what other websites have done is the best way to discover and understand best practices I hope that in this short video I have given you enough tools to keep exploring and finding better ways to optimize your next 3GS project I hope you enjoyed thanks for watching
Info
Channel: Valentin's coding book
Views: 6,913
Rating: undefined out of 5
Keywords:
Id: dc5iJVInpPY
Channel Id: undefined
Length: 17min 46sec (1066 seconds)
Published: Mon Apr 17 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.