opengl 4.1 替代方案将图像存储在 GPU 中以供以后访问、处理和渲染?
opengl 4.1 alternatives to store images in the GPU for later access, processing and rendering?
接触 opengl 不久后,我使用片段着色器渲染作为纹理加载的图像,并进行一些像素级转换,例如亮度和对比度。我在 Mac Os X 上使用 openGL 4.1,带有英特尔 Iris 图形。
现在我需要能够快速查看大图像(>40 Mpx 图像)。我想尽可能快地为它们制作动画,此外还可以在它们中的任何一个内停止并对它们进行一些 GPU 处理,避免往返 CPU。
目前,一次处理一张图像,我的片段着色器如下:
#version 410 core
in mediump vec3 ourColor;
in mediump vec2 TexCoord;
out vec4 color;
uniform mediump sampler2D ourTexture;
uniform mediump float alpha;
uniform mediump float beta;
uniform mediump float gamma;
void main()
{
mediump vec4 textureColor = texture(ourTexture, TexCoord);
mediump vec3 scaledRGB = alpha * textureColor.rgb + beta;
mediump vec3 gammaVec = vec3(gamma);
scaledRGB = pow(scaledRGB, gammaVec);
color = vec4(scaledRGB, textureColor.a);
}
到目前为止我已经读到(例如 here and there)有人会使用采样器数组,并使用统一索引来判断实际使用的纹理,限制由 GL_MAX_TEXTURE_IMAGE_UNITS 设置关于我们可以在 GPU 中使用 "at once" 的最大纹理数(除非我误解了?)。有没有办法绕过这种纹理限制?
即有什么方法可以在内存允许的情况下将尽可能多的二维浮点数组发送到 GPU,而不管纹理图像单元的限制,我以后可以将其用作着色器的纹理?我的目标硬件有 GL_MAX_TEXTURE_IMAGE_UNITS = 16(在我的 Intel Iris 上)或通常为 32,这对于最多可达数百个的时间序列图像来说小得离谱。我期待最近的 GPU 高达 2 GB RAM,必须有一种方法可以存储比 GL_MAX_TEXTURE_IMAGE_UNITS.
更多的图像
我是否缺少一个非常简单的替代方案?
谢谢
GL_MAX_TEXTURE_IMAGE_UNITS
是在单个绘制调用期间可以同时使用的不同纹理单元的最大值。这意味着 GPU(或更准确地说,您的片段着色器 - 其他可编程阶段有单独的限制)可以从最多那么多不同的纹理中采样并任意组合结果。
这不是 GPU 可以管理多少纹理的限制。您通常可以在内存允许的情况下创建尽可能多的纹理 - 这通常不仅包括 VRAM,还包括系统内存甚至交换 memory/page 文件(尽管这可能会变得非常慢)。
由于一次只需要绘制一个帧,因此只需要一个纹理单元。您只需将不同的纹理绑定到每一帧的纹理单元。我不清楚 "avoiding any round trip to the CPU" 是什么意思。您无法单独在 GPU 上为纹理制作动画。您至少需要每帧进行一次绘制调用,以及一次调用以在其间交换缓冲区。所以每次绑定不同的纹理会很容易。
请注意,您也可以使用 2D array textures。这些允许您将大量 2D 图像存储为 "slices" 个 单个 纹理对象。因此,您的着色器只需使用适当的纹理坐标进行采样即可访问所有这些图像。数组纹理要求每个切片大小相同,但这不会对您的用例造成任何问题。
接触 opengl 不久后,我使用片段着色器渲染作为纹理加载的图像,并进行一些像素级转换,例如亮度和对比度。我在 Mac Os X 上使用 openGL 4.1,带有英特尔 Iris 图形。
现在我需要能够快速查看大图像(>40 Mpx 图像)。我想尽可能快地为它们制作动画,此外还可以在它们中的任何一个内停止并对它们进行一些 GPU 处理,避免往返 CPU。
目前,一次处理一张图像,我的片段着色器如下:
#version 410 core
in mediump vec3 ourColor;
in mediump vec2 TexCoord;
out vec4 color;
uniform mediump sampler2D ourTexture;
uniform mediump float alpha;
uniform mediump float beta;
uniform mediump float gamma;
void main()
{
mediump vec4 textureColor = texture(ourTexture, TexCoord);
mediump vec3 scaledRGB = alpha * textureColor.rgb + beta;
mediump vec3 gammaVec = vec3(gamma);
scaledRGB = pow(scaledRGB, gammaVec);
color = vec4(scaledRGB, textureColor.a);
}
到目前为止我已经读到(例如 here and there)有人会使用采样器数组,并使用统一索引来判断实际使用的纹理,限制由 GL_MAX_TEXTURE_IMAGE_UNITS 设置关于我们可以在 GPU 中使用 "at once" 的最大纹理数(除非我误解了?)。有没有办法绕过这种纹理限制? 即有什么方法可以在内存允许的情况下将尽可能多的二维浮点数组发送到 GPU,而不管纹理图像单元的限制,我以后可以将其用作着色器的纹理?我的目标硬件有 GL_MAX_TEXTURE_IMAGE_UNITS = 16(在我的 Intel Iris 上)或通常为 32,这对于最多可达数百个的时间序列图像来说小得离谱。我期待最近的 GPU 高达 2 GB RAM,必须有一种方法可以存储比 GL_MAX_TEXTURE_IMAGE_UNITS.
更多的图像我是否缺少一个非常简单的替代方案?
谢谢
GL_MAX_TEXTURE_IMAGE_UNITS
是在单个绘制调用期间可以同时使用的不同纹理单元的最大值。这意味着 GPU(或更准确地说,您的片段着色器 - 其他可编程阶段有单独的限制)可以从最多那么多不同的纹理中采样并任意组合结果。
这不是 GPU 可以管理多少纹理的限制。您通常可以在内存允许的情况下创建尽可能多的纹理 - 这通常不仅包括 VRAM,还包括系统内存甚至交换 memory/page 文件(尽管这可能会变得非常慢)。
由于一次只需要绘制一个帧,因此只需要一个纹理单元。您只需将不同的纹理绑定到每一帧的纹理单元。我不清楚 "avoiding any round trip to the CPU" 是什么意思。您无法单独在 GPU 上为纹理制作动画。您至少需要每帧进行一次绘制调用,以及一次调用以在其间交换缓冲区。所以每次绑定不同的纹理会很容易。
请注意,您也可以使用 2D array textures。这些允许您将大量 2D 图像存储为 "slices" 个 单个 纹理对象。因此,您的着色器只需使用适当的纹理坐标进行采样即可访问所有这些图像。数组纹理要求每个切片大小相同,但这不会对您的用例造成任何问题。