As long as I can remember, I have always been attracted by Space. But then i heard about programming...
Hy there! Today we will create mars planet using three.js and react-three-fiber.
What are three.js and react-three-fiber?
This tutorial is for those who already know the basics of three.js. There i won't go into details since there are already so many introductory guides. Today i want to focus on practise.
But in brief:
- three.js β it's JavaScript library for creating 3D graphics.
- react-three-fiber β is a React renderer for three.js on the web and react-native.
Here we go!
First! The structure of our files in this guide:
Now let's dwell on the details. In our project, we need to create three main components:
- Sphere β this will be the planet Mars
- SkyBox β this is our space, we will use
CubeTextureLoader()
to create it. For this component we need to get 6 images for the background of each side of the cube. - CameraControls β very important component. This will give us the ability to rotate and scale our Sphere (Mars) as we want.
Sphere creating
Let's start with the Sphere component:
import React, { useRef } from "react"; import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader"; import { useFrame, useLoader } from "react-three-fiber"; const Sphere = () => { const planet = useRef(); const { nodes } = useLoader(GLTFLoader, "models/mars.glb"); useFrame(() => (planet.current.rotation.y += 0.0002)); return ( <mesh ref={planet} visible position={[0, 0, 0]} // Adding data from mars.glb to the geometry and material of the sphere geometry={nodes.Cube008.geometry} material={nodes.Cube008.material} /> ); }; export default Sphere; ``` We are using a ready-made gltf 3D file that creates the geometry and material for our sphere. We can get it from [the official NASA website](https://solarsystem.nasa.gov/resources/2372/mars-3d-model/). To work with the gltf file we use the [GLTFLoader](https://threejs.org/docs/#examples/en/loaders/GLTFLoader) from three.js and the `useLoader()` hook from react-three-fiber. Also we use the `useFrame()` hook that add rotation for our planet. ### **SkyBox creating** Notice how SkyBox returns null this is because we will not be creating any new objects with this component in our scene. Instead, we will use it as a controller to set a property in our scene, as we will see in the next step when we load and apply the skybox textures. ```javascript import { useThree } from "react-three-fiber"; import { CubeTextureLoader } from "three"; // Loads the skybox texture and applies it to the scene. const SkyBox = () => { const { scene } = useThree(); const loader = new CubeTextureLoader(); // The CubeTextureLoader load method takes an array of urls representing all 6 sides of the cube. const texture = loader.load([ "/images/front.jpg", "/images/back.jpg", "/images/top.jpg", "/images/bottom.jpg", "/images/left.jpg", "/images/right.jpg", ]); // Set the scene background property to the resulting texture. scene.background = texture; return null; }; export default SkyBox; ``` To start we need to get a reference of our Three.JS scene and for that we use `useThree()` hook. Then we create an instance of the CubeTextureLoader and then call the load method with an array containing the six URLs of your images. This will return a CubeTexture. The CubeTexture we assign to the global `scene.background` which we get a reference to with `useThree()`, and that's it our skybox is finished. ### **Skybox Textures** Also important to talk about Skybox textures creating. For this purpose i was using [Spacescape](http://alexcpeterson.com/spacescape/) program. This is a simple space landscape generator. You can use it or create assets in Photoshop or something. ### **Camera Controls** And the last thing about camera control. Here we are using [OrbitControls](https://threejs.org/docs/#examples/en/controls/OrbitControls), which allows the camera to rotate around the target. ```javascript import React, { useRef } from "react"; import { extend, useThree, useFrame } from "react-three-fiber"; import { OrbitControls } from "three/examples/jsm/controls/OrbitControls"; extend({ OrbitControls }); const CameraControls = () => { const { camera, gl: { domElement }, } = useThree(); // Ref to the controls, so that we can update them on every frame with useFrame const controls = useRef(); camera.position.z = 999; useFrame(() => controls.current.update()); return ( <orbitControls ref={controls} args={[camera, domElement]} autoRotate={false} enableZoom={false} /> ); }; export default CameraControls; ``` ### **Finish** Now we can use all created components in to the App component: ```javascript import React, { Suspense } from "react"; import { Canvas } from "react-three-fiber"; import "./styles.css"; import { CameraControls, Sphere, SkyBox } from "./components"; const App = () => { return ( <> <Canvas className="canvas"> <CameraControls /> <directionalLight intensity={1} /> <ambientLight intensity={0.6} /> <Suspense fallback="loading"> <Sphere /> </Suspense> <SkyBox /> </Canvas> </> ); }; export default App; ``` And also add Styles in to styles.css: ```css * { box-sizing: border-box; } html, body, #root { width: 100%; height: 100%; margin: 0; padding: 0; } ``` **Well that's all. Thanks for reading =)**
Top comments (1)
i love this...