跳至主要內容
相机

我们常用的相机正交相机(OrthographicCamera)和透视相机(PerspectiveCamera)两种相机,用于来捕获场景内显示的物体模型。它们有一些通用的属性和方法:

由于相机都是继承至THREE.Object3D对象的,所以像设置位置的position属性、rotation旋转和scale缩放属性,可以直接对相机对象设置。我们甚至还可以使用add()方法,给相机对象添加子类,移动相机它的子类也会跟随着一块移动,我们可以使用这个特性制作一些比如 HUD 类型的显示界面。


Emilia Zhen大约 3 分钟canvasthree.js
光照

AmbientLight 环境全局光

环境光会照亮场景中所有的物体,在计算物体的颜色的时候,都会叠加上环境光的颜色。

var light = new THREE.AmbientLight(0x404040) // 创建一个灰色的环境光
scene.add(light)

Emilia Zhen大约 5 分钟canvasthree.js
材质

材质可以看成是材料和质感的结合。在渲染程式中,它是表面各可视属性的结合,这些可视属性是指表面的色彩、纹理、光滑度、透明度、反射率、折射率、发光度等。Three.js给我们封装好了大部分的材质效果。

MeshBasicMaterial

这种材质是一种简单的材质,不会受到光的影响,直接看到的效果就是整个物体的颜色都是一样,没有立体的感觉。
set修改color,也可以赋值一个新的THREE.Color对象

var material = new THREE.MeshBasicMaterial({ color: 0x00ffff }) //设置初始的颜色为浅蓝色
material.color.set(0xff00ff)
material.color = new THREE.Color(0xff00ff) //将颜色修改为紫色

Emilia Zhen大约 4 分钟canvasthree.js
geometry几何体

一个模型是由几何体Geometry和材质material组成。Three.js内置了很多的几何体种类,如:立方体、三棱锥、球、八面体、十二面体、二十面体等等

当前Three.js内置了这两种几何体类型GeometryBufferGeometry,这两个几何体类型都是用于存储模型的顶点位置、面的索引、法向量、颜色、uv纹理以及一些自定义的属性

  1. Geometry

Emilia Zhen大约 3 分钟canvasthree.js
scene场景

场景是我们每个Three.js项目里面放置内容的容器,我们也可以拥有多个场景进行切换展示,你可以在场景内放置你的模型,灯光和照相机。还可以通过调整场景的位置,让场景内的所有内容都一起跟着调整位置

THREE.Object3D

为了方便操作,Three.js将每个能够直接添加到场景内的对象都继承至一个基类-THREE.Object3D,以后我们将继承至这个基类的对象称为3d对象,判断一个对象是否是继承至THREE.Object3D,我们可以这么判断:obj instanceof THREE.Object3D


Emilia Zhen大约 2 分钟canvasthree.js
three.js

特点

Three.js作为WebGL框架中的佼佼者,由于它的易用性和扩展性,使得它能够满足大部分的开发需求。
Three.js掩盖了3D渲染的细节:Three.jsWebGL原生API的细节抽象化,将3D场景拆解为网格、材质和光源(即它内置了图形编程常用的一些对象种类)。

  • 面向对象:开发者可以使用上层的JavaScript对象,而不是仅仅调用JavaScript函数。
  • 功能非常丰富:Three.js除了封装了WebGL原始API之外,Three.js还包含了许多实用的内置对象,可以方便地应用于游戏开发、动画制作、幻灯片制作、髙分辨率模型和一些特殊的视觉效果制作。
  • 速度很快:Three.js采用了3D图形最佳实践来保证在不失可用性的前提下,保持极高的性能。
  • 支持交互:WebGL本身并不提供拾取(picking)功能(即是否知道鼠标正处于某个物体上)。而Three.js则固化了拾取支持,这就使得你可以轻松为你的应用添加交互功能。
  • 包含数学库:Three.js拥有一个强大易用的数学库,你可以在其中进行矩阵、投影和矢量运算。
  • 内置文件格式支持:你可以使用流行的 3D 建模软件导出文本格式的文件,然后使用Three.js加载;也可以使用Three.js自己的JSON格式或二进制格式。
  • 扩展性很强:为Three.js添加新的特性或进行自定义优化是很容易的事情。如果你需要某个特殊的数据结构,那么只需要封装到Three.js即可。

Emilia Zhen大约 7 分钟canvasthree.js
canvas

视角

// setView瞬间到达指定位置,视角 flyTo动态飞往
// 天安门position
var position = Cesium.Cartesian3.fromDegrees(116.397428, 39.90923, 100)
viewer.camera.flyTo({
  // 指定相机位置
  destination: position,
  // 设置相机视角
  orientation: {
    // 相机朝向
    heading: Cesium.Math.toRadians(0),
    // 相机俯仰角 -90向下
    path: Cesium.Math.toRadians(-90),
    // 相机翻滚角度
    roll: 0,
  },
})

Emilia Zhen小于 1 分钟canvascesium.js
canvas

三维模型

// 飞机3D模型
const plane = viewer.entities.add({
  name: 'plane',
  position: Cesium.Cartesian3.fromDegrees(101.397428, 39.90923, 100000),
  model: {
    uri: '/models/CesiumAir/Cesium_Air.gltf',
    // 模型最小像素
    minimumPixelSize: 128,
    // 最大的模型像素
    maximumScale: 20000,
    //是否显示动画
    runAnimations: true,
    //是否保持最后一针的动画
    clampAnimations: true,
    // 轮廓
    silhouetteSize: 1,
    // 轮廓颜色
    silhouetteColor: Cesium.Color.WHITE,
    // 相机距离模型多远显示
    // distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 200000),
  },
})
viewer.trackedEntity = plane

Emilia Zhen大约 1 分钟canvascesium.js
canvas

开始

登录 cesium 官网注册,并拿到 token

// Token
Cesium.Ion.defaultAccessToken = 'eyJhbGciOixxxxxxx'
// 设置默认看到中国
Cesium.Camera.DEFAULT_VIEW_RECTANGLE = Cesium.Rectangle.fromDegrees(
  // 西经
  89.5,
  // 南维
  20.4,
  // 东经
  110.4,
  // 南维
  61.2
)
var viewer = new Cesium.Viewer('cesiumContainer', {
  // 地形
  // terrainProvider: Cesium.createWorldTerrain({
  //   // 地形法相
  //   requestVertexNormals: true,
  //   // 水纹
  //   requestWaterMask: true,
  // }),
  // 播放动画
  animation: false,
  // Home按钮
  homeButton: false,
  // 查询按钮
  geocoder: false,
  // 时间轴
  timeline: false,
  // 全屏
  fullscreenButton: false,
  // 场景2D/3D选择
  sceneModePicker: false,
  // 图层选择器
  baseLayerPicker: false,
  // 帮助按钮
  navigationHelpButton: false,
  imageryProvider: new Cesium.UrlTemplateImageryProvider({
    url: '/maps/terrain/{z}/{x}/{y}.jpg',
    fileExtension: 'jpg',
  }),
  infoBox: false,
  // 天空盒
  skyBox: new Cesium.SkyBox({
    sources: {
      positiveX: '/texture/px.png',
      positiveY: '/texture/ny.png',
      positiveZ: '/texture/pz.png',
      negativeX: '/texture/nx.png',
      negativeY: '/texture/py.png',
      negativeZ: '/texture/nz.png',
    },
  }),
})
// 地图叠加
var roadImageLayers = viewer.imageryLayers
var roadLayer = roadImageLayers.addImageryProvider(
  new Cesium.UrlTemplateImageryProvider({
    url: '/maps/road/{z}/{x}/{y}.jpg',
    fileExtension: 'jpg',
  })
)
roadLayer.alpha = 0.3
// 隐藏LOGO
viewer._cesiumWidget._creditContainer.style.display = 'none'
viewer.scene.debugShowFramesPerSecond = true

Emilia Zhen大约 4 分钟canvascesium.js
绘制api

绘制线条

//设置画布的起始点
context.moveTo(x, y)
//从当前位置绘制直线到x,y坐标
context.lineTo(x, y)
//开始一条路径,或重置当前的路径,并切断和上一个图形的路径联系
context.beginPath()

Emilia Zhen大约 1 分钟canvas