使用帧缓冲对象(FBO)或?屏幕外的多个渲染目标。

时间:2011-05-27 21:15:59

标签: opengl rendering framebuffer edge-detection fbo

情境:使用不同的变换和旋转生成形状和相应边的N个样本(使用Sobel滤镜或我自己的),而视口(大小= 600 * 600)和相机保持常量。即将有N个样本+ N个相应的边缘。

我想这样做,

使用一个带有2个渲染缓冲区的FBO [即每个缓冲区的大小为=(N * 600)* 600] - 第一个为N个形状,第二个为相应形状的边缘

问题:

  1. 实现上述目标的最佳途径是什么?
  2. 虽然视口大小为600 * 600像素,但形状只占50 * 50像素左右。那么是否有任何有效的方法仅在第二个缓冲区上对边界框/ AABB区域应用边缘检测?还是只能以有效的方式读取2N边界框(N个样本+ N个对应边)?

2 个答案:

答案 0 :(得分:2)

1:我不确定你称之为“最佳方式”。使用多个渲染目标:您创建两个600 * N纹理,使用glDrawArrays将它们绑定到FBO,并在片段着色器中绑定,如下所示:

layout(location = 0) out vec3 color;
layout(location = 1) out vec3 edges;

当写入“颜色”和“边缘”时,您将有效地写入纹理。

2:你不应该这样做。计算CPU上的边界框,并将它们投影(即将每个角乘以ModelViewProjection矩阵)以获得2D中的边界框

顺便说一下:首先计算你的边界框,这样你就不需要600 * 600纹理但是50 * 50 ......

编辑:您通常使用glViewPort限制绘制的区域。但是只有一个视口,你需要几个。您可以尝试Viewport array extension并生活在最前沿,或者在纹理中传递AABB,或者在性能不重要之前不要担心......

哦,你不能像那样使用Sobel ...... Sobel要求你可以阅读周围的所有纹素,但由于你当前正在渲染所述纹素,所以并非如此。要么制作没有MRT的双程算法(第一种颜色,然后是边缘),要么不使用Sobel并在着色器中猜测边缘(我真的不知道如何)

答案 1 :(得分:1)

像凯文所说的那样,你必须先将对象渲染到第一个帧缓冲区,然后将其作为纹理(使用纹理附件而不是渲染缓冲区)绑定到第二遍以找到边缘,因为边缘检测通常需要访问到像素的周围像素。

关于第二个问题,您可以使用模板缓冲区。只需在第一遍中绘制形状,然后让它们将参考值写入模板缓冲区。然后进行边缘检测(通常通过使用corrseponding片段着色器渲染屏幕大小的四边形)并将模板测试配置为仅传递模板缓冲区包含参考值的位置。这种方式(假设早期的z硬件,现在非常普遍),片段着色器只会在实际绘制形状的像素上执行。