BufferGeometry应该算是一种对机器友好,但是API不怎么友好的一种Geometry,适合对性能要求比较高的时候。
BufferGeometry应该是将所有的信息放到了 attributes 中,而不是像geometry里有各种各样的vertices,faces之类的。
其中attributes的设置基本都是对 BufferAttribute 的操作,所以来瞧一瞧。
BufferAttribute
接受一个typedarray的参数,直接存储的就是比较适合gpu的数据结构。itemSize 比如三角形为3,这样可以用来定位到对应的元素。
除此之外还有一个 normalized flag,具体后边看到的时候说。
不过值得注意的是有:usage
该buffer中的data的使用,直接与WebGL相关,static draw,dynamic draw之类的
updateRange
应该是更新的时候考虑更新哪个range,具体使用到的时候看
version
标识版本,有一个只写的属性 needsUpdate ,设为true即表示这个buffer需要更新了,因此version+1
有许多get与set函数,可以自由的获取对应的元素
onUpload 按照文档所说,是应用在向GPU传输数据时使用,这个后续需要回顾
除此之外, BufferAttribute.js export了许多其它类型的 BufferAttribute 。
以Uint8为例,是这样构造的:
function Uint8BufferAttribute( array, itemSize, normalized ) {BufferAttribute.call( this, new Uint8Array( array ), itemSize, normalized );}Uint8BufferAttribute.prototype = Object.create( BufferAttribute.prototype );Uint8BufferAttribute.prototype.constructor = Uint8BufferAttribute;
应该就是为了封装一下,能够让用户直接用对应的类型而不用自己new一个对应的typearray放进去
index
对应到WebGL的indexbuffer,也是 BufferAttribute 类型,可以直接传输到WebGL相关的绑定buffer函数中
attributes
用key-value来存储所有的attributes,这个attributes就是上述的,用来存储数据的地方
有对应的 setAttribute 、 getAttribute 和 deleteAttribute
groups
对于一个geometry,分为多个group,其中除了 start 和 count 这两个来定位外,还有一个 materialIndex ,是因为划分group是为了对于每个group使用不同的材质,所以这个设计还是很不容易的
drawRange
有时候可能只想画几何体的一部分,这里three也考虑到了,设定了 start 和 count
不过这个在哪里用到在该部分没有体现,应该是在renderer中吧
userData
TODO:这个 userData 在文件中并没有用到,也没有对应的设置函数,应该就是一些用户自定义的data可以放进去吧,直接赋值就可以,Three只是存下来,不做更多处理
Methods
BufferGeometry 中的大部分方法和 Geometry 中相同
包括一些util的函数: clone , toJSON , copy , dispose 等
变换的函数: applyMatrix4 , rotateX , translate 等
除此之外,有一系列的赋值的函数,其中,有一部分涉及 Geometry 和 BufferGeometry 的转换,用到了 DirectGeometry
DirectGeometry
computeGroups
这里算是对group怎么生成的有一个比较清楚的了解,基本上,把相邻的,material相同的放在一起,形成一个组
其它的好像没有什么特别要注意的,也就是数据格式的转换了
因此, Geometry 先转化为 DirectGeometry , 在转换为 BufferGeometry
fromGeometry: function ( geometry ) {
geometry.__directGeometry = new DirectGeometry().fromGeometry( geometry );
return this.fromDirectGeometry( geometry.__directGeometry );
}
updateFromObject
update的时候会先check DirectGeometry ,如果没有则生成
这时候提到了上一篇中geometry中的 xxxNeedUpdate 的Flag,这就用在这里,只有对应flag是true的时候,才会覆盖到对应的attribute中,这是一种效率上的优化
merge
两个 BufferGeometry merge起来,从offset开始,放geometry2,如果超出了geometry1的长度,忽略
toNoIndexed
把有index的数据变为无index的,里边主要用到了一个工具函数: convertBufferAttribute ,将index指向的data对应填充
整体来看, BufferGeometry 不像 Geometry , 更多的从WebGL的角度出发,从buffer, attribute这些用词就可以看出
这种将Buffer中的数据整合起来作为BufferGeometry,同时也可以从普通的Geometry中转换过来的思想还是很值得学习的。
