предисловие
Автор считает Three.js отличным фреймворком, почему я это говорю, потому что он позволяет нам легко создавать трехмерный мир, даже если автор написал этот урок, вы можете создать солнечную систему, в этом трехмерном мир ты создатель. Ха-ха! Кажется, это немного преувеличено! !
Полный эффект 3D солнечной системы
Изучите основы астрономии
Прежде чем научиться создавать эту трехмерную солнечную систему, сначала усвойте основные астрономические знания: в солнечной системе есть «восемь планет», а именно: Меркурий, Венера, Земля, Марс, Юпитер, Сатурн, Уран и Нептун в порядке убывания расстояния от них. солнце. Большинство направлений вращения восьми планет совпадают с направлениями их вращения. Единственными исключениями являются Венера и Уран. Венера вращается в направлении, противоположном ее вращению. Уран, напротив, «катится» по своей орбите. Например, вращение Земли составляет 23,9 часа в сутки, а ее оборот составляет 365,2 дня в году, тогда как вращение соседнего Марса составляет 24,6 часа в сутки, а его обращение составляет 687 дней в году.Другие планеты также имеют другую скорость вращения и вращения. С помощью этой информации вы можете определить некоторые основные правила
Узнайте о трех фреймворках
Некоторые основные концепции Three I am inСамый простой способ построить автосалон Three.js 3DВ этой статье также дается приблизительное введение.Чтобы углубить понимание учащихся, автор возьмет пример относительно Солнечной системы.
- Сцены
Sence
Это эквивалентно Солнечной системе. Во Вселенной существует бесчисленное множество галактик. Например, Солнечная система, о которой мы говорим сейчас. Другие галактики могут быть добавлены в будущем. Это не может добавляться вечно. o(╥﹏╥ )о - камера
Carma
Настоящий космический телескоп Хаббл - геометрия
Geometry
Эквивалент солнца и восьми планет - контроль
Controls
Вы прямо "создатель"
С помощью этих концепций мы создаем некоторые функции, которые взаимно однозначно соответствуют
полный эффект
Введите учебник
Сначала представим объекты, которые будут использоваться Three
import {
Group,
Mesh,
MeshBasicMaterial,
PerspectiveCamera,
PointCloud,
PointCloudMaterial,
Scene,
SphereGeometry,
TextureLoader,
Vector3,
WebGLRenderer
} from 'three'
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls.js'
Сцена (Солнечная система), Камера (телескоп Хаббл), Управление (Создатель)
//场景
const setScene = () => {
scene = new Scene()
renderer = new WebGLRenderer({
antialias: true,
})
renderer.setSize(innerWidth, innerHeight)
document.querySelector('#planet').appendChild(renderer.domElement)
}
//相机
const setCamera = () => {
camera = new PerspectiveCamera(60, innerWidth / innerHeight, 1, 100000)
camera.position.set(0, 500, 2000)
camera.lookAt(scene.position)
}
//控制
const setControls = () => {
controls = new OrbitControls(camera, renderer.domElement)
}
Создаем фон солнечной системы (звездный фон)
Этот эффект гипсофилы является фоном Солнечной системы.Применительно к системе частиц Three плотность планет может регулироваться сама по себе.
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)
}
Эффект следующий:
Прежде чем создавать солнце и планеты, поговорим о законе вращения планет и обращения одновременно.
Режим вращения: существует три способа реализации функции вращения.
- Повернуть камеру
- Повернуть всю сцену (Scene)
- Повернуть один элемент
Потому что скорость вращения и скорость обращения каждой планеты здесь разные. Таким образом, установка общего поворота невозможна, поэтому задайте разные свойства поворота для каждого элемента.
Планеты должны установить для себя позиционное смещение, чтобы они могли вращаться вокруг Солнца. Возьмем, к примеру, Меркурий:mercury.position.x -= 300
, при установкеmercury.rotation.y
собственности, он будет осуществлять вращение. Потому что его положение по оси Y изменилось.
когда мы переехалиmercury
час,mercuryParent
ПоложениеmercuryParent
содержитmercury
, так повернутьmercuryParent
час,mercury
Также вращается вокруг начальной оси Y по умолчанию. Таким образом, создание стольких групп означает одновременное вращение каждой планеты с разными скоростями и оборотами. Что касается установки следующих кодовых значений, то они приблизительно определяются в соответствии со временем, которое требуется планете, чтобы совершить один оборот за один день и один оборот за один год.
//设置公转函数
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
}
//设置自转函数
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
}
Создайте солнце и восемь планет
Создавайте галактики с помощью геометрических сфер + текстурных карт
Сначала поговорим о том, как создается, используется солнцеSphereGeometry
Создайте сферу, используяMeshBasicMaterial
Добавляя текстуры, солнце самое большое по массе, поэтому значение самое большое при настройке сферы. Изображение ниже представляет собой текстурную карту солнца.
// 添加设置太阳
let sun, sunParent
const setSun = () => {
sun = new Group()//建立一个组
sunParent = new Group()
scene.add(sunParent) //把组都添加到场景里
loader.load('src/assets/universe/sun.jpg', (texture) => {
const geometry = new SphereGeometry(500, 20, 20) //球体模型
const material = new MeshBasicMaterial({map: texture}) //材质 将图片解构成THREE能理解的材质
const mesh = new Mesh(geometry, material) //网孔对象 第一个参数是几何模型(结构),第二参数是材料(外观)
sun.add(mesh)//添加到组里
sunParent.add(sun)
})
}
Созданы один за другим в соответствии с ближайшими к солнцу
Создать Меркурий
Меркурий находится ближе всего к Солнцу и имеет наименьшую массу среди всех планет, поэтому значение сферы также имеет наименьшее значение. Текстурная карта Меркурия ниже
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) //球体模型
const material = new MeshBasicMaterial({map: texture}) //材质 将图片解构成THREE能理解的材质
const mesh = new Mesh(geometry, material) //网孔对象 第一个参数是几何模型(结构),第二参数是材料(外观)
mercury.position.x -= 600
mercury.add(mesh)//添加到组里
mercuryParent.add(mercury)
})
}
Создать Венеру
O(∩_∩)О, ха-ха~ Это должно быть изображение ниже, это карта текстуры планеты Венера, не используйте ее неправильно! !
let venus, venusParent
const setVenus = () => {
venus = new Group()//建立一个组
venusParent = new Group()
scene.add(venusParent)
loader.load('src/assets/universe/venus.jpg', (texture) => {
const geometry = new SphereGeometry(100, 20, 20) //球体模型
const material = new MeshBasicMaterial({map: texture}) //材质 将图片解构成THREE能理解的材质
const mesh = new Mesh(geometry, material) //网孔对象 第一个参数是几何模型(结构),第二参数是材料(外观)
venus.position.x -= 700
venus.add(mesh)//添加到组里
venusParent.add(venus)
})
}
земной шар
Как же нам не иметь своего дома, такой красивый дом нужно хорошо охранять! !
let earth, earthParent
const setEarth = () => {
earth = new Group()//建立一个组
earthParent = new Group()
scene.add(earthParent)
loader.load('src/assets/universe/earth.jpg', (texture) => {
const geometry = new SphereGeometry(100, 20, 20) //球体模型
const material = new MeshBasicMaterial({map: texture}) //材质 将图片解构成THREE能理解的材质
const mesh = new Mesh(geometry, material) //网孔对象 第一个参数是几何模型(结构),第二参数是材料(外观)
earth.position.x -= 900
earth.add(mesh)//添加到组里
earthParent.add(earth)
})
}
Марс, Юпитер, Сатурн, Уран, Нептун
Следующие настройки планет одинаковы, различаются только параметры вращения, вращения и размера планеты.
Затем карты текстур, соответствующие планетам, также рассылаются всем по очереди.
текстурная карта Марса
Текстурная карта Юпитера
Текстурная карта Сатурна
Текстурная карта Урана
Текстурная карта Нептуна
наконец
Была создана трехмерная солнечная система. Этот пример также очень подходит для студентов, которые только начали работать с three.js. Цель состоит в том, чтобы повысить их интерес к трехмерности и улучшить их чувство достижения. Конечно, мы также можем добавить некоторые функции в этот список, такие как позиционирование и маркировка информации о некоторых планетах, щелчок по планете, чтобы войти внутрь планеты, использование окна неба для создания эффекта панорамы VR и так далее. . Кроме того, моему брату нелегко найти эти карты текстур планет, особенно при поиске Венеры😏, я надеюсь, что если вам понравилась эта статья, вы можете поставить большой палец вверх и подбодрить меня. В будущем мой брат обязательно создаст для вас больше хороших статей, спасибо! ! ^_^
полный код
<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() //引入模型的loader实例
let scene, camera, renderer, group, controls // 定义所有three实例变量
// 创建场景
const setScene = () => {
scene = new Scene()
renderer = new WebGLRenderer({
antialias: true,
})
renderer.setSize(innerWidth, innerHeight)
document.querySelector('#planet').appendChild(renderer.domElement)
}
// 创建相机
const setCamera = () => {
camera = new PerspectiveCamera(60, innerWidth / innerHeight, 1, 100000)
camera.position.set(0, 500, 2000)
camera.lookAt(scene.position)
}
// 设置模型控制
const setControls = () => {
controls = new OrbitControls(camera, renderer.domElement)
}
// 添加设置太阳
let sun, sunParent
const setSun = () => {
sun = new Group()//建立一个组
sunParent = new Group()
scene.add(sunParent) //把组都添加到场景里
loader.load('src/assets/universe/sun.jpg', (texture) => {
const geometry = new SphereGeometry(500, 20, 20) //球体模型
const material = new MeshBasicMaterial({map: texture}) //材质 将图片解构成THREE能理解的材质
const mesh = new Mesh(geometry, material) //网孔对象 第一个参数是几何模型(结构),第二参数是材料(外观)
sun.add(mesh)//添加到组里
sunParent.add(sun)
})
}
// 设置水星
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) //球体模型
const material = new MeshBasicMaterial({map: texture}) //材质 将图片解构成THREE能理解的材质
const mesh = new Mesh(geometry, material) //网孔对象 第一个参数是几何模型(结构),第二参数是材料(外观)
mercury.position.x -= 600
mercury.add(mesh)//添加到组里
mercuryParent.add(mercury)
})
}
//设置金星
let venus, venusParent
const setVenus = () => {
venus = new Group()//建立一个组
venusParent = new Group()
scene.add(venusParent)
loader.load('src/assets/universe/venus.jpg', (texture) => {
const geometry = new SphereGeometry(100, 20, 20) //球体模型
const material = new MeshBasicMaterial({map: texture}) //材质 将图片解构成THREE能理解的材质
const mesh = new Mesh(geometry, material) //网孔对象 第一个参数是几何模型(结构),第二参数是材料(外观)
venus.position.x -= 700
venus.add(mesh)//添加到组里
venusParent.add(venus)
})
}
//设置地球
let earth, earthParent
const setEarth = () => {
earth = new Group()//建立一个组
earthParent = new Group()
scene.add(earthParent)
loader.load('src/assets/universe/earth.jpg', (texture) => {
const geometry = new SphereGeometry(100, 20, 20) //球体模型
const material = new MeshBasicMaterial({map: texture}) //材质 将图片解构成THREE能理解的材质
const mesh = new Mesh(geometry, material) //网孔对象 第一个参数是几何模型(结构),第二参数是材料(外观)
earth.position.x -= 900
earth.add(mesh)//添加到组里
earthParent.add(earth)
})
}
//设置火星
let mars, marsParent
const setMars = () => {
mars = new Group()//建立一个组
marsParent = new Group()
scene.add(marsParent)
loader.load('src/assets/universe/mars.jpg', (texture) => {
const geometry = new SphereGeometry(85, 20, 20) //球体模型
const material = new MeshBasicMaterial({map: texture}) //材质 将图片解构成THREE能理解的材质
const mesh = new Mesh(geometry, material) //网孔对象 第一个参数是几何模型(结构),第二参数是材料(外观)
mars.position.x -= 1200
mars.add(mesh)//添加到组里
marsParent.add(mars)
})
}
// 设置木星
let jupiter, jupiterParent
const setJupiter = () => {
jupiter = new Group()//建立一个组
jupiterParent = new Group()
scene.add(jupiterParent)
loader.load('src/assets/universe/jupiter.jpg', (texture) => {
const geometry = new SphereGeometry(150, 20, 20) //球体模型
const material = new MeshBasicMaterial({map: texture}) //材质 将图片解构成THREE能理解的材质
const mesh = new Mesh(geometry, material) //网孔对象 第一个参数是几何模型(结构),第二参数是材料(外观)
jupiter.position.x -= 1500
jupiter.add(mesh)//添加到组里
jupiterParent.add(jupiter)
})
}
// 设置土星
let saturn, saturnParent
const setSaturn = () => {
saturn = new Group()//建立一个组
saturnParent = new Group()
scene.add(saturnParent)
loader.load('src/assets/universe/saturn.jpg', (texture) => {
const geometry = new SphereGeometry(120, 20, 20) //球体模型
const material = new MeshBasicMaterial({map: texture}) //材质 将图片解构成THREE能理解的材质
const mesh = new Mesh(geometry, material) //网孔对象 第一个参数是几何模型(结构),第二参数是材料(外观)
saturn.position.x -= 1800
saturn.add(mesh)//添加到组里
saturnParent.add(saturn)
})
}
//设置天王星
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) //球体模型
const material = new MeshBasicMaterial({map: texture}) //材质 将图片解构成THREE能理解的材质
const mesh = new Mesh(geometry, material) //网孔对象 第一个参数是几何模型(结构),第二参数是材料(外观)
uranus.position.x -= 2100
uranus.add(mesh)//添加到组里
saturnParent.add(uranus)
})
}
//设置海王星
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) //球体模型
const material = new MeshBasicMaterial({map: texture}) //材质 将图片解构成THREE能理解的材质
const mesh = new Mesh(geometry, material) //网孔对象 第一个参数是几何模型(结构),第二参数是材料(外观)
neptune.position.x -= 2300
neptune.add(mesh)//添加到组里
neptuneParent.add(neptune)
})
}
//监听浏览器改变大小时重新渲染
function onWindowResize() {
const WIDTH = window.innerWidth,
HEIGHT = window.innerHeight
camera.aspect = WIDTH / HEIGHT
camera.updateProjectionMatrix()
renderer.setSize(WIDTH, HEIGHT)
}
//设置公转函数
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
}
//设置自转
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
}
// 设置太阳系背景
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)
}
// 循环场景 、相机、 位置更新
const loop = () => {
requestAnimationFrame(loop)
revolution()
selfRotation()
renderer.render(scene, camera)
camera.lookAt(scene.position)
}
//初始化所有函数
const init = () => {
setScene() //设置场景
setCamera() //设置相机
setSun() // 设置太阳
setMercury() //设置水星
setVenus() //设置金星
setEarth() // 地球
setMars() //火星
setJupiter() // 木星
setSaturn() // 土星
setUranus()// 天王星
setNeptune()//海王星
starForge()//设置满天星背景
setControls() //设置可旋转控制
loop() // 循环动画
}
onMounted(init)
window.addEventListener('resize', onWindowResize)
</script>