threejs学习第一天--3D地月环绕实战案例

实现效果

在这里插入图片描述

部分代码

index.html:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    * {
      margin: 0;
      padding: 0;
    }

    canvas {
      background-image: url(imgs/star.jpg);
      background-size: cover;
    }

    .label {
      color: #fff;
      font-size: 16px;
    }
  </style>
  <script type="module">
    import * as THREE from '../libs/build/three.module.js'
    import {OrbitControls} from '../libs/jsm/controls/OrbitControls.js'
    import {CSS2DRenderer,CSS2DObject} from '../libs/jsm/renderers/CSS2DRenderer.js'

    // 声明全局变量
    let camera,scene,renderer,labelRenderer;
    let moon,earth;
    let clock = new THREE.Clock()
    // 实例化纹理加载器
    const textureLoader = new THREE.TextureLoader()

    function init(){
      // 地球和月球的半径大小
      const EARTH_RADIUS = 2.5
      const MOON_RADIUS = 0.27
      // 实例化相机
      camera = new THREE.PerspectiveCamera(45,window.innerWidth/window.innerHeight,0.1,200)
      camera.position.set(10,5,20)

      // 实例化场景
      scene = new THREE.Scene()
      // 创建聚光灯光源以及添加光源
      const dirLight = new THREE.SpotLight(0xffffff)
      dirLight.position.set(0,0,10)
      dirLight.intensity = 2
      dirLight.castShadow = true
      scene.add(dirLight)

      // 添加环境光
      const aLight = new THREE.AmbientLight(0xffffff)
      aLight.intensity = 0.3// 设置光的亮度
      scene.add(aLight)

      // 创建月球
      const moonGeometry = new THREE.SphereGeometry(MOON_RADIUS,16,16)
      const moonMaterial = new THREE.MeshPhongMaterial({
        map:textureLoader.load('textures/planets/moon_1024.jpg')
      })
      moon = new THREE.Mesh(moonGeometry,moonMaterial)
      moon.receiveShadow = true
      moon.castShadow = true
      scene.add(moon)

      const moonDiv = document.createElement('div')
      moonDiv.className = 'label'
      moonDiv.textContent = 'moon'
      const moonLabel = new CSS2DObject(moonDiv)

      moonLabel.position.set(0,MOON_RADIUS+0.5,0)
      moon.add(moonLabel)

      
      // 创建地球
      const earthGeometry = new THREE.SphereGeometry(EARTH_RADIUS,16,16)
      const earthMaterial = new THREE.MeshPhongMaterial({
        // 镜面反射调低一点
        shininess:5,
        map:textureLoader.load('textures/planets/earth_atmos_2048.jpg'),
        specularMap:textureLoader.load('textures/planets/earth_specular_2048.jpg'),// 设置纹理
        normalMap:textureLoader.load('textures/planets/earth_normal_2048.jpg')
      })
      
      earth = new THREE.Mesh(earthGeometry,earthMaterial)
      earth.receiveShadow = true
      earth.castShadow = true
      scene.add(earth)

      const earthDiv = document.createElement('div')
      earthDiv.className = 'label'
      earthDiv.textContent = 'Earth'
      const earthLabel = new CSS2DObject(earthDiv)

      earthLabel.position.set(0,EARTH_RADIUS+0.5,0)
      earth.add(earthLabel)

      // 创建渲染器
      renderer = new THREE.WebGLRenderer({
        alpha:true
      })
      renderer.setPixelRatio(window.devicePixelRatio)// 像素比和屏幕的的像素比一致
      renderer.setSize(window.innerWidth,window.innerHeight)
      // 渲染阴影
      renderer.shadowMap.enabled = true
      document.body.appendChild(renderer.domElement)

      // 标签渲染器
      labelRenderer = new CSS2DRenderer()
      labelRenderer.setSize(window.innerWidth,window.innerHeight)
      labelRenderer.domElement.style.position = 'absolute'
      labelRenderer.domElement.style.top = '0px'
      document.body.appendChild(labelRenderer.domElement)

      // 绑定控制器和摄像头,以及场景
      const controls = new OrbitControls(camera,renderer.domElement)
    }
    var oldtime = 0
    function animate(){
      const elapsed = clock.getElapsedTime()
      moon.position.set(Math.sin(elapsed)*5,0,Math.cos(elapsed)*5)

      // 地球自转
      var axis = new THREE.Vector3(0,1,0)
      earth.rotateOnAxis(axis,(elapsed-oldtime)*Math.PI/10)
      renderer.render(scene,camera)
      labelRenderer.render(scene,camera)
      oldtime = elapsed
      requestAnimationFrame(animate)

     
    }

    init()
    animate()

    // 调整尺寸
    window.onresize = function(){
      camera.aspect = window.innerWidth/window.innerHeight
      camera.updateProjectionMatrix()
      renderer.setSize(window.innerWidth,Window.innerHeight)
    }
  </script>
</head>

<body>

</body>

</html>
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值