当 alpha 被遮罩时,为什么 WebGL 画布在第二帧上变成白色?

sin*_*unk 3 opengl-es webgl

有关详细信息,请参阅此线程

总结一下,鉴于以下情况:

gl = canvas.getContext('experimental-webgl');
gl.clearColor(0, 0, 0, 1);
gl.colorMask(1, 1, 1, 0);
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
gl.enable(gl.BLEND);
Run Code Online (Sandbox Code Playgroud)

...和一个标准的渲染循环:

function doRender() {
  gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
  // render stuff, and request another frame
  requestAnimationFrame(doRender);
}
Run Code Online (Sandbox Code Playgroud)

...然后我想知道理论上的预期输出应该是什么。

实际上,我看到第一帧渲染时好像没有 color mask,而第二帧(和后续帧)渲染整个画布不透明白色

请注意,将 alpha 级别设置为什么并不重要:即使渲染的 alpha 值非常低,第二帧始终是立即、完全的白色(包括未渲染到的区域)。

问题:上述操作对第一帧、第二帧和后续帧的预期结果是什么?另外,我遇​​到了预期的结果,还是由于 GL 驱动程序或 WebGL 实现中的一些错误?最后,如果这是预期的结果,为什么?视频卡上实际发生了什么以产生这种结果?

系统详细信息:MacBook Pro / GeForce 320M / Snow Leopard 上的 Chrome / Firefox(两者)。

gma*_*man 5

WebGL 会自动清除每一帧的绘图缓冲区,除非你告诉它不要

尝试

gl = canvas.getContext('experimental-webgl', {
   preserveDrawingBuffer: true
});
Run Code Online (Sandbox Code Playgroud)

这可能比让它清除更慢,因为它可能必须在每个帧中制作一个绘图缓冲区的副本以保留它,以便在您将新内容绘制到其中时,它有一个副本与页面的其余部分合成。因此,最好在渲染循环中调用 gl.clear 。当然,如果你想要的效果是不断地将东西混合到绘图缓冲区中,那么你要么需要告诉它像上面的例子一样被保留,或者你需要使用帧缓冲区绘制到纹理或渲染缓冲区中,然后将其渲染到绘图缓冲区。