mirror of
https://github.com/love2d/love-android.git
synced 2026-08-12 08:31:04 +02:00
Created Shaders in Android (markdown)
@@ -0,0 +1,130 @@
|
||||
Shaders in Android
|
||||
=====
|
||||
|
||||
To use shaders in LÖVE Android you use the same API as in LÖVE
|
||||
|
||||
```lua
|
||||
love.graphics.newShader[[
|
||||
Your shader code
|
||||
]]
|
||||
```
|
||||
|
||||
The reason the shader code doesn't work is that desktop machines use OpenGL and Android devices use OpenGLES, 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:
|
||||
|
||||
* [No acceptable conversion](#no-acceptable-conversion)
|
||||
* [Field selection out of range](#field-selection-out-of-range)
|
||||
* [Uniform couldn´t be initialized](#uniform-couldn-t-be-initialized)
|
||||
|
||||
If you stuck on desktops without OpenGLES driver support, you can use ANGLE, or since 11.0, [`love.graphics.validateShader(true, shaderCode)`](https://love2d.org/wiki/love.graphics.validateShader).
|
||||
|
||||
------------------
|
||||
|
||||
No acceptable conversion
|
||||
-----
|
||||
|
||||
OpenGLES doesn´t handle float and int conversions by default, instead every float or int should be manually converted. For example:
|
||||
|
||||
```glsl
|
||||
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`
|
||||
|
||||
```glsl
|
||||
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:
|
||||
|
||||
```glsl
|
||||
float foo;
|
||||
int bar;
|
||||
if (foo == bar)
|
||||
```
|
||||
|
||||
Should be:
|
||||
|
||||
```glsl
|
||||
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
|
||||
|
||||
```glsl
|
||||
uniform vec2[4] array;
|
||||
```
|
||||
|
||||
Generating an array with 4 `vec2` elements. But OpenGLES doesn´t use this notation. Instead you should write it like this:
|
||||
|
||||
```glsl
|
||||
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](http://www.love2d.org/wiki/love.graphics.newShader#Shader_Language) you can use `extern` as you would use `uniform` in OpenGLSL 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
|
||||
|
||||
```glsl
|
||||
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 OpenGLSL 1.2 (The one used in desktop environments), Android uses an OpenGLSL based on it it doesn´t include this feature.
|
||||
|
||||
Instead you could just use:
|
||||
|
||||
```glsl
|
||||
uniform float foo;
|
||||
float bar = 5;
|
||||
```
|
||||
|
||||
And in your shader code check if it´s `0.0`
|
||||
|
||||
```glsl
|
||||
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.
|
||||
|
||||
```lua
|
||||
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](https://github.com/binji/love-nacl/wiki/Modifying-your-shaders-to-work-with-L%C3%96VELINESS) page of the LÖVELINESS Wiki.
|
||||
|
||||
Look at this links for more information on shaders in Android:
|
||||
|
||||
* [OpenGL Wiki](http://www.opengl.org/wiki/Main_Page) Not everything works in OpenGL ES
|
||||
* [OpenGLES Shading Language PDF](http://www.khronos.org/files/opengles_shading_language.pdf) This file tells you what you can and can´t do, plus it list the differences with OpenGLSL.
|
||||
* [OpenGL 2.0 Spec](http://www.khronos.org/files/opengles_shading_language.pdf) OpenGLES 2.0 Shading Language is based on this OpenGLSL implemantation. It still differs.
|
||||
Reference in New Issue
Block a user