![]() |
This module provides a datatype shader
that represents an OpenGL or OpenGL ES shader program.
Shaders allow you to modify the video rendering, for example to apply a smoothing filter or to make some advanced visual effects.
Shaders are programs executed by the GPU during a rendering pass. They are written in a shading language (GLSL or GLSL ES in Solarus). Solarus compiles them at runtime when you create them with sol.shader.create(). If you activate them with sol.video.set_shader(), they are then executed on the GPU at each rendering frame.
A shader program, represented by the shader
Solarus datatype, is composed of a vertex shader and of a fragment shader (also called pixel shader).
At every rendering frame, the vertex shader is called for each of the four corners of the input texture. If no vertex shader is defined in your shader program, then a default one is used. The fragment shader is then called for each pixel of the window. The fragment shader is mandatory in a Solarus shader program.
The rest of this documentation page explains how to use shaders with the Solarus Lua API. We assume that you have some basic knowledge of shaders and GLSL or GLSL ES. See the documentation of OpenGL and OpenGL ES for more information about shaders and shading languages.
During the execution, a shader may be applied to the rendering. Use sol.video.get_shader() and sol.video.set_shader() to control this.
The id of the shader applied if any can be saved and loaded with the global settings, (as well as other preferences like the language and the volume), independently of any savegame. See sol.main.load_settings().
Additionally to the OpenGL or OpenGL ES built-in variables, Solarus automatically passes some additional useful variables to your shaders. Solarus built-in variables are always prefixed with "sol_"
.
Note that using the Lua API, you can also pass your own variables.
In a vertex shader, the following two attributes are automatically passed as input:
attribute vec4 sol_vertex
: Coordinates of the current vertex in the 3D space (same as gl_Vertex
in old GLSL versions).attribute vec4 sol_tex_coord
: Texture coordinates of the current vertex (same as gl_MultiTexCoord0
in old GLSL versions).The following uniforms are automatically passed as input if they are declared in a vertex shader or in a fragment shader:
uniform mat4 sol_mvp_matrix
: The model-view projection matrix (same as gl_ModelViewProjectionMatrix
in old GLSL versions).uniform sampler2D sol_texture
: The input texture to render.uniform vec2 sol_input_size
: Size of the input texture sol_texture
before any scaling. Equal to sol.video.get_quest_size().uniform vec2 sol_output_size
: Size of the output area, including the black bars if any. In windowed mode, equal to sol.video.get_window_size() In fullscreen mode,
equal to the screen resolution.uniform int sol_time
: Simulated time elapsed since Solarus was started. Equal to sol.main.get_elapsed_time().Here is a shader program that does nothing special: it just scales the input texture to fit the window, just like when no shader is set.
// Vertex shader: in vec2 tex_coord; void main() { gl_Position = sol_mvp_matrix * sol_vertex; tex_coord = sol_tex_coord.xy; } // Fragment shader: uniform sampler2D sol_texture; in vec2 tex_coord; void main() { gl_FragColor = texture2D(sol_texture, tex_coord); }
Now, another example of a shader program that removes the red component of all pixels:
// Vertex shader: varying vec2 tex_coord; void main() { gl_Position = sol_mvp_matrix * sol_vertex; tex_coord = sol_tex_coord.xy; } // Fragment shader: uniform sampler2D sol_texture; in vec2 tex_coord; void main() { vec3 color = texture2D(sol_texture, tex_coord); color.r = 0.0; gl_FragColor = color; }
The exact supported shader language depends on the OpenGL or OpenGL ES version Solarus is compiled with on every platform. Typically, on desktop platforms, Solarus is compiled with OpenGL support and the shader language used is some version of GLSL. On mobile platforms, OpenGL ES and GLSL ES are normally used instead.
For maximum portability, there are two possible approaches:
#version
macro, be careful because GLSL
and GLSL ES have their own history of version numbers.In any case, a good practice is to rely on the Solarus built-in variables (plus your own ones) rather than the OpenGL ones, since a lot of old OpenGL built-in variables
(like gl_Vertex
or gl_ModelViewProjectionMatrix
) are now obsolete or simply don't exist in recent OpenGL versions and in OpenGL ES.
Loads and returns a shader program.
If the loading or the compilation of the shader program fails, a Lua error is raised.
shader_id
(string): Id of the shader program to load (filename without extension, relative to the shaders
directory).Returns the OpenGL or OpenGL ES version Solarus is being run with.
Returns the GLSL or GLSL ES format supported by the OpenGL or OpenGL ES version currently used.
Returns the id of this shader program.
Returns the name of the vertex shader file of this shader program.
"shaders"
directory, or nil
if no vertex shader file was set.Returns the name of the fragment shader file of this shader program.
"shaders"
directory.Sets a uniform value to this shader.
Uniforms are input values to shader programs that are constant for all vertices and pixels during one rendering frame. Solarus automatically sets some uniform variables for you if you define them in the shader (see the built-in variables section above).
Use this function if you want to pass additional uniform values.
The type of the uniform in your shader source code will depend on the Lua type you pass here:
boolean:
should be declared as bool
in the shader.number:
should be declared as float
in the shader.number
s: should be declared as vec2
in the shader.number
s: should be declared as vec3
in the shader.number
s: should be declared as vec4
in the shader.sampler2D
in the shader.If the shader has no uniform with the given name, then this method does nothing.
uniform_name
(string): Name of the uniform in your shader program.