教你如何用Three.js创造一个三维太阳系

这篇教程详细介绍了如何使用Three.js框架创建一个三维太阳系。从了解天文知识开始,然后逐步讲解如何构建场景、设置相机、创建背景、定义行星的自转和公转规律,到最后制作太阳和八大行星,包括它们的纹理贴图。教程适合初学者,旨在提升对三维编程的兴趣和成就感。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

笔者认为Three.js是一个伟大的框架,为什么这样说,因为它可以让我们轻易创造三维世界,甚至好像笔者写这遍教程,可以创造一个太阳系,在这个三维世界里你就是创世主。哈哈!好像说得有点夸!!

了解一些基本天文知识

学习创造这个三维太阳系之前先了解一下基本的天文知识:太阳系有“八大行星”,按照离太阳的距离从近到远,它们依次为水星、金星、地球、火星、木星、土星、天王星、海王星。八大行星自转方向多数也和公转方向一致。只有金星和天王星两个例外。金星自转方向与公转方向相反。而天王星则是在轨道上“横滚”的。例如地球自转一天是23.9小时,公转一年有365.2天 ,而相邻的火星自转一天是24.6小时 公转一年则有687天,其他行星也有不同的公转和自转信息,有了这些信息就可以定义一些基本规则

image.png

了解Three框架

Three的一些基本概念我在用最简单方式打造Three.js 3D汽车展示厅一文也粗略介绍一下,为了让同学们加深理解,笔者就相对于太阳系来比如一下

  1. 场景 Sence 相当于太阳系,宇宙中有无数星系,比如现在说的太阳系,后续还可以增加其他星系,那不是永远都加不完的呀 o(╥﹏╥)o
  2. 相机 Carma 相当一枚哈勃天文望远镜
  3. 几何体 Geometry 相当于太阳和八大行星
  4. 控制 Controls 相当”创世者“的你

有了这几个概念我们就创建一些函数一一对应

完整效果

屏幕录制2021-07-12 下午2.34.26.gif

进入教程

先引入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)
    }

效果如下图:

image.png

创建太阳和行星前先说说行星自转同时公转的规律

屏幕录制2021-07-12 上午11.23.20.gif

旋转方式:实现旋转功能有三种方式

  1. 旋转照相机
  2. 旋转整个场景(Scene)
  3. 旋转单个元素

因为我们这里每个行星的自转速度,公转速度都不一样。所以设置整体旋转并不可行,所以要给每个元素设置不同的旋转属性。

行星需要让它们围绕着太阳转,就要先给它们自身设置一个位置偏移。以水星为例:mercury.position.x -= 300,而此时设置mercury.rotation.y属性,它就会实现自转。因为它的Y轴位置已经改变了。

当我们移动了mercury时,mercuryParent的位置是没有变的,自然它的Y轴也不会变,又因为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添加纹理,太阳是质量是最大的,所以设置球体的时候数值是最大。 下图是太阳的纹理贴图

sun.jpg

  // 添加设置太阳
    let sun, sunParent
    const setSun = () => {
   
   
        sun = new Group()//建立一个组
        sunParent = new Group()
        scene.add(sunParent) //把组都添加
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值