此答案适用于 Three.js r84。
Three.js 使用了 3 种几何图形:
Geometry 以用户友好的方式存储几何参数(顶点、法线、颜色...)。
BufferGeometry 将几何图形存储在 BufferAttribute 中,它们只是缓冲区(或 typed arrays)的包装器,其中包含您通常使用 gl.bufferData() 发送的数据。
(DirectGeometry 仅用于将Geometry 转换为BufferGeometry。)
基本上,常见的 Three.js 渲染器 WebGLRenderer 处理 BufferGeometry 而用户处理 Geometry。
但是,只要您不渲染场景,就不会进行几何转换,也不会向 GPU 发送任何内容。 (未创建缓冲区。)
为了防止引擎使用缓冲区等 WebGL 特定的东西污染用户空间,Three.js 实现了包含在渲染器中的某种包装器。其中两个包装器是:
用户对象和这些包装器内的对象之间的映射是通过uuid 属性完成的。
当请求渲染时,渲染器浏览场景的所有对象。如果对象uuid 不存在于其中一个包装器中,则会进行一些处理并存储转换后的对象。
这就是事情变得有趣的地方,因为这是在 WebGLGeometries 包装器内将对象的 Geometry 转换为 BufferGeometry 并在 WebGLAttributes 包装器内将 BufferGeometry 转换为一个或多个 WebGLBuffer使用您列出的功能:
gl.createBuffer();
gl.bindBuffer();
gl.bufferData();
检查此file 以查找实际呼叫。
另外,当像Geometry 这样的对象被更新时,它的version 计数器会增加,因此它不再匹配写在包装器中的version。然后渲染器知道它应该更新包装的对象。
最后,当一个对象被添加到包装器时,会附加一个侦听器,以便在删除对象时通知渲染器,从而处理包装的对象。