aritchie
aritchie

Reputation: 601

Unity Android Shader not supported on some devices

I have an Unity app that uses a custom shader for video playback. On some devices the video isn't shown and I get the following error message printed out in LogCat:

E/Unity   (11415): -------- Custom/AndroidVideoShader
E/Unity   (11415): 
E/Unity   (11415):  
E/Unity   (11415): (Filename: Runtime/GfxDevice/opengles/GlslGpuProgramGLES.cpp Line: 141)
E/Unity   (11415): 
E/Unity   (11415): -------- failed compiling fragment shader:
E/Unity   (11415): 
E/Unity   (11415):  
E/Unity   (11415): (Filename: Runtime/GfxDevice/opengles/GlslGpuProgramGLES.cpp Line: 142)
E/Unity   (11415): 
D/Unity   (11415): #ifndef SHADER_API_GLES
D/Unity   (11415):     #define SHADER_API_GLES 1
D/Unity   (11415): #endif
D/Unity   (11415): #ifndef SHADER_API_MOBILE
D/Unity   (11415):     #define SHADER_API_MOBILE 1
D/Unity   (11415): #endif
D/Unity   (11415): #line 7
D/Unity   (11415): #ifdef DUMMY_PREPROCESSOR_TO_WORK_AROUND_HLSL_COMPILER_LINE_HANDLING
D/Unity   (11415): #endif
D/Unity   (11415): #line 7
D/Unity   (11415): #ifdef DUMMY_PREPROCESSOR_TO_WORK_AROUND_HLSL_COMPILER_LINE_HANDLING
D/Unity   (11415): #endif
D/Unity   (11415):      precision mediump float;
D/Unity   (11415): varying vec2 textureCoordinates;
D/Unity   (11415):      
D/Unity   (11415):      
D/Unity   (11415):      
D/Unity   (11415):      
D/Unity   (11415):   // require GL_OES_EGL_image_external so we can access the external texture data on android's GPU
D/Unity   (11415):   #extension GL_OES_EGL_image_external : require
D/Unity   (11415):   uniform samplerExternalOES _MainTex;
D/Unity   (11415):   void main()
D/Unity   (11415):   {
D/Unity   (11415):    gl_FragColor = texture2D(_MainTex, textureCoordinates);
D/Unity   (11415):   }
D/Unity   (11415):   
D/Unity   (11415):   
E/Unity   (11415): -------- GLSL error: 0:23: P0007: Extension directive must occur before any non-preprocessor tokens
E/Unity   (11415): 0:25: L0001: Typename expected, found 'samplerExternalOES'
E/Unity   (11415): 
E/Unity   (11415): 
E/Unity   (11415): 
E/Unity   (11415):  
E/Unity   (11415): (Filename: Runtime/GfxDevice/opengles/GlslGpuProgramGLES.cpp Line: 145)
E/Unity   (11415): 
D/Unity   (11415): Warning: Creation of shader 'Custom/AndroidVideoShader' failed.
D/Unity   (11415): WARNING: Shader 
D/Unity   (11415): Unsupported: 'Custom/AndroidVideoShader' - Pass '' shader state not supported

The shader code is as follows:

Shader "Custom/AndroidVideoShader" {
Properties {
    _MainTex ("Base (RGB)", 2D) = "white" {}
}
SubShader {
    Pass{


    GLSLPROGRAM

    varying vec2 textureCoordinates;

    #ifdef VERTEX

    // get the texture offset ftom our material
    uniform mediump vec4 _MainTex_ST;

    void main()
    {
        // multiply the UV by texture scale and add the offset
        textureCoordinates.xy = (gl_MultiTexCoord0.xy * _MainTex_ST.xy) + _MainTex_ST.zw;

        //textureCoordinates = gl_MultiTexCoord0;

        gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
    }

    #endif


    #ifdef FRAGMENT

    // require GL_OES_EGL_image_external so we can access the external texture data on android's GPU
    #extension GL_OES_EGL_image_external : require

    uniform samplerExternalOES _MainTex;

    void main()
    {
        gl_FragColor = texture2D(_MainTex, textureCoordinates);
    }

    #endif

    ENDGLSL
    }
} 
FallBack "Diffuse"
}

It doesn't seem to be an android version thing as the devices I get the error on (a client's Note 2 and an Huawei Ascend Y330) are running different versions of Android (4.4.2 and 4.2.2 respectively). I have a Nexus 7 (4.2.2), Xperia M2 (4.4.4) and Galaxy Tab 8.4 (5.1.1) that all work with no problems.

I'm not experienced in shaders - is there anything obvious that's causing a problem? In Unity I've tried setting the Graphics Level to OpenGLES2.0 and OpenGLES3.0 but it doesn't make any difference.

Upvotes: 0

Views: 3642

Answers (1)

solidpixel
solidpixel

Reputation: 12109

It's a syntax error in the shader,

GLSL error: 0:23: P0007: Extension directive must occur before any non-preprocessor tokens

It isn't legal in the ESSL specification for:

#extension GL_OES_EGL_image_external : require

... to be defined after:

varying vec2 textureCoordinates;

The reason it works at all on some devices is just luck - some shader compilers are less picky than others. Change the shader so the #extension definition is the first thing in the source, and it should then all work fine.

Upvotes: 0

Related Questions