WebGL绘制OpenGL图形顺序异常:先绘制的LINES覆盖后绘制的POINTS
问题根因
你看到的绘制顺序颠倒错觉是深度测试默认配置导致的,具体原因如下:
- 你代码里所有线条和点的顶点Z坐标都为
0,两类图形的深度值完全相同 - WebGL深度测试的默认比较函数是
gl.LESS,含义是:仅当新绘制片元的深度值 小于 帧缓冲区中已存在的同位置片元深度值时,才会将新片元写入颜色缓冲区 - 你先绘制红色线条,线条对应位置的深度缓冲区已经写入了
0;之后绘制绿色点时,点的深度值也是0,不满足小于的判定条件,因此绿色点的对应像素被深度测试丢弃,最终看起来红色线覆盖在绿色点上方。
解决方法
方案1:调整深度测试规则(适合需要保留深度测试的3D场景)
在初始化WebGL上下文时,将深度比较函数修改为gl.LEQUAL,允许深度值相等的新片元覆盖已有内容:
// 初始化时配置一次即可,不要写在drawShapes循环调用里 gl.enable(gl.DEPTH_TEST) gl.depthFunc(gl.LEQUAL)
方案2:关闭深度测试(适合当前纯2D同深度绘制场景,更高效)
你当前的绘制都是2D平面内容,完全不需要深度测试,直接按代码调用顺序层叠即可,删除drawShapes函数中的gl.enable(gl.DEPTH_TEST)代码即可。
额外优化建议
你当前的drawShapes函数每次调用都会重新创建顶点缓冲区、编译链接着色器程序,属于非常低效的写法:
- 顶点缓冲区、着色器程序只需要在初始化阶段创建一次即可,绘制时直接绑定复用即可,能大幅提升渲染性能。
内容的提问来源于stack exchange,提问作者slaviboy
相关产品推荐
相关产品推荐

