1. 程序结构
    1. 场景(Scene)
      1. 网格模型(Mesh)
        1. 几何体(Geometry)
          1. 形状
          2. 尺寸
        2. 材质(Material)
          1. 颜色
          2. 贴图
          3. 透明度
      2. 光照(Light)
        1. 颜色
        2. 分类
          1. 环境光
          2. 点光源
          3. 平行光
    2. 相机(Camera)
      1. 位置
      2. 视线方向
      3. 投影方式
        1. 透射投影(PerspectiveCamera)
        2. 正射投影(OrthographicCamera)
    3. 渲染器(Renderer)
      1. 渲染器创建
        1. WebGLRenderer()
      2. 开始渲染
        1. .render(scene,camera)
      3. domElement属性
        1. canvas对象
    4. 辅助对象
      1. 坐标轴
        1. AxesHelper
      2. 光源
        1. SpotLightHelper
        2. PointLightHelper
        3. DirectionalLightHelper
  2. 几何体(Geometry)
    1. 基类Geometry
    2. BufferGeometry
      1. 内部数据组织形式与GPU所期待的数据结构保持一致,从而进一步提高了运行效率。
    3. 分类
      1. 几何体
        1. 常见
          1. 长方体(BoxGeometry)
          2. 圆柱体(CylinderGeometry)
          3. 球体(SphereGeometry)
          4. 圆锥、棱锥(ConeGeometry)
        2. 正多面体
          1. 正四面体(TetrahedronGeometry)
          2. 正八面体(OctahedronGeometry)
          3. 正十二面体(DodecahedronGeometry)
          4. 正二十面体(IcosahedronGeometry)
        3. 平面
          1. 环平面(RingGeometry)
          2. 矩形平面(PlaneGeometry)
          3. 圆平面(CircleGeometry)
        4. 2D转3D
          1. 拉伸、扫描(ExtrudeGeometry)
          2. 旋转(LatheGeometry)
          3. 管道(TubeGeometry)
        5. 轮廓填充(ShapeGeometry)
        6. 文字(TextGeometry)
        7. 参数化曲面(ParametricGeometry)
      2. 曲线
        1. Extras/Core
          1. Curve
          2. CurvePath
          3. Path
          4. Shape
          5. ShapePath
        2. Extras/Curves
          1. 基类(Curve)
          2. 2D
          3. 直线(LineCurve)
          4. 圆弧(ArcCurve)
          5. 椭圆(EllipseCurve)
          6. 样条曲线(SplineCurve)
          7. 二维贝塞尔曲线
          8. 二次(QuadraticBezierCurve)
          9. 三次(CubicBezierCurve)
          10. 3D
          11. 直线(LineCurve3)
          12. 三维样条曲线(CatmullRomCurve3)
          13. 三维贝塞尔曲线
          14. 三次(CubicBezierCurve3)
          15. 二次(QuadraticBezierCurve3)
    4. 自定义几何体
      1. 使用 Vector3 构建顶点,使用 Face3 通过顶点索引构建面。顶点顺序为顺时针则面向摄像机。
        1. 创建后执行computeFaceNormals()方法。来计算每个面的法向量。
    5. 构造实体几何体 (ConstructiveSolidGeometry)
    6. 几何体合并
      1. 性能更好。
        1. 不能为每个几何体单独添加材质。某种程度上可以用THREE.MeshFaceMaterial对象来解决。
        2. 合并后的 geometry 无法单独控制,除非能探索到相应的面和顶点,并分别对它们进行操作。
    7. 顶点
      1. 位置 position
        1. 几何体所有顶点中,每三个顶点为一组可以确定一个三角形。
      2. 颜色 color
        1. 模型的颜色取决于材质,如果把材质属性.vertexColors的值设置为THREE.VertexColors,threejs渲染模型的时候就会使用几何体的顶点颜色数据geometry.attributes.color。
      3. 法向量 normal
        1. 为了表示物体表面各个位置的法线方向,可以给几何体的每个顶点定义一个方向向量。
      4. UV
        1. 顶点纹理坐标数据,用于图片映射
        2. 和顶点位置、颜色、法向量等数据一一对应
        3. Geometry
          1. .faceVertexUvs[0]
          2. .faceVertexUvs[1]
        4. BufferGeometry
          1. .attributes.uv
          2. .attributes.uv2
  3. 材质(Material)
    1. 基础属性
    2. 融合属性
      1. 将 blending 模式设成THREE.AdditiveBlending,可以使纹理图片的黑色背景不显示。
    3. 分类
      1. 点材质(PointsMaterial)
      2. 线材质
        1. 线基础材质(LineBasicMaterial)
        2. 虚线材质(LineDashedMaterial)
      3. 网格材质
        1. 网格基础材质(MeshBasicMaterial)
          1. 不会对光源有任何反应
        2. 网格Lambert材质(MeshLambertMaterial)
          1. 暗淡、漫反射
        3. 网格Phong材质(MeshPhongMaterial)
          1. 高亮表面、镜面反射
        4. PBR材质
          1. MeshStandardMaterial
          2. 能够更好地表现塑料质感和金属质感
          3. MeshPhysicalMaterial
          4. 与 MeshStandardMaterial 相似,提供了对反光度的更多控制。
        5. 网格深度材质(MeshDepthMaterial)
          1. 外观由物体到摄像机的距离决定。将这种材质与其他材质结合使用,从而创建逐渐消失的效果。
        6. 网格法向量材质(MeshNormalMaterial)
          1. 法向量用来决定光的反射,有助于将纹理映射到三维模型,并提供有关如何计算光照、阴影和为表面像素着色的信息。
        7. 具有自发光属性,场景中没有光源时,对象表面的自发光颜色也可见。
      4. 精灵Sprite材质(SpriteMaterial)
      5. 自定义着色器材质
        1. RawShaderMaterial
          1. 和 BufferedGeometry 一起使用, 用于优化静态几何体。
        2. ShaderMaterial
      6. 材质类型和模型一一对应
    4. 联合材质
      1. SceneUtils.createMultiMaterialObject()
      2. 创建的并不是一个THREE.Mesh对象实例,而是为 materials 数组中每个指定的材质创建一个实例,并把这些实例存放在一个组里(THREE.Object3D对象)。
    5. 材质索引materialIndex
      1. Geometry
        1. 三角面Face3
          1. 材质materialIndex属性
          2. 材质索引materialIndex
          3. 一个几何体对象的不同三角面Face3可以通过材质索引设置不同的材质
        2. threejs立方体、球体等几何体API都有默认的材质索引设置materialIndex
        3. BoxGeometry
          1. 默认每一个面的包含的Face3对应一个材质对象
          2. 纹理贴图
          3. 默认每一个面都采集整张纹理贴图
        4. 默认数组材质需要材质对象元素数量
          1. 球体、平面:1
          2. 圆柱体:3
          3. 立方体:6
        5. 所谓数组材质,就是threejs几何体API的算法自动设置系列Face3的材质索引属性materialIndex
      2. BufferGeometry
        1. groups属性
          1. .groups : Array
          2. 元素
          3. { start: Integer, count: Integer, materialIndex: Integer }
          4. 材质索引materialIndex
          5. 材质count对应顶点数量
          6. start对应第几个顶点的下标
      3. 材质索引的作用
        1. 一个几何体对象不同三角形可以对应不同材质
        2. 或者说一个网格模型可以具有多个材质对象
  4. 模型
    1. 分类
      1. 点模型
        1. 渲染模式
          1. 点(Points)
      2. 线模型
        1. 渲染模式
          1. 线(Line)
          2. 闭环线(LineLoop)
          3. 间断线(LineSegments)
      3. 网格模型
        1. 渲染模式
          1. 三角形(Mesh)
        2. wireframe=true时,所有三角形会以线条形式绘制出来。
      4. 每种模型,都有对应类型的材质
    2. 模型基类
      1. Object3D
        1. 方法
          1. 平移,translate()
          2. 沿X轴平移(translateX) 沿Y轴平移(translateY) 沿Z轴平移(translateZ) 沿axis平移(translateOnAxis) 改变.position属性
          3. 旋转
          4. 绕X轴旋转(rotateX) 绕Y轴旋转(rotateY) 绕Z轴旋转(rotateZ) 绕axis轴旋转(rotateOnAxis) 改变.rotation和.quaternion属性
          5. clone()
          6. N = M.clone()表示返回一个和M相同的对象N。
          7. copy()
          8. A.copy(B)表示B属性的值赋值给A对应属性。
          9. 网格模型对象的几何体属性mesh.geometry和材质属性mesh.material的属性值都是对象的索引值。
        2. 属性
          1. 缩放,scale: Vector3
          2. 位置,position: Vector3
          3. 位置是相对于父对象的。
          4. 角度,rotation: Euler
          5. 四元数,quaternion: Quaternion
  5. 精灵模型
    1. 创建精灵模型对象不需要创建几何体对象Geometry,精灵模型对象本质上你可以理解为已经内部封装了一个平面矩形几何体PlaneGeometry。
      1. 矩形精灵模型与矩形网格模型的区别在于精灵模型的矩形平面会始终平行于Canvas画布。
    2. 粒子(Points)和精灵(Sprites)的效果是一样的。精灵多会有性能问题,但是能够单个控制。
    3. 可以基于一个复杂的几何体的顶点创建 Points 对象。
  6. 组对象
    1. 通过Threejs的组对象Group可以组织各个模型,构成一个层级结构。
    2. Group
      1. 父对象group进行旋转、缩放、平移变换,子对象同样跟着变换。
      2. 方法
        1. add()
          1. 向属性.children中添加子对象
        2. remove()
          1. 从属性.children中删除子对象
        3. traverse()
          1. 递归遍历模型对象的所有后代
        4. getObjectById()
          1. 查找树结构的某个后代对象
        5. getObjectByName()
          1. 查找树结构的某个后代对象
      3. 属性
        1. .children
          1. 访问子对象,子对象属性.children的值是数组
        2. .name
          1. 命名
      4. 本地和世界
        1. 三维坐标
          1. .position 和 getWorldPosition()
        2. 缩放系数
          1. .scale 和 .getWorldScale()
        3. 矩阵
          1. .matrix 和 .matrixWorld
          2. 一个对象的世界矩阵是对象本地矩阵和父对象的世界矩阵的乘积。
  7. 后处理
    1. 代码实现
      1. 创建THREE.EffectComposer(效果组合器)对象。
      2. 配置THREE.EffectComposer对象,使它可以渲染场景,并应用后期处理。
        1. 添加各种通道,每个通道都会按照其加入到THREE.EffectComposer的顺序执行。
      3. 在渲染循环中,使用THREE.EffectComposer来渲染场景、应用通道和输出结果。
    2. 后期处理通道
    3. 遮罩(mask):可以在特定的区域使用通道
    4. THREE.ShaderPass:自定义效果
  8. 工具
    1. 控件
      1. 摄像机控件
    2. Helper
      1. CameraHelper
        1. 通过 light.shadow.camera 调试阴影
      2. SpotLightHelper
  9. 插件
    1. 物理效果
      1. Physijs
        1. 是基于另外一个物理引擎:ammo.js
  10. 拾取
    1. CPU 拾取
      1. (1)基于屏幕上的点击位置会创建一个THREE.Vecor3向量。 (2)使用vector.unproject方法将屏幕坐标转换成三维场景中的坐标。 (3)然后,创建THREE.Raycaster。向场景中发射光线。从摄像机的位置(camera.position)向场景中鼠标的点击位置发射光线。 (4)使用raycaster.intersectObjects方法来判断指定的对象中哪些被该光线照射到了。
      2. 返回结果
        1. face和faceIndex:该网格中被选中的面。
        2. distance:从摄像机到被点击对象的距离。
        3. uv:点击位置所对应的2D纹理的uv值。
    2. GPU 拾取
  11. 加载外部模型
    1. 加载器
      1. STL
        1. .stl格式的三维模型不包含材质Material信息,只包含几何体顶点数据的信息,你可以简单地把stl文件理解为几何体对象Geometry。
        2. STLLoader
      2. obj与mtl
        1. .obj和.stl文件包含的信息一样都是几何体顶点相关数据,材质文件.mtl包含的是模型的材质信息,比如颜色、贴图路径等。
        2. OBJLoader
        3. MTLLoader
      3. FBX
        1. fbx除了包含几何、材质信息,可以存储骨骼动画等数据。
        2. FBXLoader
      4. Collada
        1. ColladaLoader2
      5. PLY
        1. PLYLoader
      6. GLTF
        1. GLTFLoader
  12. 动画
    1. 帧动画
      1. 帧动画应用
        1. 骨骼动画、变形目标动画、淡入淡出等
      2. 编辑
        1. 关键帧KeyframeTrack
          1. 位置、颜色等属性随着时间变化
          2. 离散时间点对应离散属性值
        2. 剪辑AnimationClip
          1. 多个关键帧构成一个剪辑clip对象
      3. 播放
        1. 操作AnimationAction
          1. 设置播放方式、开始播放、暂停播放...
        2. 混合器AnimationMixer
          1. 一个对象及其子对象的动画播放器
    2. 骨骼动画
      1. 骨头关节Bone
        1. 树结构,一个父关节可以有多个子关节
        2. 基类Object3D
      2. 骨骼网格模型SkinnedMesh
        1. 基类Mesh
          1. 基类Object3D
      3. Geometry
        1. .skinWeights : Array,顶点权重数组
        2. .skinIndices : Array,顶点索引
      4. 骨架对象Skeleton
        1. 骨头Bone构成骨架Skeleton
        2. 绑定skeleton和SkinnedMesh
    3. 变形动画
      1. 通过几何体Geometry的变形目标属性.morphTargets设置好变形动画。
    4. requestAnimationFrame
      1. 按照一定的周期不停地调用渲染方法.render()
  13. 相机对象
    1. 基类(Camera)
      1. 属性
        1. 视图矩阵.matrixWorldInverse
        2. 投影矩阵.projectionMatrix
    2. 分类
      1. 正投影,平行投影相机 (OrthographicCamera)
      2. 透视投影,中心投影相机 (PerspectiveCamera)
      3. 其他类型
        1. 立方相机(CubeCamera)
        2. VR相机(StereoCamera)
    3. 方法
      1. lookAt()
    4. 自适应渲染
      1. 重新获取浏览器窗口新的宽高尺寸,然后通过新的宽高尺寸更新相机Camera和渲染器WebGLRenderer的参数。
  14. 光源
    1. 基类Light
      1. 颜色(color)
      2. 强度(intensity)
    2. 分类
      1. 环境光(AmbientLight)
        1. 没有特定方向的光源,主要是均匀整体改变Threejs物体表面的明暗效果。
        2. 环境光颜色RGB成分分别和物体材质颜色RGB成分分别相乘。
        3. 不能将它作为场景中的唯一光源,否则所有物体都是同一个颜色。
      2. 平行光(DirectionalLight)
        1. 对于一个平面而言,平面不同区域接收到平行光的入射角一样。
        2. 通过位置.position和目标.target两个属性来一起确定平行光方向。
        3. 平行光漫反射简单数学模型:漫反射光的颜色 = 网格模型材质颜色值 * 光线颜色 * 光线入射角余弦值
      3. 点光源(PointLight)
        1. 光线沿着发光核心向外发散,同一平面的不同位置与点光源光线入射角是不同的,点光源照射下,同一个平面不同区域是呈现出不同的明暗效果。
      4. 聚光灯光源(SpotLight)
        1. 个沿着特定方会逐渐发散的光源,照射范围在三维空间中构成一个圆锥体。
      5. 其他类型
        1. 半球光光源(HemisphereLight)
          1. 可以创建出更加贴近自然的户外光照效果。
        2. 区域光光源(AreaLight)
        3. 光晕(LensFlare)
    3. 阴影
      1. 投影模拟计算
        1. 设置产生投影的模型对象
          1. mesh.castShadow:设置一个模型对象是否在光照下产生投影效果。
        2. 设置接收投影效果的模型
          1. mesh.receiveShadow:设置一个模型对象是否在光照下接受其它模型的投影效果。
        3. 设置光源对象
          1. light.castShadow:光源将投射动态阴影。
      2. .shadow属性
        1. DirectionalLight.shadow
          1. DirectionalLightShadow
        2. SpotLight.shadow
          1. SpotLightShadow
        3. 基类:LightShadow
          1. .camera属性
          2. 从光的角度来看,以相机对象的观察位置和方向来判断,其他物体背后的物体将处于阴影中。
          3. 结合 THREE.CameraHelper 可用于调试阴影。
          4. .mapSize属性
          5. 定义阴影纹理贴图宽高尺寸的一个二维向量Vector2。
          6. .map属性
          7. WebGL渲染目标对象WebGLRenderTarget,使用内置摄像头生成的深度图; 超出像素深度的位置在阴影中。
      3. 如果场景中的光源或物体持续运动,则必须重复计算阴影。如果是静止不动的光源和物体,则可以计算一次阴影并重复使用。
        1. 环境光遮挡贴图
        2. 光照贴图
  15. 纹理贴图
    1. 分类
      1. 颜色贴图(.map)
      2. 法线贴图(.normalMap)
        1. 复杂的三维模型3D美术可以通过减面操作把精模简化为简模,然后把精模表面的复杂几何信息映射到法线贴图.normalMap上。
        2. 法线贴图通过RGB三个分量分别表示法向量的xyz三个方向。
        3. 不需要改变模型的实际形状;所有顶点都保持在原始位置不变。这些贴图利用场景中的光照来制造伪深度和细节。
        4. 协作
          1. 3D美术
          2. 绘制精模、简模
          3. 通过精模烘培出法线贴图
          4. 导出简模和法线贴图
          5. 开发
          6. 解析导出的模型和法线贴图
        5. 优点
          1. 低模+法线贴图=高模
          2. 降低模型大小,减少顶点的计算
          3. 节约顶点数量
          4. 精模,3D美术烘培使用
          5. 简模,导出给程序员使用
      3. 凹凸贴图(.bumpMap)
        1. 图片像素的灰度值表示几何表面的高低深度
        2. 凹凸图只包含像素的相对高度,没有任何倾斜的方向信息。所以使用凹凸贴图所能表达的深度信息有限,要想实现更多细节可以使用法向贴图。
        3. 如果定义了法线贴图,则将忽略该贴图
      4. 位移贴图(.displacementMap)
        1. 法向贴图和凹凸贴图都只能在物体表面生成一种凹凸不平的假象,而移位贴图则能够根据贴图的内容,真正改变模型的形状。
        2. 模型必须具有大量顶点,否则其顶点移位效果看起来会与移位贴图并不相像。这是因为顶点过少的模型没有足够的顶点可以移动。
      5. 环境光遮挡贴图(.aoMap)
        1. 模型接受的光照差异可以被渲染(又称烘焙)到一张纹理贴图上,然后与颜色贴图混合在一起应用到模型上。
        2. 作用是指出模型上哪些部分处于阴影中,应该从环境光中接受较少的光照。
      6. 光照贴图(阴影贴图)(.lightMap)
        1. 光照贴图·lightMap是3D美术渲染好提供给开发。模型的光照信息被预先烘焙到了纹理贴图中。提高渲染性功能。
      7. 金属度贴图(.metalnessMap)
        1. 在一个表面粗糙的物体上指定一些闪亮的局部。
      8. 粗糙度贴图(.roughnessMap)
        1. 在一个光滑的物体上指定一些粗糙的局部。
      9. Alpha贴图(.alphaMap)
      10. 自发光贴图(.emissiveMap)
        1. 即使当场景中的光源很暗淡时,物体的自发光部分仍然会保持固定的亮度。
      11. 高光贴图(.specularMap)
        1. 如果网格模型外表面不同区域的镜面反射能力相同,可以直接设置材质的高光属性.specular。
        2. 如果不同,通过高光贴图.specularMap的RGB值来描述不同区域镜面反射的能力。
        3. 高光贴图用于指定物体表面中哪部分比较闪亮,与THREE.MeshStandardMaterial材质的金属光泽度贴图和粗糙度贴图的作用有些接近。
        4. 必须使用THREE.MeshPhongMaterial材质。
      12. 环境贴图(.envMap)
        1. 创建一个立方体盒子作为天空盒使用,然后把一个环境中上下左右前后六张视图图片作为立方体盒子的纹理贴图使用。
        2. 高光网格材质MeshPhongMaterial和物理PBR材质MeshStandardMaterial通常会使用环境贴图.envMap来实现更好的渲染效果。
          1. 增加metalness值使物体的镜面有反射效果。
      13. 材质对象
        1. MeshLambertMaterial、MeshBasicMaterial
          1. 没有凹凸、法线贴图属性
        2. MeshPhongMaterial
          1. 属性
          2. 颜色纹理贴图
          3. map属性
          4. 凹凸贴图
          5. .bumpMap : Texture
          6. .bumpScale : Float,表示深浅程度,默认值1
          7. 法线贴图
          8. .normalMap : Texture
          9. .normalScale : Vector2,表示深浅程度,默认值是Vector2设置为(1,1)
      14. 只能用于静态场景,或者场景中静态的物体。
    2. 创建纹理贴图
      1. TextureLoader纹理加载器
        1. .load()方法
          1. 执行load方法加载纹理图片成功后, 回调返回一个纹理对象Texture
        2. 异步加载
          1. 加载后调用render方法,或者一直循环渲染
      2. 网格模型Mesh
        1. 几何体Geometry
          1. 顶点uv坐标数据
        2. 材质Material
          1. 材质的纹理贴图属性map
          2. 值:纹理对象texture
      3. 纹理对象Texture
        1. image属性:image对象,html的img元素,或者使用 ImageLoader 来加载图像
      4. 纹理贴图缩放
        1. magFilter 属性和 minFilter 属性
        2. mipmap 属性
        3. 图片宽高最好是2的次方,比如512X512、64X64…… 支持常见的jpg、png等格式。
      5. 协作:如何映射
        1. 3D美术:创建模型和纹理贴图,一般美术导出的模型会设置好,程序员只需要解析显示就可以
        2. 开发:解析3D美术导出的资源
      6. 纹理UV坐标
        1. 映射
          1. 把图片的每个纹理坐标和模型的顶点位置建立一对一的关系,就可以实现图像到模型的映射。
          2. 矩形贴图和球面的映射图
        2. 几何体有两组UV坐标
          1. 第一组组用于.map、.normalMap、.specularMap等贴图的映射
          2. 第二组用于阴影贴图.lightMap的映射
        3. 重复纹理
          1. RepeatWrapping:允许纹理重复自己。
          2. ClampToEdgeWrapping:重复纹理边缘的像素来填满剩下的空间。
    3. Texture对象
      1. 子类
        1. CanvasTexture
        2. VideoTexture
      2. 属性
        1. 阵列
        2. 偏移
        3. 旋转
        4. matrix
          1. 本质
          2. repeat:缩放矩阵
          3. rotation:旋转矩阵
          4. offset:平移矩阵
        5. 默认不会改变faceVertexUvs
      3. 方法
        1. 纹理方法transformUv
  16. 场景
    1. 属性
      1. 雾化(fog)
      2. overrideMaterial
        1. 场景中所有物体都共享同一个材质,可以减少材质数量来提高运行效率。
  17. 可以使用THREE.WireframeGeometry 得到线框几何。
  18. 创建包含其他模型的镜面反射效果
    1. 使用THREE.CubeCamera
      1. 为一个立方体相机,拍照时它会分别对着六个方向拍摄六张照片,对包含所有物体的场景拍摄快照并用获得的快照图片来创建CubeMap。
      2. 使用CubeCamera拍摄场景快照时,要将该摄像机准确摆放在需要产生镜面反射的物体的位置上。