我正在努力提高我的 webgl 技能,并认为最好的学习方法是查看 Three.js Three.js 。我了解如何创建和绑定(bind)缓冲区、着色器等。但是我正在寻找的是例如 Three.js 如何管理绑定(bind)缓冲区的过程
gl.createBuffer
gl.bindBuffer
gl.bufferData
有人可以解释一下 Three.js 的底层是如何工作的吗?
最佳答案
此答案适用于 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 实现了某种包含在渲染器中的包装器。其中两个包装器是:
-
WebGLGeometries
它存储所有 BufferGeometry ; -
WebGLAttributes
它存储所有 WebGL 缓冲区。
用户对象和这些包装器内的对象之间的映射是通过 uuid
属性完成的。
当请求渲染时,渲染器会浏览场景的所有对象。如果某个包装器内不存在对象uuid
,则会进行一些处理并存储转换后的对象。
这就是事情变得有趣的地方,因为这是对象的 Geometry
在 WebGLGeometries
包装器和 内部转换为
转换为 BufferGeometry
的地方使用您列出的函数将 BufferGeometryWebGLAttributes
包装器内的一个或多个 WebGLBuffer
:
gl.createBuffer();
gl.bindBuffer();
gl.bufferData();
检查这个file查找实际的调用。
此外,当更新像 Geometry
这样的对象时,其 version
计数器会递增,以便它与写入的 version
不匹配不再是 wrapper 了。然后渲染器知道它应该更新包装的对象。
最后,当一个对象被添加到包装器时,一个监听器会附加到它,以便渲染器在对象被删除时收到通知,从而可以处理包装的对象。
关于javascript - Three.js 缓冲区管理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42392777/