我有两个我正在渲染两个不同对象的框架。当我使用默认的帧缓冲程序时,我都在同一对象上呈现两个对象。
我希望这种行为在使用多个Framebuffers时能起作用!我如何合并两个框架,并在顶部呈现获胜片段(经过测试的深度)!基本上就像Photoshop层合并,但进行了深度测试!
我到达默认帧缓冲器上的单个框架,但是我对如何将两个帧缓冲器合并在一起迷失了!
注意:我在框架上有颜色和深度附件。
编辑:
好吧。除了一件小事情外,我几乎对四轮锻炼的渲染设置。我的颜色缓冲使用均匀的采样器正确地发送到着色器,但我的深度值一直从深度缓冲区返回" 0"。
这就是我在Framebuffer中设置深度缓冲区的方式。
glGenFramebuffers(1, &_fbo);
glBindFramebuffer(GL_FRAMEBUFFER, _fbo);
glGenTextures(1, &_cbo);
glGenTextures(1, &_dbo);
{
glBindTexture(GL_TEXTURE_2D, _cbo);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, dim.x, dim.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
}
{
glBindTexture(GL_TEXTURE_2D, _dbo);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, dim.x, dim.y, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, nullptr);
}
glBindFramebuffer(GL_FRAMEBUFFER, _fbo);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _cbo, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, _dbo, 0);
这就是我将均匀采样器发送到着色器的方式。
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,cbo1);
glUniform1i(glGetUniformLocation(QuadShader.Program, "color1"),0);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, cbo2);
glUniform1i(glGetUniformLocation(QuadShader.Program, "color2"), 1);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, dbo1);
glUniform1i(glGetUniformLocation(QuadShader.Program, "depth1"), 2);
glActiveTexture(GL_TEXTURE3);
glBindTexture(GL_TEXTURE_2D, dbo2);
glUniform1i(glGetUniformLocation(QuadShader.Program, "depth2"), 3);
glBindVertexArray(BgVao);
glDrawArrays(GL_TRIANGLES, 0, 6);
这就是我的着色器的外观:
uniform sampler2D color1;
uniform sampler2D color2;
uniform sampler2D depth1;
uniform sampler2D depth2;
out vec4 FragColor;
void main()
{
ivec2 texcoord = ivec2(floor(gl_FragCoord.xy));
vec4 depth1 = texelFetch(depth1, texcoord,0);
vec4 depth2 = texelFetch(depth2, texcoord,0);
if(depth1.z > depth2.z)
{
FragColor = texelFetch(color1, texcoord, 0);
}
else
{
FragColor = texelFetch(color2, texcoord, 0);
}
}
您将需要一个着色器来实现此目标。没有内置的方式可以用深度值闪电。这是结合两个FBO的内容的一种方法。
顶点着色器(假设从(-1,-1)到(1,1)绘制了四边形)
layout(location = 0) in vec4 Position;
void main()
{
// Snap the input coordinates to a quad with it lower-left at (-1, -1, 0)
// and its top-right at (1, 1, 0)
gl_Position = vec4(sign(Position.xy), 0.0, 1.0);
}
像素着色器看起来像这样:
uniform sampler2D Color0;
uniform sampler2D Color1;
uniform sampler2D Depth0;
uniform sampler2D Depth1;
in vec2 TexCoords;
layout(location = 0) out vec4 FragColor;
void main()
{
ivec2 texcoord = ivec2(floor(gl_FragCoord.xy));
float depth0 = texelFetch(Depth0, texcoord, 0).r;
float depth1 = texelFetch(Depth1, texcoord, 0).r;
// possibly reversed depending on your depth buffer ordering strategy
if (depth0 < depth1) {
FragColor = texelFetch(Color0, texcoord, 0);
} else {
FragColor = texelFetch(Color1, texcoord, 0);
}
}
另请参见OpenGL-如何访问深度缓冲区值? - 或:gl_fragcoord.z vs.渲染深度到纹理的纹理,以获取深度纹理。
请注意,我在这里使用texelFetch()
,因为线性插值深度值没有有效的结果。
爆炸永远不会使用深度测试,因此您必须使用全屏着色器通行证来组合两个框架。有两个选择:
-
将两个框架组合成第三个框架。这要求颜色附件以及两个输入FBO的深度附件都是纹理。然后,您将渲染全屏四边形,并从颜色缓冲区和深度纹理中进行采样。您可以通过比较两个深度来确定您用作片段的最终输出颜色中的两个深度来手动进行深度测试。
-
使用真实的深度测试,您将其中一个框架缓和剂纳入另一个框架。在这种情况下,只有一个FBO必须使用纹理,另一个可以使用RenderBuffers或提供的窗口系统缓冲区。您只需要渲染一个全屏幕四边形,这次仅从一个输入FBO中对深度和颜色纹理进行采样,然后启用并启用深度测试的输出FBO。您只需将颜色值设置为片段着色器的输出,并将深度值输出到
gl_FragDepth
。
应该使用一个片段着色器,该片段着色器都使用框架缓冲器和框架中的颜色数据以及每个像素中的framebuffers and froms from from from for cixel和填充的深度数据,通过评估每个片段,纹理对应于每个像素赢得深度测试的片段。
#version 430
layout(location = 0) in vec2 tex_coord;
layout(binding = 0) uniform sampler2D color_texture_1;
layout(binding = 1) uniform sampler2D color_texture_2;
layout(binding = 2) uniform sampler2D depth_texture_1;
layout(binding = 3) uniform sampler2D depth_texture_2;
layout(location = 0) out vec4 fragment_color;
void main() {
float depth_1 = texture(depth_texture_1, tex_coord).z;
float depth_2 = texture(depth_texture_2, tex_coord).z;
if(!/*check to verify *something* was rendered here in either framebuffer*/)
discard;
else {
if(depth_1 > depth_2) //I'm pretty sure positive z values face the user
fragment_color = texture(color_texture_1, tex_coord);
else
fragment_color = texture(color_texture_2, tex_coord);
}
}
您会渲染一个(大概是全屏幕)四边形,使用此片段着色器的通行顶点着色器,然后附上相应的纹理。
我不知道您的深度纹理在哪种格式中;我的假设是它包含代表各个片段坐标的向量,并且z坐标包含其深度。如果不是这种情况,您需要进行调整。