android - 在 Android 设备上的 fragment 着色器中使用循环变量进行数组索引

标签 android opengl-es shader gpuimage fragment-shader

我在 Android 的 GPUImage 框架中编写着色器代码。然后我在 fragment 着色器中遇到了数组索引的问题。

根据 The OpenGL ES Shading Language 的附录,在vertex shader中,uniform数组可以用任意整数索引,varying数组可以用constant-index-expression索引。在 fragment 着色器中,两个(统一/可变)数组只能通过常量索引表达式进行索引。在constant-index-expression的定义下,for循环索引应该可以作为数组索引使用。

但是,当我在 fragment 着色器中使用循环索引作为数组索引时,事情就出错了。没有编译错误,着色器代码可以运行,但似乎程序在循环的每一轮中都将所有索引值视为 0。

这是我的 fragment 着色器代码:

uniform sampler2D inputImageTexture;
uniform highp float sample_weights[9]; // passed by glUniform1fv
varying highp vec2 texture_coordinate;
varying highp vec2 sample_coordinates[9]; // computed in the vertex shader
...
void main()
{
    lowp vec3 sum = vec3(0.0);
    lowp vec4 fragment_color = texture2D(inputImageTexture, texture_coordinate);
    for (int i = 0; i < 9; i++)
    {
        sum += texture2D(inputImageTexture, sample_coordinates[i]).rgb * sample_weights[i];
    }
    gl_FragColor = vec4(sum, fragment_color.a);
}

如果我展开循环并访问数组的 [0] 到 [8],结果将是正确的。 但是,使用循环索引时,结果不对,变成和运行一样

sum += texture2D(inputImageTexture, sample_coordinates[0]).rgb * sample_weights[0];

9次,过程中没有编译报错。

我只测试了一台设备,即搭载 Android 4.3 版的 Nexus 7。 GPUImage 框架使用 android.opengl.GLES20,而不是 GLES30。

这是对 Android 设备或 OpenGL ES 2.0 中的着色器代码的额外限制,还是一个与设备相关的问题?

更新: 在测试了更多 Android 设备(4.1~4.4)后,似乎只有 Nexus 7 设备有这个问题。在其他设备上的结果是正确的。有点奇怪。这是个别设备上的实现问题吗?

最佳答案

这是一个鲜为人知的事实,但循环内的纹理查找在 GLSL 中是未定义的。特别是小句子:“导数在非统一控制流中未定义”,参见 section 8.9 GLSL ES规范。并查看 section 3.9.2找出什么是非统一控制流。这适用于其他设备是偶然的。

不幸的是,您唯一的选择可能是取消循环。

关于android - 在 Android 设备上的 fragment 着色器中使用循环变量进行数组索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24881488/

相关文章:

iphone - 如何测量 OpenGL ES 的真实 FPS 性能?

Android OpenGL 视频捕获

three.js - 来自 uv 偏移的 GLSL webgl lerp 法线

android - 使用 Canvas/Sur​​faceview 或 OpenGL

Android SSL 错误握手失败

android - AlarmService示例错误构建找不到AlarmService_Service.class

opengl-es - 什么是 OpenGL 着色器语言中的不变量变化

android - 使用 `mailto:` 方案通过 Intent 发送电子邮件附件

opengl - 您如何使用 LIBGDX 将每像素照明合并到着色器中?

opengl-es - OpenGL : Single vertex attribute for multiple vertices?