【发布时间】:2010-09-15 22:53:56
【问题描述】:
我需要从纹理中获取特定坐标处的颜色。有两种方法可以做到这一点,通过获取和查看原始 png 数据,或者通过对我生成的 opengl 纹理进行采样。是否可以对 opengl 纹理进行采样以获得给定 UV 或 XY 坐标的颜色(RGBA)?如果有,怎么做?
【问题讨论】:
我需要从纹理中获取特定坐标处的颜色。有两种方法可以做到这一点,通过获取和查看原始 png 数据,或者通过对我生成的 opengl 纹理进行采样。是否可以对 opengl 纹理进行采样以获得给定 UV 或 XY 坐标的颜色(RGBA)?如果有,怎么做?
【问题讨论】:
在我的脑海中,你的选择是
选项 1 和 2 效率极低(尽管您可以通过使用像素缓冲区对象和异步复制来加快 2)。所以我最喜欢的 FAR 是选项 3。
编辑:如果您有 GL_APPLE_client_storage 扩展名(即您使用的是 Mac 或 iPhone),那么这就是选项 4,这是很长一段时间内的赢家。
【讨论】:
我发现最有效的方法是访问纹理数据(无论如何,您都应该将我们的 PNG 解码以制成纹理)并自己在纹素之间进行插值。假设您的 texcoords 是 [0,1],将 texwidthu 和 texheightv 相乘,然后使用它来查找纹理上的位置。如果它们是整数,直接使用像素,否则使用 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
}
【讨论】:
正如其他人所建议的那样,从 VRAM 中读回纹理效率极低,如果您甚至对性能感兴趣,也应该像瘟疫一样避免使用。
据我所知,两种可行的解决方案:
【讨论】: