Solarus quests
1.6
Quest maker's reference
|
This module provides a datatype shader
that represents an OpenGL or OpenGL ES shader program.
Shaders allow you to modify the video rendering of the window or of drawable objects like sprites, surfaces and text surfaces.
For example, shaders can be used to apply a smoothing filter or to make some advanced visual effects to a sprite, to a surface or to the whole window.
Shaders are programs executed by the GPU during a rendering pass. They are written in a shading language (GLSL or GLSL ES in Solarus).
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 texture. If no fragment shader is defined in your shader program, then a default one that keeps pixels unchanged is used.
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.
Solarus compiles them at runtime when you create them with sol.shader.create(). You can either apply a shader to the whole window with sol.video.set_shader(), or to an individual surface, text surface or sprite with drawable:set_shader().
During the execution, a shader may be applied to the rendering of the whole window. Use sol.video.get_shader() and sol.video.set_shader() to control this.
This defines how the quest surface (whose size is sol.video.get_quest_size() is drawn and scaled to fit to the window, which may be bigger. Thus, by default, the fragment shader works on an output texture of the size of the window. This can be changed using shader:set_scaling_factor().
Shaders can also alter how drawable objects are rendered on the screen, using drawable:set_shader(). In other words, you can apply a shader to any surface, text surface or sprite.
For example, if you want to apply a shader to the map surface without affecting what is displayed above, like the HUD elements or the dialog box, you can apply the shader to the camera's surface, with map:get_camera():get_surface():set_shader(my_shader)
.
Additionally to the modern 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 described below, you can also pass your own variables.
In a vertex shader, the following three attributes are automatically passed as input:
attribute vec2 sol_vertex
: Coordinates of the current vertex in the 3D space (same as gl_Vertex
in old GLSL versions).attribute vec2 sol_tex_coord
: Texture coordinates of the current vertex (same as gl_MultiTexCoord0
in old GLSL versions).attribute vec4 sol_color
: Color of the vertexThe 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 mat3 sol_uv_matrix
: The texture transform matrix.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().uniform float opacity
: Opacity of the object the shader is applied to, between 0.0
and 1.0
. Aways 1.0
if the shader is applied to the window.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. Note that #version 100
tells the GLSL compiler to treat this shader as GLSL ES.
// Vertex shader: #version 100 precision mediump float; uniform mat4 sol_mvp_matrix; uniform mat3 sol_uv_matrix; attribute vec2 sol_vertex; attribute vec2 sol_tex_coord; attribute vec4 sol_color; varying vec2 sol_vtex_coord; varying vec4 sol_vcolor; void main() { gl_Position = sol_mvp_matrix * vec4(sol_vertex, 0.0, 1.0); sol_vcolor = sol_color; sol_vtex_coord = (sol_uv_matrix * vec3(sol_tex_coord, 1.0)).xy; } // Fragment shader: #version 100 precision mediump float; uniform sampler2D sol_texture; in vec2 sol_vtex_coord; in vec4 sol_vcolor; void main() { vec4 tex_color = texture(sol_texture, sol_vtex_coord); gl_FragColor = tex_color * sol_vcolor; }
Now, another example of a shader program that removes the red component of all pixels:
// No vertex shader. // Fragment shader: #version 100 precision mediump float; uniform sampler2D sol_texture; in vec2 sol_vtex_coord; in vec4 sol_vcolor; out vec4 FragColor; void main() { vec4 tex_color = texture(sol_texture, sol_vtex_coord); FragColor = tex_color * sol_vcolor * vec4(0.0, 1.0, 1.0, 1.0); }
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, the legacy OpenGL variables and attributes such as gl_ModelViewProjectionMatrix
and gl_Vertex
are not supported on modern plaftorms. You should therefore only use Solarus built-in variables plus your own ones.
Loads and returns a shader program from a shader description file.
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).Loads and returns a shader program from the given parameters.
This function can be used for advanced purposes, but the normal way is to use sol.shader.create(shader_id), that is, to load a shader already described in a data file.
If the loading or the compilation of the shader program fails, a Lua error is raised.
properties
(table): Source and parameters of the shader program. Can have the following entries:vertex_source
(string, optional): GLSL code of the vertex shader. No values means to use a default shader that does nothing specialfragment_source
(string, optional): GLSL code of the fragment shader. No values means to use a default shader that does nothing special.scaling_factor
(number, optional): When the shader is applied to the whole window, indicates how much the input texture will be scaled by the shader. See shader:set_scaling_factor() for more details.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 vertex shader code of this shader program.
Returns the name of the fragment shader file of this shader program.
"shaders"
directory, or nil
if no fragment shader file was set.Returns the fragment shader code of this shader program.
Returns the scaling factor of this shader.
The scaling factor indicates how much the input texture will be scaled by the shader. See shader:set_scaling_factor() for more details.
nil
if no scaling factor is set.Sets the scaling factor of this shader.
The scaling factor indicates how much the input texture will be scaled by the shader when the shader is applied to the window.
This value only has an effect when the shader is applied to the window (with sol.video.set_shader()), and does nothing when the shader is applied to a drawable object (with drawable:set_shader()).
If no value is set (the default), then the output texture of the shader will directly have the size of the window. If a value is set, then the output texture of the shader will have the size of the input texture multiplied by this scaling factor (however, that output texture will then be scaled a second time to fit to the actual window). This is only useful for scaling shaders.
scaling_factor
(number): The scaling factor. A nil
value means to set no scaling factor.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.