"Interleaved rendering" 在片段着色器中
"Interleaved rendering" in fragment shader
P.S。是的,我在 Computer Graphics Stack Exchange 上发布了这个 question。不过发在那里也是希望更多人看到
简介
我正在尝试渲染多通道图像(超过 4 个通道,以便将其馈送到神经网络)。由于 OpenGL 本身不支持它,我有多个 4 通道渲染缓冲区,我在其中渲染通道的相应部分。
例如,我需要大小为 512 x 512 x 16
的多通道图像,在 OpenGL 中我有 4 个大小为 512 x 512 x 4
的渲染缓冲区。现在的问题是神经网络期望数据的步幅为 512 x 512 x 16
,即一个像素的 16 个通道值后面跟着下一个像素的 16 个通道值。然而,目前我可以通过 4 次调用 glReadPixels
有效地读取我的 4 个渲染缓冲区,基本上使数据具有跨度 4 x 512 x 512 x 4
。在客户端手动重新排序数据 无法满足我的需求,因为它太慢了。
主要问题
我想渲染到大小为 512*4 x 512 x 4
的单个 4 通道渲染缓冲区,因为在步幅方面它等同于 512 x 512 x 16
,我们只处理 4 个像素的组合连续作为单个像素的 16 通道输出图像。我们称之为“交错渲染”
但这需要我神奇地调整我的片段着色器,以便每组后续的 4 片段 将具有完全相同的顶点属性插值。有什么办法吗?
这个带有 1024 x 512
4 通道图像的 1 个渲染缓冲区的糟糕插图是应该如何渲染的示例。这样我就可以在一次调用中 glReadPixels
大步提取数据 512 x 512 x 8
编辑:更好的图片
我现在拥有的(4 个渲染缓冲区)
我想在 OpenGL 中本机执行的操作(此图像是在 Python 离线中完成的)
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 倍宽度渲染。这意味着相对于方形区域拉伸生成的基元。但这不是你想要的效果。您需要光栅化器以原始分辨率进行光栅化,然后复制光栅化产品。
这不可能。
来自评论:
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));
P.S。是的,我在 Computer Graphics Stack Exchange 上发布了这个 question。不过发在那里也是希望更多人看到
简介
我正在尝试渲染多通道图像(超过 4 个通道,以便将其馈送到神经网络)。由于 OpenGL 本身不支持它,我有多个 4 通道渲染缓冲区,我在其中渲染通道的相应部分。
例如,我需要大小为 512 x 512 x 16
的多通道图像,在 OpenGL 中我有 4 个大小为 512 x 512 x 4
的渲染缓冲区。现在的问题是神经网络期望数据的步幅为 512 x 512 x 16
,即一个像素的 16 个通道值后面跟着下一个像素的 16 个通道值。然而,目前我可以通过 4 次调用 glReadPixels
有效地读取我的 4 个渲染缓冲区,基本上使数据具有跨度 4 x 512 x 512 x 4
。在客户端手动重新排序数据 无法满足我的需求,因为它太慢了。
主要问题
我想渲染到大小为 512*4 x 512 x 4
的单个 4 通道渲染缓冲区,因为在步幅方面它等同于 512 x 512 x 16
,我们只处理 4 个像素的组合连续作为单个像素的 16 通道输出图像。我们称之为“交错渲染”
但这需要我神奇地调整我的片段着色器,以便每组后续的 4 片段 将具有完全相同的顶点属性插值。有什么办法吗?
这个带有 1024 x 512
4 通道图像的 1 个渲染缓冲区的糟糕插图是应该如何渲染的示例。这样我就可以在一次调用中 glReadPixels
大步提取数据 512 x 512 x 8
编辑:更好的图片
我现在拥有的(4 个渲染缓冲区)
我想在 OpenGL 中本机执行的操作(此图像是在 Python 离线中完成的)
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 倍宽度渲染。这意味着相对于方形区域拉伸生成的基元。但这不是你想要的效果。您需要光栅化器以原始分辨率进行光栅化,然后复制光栅化产品。
这不可能。
来自评论:
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));