preface

I think three.js is a great framework, and the reason for that is that it allows us to easily create 3d worlds, even as if I were writing this tutorial to create a solar system in which you are the creator. Ha ha! Seems to say a little kua!!

Complete 3d solar system effect

Understand some basic astronomy knowledge

Before you learn how to create this three-dimensional solar system, let’s take a look at some basic astronomy: the solar system has eight planets, in order of distance from the sun: Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, and Neptune. Most of the eight planets rotate in the same direction as the revolution. The only exceptions are Venus and Uranus. Venus rotates in the opposite direction of its revolution. Uranus, on the other hand, “rolls” in its orbit. For example, the earth rotates for 23.9 hours a day and 365.2 days a year, while neighboring Mars rotates for 24.6 hours a day and 687 days a year. Other planets also have different information about their revolutions and rotations, which can be used to define some basic rules

Understand the Three Framework

Some basic concepts of “Three” are also briefly introduced in the article of creating “Three.js 3D car showroom” in the simplest way. In order to deepen students’ understanding, the author will give an example of the solar system

  1. scenarioSenceSimilar to the solar system, there are countless galaxies in the universe, such as the solar system now, and we can add other galaxies later, it is not forever can not be added o(╥ haze ╥) O
  2. The cameraCarmaIt’s the equivalent of the Hubble Space Telescope
  3. geometryGeometryEquivalent to the sun and eight planets
  4. controlControlsYou are the creator

So with these concepts in mind, let’s create some one-to-one mappings

Full effect

Enter the tutorial

Let’s introduce the objects that Three uses

  import {
        Group,
        Mesh,
        MeshBasicMaterial,
        PerspectiveCamera,
        PointCloud,
        PointCloudMaterial,
        Scene,
        SphereGeometry,
        TextureLoader,
        Vector3,
        WebGLRenderer
    } from 'three'
     import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls.js'

Copy the code

Scene (solar system), Camera (Hubble), control (Creator)

/ / the scene
const setScene = () = > {
        scene = new Scene()
        renderer = new WebGLRenderer({
            antialias: true,
        })
        renderer.setSize(innerWidth, innerHeight)
        document.querySelector('#planet').appendChild(renderer.domElement)
    }
/ / camera
const setCamera = () = > {
        camera = new PerspectiveCamera(60, innerWidth / innerHeight, 1.100000)
        camera.position.set(0.500.2000)
        camera.lookAt(scene.position)
    }
/ / control
 const setControls = () = > {
        controls = new OrbitControls(camera, renderer.domElement)
    }        
Copy the code

Create a solar system background (stars background)

The star in the Sky effect is the background of the solar system, and when applied to the particle system of Three, the density of the planet can be adjusted by itself

 const starForge = () = > {
        const starQty = 10000
        const geometry = new SphereGeometry(10000.100.50)
        const materialOptions = {}
        const starStuff = new PointCloudMaterial(materialOptions)
        geometry.vertices = []
        for (let i = 0; i < starQty; i++) {
            let starVertex = new Vector3()
            starVertex.x = Math.random() * 20000 - 10000
            starVertex.y = Math.random() * 20000 - 10000
            starVertex.z = Math.random() * 20000 - 10000
            geometry.vertices.push(starVertex)
        }
        const stars = new PointCloud(geometry, starStuff)
        scene.add(stars)
    }
Copy the code

The effect is as follows:

Before we create the sun and the planets, let’s talk about how the planets rotate at the same time

Rotation mode: There are three ways to realize the rotation function

  1. Rotating camera
  2. Rotate the whole Scene
  3. Rotate a single element

Because each of our planets spins at a different rate, a different speed. It is not feasible to set the whole rotation, so set a different rotation attribute for each element.

In order for the planets to go around the sun, they have to set themselves a position shift. For example, mercury: mercury.position.x -= 300. When you set the mercury.rotation. Because its Y-axis position has changed.

When we move Mercury, the position of Mercury arent does not change, and its Y-axis does not change, and since mercuryParent contains Mercury, when we rotate mercuryParent, mercury will rotate around the original default Y-axis. So the idea is to set up so that each planet rotates simultaneously at different speeds and orbits. As for setting the following code values, it is roughly defined in terms of how long it takes a planet to rotate in a day or a year.

// Set the revolution function
const revolution = () = > {
        mercuryParent.rotation.y += 0.015
        venusParent.rotation.y += 0.0065
        earthParent.rotation.y += 0.05
        marsParent.rotation.y += 0.03
        jupiterParent.rotation.y += 0.001
        saturnParent.rotation.y += 0.02
        uranusParent.rotation.y += 0.09
        neptuneParent.rotation.y += 0.001
    }
    // Set the rotation function
    const selfRotation = () = > {
        sun.rotation.y += 0.004
        mercury.rotation.y += 0.002
        venus.rotation.y += 0.005
        earth.rotation.y += 0.01
        mars.rotation.y += 0.01
        jupiter.rotation.y += 0.08
        saturn.rotation.y += 1.5
        uranus.rotation.y += 1
        neptune.rotation.y += 0.1
    }
Copy the code

Create the sun and eight planets

Create galaxy using geometry sphere + texture map

First of all, let’s introduce how the sun is created. Create a sphere using SphereGeometry and add texture using MeshBasicMaterial. The sun has the largest mass, so when you set the sphere, the value is the largest. Below is a texture map of the sun

  // Add the setting sun
    let sun, sunParent
    const setSun = () = > {
        sun = new Group()// Create a group
        sunParent = new Group()
        scene.add(sunParent) // Add the groups to the scene
        loader.load('src/assets/universe/sun.jpg'.(texture) = > {
            const geometry = new SphereGeometry(500.20.20) // The sphere model
            const material = new MeshBasicMaterial({map: texture}) // Make the picture into a material THREE can understand
            const mesh = new Mesh(geometry, material)  // The first parameter of the mesh object is the geometry (structure), and the second parameter is the material (appearance).
            sun.add(mesh)// Add to the group
            sunParent.add(sun)
        })
    }

Copy the code

One by one, according to the closest to the sun

Create a mercury

Mercury is closest to the sun and has the smallest mass of all the planets, so the sphere is also given a minimum value. Below is a Mercury texture map

 let mercury, mercuryParent
    const setMercury = () = > {
        mercury = new Group()
        mercuryParent = new Group()
        scene.add(mercuryParent)
        loader.load('src/assets/universe/mercury.jpg'.(texture) = > {
            const geometry = new SphereGeometry(25.20.20) // The sphere model
            const material = new MeshBasicMaterial({map: texture}) // Make the picture into a material THREE can understand
            const mesh = new Mesh(geometry, material)  // The first parameter of the mesh object is the geometry (structure), and the second parameter is the material (appearance).
            mercury.position.x -= 600
            mercury.add(mesh)// Add to the group
            mercuryParent.add(mercury)
        })
    }
Copy the code

Create a Venus

O(∩_∩)O haha ~ should be below, this is the Venus planet texture map, do not use wrong yo!!

  let venus, venusParent
    const setVenus = () = > {
        venus = new Group()// Create a group
        venusParent = new Group()
        scene.add(venusParent)
        loader.load('src/assets/universe/venus.jpg'.(texture) = > {
            const geometry = new SphereGeometry(100.20.20) // The sphere model
            const material = new MeshBasicMaterial({map: texture}) // Make the picture into a material THREE can understand
            const mesh = new Mesh(geometry, material)  // The first parameter of the mesh object is the geometry (structure), and the second parameter is the material (appearance).
            venus.position.x -= 700
            venus.add(mesh)// Add to the group
            venusParent.add(venus)
        })
    }

Copy the code

The earth

How w can not our home, such a beautiful home to protect it ah!

let earth, earthParent
    const setEarth = () = > {
        earth = new Group()// Create a group
        earthParent = new Group()
        scene.add(earthParent)
        loader.load('src/assets/universe/earth.jpg'.(texture) = > {
            const geometry = new SphereGeometry(100.20.20) // The sphere model
            const material = new MeshBasicMaterial({map: texture}) // Make the picture into a material THREE can understand
            const mesh = new Mesh(geometry, material)  // The first parameter of the mesh object is the geometry (structure), and the second parameter is the material (appearance).
            earth.position.x -= 900
            earth.add(mesh)// Add to the group
            earthParent.add(earth)
        })
    }
Copy the code

Mars, Jupiter, Saturn, Uranus, Neptune

The following planetary Settings are similar, with different Settings for revolution, rotation, and the size of the planet.

Then the corresponding planet texture map is also sent to you one by one

Mars texture map

Jupiter texture map

Saturn texture map

Uranus texture map

Neptune texture map

The last

A three-dimensional solar system is created, this example is also very suitable for beginners of three.js students, the purpose is to improve the interest in three-dimensional, improve their sense of achievement. Of course, we can also add some functions on this example, such as locating and marking the information of some planets, clicking on the planets can enter the interior of the planets, and making a VR panoramic effect with the sky box, etc. In addition, it is not easy to find these planet texture maps, especially when looking for Venus 😏, I hope you can give a praise if you like this article, when encourage. I will create more good articles for you in the future, thank you!! ^_^

Complete code on

<template>
    <div id="planet">

    </div>
</template>
<script setup>
    import {onMounted} from 'vue'
    import {
        Group,
        Mesh,
        MeshBasicMaterial,
        PerspectiveCamera,
        PointCloud,
        PointCloudMaterial,
        Scene,
        SphereGeometry,
        TextureLoader,
        Vector3,
        WebGLRenderer
    } from 'three'
    import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls.js'

    const loader = new TextureLoader() // Import the loader instance of the model
    let scene, camera, renderer, group, controls // Define all three instance variables

    // Create the scene
    const setScene = () = > {
        scene = new Scene()
        renderer = new WebGLRenderer({
            antialias: true,
        })
        renderer.setSize(innerWidth, innerHeight)
        document.querySelector('#planet').appendChild(renderer.domElement)
    }

    // Create the camera
    const setCamera = () = > {
        camera = new PerspectiveCamera(60, innerWidth / innerHeight, 1.100000)
        camera.position.set(0.500.2000)
        camera.lookAt(scene.position)
    }

    // Set model control
    const setControls = () = > {
        controls = new OrbitControls(camera, renderer.domElement)
    }
    
    // Add the setting sun
    let sun, sunParent
    const setSun = () = > {
        sun = new Group()// Create a group
        sunParent = new Group()
        scene.add(sunParent) // Add the groups to the scene
        loader.load('src/assets/universe/sun.jpg'.(texture) = > {
            const geometry = new SphereGeometry(500.20.20) // The sphere model
            const material = new MeshBasicMaterial({map: texture}) // Make the picture into a material THREE can understand
            const mesh = new Mesh(geometry, material)  // The first parameter of the mesh object is the geometry (structure), and the second parameter is the material (appearance).
            sun.add(mesh)// Add to the group
            sunParent.add(sun)
        })
    }

    // Set Mercury
    let mercury, mercuryParent
    const setMercury = () = > {
        mercury = new Group()// Create a group
        mercuryParent = new Group()
        scene.add(mercuryParent)
        loader.load('src/assets/universe/mercury.jpg'.(texture) = > {
            const geometry = new SphereGeometry(25.20.20) // The sphere model
            const material = new MeshBasicMaterial({map: texture}) // Make the picture into a material THREE can understand
            const mesh = new Mesh(geometry, material)  // The first parameter of the mesh object is the geometry (structure), and the second parameter is the material (appearance).
            mercury.position.x -= 600
            mercury.add(mesh)// Add to the group
            mercuryParent.add(mercury)
        })
    }

    // Set Venus
    let venus, venusParent
    const setVenus = () = > {
        venus = new Group()// Create a group
        venusParent = new Group()
        scene.add(venusParent)
        loader.load('src/assets/universe/venus.jpg'.(texture) = > {
            const geometry = new SphereGeometry(100.20.20) // The sphere model
            const material = new MeshBasicMaterial({map: texture}) // Make the picture into a material THREE can understand
            const mesh = new Mesh(geometry, material)  // The first parameter of the mesh object is the geometry (structure), and the second parameter is the material (appearance).
            venus.position.x -= 700
            venus.add(mesh)// Add to the group
            venusParent.add(venus)
        })
    }
    // Set the earth
    let earth, earthParent
    const setEarth = () = > {
        earth = new Group()// Create a group
        earthParent = new Group()
        scene.add(earthParent)
        loader.load('src/assets/universe/earth.jpg'.(texture) = > {
            const geometry = new SphereGeometry(100.20.20) // The sphere model
            const material = new MeshBasicMaterial({map: texture}) // Make the picture into a material THREE can understand
            const mesh = new Mesh(geometry, material)  // The first parameter of the mesh object is the geometry (structure), and the second parameter is the material (appearance).
            earth.position.x -= 900
            earth.add(mesh)// Add to the group
            earthParent.add(earth)
        })
    }
// Set Mars
    let mars, marsParent
    const setMars = () = > {
        mars = new Group()// Create a group
        marsParent = new Group()
        scene.add(marsParent)
        loader.load('src/assets/universe/mars.jpg'.(texture) = > {
            const geometry = new SphereGeometry(85.20.20) // The sphere model
            const material = new MeshBasicMaterial({map: texture}) // Make the picture into a material THREE can understand
            const mesh = new Mesh(geometry, material)  // The first parameter of the mesh object is the geometry (structure), and the second parameter is the material (appearance).
            mars.position.x -= 1200
            mars.add(mesh)// Add to the group
            marsParent.add(mars)
        })
    }

    // Set Jupiter
    let jupiter, jupiterParent
    const setJupiter = () = > {
        jupiter = new Group()// Create a group
        jupiterParent = new Group()
        scene.add(jupiterParent)
        loader.load('src/assets/universe/jupiter.jpg'.(texture) = > {
            const geometry = new SphereGeometry(150.20.20) // The sphere model
            const material = new MeshBasicMaterial({map: texture}) // Make the picture into a material THREE can understand
            const mesh = new Mesh(geometry, material)  // The first parameter of the mesh object is the geometry (structure), and the second parameter is the material (appearance).
            jupiter.position.x -= 1500
            jupiter.add(mesh)// Add to the group
            jupiterParent.add(jupiter)
        })
    }

    // Set Saturn
    let saturn, saturnParent
    const setSaturn = () = > {
        saturn = new Group()// Create a group
        saturnParent = new Group()
        scene.add(saturnParent)
        loader.load('src/assets/universe/saturn.jpg'.(texture) = > {
            const geometry = new SphereGeometry(120.20.20) // The sphere model
            const material = new MeshBasicMaterial({map: texture}) // Make the picture into a material THREE can understand
            const mesh = new Mesh(geometry, material)  // The first parameter of the mesh object is the geometry (structure), and the second parameter is the material (appearance).
            saturn.position.x -= 1800
            saturn.add(mesh)// Add to the group
            saturnParent.add(saturn)
        })
    }

    // Set Uranus
    let uranus, uranusParent
    const setUranus = () = > {
        uranus = new Group()
        uranusParent = new Group()
        scene.add(uranusParent)
        loader.load('src/assets/universe/uranus.jpg'.(texture) = > {
            const geometry = new SphereGeometry(50.20.20) // The sphere model
            const material = new MeshBasicMaterial({map: texture}) // Make the picture into a material THREE can understand
            const mesh = new Mesh(geometry, material)  // The first parameter of the mesh object is the geometry (structure), and the second parameter is the material (appearance).
            uranus.position.x -= 2100
            uranus.add(mesh)// Add to the group
            saturnParent.add(uranus)
        })
    }

    // Set Neptune
    let neptune, neptuneParent
    const setNeptune = () = > {
        neptune = new Group()
        neptuneParent = new Group()
        scene.add(neptuneParent)
        loader.load('src/assets/universe/neptune.jpg'.(texture) = > {
            const geometry = new SphereGeometry(50.20.20) // The sphere model
            const material = new MeshBasicMaterial({map: texture}) // Make the picture into a material THREE can understand
            const mesh = new Mesh(geometry, material)  // The first parameter of the mesh object is the geometry (structure), and the second parameter is the material (appearance).
            neptune.position.x -= 2300
            neptune.add(mesh)// Add to the group
            neptuneParent.add(neptune)
        })
    }

// Listen to the browser change the size and re-render
    function onWindowResize() {
        const WIDTH = window.innerWidth,
            HEIGHT = window.innerHeight
        camera.aspect = WIDTH / HEIGHT
        camera.updateProjectionMatrix()
        renderer.setSize(WIDTH, HEIGHT)
    }

// Set the revolution function
    const revolution = () = > {
        mercuryParent.rotation.y += 0.015
        venusParent.rotation.y += 0.0065
        earthParent.rotation.y += 0.05
        marsParent.rotation.y += 0.03
        jupiterParent.rotation.y += 0.01
        saturnParent.rotation.y += 0.02
        uranusParent.rotation.y += 0.09
        neptuneParent.rotation.y += 0.01
    }

    // Set rotation
    const selfRotation = () = > {
        sun.rotation.y += 0.004
        mercury.rotation.y += 0.002
        venus.rotation.y += 0.005
        earth.rotation.y += 0.01
        mars.rotation.y += 0.01
        jupiter.rotation.y += 0.08
        saturn.rotation.y += 1.5
        uranus.rotation.y += 1
        neptune.rotation.y += 0.1
    }

    // Set the solar system background
    const starForge = () = > {
        const starQty = 10000
        const geometry = new SphereGeometry(10000.100.50)
        const materialOptions = {}
        const starStuff = new PointCloudMaterial(materialOptions)
        geometry.vertices = []
        for (let i = 0; i < starQty; i++) {
            let starVertex = new Vector3()
            starVertex.x = Math.random() * 20000 - 10000
            starVertex.y = Math.random() * 20000 - 10000
            starVertex.z = Math.random() * 20000 - 10000
            geometry.vertices.push(starVertex)
        }
        const stars = new PointCloud(geometry, starStuff)
        scene.add(stars)
    }


    // Loop scene, camera, and position updates
    const loop = () = > {
        requestAnimationFrame(loop)
        revolution()
        selfRotation()
        renderer.render(scene, camera)
        camera.lookAt(scene.position)
    }

  // Initialize all functions
    const init = () = > {
        setScene() // Set the scene
        setCamera() // Set the camera
        setSun() // Set the sun
        setMercury() // Set Mercury
        setVenus() // Set Venus
        setEarth() / / the earth
        setMars() / / Mars
        setJupiter() / / Jupiter
        setSaturn() / / Saturn
        setUranus()/ / Uranus.
        setNeptune()/ / Neptune
        starForge()// Set the Skystar background
        setControls() // Set the rotatable control
        loop() // Loop animation
    }

    onMounted(init)
    window.addEventListener('resize', onWindowResize)

</script>



Copy the code