1

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

我想这样做,

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

问题:

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

2 回答 2

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 数组扩展并生活在最前沿,或者在纹理中传递 AABB,或者在性能重要之前不要担心......

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

于 2011-05-27T23:11:59.620 回答
1

Like Calvin said, you have to first render your object into the the first framebuffer and then bind this as texture (use texture attachment rather than a renderbuffer) for the second pass to find the edges, as the edge detection usually needs access to a pixel's surrounding pixels.

Regarding your second question, you could probably use the stencil buffer. Just draw your shapes in the first pass and let them write a reference value into the stencil buffer. Then do the edge detection (usually by rendering a screen sized quad with the corrseponding fragment shader) and configure the stencil test to only pass where the stencil buffer contains the reference value. This way (assuming early-z hardware, which is quite common now) the fragment shader will only be executed on the pixels the shape has actually been drawn onto.

于 2011-05-28T01:50:06.097 回答