这样看代码不是办法,一行一行看终究是不行的,只能适合自己有很大兴趣的时候,还是需要先对整体有个了解,其中某一部分是干什么的,然后挑自己喜欢的部分先看,这样才能更高效地看代码。
在 #0 中自己主要是对文件结构做了分析,只降到src文件下,那么今天就对src文件做一个整体的了解吧。
在 Three.js 之中可以看出,three是将所有的在子目录下的东西直接export出来,所以就有各式各样的 THREE.xxx ,这在看的时候应该也是挺方便的吧,就可以只看某一部分了。
总共15个子目录,都是什么功能呢?先结合文档和源码的结构大致看一下吧。
Scene
这个文件夹对应的是 Scene 对象吧, Scene 在three中是一个container的角色,把所有的Object放进来。里边有一些util的功能。
three中的事件系统在这里有,自己之后或许要看一看。
场景里边有一些属于自己的东西,比如 background , environment texture , fog ,fog在这里还是有点有趣的,放到了场景之下,有linear和exponential square两种,具体实现之后再说。
Math
这是自己全部逐行看完的,应该还是比较清楚的,定义了好多数据结构,向量、矩阵、以及一些3D中常用的操作,比如旋转之类的,以及相应的基本物体:cube,sphere,ray,frustum等等。
Camera
three中所有的camera类型,这里涉及到了three中的坐标变换,这个需要专门集中整理下,是后续的事情了,主要是local和world坐标系,这个在cameras中体现的还是比较明显的。
其中, Camera 算是基类,其它的有各式各样的camera,用于不同的用途,其中这个 CubeCamera 还挺高级,之后可以研究下。
另外还有 ArrayCamera ,多个camera组合在一起处理,提升render时候的效率。
Audio
音频的部分,这个可以不用太管,与图形相关的比较少,可以不看。
Animation
整个Three的动画系统还是很复杂和全面的,就像文档里提到的那样:
To achieve all this in one homogeneous system, the three.js animation system has completely changed in 2015 (be aware of outdated information!), and it has now an architecture similar to Unity/Unreal Engine 4.
看了文档之后有一定的了解,结构大致说的还是很清楚的,对于动画部分还是不太了解,这个可以作为专题进行研究。
Core
core里边放了各种乱七八糟的最基本的东西,比如好多类的基类,以及其它一些比较基本的东西,值得逐个看一下。
首先有一个算是整个three里最基本的类: Object3D , 是所有object的基类
其次是 Geometry 相关的,有:
Geometry: API友好的几何类BufferGeometry: 直接跟buffer相关,效率高DirectGeometry: 用于Geometry转换到BufferGeometry
以及buffer对应的 Attribute ,就是WebGL的attribute吧,还有instanced版本的buffer或者attribute
除此之外,剩下了这么几个文件:
Clock事件相关的,应该就是封装了几个API吧EventDispatcher这个之前好戏那个看过,算是对JS本身事件的一个封装Face3用在geometry中,表示面中点的关系吧,类似于一个indexLayers层级的控制,类似一种tag的东西,用于分组,控制可见性什么的Raycaster字面意思,用于鼠标定位吧,还是值得一看的,做交互的时候很有用Uniform传到WebGL shader中的uniform,这里只是声明了一下,应该在renderer中会有对应的parser
core这一部分还是可以优先看一下的,比较基本,然后也比较重要
Extras
extras里边感觉全是乱七八糟的东西,需要好好瞧一瞧。
首先有一些util的东西,相关的帮助函数吧:
ImageUtilShapeUntil
还有两个高级的东西,某个特定的算法吧:
EarcutPMREMGenerator
有个 ImmediateRenderObject ,只有在renderer里出现过,估计是用户可以继承,然后相当于有个标签,renderer区别对待。
在 extras/core 文件夹下,有许多的基类,算是一些util的东西,或者是一些有趣的功能吧,结构还是很简单的,然后功能也相对独立。
剩下的 extras/curves 里,就是各种花式的curve了。
Geometries
经常可以看到一个 Mesh 或者 Line 构造的时候需要一个 geometry 和一个 material 的参数,这算是一种分离,一个对象通常有纯几何的部分、材质部分以及其它必要的部分构成。这里的Geometries应该就是各种几何体了。
这一部分发现three都换成ES6的语法了,高级高级,结构也是非常清晰的。
大概有两种: Geometry 和 BufferGeometry ,配上各种各样的几何体,组合出所有的geometries。这个应该内部存储的是WebGL的buffer类似的东西,可以很方便的绘制。
Helpers
算是明白了这个helper的含义,这个在真实使用的时候用不到,感觉更多的用在three那个在线的editor中,现实一些平面,坐标轴,相机灯光以及包围盒等,有一定的辅助意义吧。
具体来看,
BoxHelper : box形状的线框包围盒AxesHelper , GridHelper , PolarGridHelper : 显示坐标轴和网格平面,这个是一般三维软件需要使用的CameraHelper , DirectionalLightHelper , PointLightHelper , SpotLightHelper , HemisphereLightHelper : 相机灯光的相关显示Box3Helper :就是显示一个包围盒,和 BoxHelper 不同的是可以独立显示一个box3的线框(注意box3只是一个数学概念,画一个box的时候,用 BoxGeometry )ArrowHelper : 显示一个向量,就是一个箭头SkeletonHelper : 显示角色的骨骼,也是一种辅助线工具吧
Lights
光照应该也是相对独立的一个部分,不过可能因为阴影,或者材质等等会相关,有一定的交集。
首先是有一个基类的 Light , 然后就是各种各样的light了:
- AmbientLight
- DirectionalLight
- HemisphereLight
- PointLight
- RectAreaLight
- SpotLight
这个都在意料之中,基本都会这么组织多个light
另外还有两种对象: LightProbe 和 LightShadow
Shadow相对好理解,每种灯光计算的方式可能不同,之后要看一看阴影是如何计算的
Probe是个比较生疏的概念,源码中的文档中只有一行注释:
A LightProbe is a source of indirect-diffuse light
就效果来看,类似于一种环境光,这部分具体看代码的时候再说,或者自己再对这个概念熟悉熟悉
那么这就是Light部分的全部了,还是比较清晰的。
Loaders
Loader这一部分应该也比较清晰,算是一些外围功能,将多种东西load进来,视频、音频、贴图、图片、材质等等。
有基类 Loaders , 然后就是各种各样的继承的loader了:
AnimationLoaderAudioLoaderBufferGeometryLoader: 算是Three内部的格式了,应该之后的部分会提到CompressedTextureLoaderCubeTextureLoaderDataTextureLoaderFileLoader: load一般的文件,其它loader内部也用到了它FontLoaderImageBitmapLoaderImageLoaderMaterialLoaderTextureLoader
除此之外,还有两个辅助的东西:
LoaderUtils: 可能会用到的两个静态方法吧LoadingManager: 控制loading过程中的一些行为,比如显示开始,完成,百分比之类的
Materials
处理材质相关的代码
虽然文件很多,代码也很多,但是整体还是很清晰的,就是一个 Material 基类,然后剩下的就全是派生的各式各样的material了,具体内部的细节之后再说,毕竟材质也是很大的一块内容
Objects
Three中的内置对象,比如最经常用到的 Mesh ,除此之外还有 Line , Points 等等,这里需要注意的是,在three中, Math 里的那个 Line3 是一个抽象概念,而这里的是实实在在的,可以渲染出来的。
这里的许多概念都直接和WebGL对应,比如 Line , LineLoop , LineSegements 等等。除此之外也有一些比较有趣的object,比如 LOD , Sprite 等,用于一些特殊的地方。
整体结构就是平坦的,每个文件对应一个object,还算清晰。
Renderers
底层渲染的部分,应该是比较复杂,也是比较核心,同时也是自己需要好好看的部分。
WebGLRenderer: 应该算是最核心的部分了吧,单文件2800+line,很可以,估计是各种基本属性的设置WebGLRenderTarget: 渲染的目标,比如是屏幕上,还是某贴图上等等,可以设置到renderer中WebGLMultisampleRendererTarget,WebGLCubeRenderTarget: 两种特殊的target吧,后续再看
webxr相关的东西也有,是与AR和VR相关的
webgl文件夹先的估计就是所有的webgl相关的功能,一些封装等等,还是很多的
shader的组织方式也值得学习一下,不过这些都是之后的细节了
总体来看,renderer这一部分算是最复杂的一个部分了,也是自己日后的重点
Textures
贴图相关的部分,自己对贴图不太了解,之后需要好好看看。
Texture : 算是对WebGL的texture一些简单的封装吧
剩下的几种texture: DataTexture , VideoTexture 分别是应用到不同类别的texture上,大同小异
