附注是的,我发布了这个question关于计算机图形堆栈交换。不过发帖也是希望更多人看到
简介
我正在尝试渲染多 channel 图像(超过 4 个 channel ,以便将其输入神经网络)。由于 OpenGL 本身不支持它,因此我有多个 4 channel 渲染缓冲区,我在其中渲染相应部分的 channel 。
例如,我需要尺寸为 512 x 512 x 16
的多 channel 图像,在 OpenGL 中我有 4 个尺寸为 512 x 512 x 4
的渲染缓冲区。现在的问题是,神经网络期望数据的步幅为 512 x 512 x 16
,即一个像素的 16 个 channel 值后面跟着下一个像素的 16 个 channel 值。然而,目前我可以通过 4 次调用 glReadPixels
来有效地读取我的 4 个渲染缓冲区,基本上使数据具有 4 x 512 x 512 x 4
的步幅。在客户端手动重新排序数据对我来说不够,因为它太慢了。
主要问题
我有一个想法,渲染到大小为 512*4 x 512 x 4
的单个 4 channel 渲染缓冲区,因为跨步它相当于 512 x 512 x 16
,我们只是将一行中的4个像素的组合视为16 channel 输出图像的单个像素。我们称之为“交错渲染”
但这需要我神奇地调整我的片段着色器,以便每组后续的 4 个片段将具有完全相同的顶点属性插值。有什么办法可以做到吗?
这张糟糕的插图包含 1 个 1024 x 512
4 channel 图像的渲染缓冲区,是应该如何渲染它的示例。这样我就可以在 1 个调用 glReadPixels
中以 stride 512 x 512 x 8
提取数据。
最佳答案
But this requires me to magically adjust my fragment shader, so that every group of consequent 4 fragments would have exactly the same interpolation of vertex attributes.
不,需要的还不止这些。您必须从根本上改变光栅化的工作方式。
以 4 倍宽度渲染是以 4 倍宽度渲染。这意味着相对于正方形区域拉伸(stretch)生成的图元。但这不是你想要的效果。您需要光栅化器以原始分辨率进行光栅化,然后复制光栅化产品。
这是不可能的。
来自评论:
It just got to me, that I can try to get a 512 x 512 x 2 image of texture coordinates from vertex+fragment shaders, then stitch it with itself to make 4 times wider (thus we'll get the same interpolation) and from that form the final image
这是个好主意。您需要将所需的任何插值渲染到原始大小的纹理,类似于延迟渲染的工作方式。所以它可能不仅仅是 2 个值。您可以只存储 gl_FragCoord.xy
值,然后使用它们来计算您需要的任何内容,但直接存储插值可能更容易。
我建议在读取纹理时执行texelFetch
,因为您可以指定精确的整数纹理像素坐标。您需要的整数坐标可以从 gl_FragCoord
计算得出,如下所示:
ivec2 texCoords = ivec2(int(gl_FragCoord.x * 0.25f), int(gl_FragCoord.y));
关于opengl - 片段着色器中的 "Interleaved rendering",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69558691/