Three.js视频教程

Threejs引擎

Threejs是WebGL多款3D引擎之一,threejs相比较babylonjs、cesiumjs等引擎在国内使用的更广泛,中文资料更多,相关招聘更多。所以对于WebGL工程师来说,学习threejs是很有必要的。

视频教程发布地址

案例欣赏

下面一些案例都是通过threejs来完成的

前言

使用Threejs有几年了,一直想录制一套关于Threejs引擎的视频教程,所以想着在这里先写一个录制大纲。因为主要是写给自己看的,所以除了章节目录写的比较清楚,每一小节的内容,都是想到什么写什么。

教程大纲

在这里插入图片描述

第一章、three.js快速入门

1. 第一个3D场景
  • 引入three.js引擎,就像你使用Jquery一样
  • 路径:three.js-master/build/three.js
  • 场景Scene、网格模型Mesh、几何体对象Geometry、材质对象Material、光照Light、相机Camera、渲染器Renderer
  • .add()方法:执行scene场景对象的add()方法,可以把网格模型或者光照对象添加到场景中
  • .render方法:场景、相机、渲染器是三个相互独立JavaScript对象,场景和相机对象作为渲染器.render方法的参数出现
2.旋转动画、requestAnimationFrame周期性渲染
  • 渲染器render方法:render方法你可以简单的理解为是对WebGL API 绘制函数drawArrays()的封装,执行一次render方法,产生的渲染结果会覆盖上次执行render方法的渲染结果
  • 帧的概念:WebGL渲染器执行一次render方法,得到一帧效果图按照一定周期执行渲染器的render方法,更新显示结果,产生动画效果
  • 刷新频率:30—60FPS(两帧时间间隔16.67ms~33.33ms)
  • window.requestAnimationFrame() 方法:请求浏览器执行下一帧动画,不用指定时间间隔,浏览器会自动安排,一般最高刷新频率默认60FPS
3.鼠标操作三维场景旋转缩放
  • 控件OrbitControls.js
    路径:three.js-master\examples\js\controls
  • 模型操作
    缩放:滚动—鼠标中键
    平移:拖动—鼠标右键
    旋转:拖动—鼠标左键
4.场景插入新的几何体
  • 立方体、球体、圆柱、正多面体等API
  • position:网格模型位置属性,position属性是Vector3对象,Vector3对象具有set方法
  • BoxBufferGeometry和BoxGeometry
5.设置材质效果
  • MeshBasicMaterial
    基础网格材质
    不受光照影响的材质
  • MeshLambertMaterial
    Lambert网格材质
    与光照有反应
    漫反射
  • MeshPhongMaterial
    与光照有反应
    高光材质
  • color
    color: 0x0000ff,//材质颜色
  • wireframe
    将几何图形渲染为线框。 默认值为false
  • opacity
    透明度设置,0表示完全透明,1表示完全不透明
  • transparent
    是否开启透明,默认false
  • 半透明效果设置
    transparent:true,
    opacity:0.5,

6.光照效果设置

  • 光照计算的原理

  • 几种光源介绍,threejs API查找

  • threejs编辑器辅助介绍

  • 环境光
    AmbientLight

  • 点光源
    构造函数参数
    设置颜色
    point = new THREE.PointLight(0xffffff)
    位置属性
    point.position.set(400, 200, 300)

  • 方向光

  • add方法
    通过add方法插入场景中,不插入的话,渲染的时候不会获取光源的信息进行光照计算

第一章:总结

  • 第一章目的
    不以具体知识为目的,不需要去理解具体的对象、方法和属性,有一个感性的认识就可以
    对于非常急于上手的前端,先实现一个效果,给一些小的案例代码,可以慢慢研究。

  • 麻雀虽小五脏俱全

  • 后面的课程通常绘制本章的一些html文件基础上进行增删代码,实现一个特定的效果

  • html框架
    以后的学习在这个文件的基础上进行

第二章、顶点概念、几何体结构

1.顶点位置数据解析渲染

学习目标
没有webgl基础
建立顶点概念
有webgl基础
已经有了顶点概念
重点学习threejs的API,threejs引擎是如何封装webgl的
JavaScript类型化数组
Float32Array
32位浮点数float类型数组
Uint16Array
无符号16位整形数组
网格模型Mesh
几何体geometry
材质material
BufferGeometry基类
派生类(子类)
BoxBufferGeometry立方体
CylinderBufferGeometry圆柱体

属性:attributes对象
position位置属性
属性类型是threejs的BufferAttribute对象
BufferAttribute
缓冲区属性构造函数

2.顶点颜色数据插值计算

顶点概念
分类
顶点位置数据
顶点颜色数据
顶点位置和顶点颜色一一对应
一个顶点有一个位置坐标数据
一个顶点有一个颜色数据
BufferGeometry对象
attributes属性
position
color
值:BufferAttribute对象
材质属性vertexColors
属性值
THREE.NoColors
默认值
NoColors是默认值,并将材质的颜色应用于所有面
THREE.VertexColors
通过顶点颜色进行插值计算渲染
THREE.FaceColors
FaceColors根据每个Face3 Color值对面部进行着色
设置颜色的显示方式
材质color属性统一设置
THREE.VertexColors
需要配置顶点颜色数据使用
整个网格模型、线模型都显示统一的颜色
顶点颜色
THREE.NoColors
通过材质的color属性统一设置颜色,默认值,不需要设置
插值计算
点渲染模式
每个点一种颜色
不会插值计算
线line、网格mesh渲染模式
颜色插值计算
插值图解

3.顶点法向量数据光照计算

图解
顶点数据
顶点位置
顶点颜色
顶点法向量数据
每个顶点一个法向量
geometry.attributes
position
color
normal
光线和顶点法向量夹角
光线方向是一个向量、顶点有一个法向量
光照计算
漫反射光的颜色 = 几何体表面基色 x 光线颜色 x 光线入射角余弦值

4.顶点索引复用顶点数据

顶点数据
位置、颜色、法向量…
类型数组
Float32Array
geometry.attributes
position
color
normal
属性值:BufferAttribute
索引数据
类型数组
Uint16Array或Uint32Array
geometry.index
属性值:和顶点数据一样都是“缓冲属性对象”BufferAttribute
索引方式绘制好处
节约数据量

5.设置Geometry顶点位置、顶点颜色数据

几何体对象
Geometry
顶点数据用一个对象表示
BufferGeometry
顶点数据使用类型化数组集中表示
Geometry
属性
vertices:顶点位置
类型Array
元素:Vector3对象
colors:顶点颜色
类型Array
元素:Color对象
Vector3对象
表示顶点位置、顶点法向量数据
Color对象
表示顶点颜色数据

6.Face3对象定义Geometry的三角面

Face3对象
复用顶点位置数据
对应BufferGeometry对象的index属性
Geometry
vertices:顶点位置
colors:顶点颜色
用于点模型对象Points、线模型对象Line
不用于Mesh的渲染
faces:三角面属性
类型Array
元素Face3
Face3
顶点索引
.a .b .c
法向量
vertexNormals
Face3三角面三个顶点的法向量
normal
Face3三角面的法向量
三个顶点法向量相同,直接一次性设置
颜色
.vertexColors
Face3三角面三个顶点的颜色
.color
Face3三角面颜色
三个顶点颜色相同,直接一次性设置
用于Mesh模型的渲染

7.访问几何体对象的数据

几何体的子类
生成顶点、索引等数据的算法
Geometry属性
vertices
colors
faces
三角面Face3元素组成的 Array
Face3属性
VertexColors
BufferGeometry属性
attributes
position
color
normal

index

8.几何体旋转、缩放、平移变换

变换类型
缩放
.scale()
( x : Float, y : Float, z : Float )
平移
.translate()
( x : Float, y : Float, z : Float )
旋转
.rotateX()、.rotateY()、.rotateZ()
参数:弧度
变换的本质
改变几何体的顶点位置数据

第三章、材质对象

1.常用材质介绍

材质的本质
顶点着色器、片元着色器代码、unifomrs数据
材质枚举
点材质
PointsMaterial
线材质
LineBasicMaterial线基础材质
LineDashedMaterial虚线材质
构造函数首字母Line开头
网格材质
MeshBasicMaterial
网格基础材质
MeshPhongMaterial
网格Phong材质
高亮表面、镜面反射
MeshLambertMaterial
网格Lambert材质
暗淡、漫反射
MeshDepthMaterial
网格深度材质
渲染的效果和模型像素对应顶点距离相机的位置远近
模型逐渐远离相机,展示一个逐渐消失的效果
MeshNormalMaterial
网格法向量材质
渲染效果和模型顶点的法向量相关
构造函数首字母Mesh开头
精灵Sprite材质
SpriteMaterial
自定义着色器材质
RawShaderMaterial
ShaderMaterial
模型构成
几何体geometry
材质material
材质和模型对应关系
点材质
点模型:Points
线材质
线条类型模型
Line
LineLoop
LineSegments
网格材质
网格模型Mesh、骨骼类网格模型SkinnedMesh
精灵材质
精灵模型Sprite

2.材质共有属性、私有属性

设置属性
构造函数创建对象的时候默认设置
构造函数输入参数设置
直接设置材质对象的属性
threejs渲染的时候会通过WebGL渲染器读取材质属性的属性值
基类
material
子类
PointsMaterial、MeshPhongMaterial、LineBasicMaterial…
共有属性
来自基类Material对象
wireframe
将几何图形渲染为线框。 默认值为false
opacity
透明度设置,0表示完全透明,1表示完全不透明
transparent
是否开启透明,默认false
side
THREE.FrontSide
显示前面
THREE.BackSide
显示后面
THREE.DoubleSide
双面显示
vertexColors
THREE.NoColors,默认
THREE.VertexColors
渲染顶点颜色数据
THREE.FaceColors
私有属性
MeshPhongMaterial
specular
高光部分的颜色
shininess
高光部分的亮度,默认30
PointsMaterial
size
设置点的渲染尺寸
color颜色属性
点材质、线材质、网格材质具有
ShaderMaterial、RawShaderMaterial不具有
网格Mesh类型材质
Mesh开头的API
wireframe
线框模式渲染,Face3三角面的边线渲染出来

第四章、模型对象

1.点、线、网格模型介绍

模型对象
构造函数参数(geometry,material)
属性
几何体geometry
材质material
模型分类
点模型point
点模式渲染
线模型Line
线条模式渲染
Line
LineLoop
LineSegments
网格模型Mesh
默认:三角面渲染
wireframe:true
Face3的线条
faces
模型本身就是一种绘制方式
gl.drawArrays(mode, first, count)
解释角度
WebGL、实际效果
渲染绘制模式
基类都是Object3D的一个JavaScript对象
比较线模型的线条绘制模式和网格模型的线条绘制模式
线模型Line
wireframe:true

2.模型对象旋转平移缩放变换

属性
位置
.position:Vector3
缩放倍数
.scale:Vector3
角度
.rotation:Euler
欧拉对象Euler
属性
.x
.y
.z
方法
.set()
方法
旋转
.rotateY ( angle )
.rotateZ ( angle )
.rotateOnAxis ( axis, angle )
angle:旋转角度,单位:弧度
平移
.translateX ( distance )
.translateY ( distance )
.translateOnAxis( axis, distance )
axis
平移方向
Vector3
distance:平移距离
方法和属性
方法改变对应的属性
threejs的WebGL渲染器会读取位置、角度等属性的值进行渲染
几何变换的区别
网格模型Mesh对象
不会改变顶点位置数据
旋转平移缩放方法改变的是模型对象的scale、rotation、position属性
几何体Geometry对象
改变的是顶点位置数据

3.模型对象克隆clone复制copy(立方体线性阵列)

方法
克隆.clone()
对象返回一个新的对象
mesh2 = mesh1.clone();
网格模型对象mesh1执行克隆方法,返回一个新的网格模型对象mesh2
浅拷贝
mesh1和mesh2共享几何体geometry和材质material对象
复制的是geometry和material对象的引用
mesh1、mesh2的几何体、材质属性都指向几何体和材质对象
几何体和材质属性的属性值改变,mesh1和mesh2的颜色都会改变
深拷贝
mesh2会获得mesh1的位置、角度、矩阵等属性
比如位置属性复制的是具体的值,而不是引用
mesh2和mesh1的位置、角度等属性改变互不影响
复制.copy()
一个对象从另一个对象复制数据
从一个网格模型对象复制非几何体、材质对象
网格模型的复制继承Object3D,不会复制geometry和材质
mesh2 .copy(mesh1);
mesh2复制mesh1的位置、旋转、矩阵等属性(不包含geometry和material属性)
模型对象
网格模型、点模型、线模型…

第五章、光源对象

1.光照原理和常见光源类型

场景
模型对象
光照
模拟生活中的光源效果
光源类型
环境光
没有特定方向,只有颜色
方向

点光源
平行光源
聚光灯光源
光照算法
环境光
显示颜色 = 环境光颜色 * 材质颜色
含有方向的光照
漫反射算法
漫反射光的颜色 = 几何体表面基色 x 光线颜色 x 光线入射角余弦值
夹角通过光线方向向量、顶点法向量可以计算出来
颜色反射的乘法运算
一般情况光照是白色,比如舞台歌厅会出现特定颜色的光照
物体白色,光源红色
呈现红色
白色光源反射所有颜色光源
物体红色,光源蓝色
呈现黑色
红色物体不会反射蓝色光源

2.阴影投影计算

开启阴影计算
网格模型
接收投影
.receiveShadow属性
planeMesh.receiveShadow = true;
产生投影
.castShadow属性
mesh.castShadow = true;
光源
directionalLight.castShadow = true;
.castShadow属性
WebGL渲染器
renderer.shadowMap.enabled = true;
.shadowMap.enabled属性
所有属性全部布尔值Boolean
默认false,节约计算资源
设置投影计算区域
平行光
长方体区域
directionalLight.shadow.camera.near = 0.5;
directionalLight.shadow.camera.far = 300;
directionalLight.shadow.camera.left = -50;
directionalLight.shadow.camera.right = 50;
directionalLight.shadow.camera.top = 200;
directionalLight.shadow.camera.bottom = -100;
区域的所有模型对象都可以投影或者接受投影
聚光
锥形区域
spotLight.shadow.camera.near = 1;
spotLight.shadow.camera.far = 300;
spotLight.shadow.camera.fov = 20;
.shadow属性
SpotLight
SpotLightShadow
DirectionalLight
DirectionalLightShadow
.camera属性
SpotLightShadow
OrthographicCamera正投影
属性
near
far
left
right
top
bottom
DirectionalLightShadow
PerspectiveCamera透视投影
属性
near
far
fov
相机的空间过大,阴影纹理贴图出现严重锯齿
相机空间过小
看不到投影的阴影效果
看到局部投影效果
模糊
设置阴影对象的mapSize属性,增大
或者设置计算阴影的区域紧密包围在对象周围
LightShadow基类
.mapSize : Vector2
默认512,512
directionalLight.shadow.mapSize.set(1024,1024)
.camera : Camera

3.基类Light和Object3D

Object3D——Light——常见各种光源对象
基类Light
属性
.color : Color
光源颜色
.intensity : Float
光照强度
方法
.copy ( source : Light )
从其它光源复制复制属性
.toJSON ( meta : String )
以JSON格式返回Light数据
基类Object3D
position位置属性
平移方法
.translateX()沿着x轴平移
.translateY()沿着y轴平移
私有属性
distance距离
点光源、聚光光源
方向光、环境光不具有
光源照射距离
从起点position开始衰减
默认0,意味着光线强度不会随着距离衰减

第六章、层级模型、树结构

1.组对象Group、层级模型

mesh添加到group中,group在添加到scene中
scene
group2
group1
Mesh(Line/Points…)
group1.clone()
Mesh(Line/Points…)
group1.clone()…
Mesh(Line/Points…)
group2.clone()
group2.clone()…
树结构
根节点
scene
中间节点
group2、group1
叶子节点
Mesh(Line/Points…)
基类Object3D
属性和方法
add方法
改变父对象的children属性,增加新的元素
children属性
几何变换
属性
位置
.position:Vector3
缩放倍数
.scale:Vector3
角度
.rotation:Euler
方法
旋转
.rotateY ( angle )
.rotateZ ( angle )
.rotateOnAxis ( axis, angle )
平移
.translateX ( distance )
.translateY ( distance )
.translateOnAxis( axis, distance )
子类
scene、group
scene、group更语义化
group可以用Object3D代替
继承Object3D的add方法和children属性
继承几何变换的相关方法和属性
Mesh(Line/Points…)
继承几何变换的相关方法和属性
作为叶子节点没有必要再具有children属性
包含几何体和材质对象

2.对象节点命名、查找、遍历

属性
id
唯一的,系统自动分配
name
字符串,手动命名
type
构造函数的名字
children
parent
递归遍历方法.traverse()
参数:callback : Function
回调函数
查找方法
.getObjectByName ( name )
name:对象的属性名
遍历查找对象的子对象,返回name对应的对象(name是可以重名的,返回第一个)
.getObjectById ( id )
id – 对象id号
遍历查找对象的子对象,并返回id对应的对象

3.本地位置坐标、世界位置坐标

手动更新世界矩阵
scene.updateMatrixWorld(true);
更新对象的世界矩阵属性
该语句默认在threejs渲染的过程中执行
如果想获得世界矩阵属性、世界位置属性等属性,需要手动更新
父对象的世界矩阵更新,所有子对象的世界矩阵默认更新
本地位置坐标
position属性
.translateX ( distance )
.translateY ( distance )
矩阵属性
本地矩阵:.matrix : Matrix4
平移矩阵、旋转矩阵、缩放矩阵的乘积
世界矩阵:.matrixWorld : Matrix4
对象本身以及所有父对象本地矩阵的乘积
scene的世界矩阵就是本地矩阵
基类Object3D
.getWorldPosition()方法
返回世界坐标
.getWorldScale()
获得世界缩放参数

第七章、几何体对象、曲线、三维建模

1.常见几何体和曲线API介绍

应用场景
开发三维建模软件
一些可视化数据的解析
几何体Geometries
基类Geometry
BoxGeometry
CylinderGeometry
SphereGeometry

基类BufferGeometry
BoxBufferGeometry
CircleBufferGeometry
CylinderBufferGeometry

所谓几何体的API
就是几何体顶点数据生成的算法
API分类
常见几何体
长方体BoxGeometry
圆柱体CylinderGeometry
球体SphereGeometry
圆锥、棱锥ConeGeometry
正多面体
正四面体TetrahedronGeometry
正八面体OctahedronGeometry
正十二面体OctahedronGeometry
正二十面体DodecahedronGeometry
平面
圆平面CircleGeometry
矩形平面PlaneGeometry
环平面RingGeometry
2D转3D
拉伸、扫描
ExtrudeGeometry
拉伸
扫描
旋转
LatheGeometry
示意图
管道
TubeGeometry
线条生成管道
轮廓填充
ShapeGeometry
可视化解析地图数据
二维线条轮廓填充
文字
TextGeometry
参数化曲面ParametricGeometry
曲线
Extras / Core
Curve
CurvePath

Extras / Curves
2D
直线LineCurve
圆弧ArcCurve
椭圆SplineCurve
样条曲线SplineCurve
QuadraticBezierCurve
CubicBezierCurve
3D
直线LineCurve3
CatmullRomCurve3
CubicBezierCurve3
二次贝塞尔曲线QuadraticBezierCurve3

2.圆弧线绘制(直线、椭圆、圆弧)、基类Curve

几何体方法
geometry
.setFromPoints ( points : Array )
改变几何体的顶点属性vertices
BufferGeometry
.setFromPoints ( points : Array )
设置几何体的属性.attributes.position
points的元素是Vector2或Vector3
Vector2位于同一平面内的点
Vector3三维空间中一点
基类Curve
getPoints()方法
返回沿着曲线的顶点
从Extras / Curves类别下面的API创建的曲线对象生成点集
将曲线等分为几部分,每隔一定距离取一个顶点
Extras / Core
Curve
CurvePath

圆弧API
ArcCurve
ArcCurve( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise )
aX, aY
圆弧圆心坐标
aRadius
圆弧半径
aStartAngle, aEndAngle
起始角度
aClockwise
是否顺时针绘制,默认值为false
arc.getPoints(n)
n越大、圆弧效果越好
n是3,4,5…可以实现正多边形的效果
Extras / Curves
2D
直线LineCurve
圆弧ArcCurve
椭圆EllipseCurve
样条曲线SplineCurve
3D
直线LineCurve3
二次贝塞尔曲线QuadraticBezierCurve3

3.样条曲线、贝赛尔曲线

样条曲线
经过一系列点创建平滑的样条曲线
2D
SplineCurve
3D
CatmullRomCurve3
Catmull-Rom算法
贝赛尔曲线
二次贝赛尔曲线
起点、终点和1个控制点定义
2D
QuadraticBezierCurve
3D
QuadraticBezierCurve3
三维二次贝塞尔曲线
三次贝赛尔曲线
起点、终点和2个控制点定义
2D
CubicBezierCurve
3D
CubicBezierCurve3
三维三次Bezier曲线

4.多个线条组合曲线CurvePath

CurvePath
基类Curve
getPoints()方法:从曲线上批量返回顶点数据
属性curves
元素
Extras / Curves
2D
直线LineCurve
圆弧ArcCurve
椭圆EllipseCurve
样条曲线SplineCurve
3D
直线LineCurve3
二次贝塞尔曲线QuadraticBezierCurve3

5.曲线路径管道成型TubeGeometry

TubeGeometry
算法
通过一条曲线的顶点生成一个管道几何体geometry的顶点数据、face3数据
对于TubeBufferGeometry
顶点数据
.attributes.position
顶点索引
.index

6.旋转成型LatheGeometry

LatheGeometry
算法:一组顶点以y轴为旋转轴进行旋转生成旋转轮廓

7.Shape对象和轮廓填充ShapeGeometry

ShapeGeometry
算法:根据轮廓的顶点使用三角面Face3自动填充中间区域
第一个参数
Shape对象
Shape对象作为元素构成的数组
shape
绘制二维形状
外轮廓
shape继承基类Path的轮廓绘制方法
内部轮廓
.holes属性
数组:元素是Path对象
外部导入顶点
可视化解析地图数据
基类——子类
Curve——CurvePath——Path——Shape
Curve——CurvePath——ShapePath

8.拉伸扫描成型ExtrudeGeometry

ExtrudeGeometry
拉伸
扫描

第八章 、纹理贴图

1.创建纹理贴图

TextureLoader纹理加载器对象
.load()方法
执行load方法加载纹理图片成功后返回一个纹理对象Texture
回调函数
函数参数:纹理对象Texture
异步加载
加载后调用render方法,或者一直循环渲染
网格模型Mesh
几何体Geometry
顶点uv坐标数据
材质Material
材质的纹理贴图属性map
值:纹理对象texture
纹理对象Texture
image属性:image对象,html的img元素
图片加载器ImageLoader
加载一张图片,返回一个image对象,可以用来生成纹理
内部使用
文件加载器FileLoader
纹理贴图
图片宽高最好是2的次方
比如512X512、64X64…
支持常见的jpg、png等格式
协作:如何映射
3D美术:创建模型和纹理贴图
纹理贴图如何映射在几何体上
程序员:解析3D美术导出的资源
纹理贴图如何映射在几何体上,一般美术导出的模型会设置好,程序员只需要解析显示就可以

2.UV映射原理(顶点纹理坐标)

顶点数据
顶点位置position坐标数据
顶点颜色color数据
顶点法向量normal数据
顶点纹理坐标uv数据
和顶点位置、颜色、法向量等数据一一对应
纹理坐标和顶点坐标对应
uv映射的原理
几何体geometry纹理坐标数据
Geometry
Geometry
geometry.faceVertexUvs[0]
BufferGeometry
geometry.attributes.uv
映射
一个Face3三角形区域对应图片的一个三角形区域
Face3表示的三角形区域
顶点位置坐标数据
纹理图片的三角形区域
顶点纹理坐标
一个顶点位置坐标对应一个纹理坐标
协作:
webgl程序员只需要加载解析就可以
模型与贴图的对应关系,美术会设置好
会面会讲解3D模型的加载
纹理映射
外部模型
一般来说,有经验的3D美术都会导出符合要求的模型文件
设置好几何体的uv数据
threejs解析为缓冲类型几何体BufferGeometry
threejs的立方体、球体等API
threejs程序生成纹理坐标uv数据
球面映射

3.数组材质、材质索引materialIndex

Geometry
三角面Face3
材质materialIndex属性
材质索引materialIndex
一个几何体对象的不同三角面Face3可以通过材质索引设置不同的材质
threejs API
threejs立方体、球体等几何体API都有默认的材质索引设置materialIndex
BoxGeometry
默认每一个面的包含的Face3对应一个材质对象
纹理贴图
默认每一个面都采集整张纹理贴图
默认数组材质需要材质对象元素数量
球体、平面:1
圆柱体:3
立方体:6
所谓数组材质
就是threejs几何体API的算法自动设置系列Face3的材质索引属性materialIndex
BufferGeometry
groups属性
.groups : Array
元素
{ start: Integer, count: Integer, materialIndex: Integer }
材质索引materialIndex
材质count对应顶点数量
start对应第几个顶点的下标
材质索引的作用
一个几何体对象不同三角形可以对应不同材质
或者说一个网格模型可以具有多个材质对象
平面局部区域设置纹理贴图

4.纹理对象Texture(阵列、偏移、旋转…)

Texture对象
属性
重复、偏移、旋转等属性
纹理的matrix属性
旋转、平移改变matrix
本质
repeat:缩放矩阵
rotation:旋转矩阵
offset:平移矩阵
.offset,.repeat, .rotation
默认不会改变faceVertexUvs
方法
纹理方法transformUv
uv.applyMatrix3( this.matrix );
webgl封装
Texture.js
Texture对象
WebGLTextures.js
渲染器解析Texture对象
WebGL纹理相关API封装
gl.bindTexture
gl.activeTexture

5.canvas画布、视频作为纹理贴图

基类Texture
canvasTexture
和Texture类基本一样
封装了this.needsUpdate = true;
自动更新纹理对象
等效
CanvasTexture
texture = new THREE.CanvasTexture(canvas);
Texture
var texture = new THREE.Texture(canvas);
texture.needsUpdate = true;
注意更新
vedioTexture
texture = new THREE.VideoTexture(video)
等效
VideoTexture
Texture
var texture = new THREE.Texture(canvas);
更新
texture.needsUpdate = true;
语句位置
render函数中
保证每次执行render渲染一帧图片的时候,使用video最新的帧作为问纹理
TextureLoader.js
封装
texture.needsUpdate = true;
构造函数Texture
渲染:获取图片、canvas画布像素值
texture.image控制台打印
console.log(texture.image)
图片作为纹理

img作为纹理
canvas画布作为纹理

6.凹凸贴图、法线贴图(压缩模型)

法线贴图
法线贴图通过RGB三个分量分别表示法向量的xyz三个方向
通过图片保留几何体表面的几何细节
协作
3D美术
绘制精模、简模
通过精模烘培出法线贴图
导出简模和法线贴图
程序员
解析导出的模型和法线贴图
好处
低模+法线贴图=高模
降低模型大小,减少顶点的计算
节约顶点数量
精模
3D美术烘培使用
简模
导出给程序员使用
凹凸贴图
图片像素的灰度值表示几何表面的高低深度
如果定义了法线贴图,则将忽略该贴图
材质对象
MeshLambertMaterial、MeshBasicMaterial
没有凹凸、法线贴图属性
MeshPhongMaterial
属性
颜色纹理贴图
map属性
凹凸贴图
.bumpMap : Texture
.bumpScale : Float
表示深浅程度,默认值1
法线贴图
.normalMap : Texture
.normalScale : Vector2
表示深浅程度
默认值是Vector2设置为(1,1)

7.光照贴图添加阴影

投影在哪个网格模型的表面,就设置哪个网格模型的lightMap属性
属性值:阴影纹理图片
材质属性
lightmap
阴影贴图
lightMapIntensity
阴影明暗
作为投影平面的网格模型
设置投影Mesh几何体的uv
planeGeometry.faceVertexUvs[1] = planeGeometry.faceVertexUvs[0];
设置投影Mesh的材质属性
lightMap:textureLight,
faceVertexUvs
每个UV图层都是一个UV数组,与面中顶点的顺序和数量相匹配
[
[[Vector2, Vector2, Vector2],[Vector2, Vector2, Vector2]…],

[[Vector2, Vector2, Vector2],[Vector2, Vector2, Vector2]…] …
]
Array
元素1:Array
元素:[Vector2, Vector2, Vector2]
元素2:Array
元素:[Vector2, Vector2, Vector2]
faceVertexUvs[0]
材质map属性对应纹理贴图的坐标
元素:Vector2表示的纹理映射坐标,与几何体顶点坐标一一对应
采集像素值RGB
faceVertexUvs[1]
材质lightMap属性对应贴图的坐标
元素:Vector2表示的纹理映射坐标,与几何体顶点坐标一一对应
采集像素值RGB

8.高光贴图

MeshPhongMaterial
.specularMap : Texture
高光贴图属性
MeshLambertMaterial
MeshPhongMaterial
MeshPhongMaterial
specular
高光部分的颜色
shininess
高光部分的亮度,默认30
统一调整整个网格模型的高光效果
高光贴图
一个网格模型表面的不同位置可以通过图片不同灰度值表征表面反射效果

9.环境贴图

模拟环境反射,渲染效果更好
立方体纹理对象CubeTexture
基类Texture
image属性
Texture:一个img对象
CubeTexture:6个img对象组成的Array
纹理加载器
CubeTextureLoader:返回CubeTexture对象
textureLoader:返回Texture对象
通过环境贴图模拟要渲染的对象对周围环境的反射
设置环境贴图渲染的效果更好
一般美术做好相应的素材,程序员直接解析就可以
汽车效果查看
webgl_effects_parallaxbarrier.html

10.数据纹理对象DataTexture

生成含有透明度的像素数据
material材质对象
transparent:true,//允许透明设置
DataTexture构造函数
参数4:THREE.RGBAFormat
RGBA四个分量的范围0~255
透明度A设置:255*0.5表示半透明
纹理对象Texture
.type : number
这必须与.format相对应。 默认值为THREE.UnsignedByteType,将用于大多数纹理格式。
默认值THREE.UnsignedByteType
webgl:gl.UNSIGNED_BYTE
无符号整型,RGB每个颜色分量一个字节
THREE.UnsignedShort565Type
gl.UNSIGNED_SHORT_5_6_5
RGB每个分量分别占5、6、5比特
THREE.UnsignedShort4444Type
gl.UNSIGNED_SHORT_4_4_4_4
RGBA四个分量各占4比特
THREE.UnsignedShort5551Type
gl.UNSIGNED_SHORT_5_5_5_1
RGB三个分量各占5比特,A分量占1比特
.format : number
默认值为THREE.RGBAFormat,尽管TextureLoader会自动将此设置为THREE.RGBFormat以用于JPG图像。
图片格式
RGB
jpg、BMP
webgl
gl.RGB
three.js
THREE.RGBFormat
RGBA
PNG
webgl
gl.RGBA
three.js
THREE.RGBAFormat
Alpha
THREE.AlphaFormat
gl.Alpha
(0,0,0,A)
无论数据的RGB是多少都默认为0,黑色
TextureLoader.js
import { RGBAFormat, RGBFormat } from ‘…/constants.js’;
texture.format = isJPEG ? RGBFormat : RGBAFormat;
根据url正则判断是否是jpg或jpeg格式
jpg格式
RGBFormat
非jpg格式
RGBAFormat

第九章、相机对象(投影方式)

1.正投影和透视投影相机

相机对象
场景—相机—渲染器
相机拍照:本质就是投影计算的过程
物体是三维的,人看到的物体相当于物体在一个方向上的投影
正投影
透视投影
应用场景
正投影相机
小的场景,比如产品在线展示、机械、工业设计类三维建模软件模型的显示
投影效果
物体不受物体与相机的距离影响
透视投影相机
大的场景,比如游戏场景
投影效果
随着距离的变化显示的大小会变化
对比图
相机位置和拍摄方向属性
基类Object3D
相机位置属性position
相机目标观察点
.lookAt()方法
示意图
正投影相机OrthographicCamera
构造函数参数
透视投影相机PerspectiveCamera
构造函数参数
看到的场景多少
正投影
上下左右四个边界值整体缩放
远近边界
透视投影
调整视场角和距离场景中物体的距离
远近边界
相机对象Camera
视图矩阵
.matrixWorldInverse : Matrix4
世界矩阵matrixWorld的逆矩阵
投影矩阵
.projectionMatrix : Matrix4

2.窗口变化自适应渲染

相机对象
正投影相机
上下左右四个边界属性
k = window.innerWidth/window.innerHeight;//窗口宽高比
camera.left = -sk;
camera.right = s
k;
camera.top = s;
camera.bottom = -s;
前后边界属性不需要设置
透视投影相机
设置长宽比aspect
camera.aspect = window.innerWidth/window.innerHeight;
更新投影矩阵
正投影上下左右边界属性、透视投影长宽比属性变化,都会影响到各自投影矩阵的变化
默认情况,这些属性变化了,threejs不会自动更新投影矩阵,如果不手动更新,threejs渲染器渲染的时候读取相机的投影矩阵仍然是原来的
camera.updateProjectionMatrix ();
窗口事件
window.onresize
渲染器
重置渲染区域
renderer.setSize(window.innerWidth,window.innerHeight);

第十章、精灵模型、粒子系统

1.精灵模型对象Sprite

应用
大数据可视化
下雨、下雪、森林等效果
通过大量的精灵对象近似模拟
精灵模型Sprite
渲染效果
无论相机如何变化,始终平行于桌面的矩形区域
等价于
一个PlaneGeometry创建的矩形网格模型,正面永远朝着屏幕
基类Object3D
scale属性
设置精灵模型对象的大小
position属性
设置精灵模型对象的位置
不需要旋转属性
正面一直朝着屏幕
属性
.center : Vector2
精灵旋转点
值(0.5,0.5)对应于精灵的中点。 值(0,0)对应于精灵的左下角。 默认值为(0.5,0.5)
缩放、位置受相机影响
缩放:scale
位置:position
和网格模型受正投影、透视投影相机的影响一样
精灵材质SpriteMaterial
基类Material
.visible
.needsUpdate
.transparent

属性
颜色color
纹理贴图map
旋转rotation
弧度值,绕垂直屏幕方向旋转
lights
是否受光照影响,默认false
模型对比
点Points、线模型Line、网格模型Mesh
几何体geometry
材质material
点材质
线材质
网格材质
精灵模型Sprite
精灵材质SpriteMaterial
不包含几何体geometry参数
webgl封装
一个点精灵就是一个平面网格模型
4个顶点
WebGLSpriteRenderer.js
2个三角形,4个顶点,2个顶点复用,渲染出来一个矩形效果
矩形尺寸
1x1
四个顶点正负0.5,长宽都是1

2.中国城市PM2.5可视化案例

实现一个大小可控的圆形模型
Points不能表示,大小受限
Plane几何体+纹理贴图
精灵模型Sprite+纹理贴图
Circle几何体直接绘制出来圆形轮廓
2D可视化一般相机设置
沿着z轴观察
camera.position.set(0, 0, 200);
禁止相机控件旋转操作
controls.enableRotate = false;

3.树林效果

树林效果
一个树的颜色纹理贴图
足够数量精灵模型对象
精灵模型对象的位置在一个平面上随机分布
森林效果
多个树木、灌木、草的纹理贴图
每一种植物对应精灵的位置随机分布

4.下雨场景效果模拟

雨滴贴图
足够多精灵对象构成一个粒子系统
运动效果
雨滴在空间中随机分布
沿着一个方向运动,如果超出某个临界位置,重置雨滴对应精灵的位置

第十一章、帧动画模块

1.编辑关键帧并解析播放

帧动画应用
骨骼动画、变形目标动画、淡入淡出等
动画对象
关键帧KeyframeTrack
位置、颜色等属性随着时间变化
离散时间点对应离散属性值
剪辑AnimationClip
多个关键帧构成一个剪辑clip对象
操作AnimationAction
设置播放方式、开始播放、暂停播放…
混合器AnimationMixer
一个对象及其子对象的动画播放器
编辑动画
一般不会手动编辑,都是外部模型编辑好
播放动画

2.解析外部模型的的帧动画

模型文件
不支持
不是所有模型格式支持帧动画
比如stl、obj不支持
支持
支持格式threejs格式、GLTF、FBX等
支持格式对应加载器
threejs格式
THREE.JSONLoader
THREE.ObjectLoader
THREE.GLTFLoader
网络通用格式
THREE.FBXLoader
THREE.BVHLoader
THREE.ColladaLoader
THREE.MMDLoader
THREE.SEA3DLoader

3.播放设置(暂停、时间段、时间点)

.paused
可以暂停动画操作对象的播放
暂停
AnimationAction.paused = false;
恢复播放
AnimationAction.paused = true;
特定时间段播放clip
播放时间区间10~18
开始时间
AnimationAction.time=10;
结束时间
clip.duration = 18;
定位到clip的特定时间点
clip.duration = AnimationAction.time
始结束时间设置为一样,相当于播放时间为0,直接跳转到时间点对应的状态

第十二章 、骨骼、变形动画

1.骨骼动画原理

骨头关节Bone
树结构
通过该对象可以构建一个树结构
比如角色模型全身的运动关节
根据所有骨关节局部变换计算出每个关节的世界矩阵
父关节变化影响子关节位置
本质:矩阵运算
Bone1.add(Bone2);
Bone2是Bone1的子关节
通过Bone1的children属性可以访问Bone2
一个父关节可以有多个子关节
基类Object3D
继承相关的属性,可以进行矩阵运算
树结构
父关节运动会带动子关节运动
本质:矩阵运算
局部矩阵、世界矩阵
骨架对象Skeleton
骨架对象skeleton是通过骨头Bone构成的数组创建的
THREE.Skeleton([Bone1, Bone2, Bone3])
参数转化为.bones属性的值
.bones : Array
包含所有骨头关节对象
.boneInverses : Array
各个骨骼Bone世界矩阵matrixWorld的逆矩阵Matrix4构成的数组
骨头关节Bone角度变化,就会影响该属性
Geometry
.skinWeights : Array
每个顶点最多可以有4个骨骼对象Bone影响它
skinWeights属性是一个权重值数组
对应于几何体中顶点的顺序
顶点可以被4个骨骼Bone修改,因此Vector4用于表示该顶点的皮肤skin的权重weights
向量vector分量的值通常应在0和1之间
.skinIndices : Array
像skinWeights属性一样,skinIndices的值对应于几何体的顶点. 每个顶点最多可以有4个与之关联的骨骼
对比
对应关系
顶点位置、顶点颜色、顶点蒙皮权重、顶点蒙皮索引
一 一对应
顶点数据表示
位置坐标、法向量
三维向量Vector3表示
顶点蒙皮权重、顶点蒙皮索引
四维向量Vector4表示
属性
.vertices : Array
顶点位置坐标构成的数组
[ Vector3( 0.8,0.9,3.2 ), Vector3( 1.8,0.9,3.9 ) …]
.skinWeights : Array
顶点蒙皮权重构成的数组
[ Vector4( 0.8,0.1,0,0 ), Vector4( 0.3,0.2,0.1,0 ) …]
.skinIndices : Array
顶点蒙皮索引构成的数组
索引对应骨架对象Skeleton的属性.bones : Array
.bones包含所有骨头关节对象Bone
[ Vector4( 1,2,0,0 ), Vector4( 0,1,2,0 ) …]
改变几何体Geometry顶点
蒙皮索引属性
影响每个顶点的关节枚举
蒙皮权重属性
每个关节对应权重
骨关节自身的变化
世界矩阵
顶点坐标*权重然后执行矩阵变换
骨骼网格模型SkinnedMesh
基类Object3D → Mesh →SkinnedMesh
根关节添加到SkinnedMesh
执行
add()方法
SkinnedMesh.add(Bone1);
结果
children属性
骨骼根关节:SkinnedMesh.children[0]
绑定骨架对象skeleton和SkinnedMesh
执行
bind()方法
SkinnedMesh.bind(skeleton)
结果
.skeleton : Skeleton

2.加载外部模型骨骼动画

协作
美术
一般美术通过三维软件绘制好骨骼动画模型,然后导出
程序员
通过加载器加载模型,无论任何格式,返回的都是threejs的对象
然后使用帧动画模块的API解析骨骼动画数据
骨骼模型动画
网格模型绑定骨骼系统,网格模型的几何体设置蒙皮权重和蒙皮索引
通过帧动画的API控制骨骼的运动,进而控制网格模型几何体顶点坐标的变化

3.变形目标动画原理

几何体Geometry
.morphTargets : Array
变性目标morph targets作为元素组成的数组.
变形目标
{ name: “targetName”, vertices: [ new THREE.Vector3(), … ] }
一一对应
变形目标对象顶点属性vertices包含的顶点
几何体Geometry对象顶点属性vertices包含的顶点
按照顺序,一一对应
.morphNormals : Array
变形目标法线数据构成的数组. 变形法线具有与变形目标相似的结构
数组元素: 变形目标法线
{ name: “NormalName”, normals: [ new THREE.Vector3(), … ] }
.computeMorphNormals ()
计算几何体变形法线 .morphNormals.
材质Material
MeshLambertMaterial、MeshPhongMaterial…
.morphNormals : boolean
定义材质是否使用morphNormals. 默认 false.
.morphTargets : Boolean
定义材质是否使用morphTargets. 默认 false.
Mesh
.morphTargetInfluences : Array
变形目标影响权重组成的数组
权重:0~1之间

4.解析外部模型变形目标数据

协作
美术
设置好变形目标顶点数据,然后导出
程序员
通过加载器加载模型,无论任何格式,返回的都是threejs的对象
然后使用帧动画模块的API解析变形目标数据
获得帧动画数据
geometry.animations
变形目标生成帧动画
剪辑对象AnimationClip
CreateFromMorphTargetSequence()方法
从几何体的变形目标自动生成帧动画数据

第十三章 、语音模块

1.音频与场景关联(音源、监听者)

音频相关API
threejs音频相关API
是对原生Web Audio API的封装
PositionalAudio
基类Object3D → Audio →PositionalAudio
位置音频
AudioListener
监听者
Audio
非位置音频
AudioAnalyser
AudioContext
3D音效
PositionalAudio
基类Object3D → Audio →PositionalAudio
位置音频
音频源位置发生变化,听到的声音有所变化,比如音量大小
方向感、方位感、距离感…
作为对象的子对象出现
比如网格模型,模型位置变化表示音源位置变化
AudioListener
音频的虚拟监听者
监听者和音源距离变大,音量变小
监听者和音源关联
作为Audio或PositionalAudio构造函数的参数出现
camera
监听者listener对象是摄像机camera对象的子对象
相机的3D变换代表了监听者listener的3D变换
相机靠近声源:人靠近声源
相机旋转:人的头带着耳朵旋转
Audio
非位置音频
音量大小不受音源和监听者的距离影响

2.音乐可视化

AudioAnalyser
音频分析器
获得音频时域数据,进行快速傅里叶变换
构造函数
AudioAnalyser( audio, fftSize )
audio:音频对象
fftSize
快速傅里叶变换数据量的大小
一般为2的n次方,如512,1024,2048,4096等
默认2048
方法
getAverageFrequency
返回平均频率
getFrequencyData
返回所有频率

第十四章 、模型文件加载

1.Three.js数据结构、导入导出

课程目标
通过本节课的学习对三维模型文件的导出导入有更清晰的认知
threejs运行程序
threejs运行对象的数据结构
threejs保存导出对象的数据结构
数据结构
JavaScript API创建
通过JavaScript调用threejs API创建对象,对象包含一系列的属性
threejs渲染器WebGLRender通过解析对象的属性进行渲染
场景Scene
组Group…
模型Mesh/Line/Points
几何体
材质
纹理贴图
精灵模型Sprite
材质
光源对象Light
相机camera
导出
导出方法toJSON()
几何体、网格模型、材质、光源、相机…
导出数据
几何体
模型
场景scene
模型
光源
导出一个.json文件的过程
threejs对象
JavaScript语言调用threejs API生成一个对象
运行状态,解析以此为准
从threejs对象提取数据
执行toJSON方法得到一个对象
和原来threejs对象结构不同,但是表达的信息一致
JSON.stringify()方法
将JSON对象转为字符串
执行stringify方法,会自动调用toJSON来转换
HTML5的文件保存模块
加载解析
加载解析过程
加载josn文件
字符串转化为JSON对象
JSON.parse(string)
解析
根据JSON信息,JavaScript调用threejs相应的API创建对象
例如
BufferGeometryLoader.js
new Materials json.type ;
MaterialLoader.js
new BufferGeometry()
new TYPED_ARRAYS index.type
解析three.js格式的JOSN文件
加载器
根据需要选择
MaterialLoader
材质
BufferGeometryLoader
加载几何体顶点等数据
AnimationLoader
帧动画数据
TextureLoader
纹理数据
JSONLoader
ObjectLoader
对象
网格模型对象
模型构成的组
场景Scene
模型
光源

2.加载stl文件并解析

stl数据结构
stl格式
包含几何信息
没有材质等其他数据
STLLoader.js
three.js-master/examples/js/loaders/STLLoader.js
问题诊断
看不到
不在正中间
比例问题

3.加载obj文件(几何体、材质、贴图)

结构
obj文件
维基百科
没有光照信息
光照需要自己添加设置
.obj
OBJLoader.js
three.js-master/examples/js/loaders/OBJLoader.js
.mtl
MTLLoader.js
three.js-master/examples/js/loaders/MTLLoader.js
路径设置
obj文件的mtl文件名字
mtl中纹理贴图的名字
map_kd
map
map_ks
specularMap
map_bump/bump
bumpMap
解析原理
文件就是一串复合特定的标准的字符串
通过正则表达式提取信息
根据正则表达式得到一个obj、mtl对应对象
然后根据obj对象、mtl对象调用threejs对应的API进行创建场景对象
threejs渲染器渲染解析字符串创建好的场景
MTLLoader.js
createMaterial_
创建材质函数
默认使用MeshPhongMaterial材质描述obj模型的材质
解析规则
‘kd’
颜色属性color
‘ks’
高光颜色属性specular
‘map_kd’
漫反射纹理贴图Diffuse texture map
map属性
‘map_ks’
高光贴图specularMap属性
‘norm’
normalMap法线贴图属性

4.加载FBX并解析骨骼动画

结构
fbx
stl、obj都是静态模型,不可以包含动画
fbx除了包含几何、材质信息,可以存储骨骼动画等数据
FBXLoader.js
three.js-master/examples/js/loaders/FBXLoader.js
max、maya等软件可以直接导出

5.手镯在线预览(商品展示)

美术
包含贴图的obj模型
threejs editor导出json
贴图切换
美术导出多个纹理贴图
通过程序来切换

6.心脏预览(法线、高光、环境贴图)

贴图
普通颜色纹理贴图map
提供RGB值
法线贴图normalMap
减少模型顶点数量,节约计算资源,加快传输速度
高光贴图specularMap
一个网格模型不同的区域反射光线的能力不同
环境贴图envMap
反射周围环境,效果更逼真
光照
环境光和有方向的光源结合使用

第十五章、WebGL渲染器

1.场景渲染结果网页局部显示

场景scene
模型、光照
相机camera
渲染器WebGLrenderer
.domElement属性
渲染结果
renderer.domElement
含有3D场景投影信息的canvas对象
可以插入到body、div元素中
document.body.appendChild(renderer.domElement)
document.getElementById(‘pos’).appendChild(renderer.domElement)
.setSize()方法
设置渲染尺寸
控制canvas大小
输出画布canvas的大小调整为(width, height)
renderer.setSize(width, height)
注意
渲染尺寸更改后,相机的相关设置要改下
透视相机
渲染器:WebGLRenderer
得到一个含有3D场景投影信息的canvas对象

猜你喜欢

转载自blog.csdn.net/u014291990/article/details/82778586