【问题标题】:Texture lookup in vertex shader behaves differently on iPad device vs iPad simulator - OpenGL ES 2.0顶点着色器中的纹理查找在 iPad 设备与 iPad 模拟器上的行为不同 - OpenGL ES 2.0
【发布时间】:2010-11-15 18:56:09
【问题描述】:

我有一个顶点着色器,我在其中进行纹理查找以确定 gl_Position。我将其用作 GPU 粒子模拟系统的一部分,其中粒子位置存储在纹理中。

似乎:vec4 textureValue = texture2D(dataTexture, vec2(1.0, 1.0)); 在模拟器上的行为与 iPad 设备上的行为不同。在模拟器上,纹理查找成功(该位置的值为 0.5、0.5)并且我的粒子出现在那里。但是,在 iPad 本身上,纹理查找不断返回 0.0、0.0。

我已经尝试过 GL_FLOAT 和 GL_UNSIGNED_BYTE 格式的两种纹理。

有其他人经历过吗? GLSL ES 规范说纹理查找可以在顶点和片段着色器中完成,所以我看不出问题出在哪里。

我正在使用 iOS SDK 4.2 的最新 GM Beta

【问题讨论】:

    标签: ipad ios opengl-es shader


    【解决方案1】:

    我也刚刚对此进行了测试。使用 iOS 4.3,您可以在设备和模拟器上的顶点着色器上进行纹理查找。虽然有一点奇怪(这也许就是为什么它不像 szu 提到的那样“官方”)。在实际设备上(我在 iPad 2 上测试过),您必须在片段着色器和顶点着色器上进行查找。也就是说,如果您实际上并没有在片段着色器上使用它,您仍然必须以某种方式引用它。这是一个简单的例子,我传入一个纹理并使用红色像素将顶点的 y 值重新定位一点:

    /////fragment shader
    uniform sampler2D tex; //necessary even though not actually used
    
    void main() {
      vec4 notUsed = texture2D(tex, vec2(0.0,0.0)); //necessary even though not actually used
      gl_FragColor = vec4(1.0,1.0,1.0,1.0);
    }
    
    /////vertex shader
    attribute vec4 position;
    attribute vec2 texCoord;   
    uniform sampler2D tex; 
    
    void main() {
      float offset = texture2D(tex, texCoord).x;
      offset = (offset - 0.5) * 2.0; //map 0->1 to -1 to +1
      float posx = position.x;
      float posy = position.y + offset/8.0;
    
      gl_Position = vec4(posx, posy, 0.0, 1.0);  
    }
    

    我在http://www.mat.ucsb.edu/a.forbes/blog/?p=453 有一个稍微完整的文章

    【讨论】:

    • 你发现的一定是一个错误或“快乐的意外”。在我的 iPad(当然是 4.2.1)上,GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 返回 0,这意味着不能在顶点着色器中进行纹理查找。我很好奇你在 iPad2 上获得 GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 的价值。
    • 嗨,我的 iPad 2 使用 4.3.4 也为 GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 返回 0(对于 GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 和 GL_MAX_TEXTURE_IMAGE_UNITS 都返回 8)。我的猜测是 iPad 2 上的显卡支持它,但由于某种原因,驱动程序禁用了它,以便在各种 iOS 设备上有统一的行为。我还没有在 iPhone 或 iPad 1 上尝试过。 iOS iPad 4.3 模拟器也为 GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 报告 0,但允许您从顶点着色器正常访问纹理(无需在片段着色器中添加假纹理查找)。
    • 嗯,有趣.. 尽管我很想使用该功能,但如果我的应用程序忽略报告的值,我对未来的硬件会破坏我的应用程序感到过于偏执。 :(
    • 没错,我不会向公众发布使用顶点纹理的应用程序。希望 iOS 5 将添加此功能。
    • iOS 7 又回来了 - 适用于所有设备。现在它也是官方的。他们只花了 3 年时间就修复了任何错误:)
    【解决方案2】:

    来自官方的“OpenGL ES Programming Guide for iOS”,“Platform Notes”部分

    “您不能在顶点着色器中使用纹理查找。”

    【讨论】:

      【解决方案3】:

      这不是 sim 和设备中唯一表现不同的东西。我会给你和其他人一样的建议:当你需要测试东西在设备上看起来应该如何时,忽略模拟器。只测试逻辑、功能之类的东西,不要看模拟,而且只有在可以的情况下。

      【讨论】:

      • 对,这就是我一直在做的;但我找不到在设备上实现正确行为的方法。这是一个简单的纹理查找,所以我不知道如何修复它。
      【解决方案4】:

      我感觉 iPad(或 iPhone)上的 GLES 不支持在顶点着色器中查找纹理,但不要引用我的话。

      如果它确实支持顶点着色器中的纹素查找,也许你的纹理坐标被剪裁或包裹?因为 1.0x1.0 在纹理 IIRC 之外。

      环绕模式下的 1.0x1.0 应该是 0.0x0.0。 剪裁中的 1.0x1.0 应该是最后一个纹素。

      【讨论】:

      • 对,在这种情况下,我的纹理是完全一样的“颜色”。数据到处都是 0.8。仍然得到 0,0 作为返回值。
      • 我要做的第一件事是在同一纹理上测试一个简单的片段着色器,并尝试尽可能少地更改代码。如果它显示正确,要么顶点着色器出现问题,要么无法进行纹素查找。
      • 是的,我使用单独的着色器将纹理显示在四边形上,效果很好。我想答案是不能在 iPad 硬件上的顶点着色器中进行纹理查找。
      • 如果能得到证实就太好了。我会进一步检查文档,因为我觉得我在某个地方读到了这篇文章。
      【解决方案5】:

      我自己尝试过,Texture2D 确实在 iOS 4.2 下的 iPad(设备和模拟器)上在顶点着色器中使用时工作。

      我最好的猜测是您启用了 mip 映射,这就是问题所在。我注意到使用 Texture2D 的顶点着色器中的 mip 映射查找在模拟器中有效,但在设备上无效。您不能在顶点着色器中使用带有 Texture2D 的 mip 贴图,因为它无法选择要使用的 mip-map 级别。您需要禁用该纹理的 mip-mapping,或者改用支持 mip 贴图的 Texture2DLod。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-05-04
        • 1970-01-01
        • 2011-11-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多