Skip to content

Threejs入门基本知识

3D引擎组成包括以下部分:场景(scene)、摄像机(camera)、渲染器(renderer)、几何体(geometry)、灯光(light)、贴图(texture)、材质(material)

场景(scene)

一个容器,容纳着除渲染器以外的三维世界里的一切。场景的元素采用右手笛卡尔坐标系,x轴正方向向右,y轴正方向向上,z轴由屏幕从里向外

创建场景

js
        // 初始化场景
        const initScene = () => {
            scene = new THREE.Scene()
            scene.background = new THREE.Color(0x1A1A1A)
            // 场景雾化
            scene.fog = new THREE.Fog(0x1A1A1A, 1, 1000)
        }

场景雾化

Fog 类定义的是线性雾,雾的密度随着距离线性增大,即场景中物体雾化效果随着随距离线性变化。

js
Fog(color, near, far)
js
scene.fog = new THREE.Fog(0x1A1A1A, 1, 1000)

color: 表示雾的颜色,如设置为白色,场景中远处物体为蓝色,场景中最近处距离物体是自身颜色,最远和最近之间的物体颜色是物体本身颜色和雾颜色的混合效果。

near:表示应用雾化效果的最小距离,距离活动摄像机长度小于 near 的物体将不会被雾所影响。

far:表示应用雾化效果的最大距离,距离活动摄像机长度大于 far 的物体将不会被雾所影响。

控制器

初始化镜头轨道控制器 OrbitControls ,通过它可以对三维场景用鼠标 🖱 进行缩放、平移、旋转等操作,本质上改变的不是场景,而是相机的位置参数。可以选择通过设置controls.enableDampingtrue 来开启控制器的移动惯性,这样在使用鼠标交互过程中就会感觉更加流畅和逼真。

js
import { OrbitControls } from 'https://threejsfundamentals.org/threejs/resources/threejs/r132/examples/jsm/controls/OrbitControls.js'

const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;

摄像机(camera)

就像人的眼睛,在一个空间里可以看向任意方向,可以通过参数调节可视角度和可视距离。

一般我们使用符合物理世界近大远小真实情况的透视相机PerspectiveCamera,还有一些特殊情况,需要远近大小是一样的,那就要用正交相机OrthographicCamera

渲染器(renderer)

将camera在scene里看到的内容渲染/绘制到画布上

几何体(geometry)

3D世界里的所有物体都是点组成面,面组成几何体。

  • 球体
  • 立方体
  • 圆锥体
  • 圆柱体

面是由点构成的,面又可以组成各式各样的几何体。以球体举例,球体面上的点越多,球就越圆。但点越多,运算量也会越大...

另外我们一般说的3d模型就是一个或多个几何体,只是有的3d模型文件里除了包含几何体还可以包含一些额外的信息,比如贴图,材质等...需要在读取模型文件时解析出来

下面汇总了 Three.js 常用几何体的分类介绍以及构造器的参数,后续使用过程中可通过此表查询。由于本文篇幅内容有限,就不一一展示具体形状,大家在学习过程中一定要亲自动手试试各种几何体创建后是什么样子的,也可以多看看 threejs.org 官网文档。

名称构造器参数
PlaneGeometry【平面几何体】 width — 平面沿着X轴的宽度。默认值是 1。height — 平面沿着 Y轴 的高度。默认值是 1。widthSegments — 可选,平面的宽度分段数,默认值是 1。 heightSegments — 可选,平面的高度分段数,默认值是 1。
CircleGeometry【圆形几何体】 radius — 圆形的半径,默认值为1。 segments — 分段的数量,最小值为 3,默认值为 8。thetaStart — 第一个分段的起始角度,默认为 0。thetaLength — 圆形扇区的中心角,通常被称为 θ。默认值是 2*Pi,这使其成为一个完整的圆。
RingGeometry【环形几何体】 innerRadius — 内部半径,默认值为 0.5。outerRadius — 外部半径,默认值为 1。thetaSegments — 圆环的分段数。这个值越大,圆环就越圆。最小值为 3,默认值为 8。phiSegments — 最小值为 1,默认值为 8。thetaStart — 起始角度,默认值为 0。thetaLength — 圆心角,默认值为 Math.PI * 2。
ShapeGeometry【形状几何体】 shapes — 一个单独的 shape,或者一个包含形状的 Array。 curveSegments - Integer - 每一个形状的分段数,默认值为 12。
BoxGeometry【立方几何体】 width — X轴上面的宽度,默认值为 1。 height — Y 轴上面的高度,默认值为 1。 depth — Z 轴上面的深度,默认值为 1。widthSegments — 可选,宽度的分段数,默认值是 1。heightSegments — 可选,宽度的分段数,默认值是 1。depthSegments — 可选,宽度的分段数,默认值是 1。
SphereGeometry【球几何体】 radius — 球体半径,默认为 1。widthSegments — 水平分段数,最小值为 3,默认值为 8。heightSegments — 垂直分段数,最小值为 2,默认值为 6。phiStart — 指定水平起始角度,默认值为 0。 phiLength — 指定水平扫描角度的大小,默认值为 Math.PI * 2。thetaStart — 指定垂直起始角度,默认值为 0。thetaLength — 指定垂直扫描角度大小,默认值为 Math.PI。
CylinderGeometry【圆柱几何体】 radiusTop — 圆柱的顶部半径,默认值是 1。radiusBottom — 圆柱的底部半径,默认值是 1。height — 圆柱的高度,默认值是 1。radialSegments — 圆柱侧面周围的分段数,默认为 8。 heightSegments — 圆柱侧面沿着其高度的分段数,默认值为 1。openEnded — 一个 Boolean 值,指明该圆锥的底面是开放的还是封顶的。默认值为 false,即其底面默认是封顶的。thetaStart — 第一个分段的起始角度,默认为 0。thetaLength — 圆柱底面圆扇区的中心角,通常被称为 “θ”。默认值是 2*Pi,这使其成为一个完整的圆柱。
ConeGeometry【圆锥几何体】 radius — 圆锥底部的半径,默认值为 1。height — 圆锥的高度,默认值为1。 radialSegments — 圆锥侧面周围的分段数,默认为 8。heightSegments — 圆锥侧面沿着其高度的分段数,默认值为 1。openEnded — 一个Boolean值,指明该圆锥的底面是开放的还是封顶的。默认值为 false,即其底面默认是封顶的。·thetaStart· — 第一个分段的起始角度,默认为 0。thetaLength — 圆锥底面圆扇区的中心角,通常被称为 “θ”。默认值是 2*Pi,这使其成为一个完整的圆锥。
TorusGeometry【圆环几何体】 radius - 圆环的半径,从圆环的中心到管道的中心。默认值是 1。tube — 管道的半径,默认值为 0.4。radialSegments — 圆环的分段数,默认值为 8。tubularSegments — 管道的分段数,默认值为 6。arc — 圆环的中心角,默认值为 Math.PI * 2。
TextGeometry【文本几何体】 font — THREE.Font 的实例。size — Float。字体大小,默认值为 100。height — Float。挤出文本的厚度。默认值为 50。curveSegments — Integer。曲线上点的数量。默认值为 12。bevelEnabled — Boolean。是否开启斜角,默认为 false。bevelThickness — Float。文本上斜角的深度,默认值为 20。bevelSize — Float。斜角与原始文本轮廓之间的延伸距离。默认值为 8。bevelSegments — Integer。斜角的分段数。默认值为 3。
TetrahedronGeometry【四面几何体】 radius — 四面体的半径,默认值为 1。detail — 默认值为 0。将这个值设为一个大于 0 的数将会为它增加一些顶点,使其不再是一个四面体。
OctahedronGeometry【八面几何体】 radius — 八面体的半径,默认值为 1。detail — 默认值为 0,将这个值设为一个大于 0 的数将会为它增加一些顶点,使其不再是一个八面体。
DodecahedronGeometry【十二面几何体】 radius — 十二面体的半径,默认值为 1。detail — 默认值为 0。将这个值设为一个大于 0 的数将会为它增加一些顶点,使其不再是一个十二面体。
IcosahedronGeometry【二十面几何体】 radius — 二十面体的半径,默认为 1。detail — 默认值为 0。将这个值设为一个大于 0 的数将会为它增加一些顶点,使其不再是一个二十面体。当这个值大于 1 的时候,实际上它将变成一个球体。
TorusKnotGeometry【圆环扭结几何体】 radius - 圆环的半径,默认值为 1。tube — 管道的半径,默认值为 0.4。tubularSegments — 管道的分段数量,默认值为 64。radialSegments — 横截面分段数量,默认值为 8。p — 这个值决定了几何体将绕着其旋转对称轴旋转多少次,默认值是 2。q — 这个值决定了几何体将绕着其内部圆环旋转多少次,默认值是 3。
PolyhedronGeometry【多面几何体】 vertices — 一个顶点 Array:[1,1,1, -1,-1,-1, … ]。indices — 一个构成面的索引 Array, [0,1,2, 2,3,0, … ]。radius — Float - 最终形状的半径。detail — Integer - 将对这个几何体细分多少个级别。细节越多,形状就越平滑。
TubeGeometry【管道几何体】 path — Curve - 一个由基类 Curve 继承而来的路径。tubularSegments — Integer - 组成这一管道的分段数,默认值为 64。radius — Float - 管道的半径,默认值为 1。radialSegments — Integer - 管道横截面的分段数目,默认值为 8。closed — Boolean 管道的两端是否闭合,默认值为 false。

灯光(light)

TIP

3d引擎在没有手动创建光的情况下会默认有个环境光,不然你什么都看不到。常见的灯光有以下几种类型

  • AmbientLight(环境光,没有方向全局打亮,不会产生明暗)

  • DirectionLight(平行光,参考日光来理解)

  • PointLight(点光源,参考灯泡来理解)
  • SpotLight(聚光灯,参考舞台聚光灯)

Three.js 中提供了很多种光源,它们可以模拟现实世界中大部分场景的光照效果。光源的使用方法也大致和本文示例中是一样的。下表列出了几种常用的光源,可以根据自己的需求场景分别选择不同的光源。

光源名称描述
AmbientLight环境光,是一种基础光源,它的颜色会添加到整个场景和所有对象的当前颜色上
PointLight点光源,空间中的一点,朝所有的方向发射光线
SpotLight聚光灯光源,这种光源有聚光的效果,类似台灯、天花板上的吊灯,或者手电筒
DirectionLight方向光,也称为无限光。从这种光源发出的光线可以看着平行的。例如,太阳光
HemishpereLight半球光,这是一种特殊光源,可以用来创建更加自然的室外光线,模拟放光面和光线微弱的天空
AreaLight面光源,使用这种光源可以指定散发光线的平面,而不是空间中的一个点
LensFlare镜头眩光,不是源,但可以通过 LensFlare 为场景中的光源添加镜头光晕效果

光源的一些通用属性:

color:光源颜色。

intensity:光照强度。默认值是 1。

visible:如果设为 true,该光源就会显示;如果设置为false,光源就会消失。

贴图(texture)

想象一下你手里有一个立方体,你用一张A4纸包裹上立方体的所有面,并在上面画画。你画的内容就是贴图。

为了模拟更加真实的效果,就要给模型材质添加贴图,贴图就像模型的皮肤一样,使其三维效果更佳。添加贴图的原理是通过纹理贴图加载器 TextureLoader() 去新创建一个贴图对象出来,然后再去调用里面的 load() 方法去加载一张图片,这样就会返回一个纹理对象,纹理对象可以作为模型材质颜色贴图 map 属性的值,材质的颜色贴图属性 map 设置后,模型会从纹理贴图上采集像素值。下面列出了几种常用的贴图类型以及加载贴图的基本流程。

  • map:材质贴图

  • normalMap:法线贴图

  • bumpMap:凹凸贴图

  • envMap:环境贴图

  • specularMap:高光贴图

  • lightMap:光照贴图

代码示例:

js
const texLoader = new THREE.TextureLoader();
loader.load('assets/models/meta.fbx', function (mesh) {
  mesh.traverse(function (child) {
    if (child.isMesh) {
      if (child.name === '需要添加贴图的模型') {
        child.material = new THREE.MeshPhysicalMaterial({
          map: texLoader.load("./assets/images/metal.png"),
        });
      }
    }
  });
})

材质(material)

TIP

3d引擎在没有手动创建光的情况下会默认有个环境光,不然你什么都看不到。常见的灯光有以下几种类型

  • MeshBasicMaterial(基础材质,不受光照影响)

  • MeshStandardMaterial(PBR标准材质)

  • MeshPhongMaterial(高光材质,适用于陶瓷,烤漆类质感)

  • MeshToonMaterial(卡通材质,俗称三渲二)

  • MeshStandardMaterial(PBR标准材质模拟金属反射)

材质可以模拟现实世界中物体表面的物理特性,Three.js 也提供的丰富的材质,我们在创建不同物体时可以选择不同的材质,比如创建木制桌面时可以选择 MeshPhysicalMaterial 物理网格材质,创建卡通风格模型时可以选择 MeshToonMaterial 卡通网格材质。下表列出了几种常用的材质类型及其说明。

名称描述
MeshBasicMaterial基础网格基础材质,用于给几何体赋予一种简单的颜色,或者显示几何体的线框。
MeshDepthMaterial网格深度材质,这个材质使用从摄像机到网格的距离来决定如何给网格上色。
MeshStandardMaterial标准网格材质,一种基于物理的标准材质,使用 Metallic-Roughness 工作流程
MeshPhysicalMaterial物理网格材质,MeshStandardMaterial 的扩展,能够更好地控制反射率。
MeshNormalMaterial网格法向材质,这是一种简单的材质,根据法向向量计算物体表面的颜色。
MeshLambertMaterial网格 Lambert 材质,这是一种考虑光照影响的材质,用于创建暗淡的、不光亮的物体。
MeshPhongMaterial网格 Phong 式材质,这是一种考虑光照影响的材质,用于创建光亮的物体。
MeshToonMaterial网格 Phong 式材质,MeshPhongMaterial 卡通着色的扩展。
ShaderMaterial着色器材质,这种材质允许使用自定义的着色器程序,直接控制顶点的放置方式以及像素的着色方式。
LineBasicMaterial直线基础材质,这种材质可以用于 THREE.Line 直线几何体,用来创建着色的直线。

网格(Mesh)

需要传入几何体和材质组合为一个带有位置和方向的特殊几何体。

参考

作者:dragonir 链接:https://juejin.cn/post/7146383940931026958 来源:稀土掘金 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

上次更新于: