drawElements只渲染出模型的一部分,顶点数量太多——WebGL开发中的问题记录(2)

此系列文章用于记录我使用WebGL开发3D引擎时遇到的问题和解决方案(也可能暂未解决)。

项目demo地址:cool.js

项目源码地址:cool.js——码云

----------------------正文分割线---------------------------------

开始做渲染GLTF模型时,出现只能渲染出一部分的问题。经查,是由于我创建index数据时用的Uint8Array类型

下面是错误做法:

var indices = new Uint8Array([0,1,2,1000,...]); // 错误! 大于255的数据会被错误读取

var indexBuffer = gl.createBuffer(); //创建buffer
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer); //绑定buffer
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW); //绑定数据

gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_BYTE, 0); //Uint8Array对应UNSIGNED_BYTE

Uint8Array类型的取值范围是0~255,所以数据中大于255的数据会被截断到二进制的前8位,读取出的值就错了。结果就是只渲染出顶点数据里的前255个!

注意,drawElements第3个参数要和index的数据类型一致,否则会出错。Uint8Array对应gl.UNSIGNED_BYTE。

正确做法如下:

var indices = new Uint16Array([0,1,2,1000,...]); // Uint16Array最大可以到65535

var indexBuffer = gl.createBuffer(); //创建buffer
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer); //绑定buffer
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW); //绑定数据

gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT, 0); //Uint16Array对应UNSIGNED_SHORT

Uint16Array类型的取值范围是0~65535。注意,此时drawElements第3个参数要用gl.UNSIGNED_SHORT。

这样就没问题了!

总结:

drawElements第3个参数有两种选择:byte和short。

如果模型的顶点数量小于等于255,可以用byte,对应index数据用Uint8Array类型。

如果模型的顶点数量大于255,只能用short,对应index数据用Uint16Array类型。

-------------------------------讨论---------------------------------

如果模型的顶点数量大于65536怎么办?我觉得只能把模型拆成几个小的分开渲染,或者用drawArray。有大佬知道更好的解决方案求告知一下,感激不尽。

-------------------------------------------------------

转载请注明出处:微笑君的博客

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值