为何WebGL未调用gl.clear仍丢失已绘制的旧点?
WebGL绘图时旧点消失的原因及解决办法
为什么旧点会消失?
这跟WebGL的默认渲染逻辑直接相关:
- WebGL默认是单帧覆盖绘制,浏览器在每次渲染循环结束后(比如你用
requestAnimationFrame驱动绘图时),会自动清除画布内容,为下一帧渲染腾空间——哪怕你没调用gl.clear()。这是因为创建WebGL上下文时,默认的preserveDrawingBuffer参数是false,浏览器为了性能会复用帧缓冲区。 - 你的逻辑是只绘制新增的点,但上一帧的旧点已经被浏览器清掉了,这一帧又没重新画它们,自然就看不到了。
你的代码问题在哪?
你用bufferSubData把新点追加到缓冲区的操作是对的,但调用gl.drawArrays时只从lastDrawnPoints开始画新点,相当于这一帧只渲染新增部分,完全没管之前的旧点,旧点自然就消失了。
两种可行的解决办法
办法1:每次重绘所有点(推荐)
这是WebGL的常规做法,性能上只要点的数量不是特别夸张(比如几万以内)都没问题。更新缓冲区后,直接从第0个点开始绘制全部点:
// 更新缓冲区后,绘制所有点 gl.drawArrays(gl.POINTS, 0, totalPointsCount)
这里的totalPointsCount是你缓冲区里所有点的总数(比如每次加新点后累加计数)。
办法2:开启帧缓冲区保留
创建WebGL上下文时,设置preserveDrawingBuffer: true,让浏览器保留每帧的绘制内容,这样旧点就不会被自动清除了:
const canvas = document.getElementById('your-canvas'); const gl = canvas.getContext('webgl', { preserveDrawingBuffer: true });
但要注意,这个设置会降低一点性能,因为浏览器不能再复用帧缓冲区了,适合点数量极大、不想每次重绘所有点的场景。
内容的提问来源于stack exchange,提问作者CyberNinjaX
相关产品推荐
相关产品推荐

