【WebGL】颜色缓冲区是什么时候被重置的?

如果对WebGL感兴趣,可以点击easy-webgl关注

颜色缓冲区

在 WebGL 渲染管线的最终阶段,经过顶点处理、图元装配、光栅化以及片元处理后,每个片元的颜色值会被写入颜色缓冲区。这些颜色值决定了屏幕上每个像素最终显示的颜色,最终呈现出完整的 3D 场景画面。

如上图,webgl 系统中的绘制操作实际上是在颜色缓冲区中进行绘制的,绘制结束后系统将缓冲区中的内容显示在屏幕上,然后颜色缓冲区就会被重置,其中的内容会丢失。那颜色缓冲区在什么时候会被重置?

Demo1:同步多次调用drawArrays

在下面的代码中,我们先后两次调用gl.drawArrays分别在(0.5, 0.0, 0.0)和(0.3, 0.0, 0.0)处绘制两个红色的点。

js 复制代码
const canvas = document.getElementById('webgl')
const gl = canvas.getContext('webgl')

const vertexShaderSource = `
    attribute vec4 a_Position;
    void main() {
        gl_Position = a_Position;
        gl_PointSize = 10.0;
    }
`;

const fragmentShaderSource = `
    precision mediump float;
    void main(){
        gl_FragColor = vec4(1,0,0,1.0);
    }
`;

const program = initShaders(gl, vertexShaderSource, fragmentShaderSource);
gl.useProgram(program);
const a_Position = gl.getAttribLocation(program, "a_Position");
gl.clearColor(0, 0, 0, 1);
gl.clear(gl.COLOR_BUFFER_BIT);

gl.vertexAttrib3f(a_Position, 0.5, 0.0, 0.0);
gl.drawArrays(gl.POINTS, 0, 1);

gl.vertexAttrib3f(a_Position, 0.3, 0.0, 0.0);
gl.drawArrays(gl.POINTS, 0, 1);

这里,我们同步调用 drawArrays,页面显示如下:

Demo2:先同步后宏任务调用drawArrays

在下面的代码中,我们先后调用两次drawArrays方法绘制两个点,然后在定时器中再调用一次绘制一个点。

js 复制代码
gl.clearColor(0, 0, 0, 1);
gl.clear(gl.COLOR_BUFFER_BIT);

gl.vertexAttrib3f(a_Position, 0.5, 0.0, 0.0);
gl.drawArrays(gl.POINTS, 0, 1);

gl.vertexAttrib3f(a_Position, 0.3, 0.0, 0.0);
gl.drawArrays(gl.POINTS, 0, 1);

setTimeout(() => {
  gl.vertexAttrib3f(a_Position, 0.0, 0.5, 0.0);
  gl.drawArrays(gl.POINTS, 0, 1);
}, 0);

刷新页面,可以看到先显示绘制黑色的背景,黑色背景有两个红色的点。然后立马绘制白色背景,上面只有一个点,黑色背景一闪而过,页面最终的状态如下:

Demo3:微任务

在下面的代码中,我们先后调用两次drawArrays方法绘制两个点,然后在Promise中再调用一次绘制一个点。

js 复制代码
gl.clearColor(0, 0, 0, 1);
gl.clear(gl.COLOR_BUFFER_BIT);

gl.vertexAttrib3f(a_Position, 0.5, 0.0, 0.0);
gl.drawArrays(gl.POINTS, 0, 1);

gl.vertexAttrib3f(a_Position, 0.3, 0.0, 0.0);
gl.drawArrays(gl.POINTS, 0, 1);

Promise.resolve().then((res) => {
  gl.vertexAttrib3f(a_Position, 0.1, 0.0, 0.0);
  gl.drawArrays(gl.POINTS, 0, 1);
});

刷新页面,可以看到三个点是同时绘制出来的,页面最终效果如下:

小结

从上面的示例中,我们可以得出结论,颜色缓冲区大概是在微任务之后,宏任务之前被清空的

如何手动清除颜色缓冲区?

如果需要手动清除颜色缓冲区,可以使用gl.clearColor()函数设置清除颜色,再调用gl.clear(gl.COLOR_BUFFER_BIT)函数,就能将颜色缓冲区的内容全部替换为指定颜色,一般在每次渲染新的一帧画面之前会执行这个操作,以避免之前帧的残留信息影响当前帧的显示。在片元着色器中,通过设置gl_FragColor变量来确定每个片元的颜色值,这些值会被自动写入颜色缓冲区。

相关推荐
0思必得06 小时前
[Web自动化] Selenium处理动态网页
前端·爬虫·python·selenium·自动化
东东5166 小时前
智能社区管理系统的设计与实现ssm+vue
前端·javascript·vue.js·毕业设计·毕设
catino6 小时前
图片、文件的预览
前端·javascript
layman05288 小时前
webpack5 css-loader:从基础到原理
前端·css·webpack
半桔8 小时前
【前端小站】CSS 样式美学:从基础语法到界面精筑的实战宝典
前端·css·html
AI老李8 小时前
PostCSS完全指南:功能/配置/插件/SourceMap/AST/插件开发/自定义语法
前端·javascript·postcss
_OP_CHEN9 小时前
【前端开发之CSS】(一)初识 CSS:网页化妆术的终极指南,新手也能轻松拿捏页面美化!
前端·css·html·网页开发·样式表·界面美化
啊哈一半醒9 小时前
CSS 主流布局
前端·css·css布局·标准流 浮动 定位·flex grid 响应式布局
PHP武器库9 小时前
ULUI:不止于按钮和菜单,一个专注于“业务组件”的纯 CSS 框架
前端·css
电商API_180079052479 小时前
第三方淘宝商品详情 API 全维度调用指南:从技术对接到生产落地
java·大数据·前端·数据库·人工智能·网络爬虫