1

我需要从纹理中获取特定坐标处的颜色。有两种方法可以做到这一点,通过获取和查看原始 png 数据,或者通过对我生成的 opengl 纹理进行采样。是否可以对 opengl 纹理进行采样以获得给定 UV 或 XY 坐标的颜色(RGBA)?如果是这样,怎么做?

4

3 回答 3

2

我发现最有效的方法是访问纹理数据(无论如何,您都应该将我们的 PNG 解码为纹理)并自己在纹素之间进行插值。假设您的 texcoords 是 [0,1],将 texwidth u 和 texheight v 相乘,然后使用它来找到纹理上的位置。如果它们是整数,则直接使用像素,否则使用 int 部分查找边界像素并根据小数部分在它们之间进行插值。

这是一些类似 HLSL 的伪代码。应该很清楚:

float3 sample(float2 coord, texture tex) {
    float x = tex.w * coord.x; // Get X coord in texture
    int ix = (int) x; // Get X coord as whole number
    float y = tex.h * coord.y;
    int iy = (int) y;

    float3 x1 = getTexel(ix, iy); // Get top-left pixel
    float3 x2 = getTexel(ix+1, iy); // Get top-right pixel
    float3 y1 = getTexel(ix, iy+1); // Get bottom-left pixel
    float3 y2 = getTexel(ix+1, iy+1); // Get bottom-right pixel

    float3 top = interpolate(x1, x2, frac(x)); // Interpolate between top two pixels based on the fractional part of the X coord
    float3 bottom = interpolate(y1, y2, frac(x)); // Interpolate between bottom two pixels

    return interpolate(top, bottom, frac(y)); // Interpolate between top and bottom based on fractional Y coord
}
于 2008-10-08T07:55:33.683 回答
2

在我的脑海中,你的选择是

  1. 使用 glGetTexImage() 获取整个纹理并检查您感兴趣的纹素。
  2. 绘制您感兴趣的纹素(例如,通过渲染 GL_POINTS 基元),然后使用 glReadPixels 从帧缓冲区中获取您渲染它的像素。
  3. 将纹理图像的副本放在手边,不要使用 OpenGL。

选项 1 和 2 效率极低(尽管您可以通过使用像素缓冲区对象和异步复制来加快 2 的速度)。所以我最喜欢的 FAR 是选项 3。

编辑:如果您有GL_APPLE_client_storage扩展名(即您在 Mac 或 iPhone 上),那么这就是选项 4,这是很长一段时间内的赢家。

于 2008-10-08T08:36:28.547 回答
0

正如其他人所建议的那样,从 VRAM 读回纹理效率非常低,如果您甚至对性能感兴趣,也应该像瘟疫一样避免。

据我所知,两种可行的解决方案:

  1. 随身携带一份像素数据的副本(虽然会浪费内存)
  2. 使用着色器进行
于 2008-10-08T09:46:11.027 回答