Three.js - 模拟太阳、地球、月亮的运动(十一)

简介

本节我们简单的模拟地球绕着太阳转,月球绕着地球转。从月球的角度看,它是在地球的 "局部空间 "中绕着地球转,地球和月球合成一组是在全局空间绕着太阳转。

基础场景

DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>学习title>
  head>
  <body>
    <canvas id="c2d" class="c2d" width="1000" height="500">canvas>
    <script type="module">
      // 官网地址
      import * as THREE from 'https://threejsfundamentals.org/threejs/resources/threejs/r132/build/three.module.js'
      import { OrbitControls } from 'https://threejsfundamentals.org/threejs/resources/threejs/r132/examples/jsm/controls/OrbitControls.js'

      const canvas = document.querySelector('#c2d')
      // 渲染器
      const renderer = new THREE.WebGLRenderer({ canvas, antialias: true })

      const fov = 40 // 视野范围
      const aspect = 2 // 相机默认值 画布的宽高比
      const near = 0.1 // 近平面
      const far = 1000 // 远平面
      // 透视投影相机
      const camera = new THREE.PerspectiveCamera(fov, aspect, near, far)

      // 相机位置
      camera.position.set(0, 0, 50)
      camera.up.set(0, 0, 1)
      camera.lookAt(0, 0, 0)
      // 控制相机
      const controls = new OrbitControls(camera, canvas)
      controls.update()

      // 纹理加载器
      const loader = new THREE.TextureLoader()
      // 创建场景
      const scene = new THREE.Scene()

      {
        const color = 0xffffff
        const intensity = 1
        // 创建光源
        const light = new THREE.PointLight(color, intensity)
        // 光源 加入场景
        scene.add(light)
      }

      function render(time) {
        time *= 0.001

        // 加载渲染器
        renderer.render(scene, camera)

        // 开始动画
        requestAnimationFrame(render)
      }

      // 开始渲染
      requestAnimationFrame(render)
    script>
  body>
html>

添加背景

  • 添加星空背景,修改背景展示图片纹理。
  const bgTexture = loader.load('../img/4.jpg')
  scene.background = bgTexture

Three.js - 模拟太阳、地球、月亮的运动(十一)_第1张图片

添加太阳

      // 物体网格对象
      const objects = []
      {
        // 一球多用
        const radius = 2
        const widthSegments = 36
        const heightSegments = 36
        const sphereGeometry = new THREE.SphereGeometry(radius, widthSegments, heightSegments)

        // 太阳
        const sunTexture = loader.load('../img/1.jpg')
        const sunMaterial = new THREE.MeshBasicMaterial({ map: sunTexture })
        const sunMesh = new THREE.Mesh(sphereGeometry, sunMaterial)
        // 放大3倍
        sunMesh.scale.set(3, 3, 3)
        scene.add(sunMesh)
        // 放入控制对象
        objects.push(sunMesh)
      }
  1. 创建一个球几何体,太阳、地球、月亮都是球形,我们可以公用一个球体。
  2. 使用基础材质加载太阳纹理。因为灯光是点光源,发光点在中心,太阳也在中心,使用其他材质是无法接收光源。
  3. 太阳比其他球体大,放大3倍。
    // 网格对象 旋转
    objects.forEach((obj) => {
      obj.rotation.y = time
    })
  1. 在渲染循环中添加,使网格对象(objects)中的物体旋转。

添加地球

    // 地球
    const earthTexture = loader.load('../img/3.jpg')
    const earthMaterial = new THREE.MeshPhongMaterial({
      map: earthTexture
    })
    const earthMesh = new THREE.Mesh(sphereGeometry, earthMaterial)
    earthMesh.position.x = 20
    scene.add(earthMesh)
    // 放入控制对象
    objects.push(earthMesh)
  • 这里重复使用sphereGeometry球几何体,创建.MeshPhongMaterial()材质。将其定位在太阳的左边 20个单位。

  1. 可以看到太阳和地球都在自转,但地球并没有绕着太阳转。
  2. 如果我们通过计算的方式修改地球的全局坐标围绕太阳转是可以的,但是这样很麻烦。这里我们添加一个新场景太阳系,把地球和太阳都放入场景中,旋转太阳系这个场景,因为太阳在中心,实现的效果就是地球围绕太阳转。
    屏蔽掉 太阳加入全局场景
    // scene.add(sunMesh) 
    屏蔽掉 地球加入全局场景
    // scene.add(earthMesh)

    // 太阳系 物体对象
    const solarSystem = new THREE.Object3D()
    scene.add(solarSystem)
    objects.push(solarSystem)

    solarSystem.add(sunMesh)
    solarSystem.add(earthMesh)

添加月球

  • 同样的月球要围绕地球转,添加一个地月系到太阳系中旋转。
    // earthMesh.position.x = 20
    // solarSystem.add(earthMesh)
     
    // 地月系 物体对象
    const landOrbit = new THREE.Object3D()
    landOrbit.position.x = 20
    solarSystem.add(landOrbit)
    objects.push(landOrbit)
  • 定位地月系位置到原来地球的位置放入太阳系中,取消地球的定位和取消放入太阳系中。
    // 月球
    const moonTexture = loader.load('../img/2.jpg')
    const moonMaterial = new THREE.MeshPhongMaterial({ map: moonTexture })
    const moonMesh = new THREE.Mesh(sphereGeometry, moonMaterial)
    moonMesh.scale.set(0.5, 0.5, 0.5)
    moonMesh.position.x = 5
    objects.push(moonMesh)

    // 加入地月系
    landOrbit.add(earthMesh)
    landOrbit.add(moonMesh)
  • 定位月球在地球左边5个单位,并缩小体积。然后全部加入地月系中。

你可能感兴趣的:(three.js,学习,前端,javascript,three.js)