Three.js and 3D Models in React: A Beginner-Friendly Guide
If you're captivated by the possibilities of 3D graphics but find the idea of creating 3D models from scratch impossible - fear not!
Three.js, a powerful JavaScript library, comes to the rescue allowing us to easily integrate existing 3D models into React applications.
Therefore, in this article, I'll go into the essentials of Three.js and guide you through the incorporation of stunning 3D models in your projects.
How it all started
Once upon a time...
"In the neon-soaked depths of the digital abyss, it all began. A single line of code, a whisper of electricity through the wires, and the world was forever changed. The shadows held secrets, and within them, the genesis of a dark, synthetic future. How it all started, they say, was with a hack, a breach, a download that echoed through the circuits, triggering a revolution of ones and zeroes."
So recently, I found myself going through my old portfolio which was in desperate need of a revamp because it was made when I was just starting out with programming. We can move past its visual details. ??
In terms of design, I knew I wanted something more authentic and since I like video games, I was aching to throw in some cool 3D model.
But here's the catch - I had zero to little Three.js knowledge and didn't want a boring sphere or cube.
Therefore, I rolled up my sleeves, started researching and sooner than later I found my 3D model and decided to stick with the idea of having that 3D model in my portfolio no matter what!
The model is a masterpiece by Oscar Creativo and this is his profile on Sketchfab. I highly recommend you to check it out!
Since I spent a fair amount of time finding the solution, then incorporating some best practices and optimization and because I know that there are more stubborn people just like me, I decided to make their lives easier and share my experience and the steps for achieving the same result.
My goal is to simplify the whole process by offering a simple and clear explanation and make it beginner-friendly.
So let's start!
About Three.js and prerequisites
While Three.js offers an extensive toolkit to build 3D experiences from the ground up, my focus will be on leveraging the immense repository of pre-made 3D models available to developers. Why?
Because by doing so, we can level up our React applications in no time and introduce something truly impressive.
Nevertheless, it's essential to weigh the pros and cons before making a decision. While utilizing pre-made 3D models presents clear benefits such as time-saving, great quality, a wide range of choices, potential cost saving, and quicker learning curve, we must also take into account downsides like limited customization, possible overloading, licensing constraints, and potential challenges in seamless integration that may require careful consideration and adaptation.
My suggestion is to explore the available free 3D models and be sure to check and include the appropriate licensing information. Alternatively, consider opting for a paid model that aligns with your preferences.
Now, let's gear up to breathe life into your application!
Prerequisites
1. A fantastic 3D model ??
After you select your 3D model, proceed to download it. The following modal will appear:
As you'll see, there are different formats and while Three.js can handle all of it, GLTF or GLB are preferred due to their efficiency, versatility, and wide support within the Three.js community and the broader web development ecosystem.
Here's a short explanation for each:
In this article, I'll use the GLTF format because of the reasons mentioned above. The files will be downloaded as a zip archive that you'll need to unzip afterward.
2. React app with the following libraries installed ??:
npm install three @react-three/drei @react-three/fiber
yarn add three @react-three/drei @react-three/fiber
About the folder structure and files ??
public -> 3DfolderName
src -> components (containing Loader.jsx) -> canvas folder -> CyberGirl.jsx + index.js
Code and explanation
CyberGirl.jsx
The useGLTF hook is used to load a 3D model from the specified path. It fetches and prepares the 3D model for rendering within the Three.js environment.
领英推荐
The useRef() creates a React ref called modelRef. Refs in React are used to access and interact with the DOM or React elements directly. It is used to reference the 3D model within the component and apply transformations or interact with it.
Levels of Detail (LOD) is a feature from the Three.js library to optimize the rendering of a 3D model. It begins by creating an instance of the LOD class to manage different versions of the model. In this case, four cloned instances of the original 3D model are created with each one representing a varying level of detail. This LOD improves rendering performance by displaying simplified models when they are farther from the camera, reducing computational load.
The LOD system operates independently of zooming or camera control settings. It's designed to automatically switch between different versions of a 3D model based on the distance between the camera and the model, regardless of whether zooming is enabled or not.
LOD is primarily used to optimize the rendering of 3D models in scenarios where rendering high-detail models at a long distance is unnecessary and computationally expensive. As the camera moves closer or farther away from the model, the LOD system automatically switches to the appropriate level of detail.
The <primitive/> is a Three.js element and is used to render the 3D model. It uses the gltf.scene as the model/object to display and sets the model's scale, position, and rotation in the 3D space. Both position and rotation use an array with three values [ X, Y, Z ] representing the coordinates along the X, Y, and Z axes. The use of a reference (modelRef) allows for potential programmatic interactions with the rendered 3D model.
The Canvas component sets up shadows and a demand-based frame loop, along with a device pixel ratio of 1 and 2 for different displays.
The Suspense, renders the CanvasLoader component as a fallback and displays a loading progress indicator while the 3D model is being loaded.
The ambientLight is a type of light source that illuminates all objects in the scene uniformly, regardless of their position or orientation. It's typically used to provide a basic level of light to the entire scene, simulating global illumination. Ambient light doesn't cast shadows or have a specific direction, instead it just brightens everything. For more information on the props, check this.
The pointLight is a more directional light source that emits light in all directions from a specific point in 3D space. It simulates a point source of light, like a light bulb. It can cast shadows and has various properties such as position, color, and intensity. position specifies where the light is located, while color and intensity control the light's color and brightness, respectively. Point lights are useful for creating localized, realistic lighting effects. For more information on the props, check this.
The OrbitControls component allows for interactive camera control in 3D scenes. It enables the user to pan, zoom, and orbit around a 3D object.
To find a comprehensive list of available properties for configuring the OrbitControls component, please refer to the this resource.
The Preload component is used to preload assets before rendering a 3D scene. Specifically, it is used to preload textures, models, or other assets asynchronously, ensuring that they are fully loaded and available before the scene starts rendering. It should be placed within the Suspense component to provide a fallback UI while assets are being preloaded.
Loader.jsx
The goal of the CanvasLoader component is to display a loading element until the 3D model is loading. It imports two elements, Html and useProgress, from the "@react-three/drei" library to track the loading progress of 3D assets.
The loading progress is displayed as a percentage within a p nested inside the Html element which is centered. Since the progress const holds a floating-point number with several decimal places, using toFixed(2) will ensure that it is displayed with exactly two decimal places in the final output.
index.js
This file serves as a central export point for the CyberGirl component, making it more convenient to import from other parts of the application. This practice keeps import statements clean and organized, and it can easily scale to include additional 3D components.
Hero.jsx - where the 3D model is used
Lastly, the CyberGirl component is imported from the index.js file from the canvas folder.
While there are many more options to explore and customize, this example serves as a straightforward approach to integrate an impressive pre-made 3D model using Three.js. The source code can be found on my GitHub.
Logging Off: A Cyberpunk Conclusion
In conclusion, the marriage of Three.js and React opens up a world of creative possibilities, allowing us to seamlessly integrate captivating 3D models into our web applications. With the wealth of pre-made 3D models available and the simplified React integration provided by libraries like react-three/fiber and react-three/drei, breathing life into our applications is just so cool and easy!
I hope you've found this article informative and insightful. Feel free to share your thoughts, questions, or experiences in the comments section below – I'd love to hear from you. If you'd like to continue the conversation or have any additional questions, don't hesitate to connect with me on LinkedIn.
May your data always remain encrypted and your implants never glitch. Remember, we're just data in the machine...
Happy coding! ????
Turning energy to code since 2014
6 个月For what exactly are you doing the LOD? Because in this case, you only clone the same gltf scene multiple times. And because it's the same gltf file it should have the same LOD no matter if you are far away or very close to the model. Can you explain it a bit?