繁体   English   中英

Open GL中的纹理采样

[英]Texture Sampling in Open GL

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

我发现这样做最有效的方法是访问纹理数据(你应该将我们的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
}

在我的头顶,您的选择是

  1. 使用glGetTexImage()获取整个纹理并检查您感兴趣的纹素。
  2. 绘制您感兴趣的纹素(例如,通过渲染GL_POINTS原语),然后使用glReadPixels抓取从帧缓冲区渲染它的像素。
  3. 保留纹理图像的副本,并将OpenGL从中移除。

选项1和2非常低效(尽管你可以通过使用像素缓冲对象并异步进行复制来加速2)。 所以我最喜欢的FAR是选项3。

编辑:如果你有GL_APPLE_client_storage扩展名(即你在Mac或iPhone上),那么选项4就是获胜者。

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

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

  1. 保留pixeldata的副本方便(虽然浪费内存)
  2. 使用着色器进行

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM