【问题标题】:Texture Sampling in Open GLOpen GL 中的纹理采样
【发布时间】:2010-09-15 22:53:56
【问题描述】:

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

【问题讨论】:

    标签: c++ opengl


    【解决方案1】:

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

    1. 使用 glGetTexImage() 获取整个纹理并检查您感兴趣的纹素。
    2. 绘制您感兴趣的纹素(例如,通过渲染 GL_POINTS 基元),然后使用 glReadPixels 从帧缓冲区中抓取您渲染它的像素。
    3. 请随身携带一份纹理图像,不要使用 OpenGL。

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

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

    【讨论】:

    • 在选项 2 之外,您需要一种基于 texcoords 的采样方法,但这是困难的部分——这在我的回答中有所描述。
    • 我的理解是,发帖人问的是如何实现示例中的“getTexel”部分,而不是如何复制过滤(这取决于他想要复制的过滤类型)。
    • 我有点想问 getTexel 部分,但是,他说得对,1 和 2 太慢了,尤其是考虑到我正在使用移动设备。谢谢:)
    • 移动设备?那会是一部iPhone吗?查看更新的答案。
    • 确实会是 Mike F,感谢您的提示...尽管在这种情况下,数据确实可以在创建 openGL 纹理之前作为原始图像数据进行预处理。跨度>
    【解决方案2】:

    我发现最有效的方法是访问纹理数据(无论如何,您都应该将我们的 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
    }
    

    【讨论】:

      【解决方案3】:

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

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

      1. 随手保留一份像素数据的副本(虽然会浪费内存)
      2. 使用着色器实现

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-12-15
        • 2012-07-29
        • 1970-01-01
        • 1970-01-01
        • 2020-03-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多