Shaders in Android - love2d/love-android GitHub Wiki

Shaders in Android

To use shaders in LÖVE Android you use the same API as in LÖVE

love.graphics.newShader[[
    Your shader code
]]

The reason the shader code doesn't work is that desktop machines use OpenGL and Android devices use OpenGL ES, and the shader language implementation is different in some aspects. This guide details the differences that you should take into account when writing shader code for Android.

The problems that may arise are:

If you stuck on desktops without OpenGL ES driver support, you can use ANGLE, or since 11.0, love.graphics.validateShader(true, shaderCode).


No acceptable conversion

OpenGL ES doesn't handle float and int conversions by default, instead every float or int should be manually converted. For example:

float foo;
if (foo == 0)

This would return an error since foo is a float and 0 is an int, yeah 0 is a perfect float but the shader language doesn´t see it that way. Instead you should use 0.0

float foo;
if (foo == 0.0)

If you are working with too different variables it may be easier to cast the int into a float. For example:

float foo;
int bar;
if (foo == bar)

Should be:

float foo;
int bar;
if (foo == float(bar))

Field selection out of range

This error occurs when creating arrays, in OpenGL you would use the following code

uniform vec2[4] array;

Generating an array with 4 vec2 elements. But OpenGL ES doesn't use this notation. Instead you should write it like this:

uniform vec2 array[4];

The length must be specified in the identifier and not in the type

Uniform couldn't be initialized

Well this took me a while to find but it´s rather simple. In LÖVE Shader Language you can use extern as you would use uniform in GLSL so that you can then send data to the shader using Shader:send(). The problem comes when you need to have a default value in the variable. In OpenGL you would normally do

uniform float foo = 5;

So if you pass a number to foo it will take that value, but if you don't send anything it would take 5 as it's own value. This was added in GLSL 1.2 (The one used in desktop environments), but ESSL doesn't support this feature.

Instead you could just use:

uniform float foo;
float bar = 5;

And in your shader code check if it's 0.0

if (foo == 0.0) {
    bar = 5;
} else {
    bar = foo;
}

This code doesn't allow you to have bar == 0.0. If you don't like that then there is another alternative, you can just store the variable value in Lua and send it before running the shader.

shader = love.graphics.newShader[[
   //Shader Code//
   uniform float foo;
   //Shader Code//
]]

foo = 5
--Your lua code that may or may not change foo
shader:send("foo", foo) --Shader is the shader created before, that makes use of foo
love.graphics.setShader(shader)

This is a better solution and should behave as expected


More Info

This file is based in the Modifying your shaders to work with LÖVELINESS page of the LÖVELINESS Wiki.

Look at this links for more information on shaders in Android: