当前位置: 代码网 > it编程>编程语言>Javascript > Three.js 创建 3D 地球

Three.js 创建 3D 地球

2024年08月06日 Javascript 我要评论
Three.js经常会和WebGL混淆, 但也并不总是,Three.js其实是使用WebGL来绘制三维效果的。WebGL是一个只能画点、线和三角形的非常底层的系统。想要用WebGL来做一些实用的东西通常需要大量的代码, 这就是Three.js的用武之地。它封装了诸如场景、灯光、阴影、材质、贴图、空间运算等一系列功能,让你不必要再从底层WebGL开始写起。
# 实现效果 

# threejs 基础概念简单介绍

threejs和webgl的关系

three.js经常会和webgl混淆, 但也并不总是,three.js其实是使用webgl来绘制三维效果的。webgl是一个只能画点、线和三角形的非常底层的系统。想要用webgl来做一些实用的东西通常需要大量的代码, 这就是three.js的用武之地。它封装了诸如场景、灯光、阴影、材质、贴图、空间运算等一系列功能,让你不必要再从底层webgl开始写起。

基础threejs场景

一个最基础的three.js程序包括渲染器(renderer)、场景(scene)、相机(camera)、灯光(灯光),以及我们在场景中创建的物体(earth)。

#入口文件

使用webpack打包,src/index.html是入口文件

文件列表

index.html

<div id="loading">
  <div class="sk-chase">
    <div class="sk-chase-dot"></div>
    <div class="sk-chase-dot"></div>
    <div class="sk-chase-dot"></div>
    <div class="sk-chase-dot"></div>
    <div class="sk-chase-dot"></div>
    <div class="sk-chase-dot"></div>
  </div>
  <div>加载资源中...</div>
</div>
<div id="html2canvas" class="css3d-wapper">
  <div class="fire-div"></div>
</div>
<div id="earth-canvas"></div>
  • #loading: 加载中的loading效果

  • #earth-canvas:将canvas绘制到此dom下面

  • #html2canvas:将html转换成图片,显示地球标点

index.ts 

webpack 会将此文件打包成js,放进 index.html 中 


import world from './world/word'
// earth-canvas 
const dom: htmlelement = document.queryselector('#earth-canvas') 
// 将dom传进去
new world({ dom, })

world.ts 创建3d世界 


// 传入dom,创建出threejs场景、渲染器、相机和控制器。
this.basic = new basic(option.dom)
this.scene = this.basic.scene
this.renderer = this.basic.renderer
this.controls = this.basic.controls
this.camera = this.basic.camera

// 传入dom,主要进行dom尺寸计算和管理resize事件。
this.sizes = new sizes({ dom: option.dom })

this.sizes.$on('resize', () => {
  this.renderer.setsize(number(this.sizes.viewport.width), number(this.sizes.viewport.height))
  this.camera.aspect = number(this.sizes.viewport.width) / number(this.sizes.viewport.height)
  this.camera.updateprojectionmatrix()
})

// 传一个function,资源加载完成后会执行此function。
this.resources = new resources(async () => {
  await this.createearth()
  // 开始渲染
  this.render()
})
// 地球相关配置
type options = {
  data: {
    startarray: {
      name: string,
      e: number, // 经度
      n: number, // 维度
    },
    endarray: {
      name: string,
      e: number, // 经度
      n: number, // 维度
    }[]
  }[]
  dom: htmlelement,
  textures: record<string, texture>, // 贴图
  earth: {
    radius: number, // 地球半径
    rotatespeed: number, // 地球旋转速度
    isrotation: boolean // 地球组是否自转
  }
  satellite: {
    show: boolean, // 是否显示卫星
    rotatespeed: number, // 旋转速度
    size: number, // 卫星大小
    number: number, // 一个圆环几个球
  },
  punctuation: punctuation,
  flyline: {
    color: number, // 飞线的颜色
    speed: number, // 飞机拖尾线速度
    flylinecolor: number // 飞行线的颜色
  },
}
// 1.将earth中的group添加到场景中
this.scene.add(this.earth.group)

// 2.通过await init创建地球及其相关内容,因为创建一些东西需要时间,所以返回一个promise
await this.earth.init()

// 3.地球创建完之后隐藏dom,添加一个事先定义好的类名,使用animation渐渐隐藏掉dom
const loading = document.queryselector('#loading')
loading.classlist.add('out')

// 1.将earth中的group添加到场景中
this.scene.add(this.earth.group)

// 2.通过await init创建地球及其相关内容,因为创建一些东西需要时间,所以返回一个promise
await this.earth.init()

// 3.地球创建完之后隐藏dom,添加一个事先定义好的类名,使用animation渐渐隐藏掉dom
const loading = document.queryselector('#loading')
loading.classlist.add('out')

#加载资源 

地球中需要若干个贴图,在创建地球前,先把贴图加载进来。 

assets.ts 整理资源文件 


/**
 * 资源文件
 * 把模型和图片分开进行加载
 */

interface itextures {
  name: string
  url: string
}

export interface iresources {
  textures?: itextures[],
}

const filepath = './images/earth/'
const filesuffix = [
  'gradient',
  'redcircle',
  "label",
  "aperture",
  'earth_aperture',
  'light_column',
  'aircraft'
]

const textures = filesuffix.map(item => {
  return {
    name: item,
    url: filepath + item + '.png'
  }
})

textures.push({
  name: 'earth',
  url: filepath + 'earth.jpg'
})

const resources: iresources = {
  textures
}

export {
  resources
}
通过使用threejs提供的loadingmanager方法,
管理资源的加载进度,以及保存一个textures对象,
key为name,value为texture对象

 #添加地球

图片

图片

  • earth:创建一个地球mesh,

    并赋予shadermaterial材质和贴上地球贴图,

    之后可以通过着色器动画实现地球扫光效果。

  • points:创建一个由points组成的包围球,

    放在外围。


const earth_geometry = new spherebuffergeometry(
  this.options.earth.radius,
  50,
  50
);


const earth_border = new spherebuffergeometry(
  this.options.earth.radius + 10,
  60,
  60
);


const pointmaterial = new pointsmaterial({
  color: 0x81ffff, //设置颜色,默认 0xffffff
  transparent: true,
  sizeattenuation: true,
  opacity: 0.1,
  vertexcolors: false, //定义材料是否使用顶点颜色,默认false ---如果该选项设置为true,则color属性失效
  size: 0.01, //定义粒子的大小。默认为1.0
})
const points = new points(earth_border, pointmaterial); //将模型添加到场景


this.earthgroup.add(points);


this.options.textures.earth.wraps = this.options.textures.earth.wrapt =
  repeatwrapping;
this.uniforms.map.value = this.options.textures.earth;


const earth_material = new shadermaterial({
  // wireframe:true, // 显示模型线条
  uniforms: this.uniforms,
  vertexshader: earthvertex,
  fragmentshader: earthfragment,
});


earth_material.needsupdate = true;
this.earth = new mesh(earth_geometry, earth_material);
this.earth.name = "earth";
this.earthgroup.add(this.earth);

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com