| function | args | returns | description |
|---|---|---|---|
| [image_shader] | vid, shader_id | Change the active shader of the specified VID. | |
| [mesh_shader] | vid, shader_id, slot | Associate a shader for the specified mesh slot. | |
| [build_shader] | vshdr, fshdr, label | shader_id | |
| [shader_uniform] | shader_id, symbol, fmtstr, persist, ... | Define a value for the symbol slot uniform in the specifed shader, using a fmtstr to define how the variadic arguments at the end should map. |
Shaders, in the sense used herein, cover programs intended to be run in the varying stages of data transformation in modern graphics pipelines and are central to most accelerated 3D (and nowadays 2D) rendering.
All VIDs, including those mapped to a 3D model, are associated with a default shader that only applies a single texture (image) with uniform blending based on the opacity property in the object associated with a VID.
For many effects, one may want or need to replace this behavior with a custom defined one, and this is where this category of functions may be useful. Only shaders written in the GLSL language are supported, and only for the vertex and fragment stages, not the geometry one.
To ease loading and management, also check [3dsupport.lua]
For a more verbose description of shaders and GLSL, please consult a more thorough guide, e.g. http://nehe.gamedev.net/article/glsl_an_introduction/25007/
The rest of these pages assume some moderate experience with shaders.
Shaders have their own shared namespace that is handled a bit differently from VIDs and AIDs. For one is that there is a compile-time defined upper limit and that each compiled tuple of programs are associated with both a unique text label and an ID. A shader that have been built stays allocated for the remainder of the program lifespan.
A call to [build_shader] such as:
shid = build_shader( vertprogram, fragprogram, "background");
would try and compile vertprogram and fragprogram into a shader tagged as 'background'. The resulting SHID can then be used with the [image_shader] [build_shader] and [shader_uniform] functions.
The shader compilation step depends on the quality of the compiler in the graphics drivers or GL libraries (e.g. MesaGL) and can be a source of much headache. Having GDebugger http://www.gremedy.com or similar tools ready for debugging purposes is recommended as they can fail for very subtle reasons and error messages aren't always helpful. Keep in mind that there is a full C- style preprocessor part in every GLSL shader (e.g. #define, #ifdef, all work ...)
There are a few formalized ways of passing data to/between shaders, e.g. attributes and uniform variables and there are a few hard-coded symbols that Arcan will try and look for, and update whenever relevant.
User-defined uniforms can be set and manipulated through the [shader_uniform] function.
Arcan-defined uniforms (will be set if used by shader):
| Uniform | Kind | Use |
|---|---|---|
| modelview | matr4x4 | object->eye transform. |
| projection | matr4x4 | eye(camera) -> clip transform. |
| texturem | matr4x4 | not in use currently. |
| obj_opacity | float | opacity value (0..1 range) |
| fact_timestamp | float | (001..0.999) towards next time-tick (for interpolations) |
| timestamp | int | current monotonic time value |
Arcan-defined attributes (will be set if used by shader, vertex and texcoord will almost always be needed):
| Attributes | Use |
|---|---|
| vertex | object space vertex values |
| normal | object space normal |
| color | per vertex color |
| texcoord | per vertex texture coordinate |
The default fragment shader (version 120) for the 2D pipeline looks like this:
uniform sampler2D map_diffuse;
varying vec2 texco;
uniform float obj_opacity;
void main(){
vec4 col = texture2D(map_diffuse, texco);
col.a = col.a * obj_opacity;
gl_FragColor = col;
}
(unset samplers default to 0, the first texture unit). The default vertex shader for the 2D pipeline looks like this:
uniform mat4 modelview;
uniform mat4 projection;
attribute vec2 texcoord;
attribute vec4 vertex;
varying vec2 texco;
void main()
{
texco = texcoord;
gl_Position = (projection * modelview) * vertex;
}