当有多个着色器程序时使用 glClear()

Posted

技术标签:

【中文标题】当有多个着色器程序时使用 glClear()【英文标题】:Using glClear() when there are multiple shader programs 【发布时间】:2016-03-18 20:29:47 【问题描述】:

假设我想在两个视口中渲染一个 OpenGL 场景。第一个视口渲染彩色图像,第二个视口渲染深度图像。每个都有自己的顶点着色器和片段着色器,每个都有自己的着色器程序。着色器是相似的,唯一的区别是对于彩色图像,顶点颜色是基于顶点法线在顶点着色器中定义的,而对于深度图像,顶点颜色是基于顶点深度在片段着色器中定义的.为了进行渲染,我glUseProgram()颜色着色器程序,绘制颜色场景,然后glUseProgram()深度着色器程序,绘制深度场景。

我不确定的是,当有两个着色器程序时,glClear() 是如何工作的。我是否需要在每个渲染循环中调用它两次——一次在渲染彩色图像之前,一次在渲染深度图像之前?当我只调用一次时它似乎有效,但这对我来说似乎很奇怪。我原以为每个着色器程序都会写入颜色和深度缓冲区一次。因此,在渲染深度图像时,它会保留渲染彩色图像时留下的缓冲区……但这似乎并非如此。有人可以向我解释一下吗?谢谢!

【问题讨论】:

【参考方案1】:

我不确定的是当有两个着色器程序时 glClear() 是如何工作的。

如果您不确定清除如何与着色器交互,那么您对正在发生的事情有某种误解。

glClearclears the framebuffer。使用什么着色器程序在该帧缓冲区中创建像素完全无关紧要。使用多少程序来生成像素数据并不重要。

在概念上与此没有什么不同:

int foo = <insert large expression here>;
foo = 5;

无论初始化表达式有多大和多么复杂,向变量写入 5 都会覆盖其中的任何内容。就像清除帧缓冲区将清除帧缓冲区一样,无论它是如何到达那里的。

我是否需要在每个渲染循环中调用它两次——一次在渲染彩色图像之前,一次在渲染深度图像之前?

视口在 OpenGL 中并不是真正的构造。它们只是NDC-to-window-space transformation 的一部分。裁剪后,您的顶点将转换到窗口内的某个位置;视口只是让您决定它们在窗口内的位置。您看不到视口之外的部分,因为这些顶点已被剪切阶段剪切。

视口不会创建帧缓冲区、子帧缓冲区、迷你帧缓冲区或与帧缓冲区有关的任何内容。视口只是图元的转换技巧。

并且帧缓冲区清除操作不涉及primitives。因此,帧缓冲区清除不关心当前视口。它们会影响整个帧缓冲区。

帧缓冲区清除尊重scissor box,如果在您发出清除时启用了剪刀测试。但视口与清零无关。

【讨论】:

感谢您的回答。不过我还是有点困惑......所以当我使用颜色着色器程序渲染我的场景时,它会将数据写入帧缓冲区和深度缓冲区,然后使用视口为我的颜色渲染到屏幕图片。然后,我切换到使用深度着色器程序,并渲染到我的深度图像的视口。这不会写入相同的帧缓冲区和深度缓冲区吗?使用颜色着色器程序进行渲染时,所有数据仍然写入其中?

以上是关于当有多个着色器程序时使用 glClear()的主要内容,如果未能解决你的问题,请参考以下文章

具有多个缓冲区的片段着色器颜色错误

退出时删除多个着色器?

OpenGL gluLookat 不适用于着色器

GLSL 问题:一个程序中有多个着色器

跨多个着色器的 OpenGL 统一

深度缓冲区不使用多个着色器程序