Video Summary and Transcription
Threads.js, a Vue custom renderer for creating declarative 3D scenes, has gained popularity with over 1,700 GitHub stars, 9K monthly NPM downloads, and a strong developer community. Version 4 introduces performance improvements, on-demand rendering, typing support, and memory management. Event bubbling and primitive creation are key features, along with enhanced memory management and scene inspection capabilities. The roadmap includes translated documentation, a new cookbook, and the launch of post-processing and XR VR packages. Performance enhancements, a new 3D course, and updates to Tres Leches UI library are also in the works.
1. Introduction to Threads.js
One year ago, we presented Threads.js on Vue.js live one and open sourced the project. Now, the Threads.js ecosystem has more than 1,700 GitHub stars, with the core package being the most popular. We have over 250 developers using the core, and around 40 contributors. The library has almost 9K monthly NPM downloads and has seen a lot of traffic in the last year. Let's dive into the new features of Threads.js version 4.
Hello, Vue.js life. One year ago, we had the honor of presenting Threads.js to the audience on Vue.js live one. If you were there, you probably remember me, Dreset, as a Slytherin student, and probably also remember that we open sourced the project live on stage.
A year later, this is how the Threads.js ecosystem is looking like. We have more than 1,700 GitHub stars across the whole ecosystem, being the core package the one with more stars, almost 1.5K, followed by CentOS and the Nuxt module. Only the core is being used by more than 250 developers, and we have around 40 contributors.
This is the amount of NPM downloads monthly, and we're almost racing to the 9K, which is pretty cool for a library that only has one year old. These are some of the stats of the websites and documentation, having a lot of traffic in the last year. With that being said, let's see what's hot on the new version of Threads.js version 4, coming up soon before summer.
2. Overview of Threads.js Version 4
I'm Alvaro Sabu, a DevRel engineer and the author of Threads.js. Threads.js is a Vue custom renderer for creating declarative 3D scenes. Get started with your choice of package manager or try it on our official playground. In version 4, we addressed performance issues, on-demand rendering, typing support, and memory leaks. We also added event handlers to primitives and made the prop object reactive.
Hello, everyone. My name is Alvaro Sabu. I'm a DevRel engineer at StudyBlock. I'm also a content creator. I have my YouTube channel, Alvaro DevLabs, where I create tutorials and courses about open source in general, Vue, and Nuxt. I am also the author of Threads.js. I have my portfolio that I never finish, and you can always say hi on my networks and Alvaro Sabu on Twitter and message.
So before I start, I assume that 30% of you might have heard about Threads.js. A little bit more if you were here last year, but the other 70%, what I can tell you is that you will be amazed by the end of this talk. What is Threads.js? Threads.js is a Vue custom renderer that allows you to create 3D scenes in a declarative way by using Vue components and composables. So imagine the same way you create UI components and elements in your apps, doing the same for 3D. So Threads.js is the Spanish word for tree, because this library is based on 3Ds and also because the French word was already taken by another library.
How do you get started? You can choose your package manager of choice. In my case, I use pnpm, and you can do pnpm add at Threads.js core. This is a core package, and install tree as a pure dependency, or you can always play around with it on our official playground, which is similar to the Vue single file component playground. If you click here, you're going to see a place where you can edit the code and see the changes right away here, so you can experiment with Threads.js.
With that being said, let's jump to the new features that you can expect on Threads.js version 4. For the last year, we recollected a lot of feedback from the community, a lot. Bunch of users were complaining about some performance issues. A lot of them were requesting on-demand rendering. We have a lot of issues with typing support, especially after they released 156 from 3DS. We also experimented memory leaks on view route changes, so whenever the user was changing the route from one page to another, the memory of the GPU and CPU weren't clear. Some materials and geometries were left there, occupying space. This is bad, especially if you are creating 3D experiences on mobile devices.
Next on the list, we added event handlers on primitives, such as pointer events. We took all that feedback and started working on new features for version 4. The first one is on-demand rendering. Then we refactored the event store and added a logic for propagation. We added event handlers to primitives. Using primitives, now the prop object is reactive.
3. New Features in Threads.js Version 4
We added better disposal of resources for memory management. With on-demand rendering, users can decide when to render scenes. We also support manual invalidation. The event manager was completely refactored to a store, and event bubbling logic was improved.
We added better disposal of resources for memory management, and a lot of bug fixing and improvements.
Let's take the first feature and let's explain a little bit what it means. Until now, whenever you are rendering a scene with 3DS, it's always rendering, no matter what happens on the scene. So even if the scene is still, it's going to render every frame per second. With on-demand rendering, we are adding a possibility to the user to decide when to render. So one of the possible values of the new prop render mode on the Tress canvas is on-demand. This will automatically invalidate whenever it detects a change on the scene. This change can be instances prop changes, so whenever you're changing the position or color of a material. Then context state changes, for example, if you have the Tress canvas and you change the background or you resize the screen. And whenever you're using the VIF directive to remove nodes on the scene.
Here is a demonstration of how it works. So we have the Tress canvas and we add the prop on-demand. So if you take a look here, you now can see that it only renders whenever there is a change on the camera. Let's take a look again. Right now, it's always rendering. We add the prop. And then you can see that it goes to zero. And only when I change the camera, it's rendering the scene. This is incredibly powerful for the performance of your scenes. Then we also support manual invalidation. So if you want to avoid having on-demand, you can always use manual as the prop value. And then you have a method from the use Tress composable called invalidate. So whenever you are doing a change, you can manually invalidate the next frame. Such as watching the box ref whenever it's available and then changing the position and invalidating manually.
The next feature on the list is the complete refactor of the event manager to a store and also the work done on the propagation logic. So until before, we had some basic pointer events, such as the click, the pointer move, the pointer enter, and the pointer leave. This was okay for basic applications. But when you want to do more cool stuff, you needed way more than that. So before, we added context menu, which is the right-click, double-click, pointer down, and pointer up, wheel movement, and pointer missing. But the thing that excites me the most is the new logic for event bubbling.
4. Event Bubbling and Primitives
To understand how event bubbling works on Tress ES, we need to understand that it's completely different on how it works on the DOM. In Tress ES, we use a canvas to visualize elements on the scene, while in the normal DOM, we have a component or element tree. Occlusion is a concept unique to 3D, where objects can block the view of other objects. In version 4, we added a stop propagation feature to selectively stop event triggering in objects during ray casting. Primitives in Tracks.js allow for programmatically creating instances and adding them to the scene graph. This is useful for loading models and creating complex components.
To understand how event bubbling works on Tress ES, we need to understand that it's completely different on how it works on the DOM. Because in Tress ES, or in 3D in general, we're using a canvas to visualize all the elements on the scene, when using the normal DOM, you have a component or element tree to work with. Also, there is a concept called occlusion that is only available on 3D. What occlusion means is that if I have a camera, and to catch the events in 3D, we draw an invisible line using a technique called ray casting. So this ray casting beam is going through the whole scene, going through different objects.
For example, we have a pyramid here, a cube here, and a sphere here. So this means that the pyramid here is in front of the camera, and it's occluding the rest of the objects. Maybe we can see it a little bit easier here. So right now the camera is watching the three elements at once. But if I do this, and I put the pyramid in front, if I click this pyramid, it shouldn't replicate on the other objects. This is not the case before v4, because whenever you were ray casting in the different objects, all the different objects here were triggering an event. Now in v4 we added a stop propagation, meaning that you can select what object will stop the propagation on Event Handler, and stopping the rest of the objects in the ray casting beam to be triggered. But how does this look on the actual code? So if you have a mesh that we want to use for this matter, we can pass a function to the Event Handler, click in this case, and as a parameter we're going to have the output event that was clicked. So we can use that object to stop the propagation using this method right here. And as easy as that, we just stop the propagation through the rest of the objects, as a cat popping up a bubblegum.
Let's talk now about primitives, which are one of the essential features of Tracks.js. So what do you think whenever you heard primitive? You might think it's something really ancient. But in this case it has nothing to do with that. The primitives are the Tracks.js version of the component isOnView, meaning that you can create programmatically any of the instances of Tracks.js. For example, here we're creating a mesh that is compound on a geometry and a material, and then we're passing that mesh through the prop object of a primitive. This is going to add that mesh into the scene graph of our application. This is incredibly powerful because for things that you cannot convert directly to a component such as models, you can use here the abstraction from Tracks.js to load a model from this path, a glTF model, and then when the await completes, you will have a variable of the model with all the different group of meshes compounding that object. And you can pass it to the primitive right away. The end result is something like this.
5. Primitives and Memory Management
The primitives in Tracks.js allow for programmatically creating instances and adding them to the scene graph. Conditional rendering and event handlers can now be applied to primitives. Memory management has been improved with automatic disposal of resources and a manual dispose utility. Dev tools have also been enhanced with renderer info.
The primitives are the Tracks.js version of the component isOnView, meaning that you can create programmatically any of the instances of Tracks.js. For example, here we're creating a mesh that is compound on a geometry and a material, and then we're passing that mesh through the prop object of a primitive. This is going to add that mesh into the scene graph of our application. This is incredibly powerful because for things that you cannot convert directly to a component such as models, you can use here the abstraction from Tracks.js to load a model from this path, a glTF model, and then when the await completes, you will have a variable of the model with all the different group of meshes compounding that object. And you can pass it to the primitive right away. The end result is something like this. We have our model added to the scene.
Now before, this object prop wasn't reacting, meaning that you couldn't dynamically change the model that was rendered on the scene. But now it is possible. If we define a ref variable here like isCube and then we use a ternary operation to, depending on the value, render the cube model or the aqua model, we're going to end up with something like this. If we check the checkbox, we can dynamically change the model that is rendered. Then we have conditional rendering for primitives. Until now, you could grab any Tracks.js component and just basically apply a directive be if to render or not in the scene. But that was not possible with objects, meaning that for example, models weren't possible to unrender or render again. So if we create a ref with isVisible and we pass it as a be if, now we can toggle the rendering of the models itself inside of the scene. We also add event handlers to them. So part of the previous pointer event refactor was adding event handlers to primitives. So now it's possible to attach a function to the event handler on models, for example.
Next in the line is memory management. This was really tough to make it happen. The problem is when you're dealing with 3ds objects is that the materials and the geometries and textures are saved on the GPU. So if you don't dispose them correctly, meaning that when we use a be if, for example, and we remove the node, if we don't delete those and also delete the reference for the CPU memory, we end up having memory leaks, especially if we are changing routes and the components are not being unmounted correctly. So to achieve this, we added automatic disposal of resources whenever the component is unmounted. So using the custom render API, we managed to dispose all the objects and all the children's properties that are like materials, geometries and others to be disposed correctly and also deleting the references. We also added a manual dispose utility method that you can import from 3ds to dispose resources manually, for example, for primitives. This utility free both CPU and GPU memory. We also made some improvements in the dev tools. So like three months ago or a little bit more, we launched official support for buildup tools with an object-to-scene graph that you can inspect and check all your instances. But we wanted to improve it even further. And we add renderer info that is now available on the when you inspect the scene.
6. Scene Info and Search Functionality
The info tab provides useful information about memory usage and rendering details. A list of shader programs and materials is available for inspection, and the search functionality allows you to filter the scene graph.
So whenever you click on the scene, you're going to have on the right several tabs and one of them is going to be the info, which has information like the memory use, how many objects are being rendered, how many calls have been done, how many triangles, points and lines. So this is really useful whenever you want to check the poly count of your scene, especially dealing with models. Then we added another one that is a list of all the shader programs or materials that are being rendered at that time and are available to inspect. You're going to have a list, for example, of the materials done in the scene with a mesh to material, a mesh depth material and such. We also added the search functionality. So whenever you search here on the top of the search instances, you're going to be able to filter the scene graph.
7. Updates and Roadmap
The core team has been working on improvements, including translated documentation available in multiple languages. A new cookbook with basic examples has been created. The roadmap for TresCS includes releases of the stable version, updates to Cientus and the ecosystem, and the launch of post-processing and XR VR packages. The year 2024 will bring exciting developments. Thanks to all the contributors and sponsors. Poll results show Fixix and GameUtils as popular choices.
Although this will cover all the new features for V4, the core team has been working on a lot of improvements in the meantime. One of those is the anticipated translated documentation. So we're proud to say that over the last couple of months, we have been working on several translations with the community. And nowadays it's available on English, Spanish, Chinese, German, French and Dutch. So I really want to thank all the community for the effort of translating the whole documentation of the core package into different languages. Hopefully this will open Tres-ES to more audiences and new communities out there.
We also created a new cookbook. So this idea came from the Astro documentation and we thought about how we could provide the community with the best examples, really narrow down to the basics and how to use Tres-ES. So we thought about this idea of cookbook with different recipes on how to get started with. So if you go to the documentation and you find for the cookbook, you're going to see different recipes with things like basic animations, how to use groups, how to use slides, how to load the model, et cetera.
So what's next? This is how the roadmap has been updated over the year. This is how it's looking at the moment. So we are in the final steps of releasing the alpha for the core version four, and we are planning to finish a stable release at least at the end of the Q1. The translated docs have been translated right now. We are aiming for other languages as well. So we are going to cover this on the first two quarters. And in the second quarter, we're planning to update Cientus to a v4 and also the rest of the ecosystem with a lot of new changes on Cientus. We are also planning the final release of the post-processing version one, which is going to be another package of the ecosystem to add post-processing effects into your scene. In the middle of Q2, we plan to start working on an XR VR package to be able to use it with VR glasses. And somewhere in between Q3 and Q4, we plan to launch our own package for physics using a wrapper on early hood. Although this is not everything that we're working on, these are the highlights of what you can expect this 2024 on TresCS.
Last but not least, I want to thank all the contributors that make TresCS possible. Between the core team and as well all the amazing community members that have been contributing in the last year, thank you very much. Also thank you to our sponsors, both personal and the organization. And if you want to sponsor TresCS, please go ahead on GitHub sponsors and buy us a coffee. Thank you very much and see you in the next one. Ciao ciao.
Hi Alvaro. Hello, how's it going? Really great and you? Well, let's see, because the poll results are really interesting. We can see that Fixix is winning, but then afterwards GameUtils is also going in, too.
Community Poll and Performance
The community has expressed interest in physics and game development. To ensure good performance, it is recommended to avoid using reactivity and instead use plain objects. More performance enhancements are planned, including better mobile support.
But it seems that it's related. So what do you think about the results? Is what you expected? I kind of expected it and I wanted to do this poll because I wanted to feel more from the community what's the most interesting feature that I want to see. And a lot of people have requests in physics and things to create games, which I'm super excited because I love games. So it makes my life like happy.
No, but that's really cool because you're allying with the community then. Let's see one of the questions that is really trendy in the Q&A. We can see how can we ensure a good performance? Yeah. A really good question. That's a really good question. So most of the work that we did in the before was to ensure better performance in terms of memory consumption, trying to dispose objects and textures in a better way, trying to free the memory for GPU and CPU. But in a general thing, from the end user perspective, think of using when you're treating with animations or rendering loops, try to avoid using reactivity, which is based on proxies, and it's not going to be as performant as a plain object. So that's why normally we suggest that you took the template ref and you take the instance from the view component and use it for animation instead. We're going to work on more stuff for performance, of course, and to ensure good balance in mobiles and such. But yeah, thanks for the question. No, I think the community is looking forward to more improvements on this side, but you are also taking care of that.
3D Course and Tres Leches
A new course on creating 3D product configurators has been launched. Tres Leches, the UI library, will move forward with a rethinking of the API based on community feedback. Taking control over the render loop is currently not available, but exploratory work is being done to provide a better solution.
And there is another question, really interesting one. Is there a good course that you can recommend for learning 3D? Yes. Anything you need to sponsor yourself? Actually, yes. I just launched a course with Egghead.io. It's about creating 3D product configurators. You are going to be able to create your own product and then let the end user customize the materials and the lookalike of that product. So I will probably share in my socials after this the link for the course. Feel free to join because I have a blast doing that course. And you can expect more courses in the future about 3DS.
Nice. Nice to hear that. So in the Egghead platform, you have that. And then we have another one. What happened with Tres Leches, UI library? Is it going to move forward or did you stop working on it? Yeah, Tres Leches is going to move forward. I promise it's something that I needed a way to debug and control the different aspects of an application. Now, with the DevTools work that we did with the official DevTools, it's easy to control and see what's happening on the scene. But we left that aside because we weren't happy with the API. It's still not in a stable release or anything. And what we're going to do after the v4 and v4 of Cientos is actually rethink the API based on the community feedback. A lot of people in the community share their concerns about the usage and they were not pretty happy or comfortable how we use it. So we're going to work on that and provide a better solution.
OK, nice. But it seems that you have all covered by your own thoughts. So that's really cool that you're really working on all the questions that we have. And yeah, let's I think finish with another one. There is a way to take control over the render loop? Not as today. We were working on a feature that didn't make it to the v4 because implied a breaking change in terms of how they use render loop. And probably will break all the different applications and playgrounds that we have right now. So we were a little bit scared of doing that. And we are exploring doing POCs to see how we can better provide it to the community.
Vue DevTools and Community
The new Vue DevTools will have a unified API and kit. Contributions are welcome in the Trace library, which already has an active community. Join the Discord to get involved and receive Swaggy stickers.
So it's not a breaking change. Maybe an optional API. We're going to think on it. But yes, it's one of the first features that we're going to work after the v4.
Hmm. OK, good to know. It sounds really technical. I think we have time for another one. Why not? Is there going to be a program for the new Vue DevTools?
Yes. So we initially played around with the new Vue DevTools. And the developer experience was going to be similar to the Trace NUX DevTools. But since I talked with the authors, they are working on a unified API and kit. So I'm waiting for something more stable to jump in and say, hey, we're going to release some new DevTools for Vue and Trace.
Oh, nice. Nice. My God, you have almost everything planned. So that's really good for Trace. I think the community is already really active and making your library better. We need more people, though. If you want to contribute, feel free, because we need more hands to achieve everything. We need more hands. So even you, Alba, or anyone in the audience that want to join, join the Discord, and we're happy to onboard you in Trace.
Yeah, of course. People that are interested in contributing to this library, they are open for more contributors. And they also have Swaggy. You can see that they have a sticker. This sticker was from the Vue.js Amsterdam conference, and they gave me one in person, so that's really cool. And you can have one if you come to any conference in person, actually. That's right. Thank you for the shout out, and thank you very much for having me.
Comments