我正在使用具有多个颜色附件(绘制缓冲区)的帧缓冲区,并使用多个着色器程序编写颜色。
每个着色器程序使用不同的渲染目标。
例如,SHADER1仅使用第一个绘制缓冲区,而SHADER2使用第二个和第三个绘制缓冲区。
但是,如果我只在片段着色器中指定渲染目标,如下所示:
// SHADER1.frag
layout(location = 0) out vec4 color;
void main() { color = vec4(1.0); }
这将导致在每个绘制缓冲区中写入颜色,因此我必须清除第二个和第三个绘制缓冲区。
这是默认行为吗?
我应该为每个着色器程序更新glDrawbuffers状态吗?
glUseProgram(SHADER1);
GLenum drawBuffers1[] = { GL_COLOR_ATTACHMENT0, GL_NONE, GL_NONE};
glDrawBuffers(3, drawBuffers1);
...
glUseProgram(SHADER2);
GLenum drawBuffers2[] = { GL_NONE, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2};
glDrawBuffers(3, drawBuffers2);
...
设置的状态glDrawBuffers()
是帧缓冲对象(FBO)状态的一部分。因此,只要对所有渲染使用相同的FBO,则glDrawBuffers()
每次绘制到不同的缓冲区时都必须调用。
根据您的描述,我认为使用多个FBO会容易得多。使用与问题中使用的伪符号类似的伪符号,可以在设置过程中进行一次这些调用:
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, FBO1);
glFramebufferTexture2D(..., GL_COLOR_ATTACHMENT0, ..., BUFFER1, ...);
GLenum drawBuffers1[] = {GL_COLOR_ATTACHMENT0};
glDrawBuffers(1, drawBuffers1);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, FBO2);
glFramebufferTexture2D(..., GL_COLOR_ATTACHMENT0, ..., BUFFER2, ...);
glFramebufferTexture2D(..., GL_COLOR_ATTACHMENT1, ..., BUFFER3, ...);
GLenum drawBuffers2[] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1};
glDrawBuffers(2, drawBuffers2);
然后,每次渲染时:
glUseProgram(SHADER1);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, FBO1);
...
glUseProgram(SHADER2);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, FBO2);
...
为此,您SHADER1
将有一个输出(位置0),SHADER2
两个输出(位置0和1)。
如果出于某种原因您想要坚持一个FBO,并使您的方法可行,则必须小心以获得所需的结果:
GLenum drawBuffers2[] = { GL_NONE, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2};
glDrawBuffers(3, drawBuffers2);
使用这些设置,并使用具有两个输出的着色器,您必须将输出的位置设置为1和2(使用glBindFragDataLocation()
,或location
着色器代码中的指令)。
您也可以使用以下代码:
GLenum drawBuffers2[] = {GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2};
glDrawBuffers(2, drawBuffers2);
片段着色器输出的位置0和1。这样做的缺点之一是,如果您要将代码移植到OpenGL ES,它将无法正常工作。在ES中,第i个缓冲区只能是GL_NONE
或GL_COLOR_ATTACHMENT
i。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句