Exploded view of a 3D model using React-Three-Fiber
Ever marveled at the intricate details of a 3D model and wished to present it in a captivating way? Let me guide you through crafting an exploded view of a 3D engine model, utilizing straightforward mathematical principles. 💣 This technique not only adds visual depth to your presentation but also highlights the complexity and craftsmanship of your model.
For this endeavor, we'll leverage React-Three-Fiber to simplify our development process. However, the concepts we'll discuss are fully applicable within the native three.js environment, ensuring you can adapt this method regardless of your preferred framework.
The exploded view technique is an excellent way to dissect and display each part of your 3D model, making it particularly useful for educational content, product showcases, or even artistic presentations. By spacing out the components, viewers can appreciate the individual parts that make up the whole, offering a unique perspective on the engineering and design intricacies of your model.
Disclaimer: While this guide aims to demystify the process of creating an exploded view with React-Three-Fiber and three.js, my journey with these technologies is an ongoing adventure. I welcome your feedback and questions. Should you spot any areas of improvement, typos, or wish to share your thoughts, reaching out on Twitter (opens in a new tab) would be much appreciated. Your engagement and insights contribute greatly to the collective learning experience.
Thank you for embarking on this creative journey with me. Together, let's unlock new dimensions of 3D visualization. ✨
Prepare the model
First, open your favorite modeling tool to split your model (if needed) in several parts.
For instance, I am using this cool asset (opens in a new tab), which needs a bit of work before being able to use it.
- Select the model
- Go to
Edit mode
- Select a triangle that is part of the element you want to separate.
- Press Ctrl + L, that will select all the linked triangles. (Ensure that it selects the part you want or select all the triangles manually)
- Press F3 which enable the Quick Actions panel to show up, and begin to write
Separate
. Select the first option. - Congratulations, you have now two separate meshes. Be sure to rename it in an understandable manner. Repeat the process ad nauseam, until you get all of the separate parts.
- Back in
Object mode
(press TAB), select all the elements (press A), press F3 and typecenter
and select the optionOrigin to Center of Mass (Volume)
. It will basically set the center of each mesh to its center of mass, (some average point of the matter). - Export to GLB and you are good to go.
Exploded View Effect in React-Three-Fiber
Here is what becomes to be interesting. Let's see with my incredible drawings, how we can achieve somewhat of an automatic exploded view effect. First the theory, then the implementation.
(Boring?) Theory 📐
Here is the drill in 2D. The most naive way of thinking is to take the world center (0,0,0) as the reference of our exploded view. For the drill, it will not be that pretty considering the shape. We want the epicenter to be higher so the rotating part that are on the same rotating axis, are moving forward. But anyway it is the same principle whatever is your epicenter point.
- You want to find the direction of the displacement.
"What gives us a direction?", you will ask. A vector. (I prefer to explain from scratch, so everyone can eat at the table).
The formula is quite simple:
vector BA = point A - point B
So in our context, we will say displacement vector = center of mass of the piece - epicenter
We can normalize this vector so it is unit vector (it means that the length is 1). It will be easier for us that way to control the strength of displacement along side each vectors.
- We need a criteria to displace the part of our drill A simple criteria to take is the distance between the part's center and the epicenter of the explosion. The more you are far from the epicenter, the more we expect you to go away in our exploded view. Let's call this the magnitude of the vector we calculated in the previous step.
On the drill, like I said previously, we will take an higher (in Y axis) point for the epicenter, so the rotating element are kept along the same axis.
Here you go, let's implement this.
The cool part: Implementation 💥
1. Load the model
Load the model using useGLTF
from the library drei (opens in a new tab) (or use the GLTFLoader if you
are using three.js native)
2. Displacement calculation
Traverse the scene to calculate each displacement. (You can discard the main object if you want to freeze it like me).
-
object.position.distanceTo(explosionCenter)
is to calculate the distance from the epicenter as I explained it previously. The explosion factor is a way to control uniformly the expansion of each part. You can tweak it as you want. -
const vector = object.position.clone().sub(explosionCenter).normalize();
is the direction we need to calculate to expand around the epicenter. We normalize it as you remember, to have a unit vector per part (length of 1), that way we can control uniformly through the explosion factor, the magnitude.
I store all of this in a Map, that will act as a dictionnary for each part. I want to use these displacement value later (with GSAP animation library for instance) to animate the explosion.
3. Let's animate a bit
We are going to use GSAP but you can use your favorite animation library.
Through gsap.timeline().to()
, we animate the position of the current object of the loop, using its displacement.
1. Load the model
Load the model using useGLTF
from the library drei (opens in a new tab) (or use the GLTFLoader if you
are using three.js native)
2. Displacement calculation
Traverse the scene to calculate each displacement. (You can discard the main object if you want to freeze it like me).
-
object.position.distanceTo(explosionCenter)
is to calculate the distance from the epicenter as I explained it previously. The explosion factor is a way to control uniformly the expansion of each part. You can tweak it as you want. -
const vector = object.position.clone().sub(explosionCenter).normalize();
is the direction we need to calculate to expand around the epicenter. We normalize it as you remember, to have a unit vector per part (length of 1), that way we can control uniformly through the explosion factor, the magnitude.
I store all of this in a Map, that will act as a dictionnary for each part. I want to use these displacement value later (with GSAP animation library for instance) to animate the explosion.
Scroll based animation
Here is a little bonus gift for you that stayed until the end. By harnessing the power of scroll-based animation, you can trigger the expansion or transformation of objects and scenes right within the viewer's browser.
Imagine diving into a web page where each scroll unveils a part of the story you're telling. Whether it's a three.js-powered 3D model gradually assembling as your audience scrolls down, or a dynamic scene unfolding piece by piece, the ScrollTrigger plugin enables us to create web experiences that are not only visually engaging but also deeply immersive.
Here's the scoop: using ScrollTrigger isn't just about adding flair to your site; it's about redefining how users interact with content. By integrating this technique, you encourage visitors to explore your content more thoroughly, enhancing user engagement and providing a memorable journey through your digital landscape.
Whether you're showcasing a complex three.js scene, unveiling a new product piece by piece, or telling a compelling story through scrolling, the scrub property ensures a smooth, controlled animation that keeps users glued to their screens. This approach doesn't just display your content; it transforms your web page into an interactive adventure.
Ready ? Let's dig in:
Setting the scrub property to true
, is binding the animation directly to the scroll. Using a value, it is adding some inertia to the animation, that I think is prettier.
Based on the same animation than the previous section you just need to add the ScrollTrigger plugin with gsap.registerPlugin(ScrollTrigger);
Then change the animation to:
Give some room for your page to scroll, set the canvas to position: fixed
in CSS, add some placeholder sections that are like 100vh
height.
Then when scrolling, you will see the model expanding.
Conclusion
As we wrap up this guide on creating an exploded view of a 3D model with React-Three-Fiber and three.js, I hope you've gained valuable insights and feel motivated to explore further. Visualizing the complex parts of 3D models in this way can significantly enhance your presentations, making them both more interactive and insightful.
Consider this tutorial a first step towards unlocking the potential that React-Three-Fiber and three.js hold for 3D modeling and web-based visualizations. My own fascination with the detailed exploded views of machinery, and how every piece comes together, led me here. It's exciting to think that we can now bring these concepts into the digital age, making them accessible and engaging through the power of modern web technologies.
React-Three-Fiber and three.js not only help us pay respect to the art of mechanical diagrams but also introduces new possibilities for creativity and design in the 3D space. It's about merging technical skill with creative vision to build models that are not just visually appealing but also interactive and informative. This is how we make our digital content not just seen, but experienced.
The evolution of 3D on the web is creating new opportunities for interactive experiences, transforming how we interact with content online.
I'm eager to hear your thoughts and any suggestions you might have. Your feedback is crucial for making guides like this better and more useful for everyone. If you've found new ways to apply these techniques or have questions on how to refine them, don't hesitate to share.
Thanks for joining me in this exploration. Together, let's explore the limitless possibilities of 3D web development.
Wishing you a great day and happy modeling!