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
- scenario
Sence
Similar 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 - The camera
Carma
It’s the equivalent of the Hubble Space Telescope - geometry
Geometry
Equivalent to the sun and eight planets - control
Controls
You 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
- Rotating camera
- Rotate the whole Scene
- 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