Inconsistent shaders across platforms

I’ve made a very simple modified version of the built-in tile map shader which makes magenta transparent.

varying mediump vec4 position;
varying mediump vec2 var_texcoord0;

uniform lowp sampler2D DIFFUSE_TEXTURE;
uniform lowp vec4 tint;

void main()
{
    lowp vec4 tex_color = texture2D(DIFFUSE_TEXTURE, var_texcoord0.xy);
    
    // Pre-multiply alpha since all runtime textures already are
    lowp vec4 tint_pm = vec4(tint.xyz * tint.w, tint.w);
    
    // Make magenta transparent.
    if (tex_color.r == 1.0 && tex_color.g == 0.0 && tex_color.b == 1.0)
    {
    	tint_pm.x = 0.0;
    	tint_pm.y = 0.0;
    	tint_pm.z = 0.0;
    	tint_pm.w = 0.0;
    }
    
    gl_FragColor = tex_color * tint_pm;
}

I set up a material etc. This works perfectly well on Windows, Mac, HTML5 and Android 4, but it inexplicably doesn’t work on Android 6 and sends this to the console:

WARNING:GRAPHICS: 0:23: L0002: Undeclared variable 'f'

WARNING:RESOURCE: Unable to create resource: /build/default/render/my_tile_map.fpc
WARNING:RESOURCE: Unable to create resource: /build/default/render/my_tile_map.materialc
WARNING:RESOURCE: Unable to create resource: /build/default/main/levels/level_00.tilegridc
WARNING:RESOURCE: Unable to create resource: /build/default/main/levels/level.goc
ERROR:GAMEOBJECT: Could not instantiate game object from prototype /main/levels/level.goc.
WARNING:RESOURCE: Unable to create resource: /build/default/main/level_select.collectionc
ERROR:GAMESYS: The collection /main/level_select.collectionc could not be loaded.
WARNING:GRAPHICS: 0:23: L0002: Undeclared variable 'f'

WARNING:RESOURCE: Unable to create resource: /build/default/render/my_tile_map.fpc
WARNING:RESOURCE: Unable to create resource: /build/default/render/my_tile_map.materialc
WARNING:RESOURCE: Unable to create resource: /build/default/main/levels/level_00.tilegridc
WARNING:RESOURCE: Unable to create resource: /build/default/main/levels/level.goc
ERROR:GAMEOBJECT: Could not instantiate game object from prototype /main/levels/level.goc.
WARNING:RESOURCE: Unable to create resource: /build/default/main/game.collectionc
ERROR:GAMESYS: The collection /main/game.collectionc could not be loaded.

I have no idea what to do about that as it seems like a nonsense error - there is no ‘f’! If I make my_tile_map.fp match the built-in tile_map.fp then it works fine even on Android 6.

Separately, another inconsistency I found was that if you have ‘f’ at the end of numbers in shaders e.g. 0.0f instead of 0.0 then it will work fine on Windows but not on Mac, HTML5 or Android. Here’s the error log thrown in HTML5:

WARNING:GRAPHICS: ERROR: 0:25: '0.0f' : Floating-point suffix unsupported prior to GLSL ES 3.00 
printErr @ dmloader.js:299
dmloader.js:299 ERROR: 0:25: '0.0f' : syntax error 
printErr @ dmloader.js:299
2dmloader.js:299 
printErr @ dmloader.js:299
dmloader.js:299 WARNING:RESOURCE: Unable to create resource: ./game.darc/render/my_tile_map.fpc
printErr @ dmloader.js:299
dmloader.js:299 WARNING:RESOURCE: Unable to create resource: ./game.darc/render/my_tile_map.materialc
printErr @ dmloader.js:299
dmloader.js:299 WARNING:RESOURCE: Unable to create resource: ./game.darc/main/levels/level_00.tilegridc
printErr @ dmloader.js:299
dmloader.js:299 WARNING:RESOURCE: Unable to create resource: ./game.darc/main/levels/level.goc
printErr @ dmloader.js:299
dmloader.js:299 ERROR:GAMEOBJECT: Could not instantiate game object from prototype /main/levels/level.goc.
printErr @ dmloader.js:299
dmloader.js:299 WARNING:RESOURCE: Unable to create resource: ./game.darc/main/level_select.collectionc
printErr @ dmloader.js:299
dmloader.js:299 ERROR:GAMESYS: The collection /main/level_select.collectionc could not be loaded.
printErr @ dmloader.js:299
dmloader.js:299 WARNING:GRAPHICS: ERROR: 0:25: '0.0f' : Floating-point suffix unsupported prior to GLSL ES 3.00 
printErr @ dmloader.js:299
dmloader.js:299 ERROR: 0:25: '0.0f' : syntax error 
printErr @ dmloader.js:299
2dmloader.js:299 
printErr @ dmloader.js:299
dmloader.js:299 WARNING:RESOURCE: Unable to create resource: ./game.darc/render/my_tile_map.fpc
printErr @ dmloader.js:299
dmloader.js:299 WARNING:RESOURCE: Unable to create resource: ./game.darc/render/my_tile_map.materialc
printErr @ dmloader.js:299
dmloader.js:299 WARNING:RESOURCE: Unable to create resource: ./game.darc/main/levels/level_00.tilegridc
printErr @ dmloader.js:299
dmloader.js:299 WARNING:RESOURCE: Unable to create resource: ./game.darc/main/levels/level.goc
printErr @ dmloader.js:299
dmloader.js:299 ERROR:GAMEOBJECT: Could not instantiate game object from prototype /main/levels/level.goc.
printErr @ dmloader.js:299
dmloader.js:299 WARNING:RESOURCE: Unable to create resource: ./game.darc/main/game.collectionc
printErr @ dmloader.js:299
dmloader.js:299 ERROR:GAMESYS: The collection /main/game.collectionc could not be loaded.
printErr @ dmloader.js:299

But again it works just fine with no warnings or errors on Windows. It seems like this is happening because there are different API versions of GL being used on different platforms and even on different iterations of the same platform (Android 4 vs. Android 6). The Windows version allows ‘f’ on the end of numbers but the HTML5 version doesn’t. I get that different platforms support different features and APIs, but there doesn’t seem to be any way to know what the target will be or to test against specific GL versions from the same platform. For custom shaders to be viable I really need to know what features are supported where and to be able to test different target APIs from a single dev platform (in my case Windows).

Am I missing something? Are the GL versions listed somewhere, can I build for the lowest version required for my target platforms? I keep writing shaders on Windows only to find they don’t work anywhere else :confused:

1 Like

According to this answer you need to write shader code for the lowest common denominator, namely Open GL ES 2.0.

2 Likes

Ahhh, thanks! You posted in that thread saying it should go on the FAQ - I strongly agree! Now I need to work out how to do post-processing on OpenGL ES 2.0…

Let us know if you need any help!

@sicher: Could you please update the FAQ and any other relevant sections of the documentation with this info?

2 Likes

Yep, it’ll be part of the next release.

2 Likes