How to render 3D model in a React JS application
Tags: react, javascript, beginners, webdev
Published: 2022-09-15 13:31:33

Hey there👋,

Nowadays the browsers are becoming more powerful then in the past and now they can render different complex animations with ease. You might have seen lot of websites rendering 3D model without any performance issues. In this article we are going to use [Three.js](https://threejs.org/) to render an iPhone model in a React application. 

Before we start this tutorial let me show you a demo website which renders this model. 

Here is the demo link: https://apple-iphone14.vercel.app/

For this website I have used Three.JS along with the GSAP to add smooth scrolling animations. If you want to learn to make this responsive 3D landing page you can watch the following tutorial👇.

{% youtube cT160dOzpGY %} 

Let's render an awesome 3D model in our React application.

## Setup and Installation

For this tutorial we will be using [CRA](https://create-react-app.dev/)(create-react-app) template. Open your project folder and use the following command to install CRA template.

```
npx create-react-app 3d-model-in-reactjs
```

You can name your application as you wish for this tutorial I have kept it as "3d-mode-in-reactjs".

> Here the **npx** is a utility that comes when you install the npm, It helps us to run any npm package available on npm registry without installing that package.

Let's install required libraries to render 3D model.
Change the directory to "3d-mode-in-reactjs" using the following command.

```
cd 3d-mode-in-reactjs
```
Use the following command to install two libraries the [@react-three/fiber](https://github.com/pmndrs/react-three-fiber) and [@react-three/drei](https://github.com/pmndrs/drei).

```
npm install @react-three/fiber @react-three/drei
```
- `@react-three/fiber`: It is a React renderer for threejs.

- `@react-three/drei`: It is a collection of useful helpers and fully functional, ready-made abstractions for @react-three/fiber.

For this tutorial we are going to use a 3D model of Apple iPhone 13 Pro Max. You can get this model from the following link👇. 

- ["Apple iPhone 13 Pro Max"](https://skfb.ly/o7nDN) by DatSketch is licensed under [Creative Commons Attribution](http://creativecommons.org/licenses/by/4.0/). Before you use this model in any project make sure to check it's license. 
 
Open the given link and download the model in `gltf` format.
Why GLTF? As per the threejs [documentation](https://threejs.org/docs/index.html#manual/en/introduction/Loading-3D-models) *glTF is focused on runtime asset delivery, it is compact to transmit and fast to load.*

Once you download the file, create one folder called **assets** inside the **src** folder and extract all the model file under folder called **3D-Model**.

Open the `App.css` file and replace all code with the following css.

```
.App {
  width: 100vw;
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
}

```
Now we are ready to render the model.

## Let's understand the basics of rendering a 3D model

Now there are 3 things that you have to keep in mind while rendering a model.

1. scene: Here you can setup all objects, lights and cameras.
2. camera: It is used to view the 3D model through different angels.
3. renderer: It is used to display/render a scene on an HTML element called `canvas`.

If you are directly using threejs in a plain JavaScript project then you might have to setup all these things from the basics, but in this tutorial we are using `@react-three/fiber` and `@react-three/drei` so we don't have to do all the things from scratch.

Open the `App.js` file, clean up the default code and let's import the `canvas` element from `@react-three/fiber`. Checkout the following code snippet.

```
import "./App.css";
import { Canvas } from "@react-three/fiber";

function App() {
  return (
    <div className="App">
      <Canvas>{/* Here we will render out model */}</Canvas>
    </div>
  );
}

export default App;
```
Here the `Canvas` component sets up the `scene` and the `camera` and renders `scene` every frame.

Now copy the following code inside the `<Canvas />` component.

```
<Canvas>
  <mesh>
    <boxGeometry />
    <meshStandardMaterial />
  </mesh>
</Canvas>
```

Let's understand each of these elements.

- `<mesh>`: A *mesh* is a class that inherits from Object3d and it represents polygon objects. In the mesh you can instantiate the polygon object by using [Geometry](https://threejs.org/docs/?q=geomet#api/en/geometries/BoxGeometry) and [Material](https://threejs.org/docs/?q=materia#api/en/materials/Material).

- `<boxGeometry />`: It is a geometry class for a rectangular cuboid with a given 'width', 'height', and 'depth'
 
- `<meshStandardMaterial />`: It is a standard physically based material. 

For now you might see one black square in the middle that does not look like a 3D object. 

![Output of mesh element](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7r7lh8o0c3k4jjyiscj5.png)

Let's add controls so that we can move the camera angle around this 3D object. Import the `<OrbitControls />` from the `@react-three/drei` by using the following line.

```
import { OrbitControls } from "@react-three/drei";
```
Now render this `<OrbitControls  />` inside the `<Canvas>` components and after the `<mesh>`. Refresh the development server page and try to grab the object. Now you might be able to see this square as an 3D object. This `<OrbitControls  />` allow the camera to orbit around a target.

Now the object is total black because there is no source of light. So let's add lights in our scene. Inside the `<Canvas />` component add the following line before the `<mesh>`.

```
<ambientLight />
```
Here this `ambientLight` globally illuminates all objects in the scene equally. Now you are able see the off-white color of the mesh material. We can also change the intensity of ambient light through props as shown in the following code.

```
<ambientLight intensity={1.25} />
```
You can also change the color of 3D object by using `color` prop in the `<meshStandardMaterial />`. checkout the following line.

```
<meshStandardMaterial color="green"/>
```

Now the color of the 3D object is green. There are lot of different lights and elements are available which you can use to create whole model. For that you can refer the documentation of [threejs](https://threejs.org/docs/index.html#manual/en/introduction/Creating-a-scene). That's it for the basics not let's render our iPhone.

## Converting model to JSX component

Open the model files and you will see different files like *textures*, *scene.gltf*, *scene.bin* etc. We will convert *scene.gltf* into a JSX component so that we can easily render it in our React application.

Now to convert any GLTF files to JSX component we will use one simple command line tool called as [gltfjsx](https://github.com/pmndrs/gltfjsx). As per the documetation the `gltfjsx` is a small command-line tool that turns GLTF assets into declarative and re-usable react-three-fiber JSX components.

Now open the terminal/cmd and go to the directory where you have stored all the model files, in my case it is inside the *3D-Model* folder which is in the *assets* folder. So I will use the following command to change the directory.

```
cd src/assets/3D-Model
```

Now use the following command.

```
npx gltfjsx scene.gltf
```

This command will take few seconds and returns the *Scene.js* file which is the JSX component.
 
> NOTE: This gltfjsx command might give you an error if you are using latest NodeJS version. I'm currently using 17.2.0 and this command is working fine. If you face any error please downgrade your NodeJs version and try this code again. You can use tools like [nvm](https://github.com/nvm-sh/nvm) to use different versions of the NodeJs.

### Important!

Before we render the model from *Scene.js* file we have to copy the model files into *public* directory since if you look in the *Scene.js* file it uses `useGLTF` hook which loads nodes and materials from `/scene.gltf` file. So copy *textures*, *scene.bin* and *scene.gltf* into *public* folder of your project. 

## Rendering the 3D model

Open the *App.js* file and remove the `<mesh>`. Let's import the `Model` from *Scene.js* file.

```
import Model from "./assets/3D-Model/Scene";
```
Now render the `<Model />` inside the `<Canvas />` component, before the `<OrbitControls />`. 

```
<Canvas>
  <ambientLight intensity={1.25} />
     <Model />
  <OrbitControls />
</Canvas>
```

Refresh the output page. Now you should be able to see the iphone rendering on the screen, you can zoom in and zoom out and move the model. Let's increase the view of the model. You can directly access the camera from the canvas element. Add the camera inside canvas as the following code snippet.

`
<Canvas camera={{fov: 18}}>
`
Here the `fov` stands for the "field of view". After setting the `fov` refresh the page to see the output. For now we have set the `fov` to 18. You can try different numbers and see the output.

For now there is no reflection on the model. To add reflection on the model you have to set images around this model so that these images can reflect on the surface of this model. Instead of adding these images let's use `<Environment />` [component](https://github.com/pmndrs/drei#environment) from the `@react-three/drei` library. 

Let's import the `<Environment />`,

```
import { Environment, OrbitControls } from "@react-three/drei";
```
Now after the model, let's add the Environment.

```
<Environment preset="sunset" />
```

Here the preset sets different types of environment surrounding the model. For now we have set it to "sunset". You can check the different presets available from [here](https://github.com/pmndrs/drei/blob/master/src/helpers/environment-assets.ts).

After adding this environment you should see the beautiful reflection on our iPhone. Let's render out model inside the `Suspense` component of the React so that it can load asynchronously. 

```
<Suspense fallback={null}>
   <Model />
</Suspense>
```

Here is the final code. 

{% gist https://gist.github.com/codebucks27/6defde4db7e290d95d7ff1ae39078a06 %}

## Final Thoughts 

That's the end of this tutorial. You can use https://docs.pmnd.rs/ to read the documentation of the `@react-three/fiber` and `@react-three/drei` and try different elements.

If you want to create full fledge website using the 3D model and animate it's colors then you can follow the video tutorial given at the start of this lesson. 

If you like this tutorial then you should checkout awesome tutorials I have on my YouTube channel called **CodeBucks**. You can check it from [here](https://www.youtube.com/codebucks).

### You might also like these website templates:

- A beautiful portfolio template in ReactJS => [here](https://codebucks.gumroad.com/l/hsTPD)
- NFT collection landing page in ReactJS => [here](- A beautiful portfolio template in ReactJS => [here](https://codebucks.gumroad.com/l/hsTPD))

Thank you for reading this tutorial. Have a great day!