Android OpenGL ES2.0,着色器在某些设备上编译错误

Android OpenGL ES2.0, shader compile false on some devices

从 firebase 日志中,我可以看到大约 1% 的应用用户遇到了着色器编译错误。

我阅读了源代码,但不知道为什么它不能在某些设备上运行。

这是顶点着色器。

precision mediump float; 
uniform mat4 uMVPMatrix;  
attribute vec4 vPosition;  
varying vec2 textureCoordinate;  
void main() {   
    textureCoordinate=vec2((1.0+vPosition.x)/2.0, (1.0-vPosition.y)/2.0); 
    gl_Position = uMVPMatrix * vPosition;  
} 

这是片段着色器。

    precision mediump float;  
varying vec2 textureCoordinate;  
uniform sampler2D inputImageTexture;  
uniform float flipH;  
uniform float flipV;  
uniform float angle;  
uniform float blendAlpha; 
uniform vec4 sampleCoord1;  
uniform vec4 sampleCoord2;  
uniform float blurV;  
uniform sampler2D inputImageTexture1; //frame   
uniform sampler2D inputImageTexture2;   
uniform sampler2D inputImageTexture3;   
uniform sampler2D inputImageTexture4;   
uniform sampler2D inputImageTexture5;   
uniform sampler2D inputImageTexture6;   
uniform sampler2D inputImageTexture7;   
uniform float fW;  //sample proportionally   
uniform float fH;   
uniform float sX; // start of x and y.   
uniform float sY;   
vec3 texel;   
uniform float iGlobalTime; //for video   
uniform float alpha;  

vec3 effect(vec3 texel){ 
    return texel; 
} 

vec2 cllCoord1(float s, float t){
    return vec2(sampleCoord1.x + s*sampleCoord1.z, sampleCoord1.y + t*sampleCoord1.w);
} 
vec2 cllCoord2(float s, float t){
    return vec2(sampleCoord2.x + s*sampleCoord2.z, sampleCoord2.y + t*sampleCoord2.w);
} 

void main() {  
    float s=textureCoordinate.x; 
    float t=textureCoordinate.y; 
    vec3 srcTexel = texture2D(inputImageTexture1, cllCoord1(s,t)).rgb; 
    vec3 desTexel = texture2D(inputImageTexture7, cllCoord2(s,t)).rgb; 
    if( s <= blendAlpha ){  
        desTexel = texture2D(inputImageTexture7, cllCoord2(1.0 + s -blendAlpha, t)).rgb; 
    }else{ 
        desTexel = vec3(0.0); 
    } 

    if(length(textureCoordinate-vec2(0.0, 1.0))>= blendAlpha*1.42){      
        texel=srcTexel; 
    }else{      
        texel=desTexel; 
    } 

    texel=effect(texel); 
    gl_FragColor= vec4(texel, alpha);  
} 

编译后compileStatus[0]为false

    final int[] compileStatus = new int[1];
    GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compileStatus, 0);

    if (compileStatus[0] != GLES20.GL_TRUE) {

我尝试分析上面的着色器,但我不知道为什么它在某些设备上不起作用。在我自己的 devices/emulators 中,它总是工作正常!

应该不是编译错误,否则我会得到更详细的日志,比如哪一行没有编译。

如果低至 1% 的用户失败,那么您可能处于驱动程序错误的境界。 运行 通过 GLSL 参考编译器编写代码来确认这一点通常很有用,但我强烈怀疑是这种情况:glslang

如果我不得不猜测你做了什么让不兼容的编译器感到困惑,我会选择:

  1. 一个名为 texel 的变量被用作全局变量和函数参数。
  2. 您有 6 个未使用的采样器
  3. 您有一个对 texture2D 的调用,可以通过 if 语句跳过。如果有 mipmap,这是未定义的行为。

Accessing mip-mapped textures within the body of a non-uniform conditional block gives an undefined value. A non-uniform conditional block is a block whose execution cannot be determined at compile time.