Jump to content

Shaders

Leadwerks Engine provides support for vertex and fragment (pixel) shaders. Shaders can be used to render a material or for full-screen post-processing effects.

Includes


Leadwerks Engine will pre-parse shader files. One feature the parse adds is the ability to include other files. This is performed with the keyword Include:
Include "MyShaderCode.frag"
It does not matter what the file extension is called, but the .vert and .frag extensions are usually used for vertex and fragment shader, respectively.
This feature allows the programmer to work with a much smaller set of shader source code files. For example, the lighting routines are written in separate .glsl files, and both the mesh and terrain fragment shaders use the same code. The file path specified may use the abstract file system too (e.g. load "abstract::MyShaderCode.frag").
Leadwerks Engine allows the programmer to pass values to the shader during program execution. This allows dynamic values to be used in rendering, or real-time changes of colors or other settings.

Defines


Includes can be combined with defines. The shader pre-processor uses define statements to dismiss or keep sections of code before the shader is compiled. A Define statement tells the pre-compiler to "keep this chunk of code".
This fragment shader will draw a black fragment:
void main () {
 	gl_FragColor=vec4(0.0,0.0,0.0,1.0);
 	#ifdef LW_FOO
 	gl_FragColor=vec4(0.0,0.0,1.0,1.0);
 	#endif
 }
This fragment shader will draw a blue fragment:
 #define LW_FOO
 void main () {
 	gl_FragColor=vec4(0.0,0.0,0.0,1.0);
 	#ifdef LW_FOO
 	gl_FragColor=vec4(0.0,0.0,1.0,1.0);
 	#endif
}
We can use an include and a define to create new shaders from a base shader:
 #define LW_FOO
 Include "foo.frag"
}
Foo.frag:
void main () {
 	gl_FragColor=vec4(0.0,0.0,0.0,1.0);
 	#ifdef LW_FOO
 	gl_FragColor=vec4(0.0,0.0,1.0,1.0);
 	#endif
}
The engine will load this shader and send the following source code to the GPU pre-processor:
#define LW_FOO
 void main () {
 	gl_FragColor=vec4(0.0,0.0,0.0,1.0);
 	#ifdef LW_FOO
 	gl_FragColor=vec4(0.0,0.0,1.0,1.0);
 	#endif
}
The GLSL pre-processor will parse the GLSL define statements and the final code that gets compiled will look like this:
void main () {
 	gl_FragColor=vec4(0.0,0.0,0.0,1.0);
 	gl_FragColor=vec4(0.0,0.0,1.0,1.0);
}
By using defines, we can greatly reduce the number of shader code files we have to edit, and eliminate redundant code. For example, all variations of the mesh shaders are packed into the main mesh.vert and mesh.frag files. Different features can be enabled by using a shader that declares define statements and then includes the main mesh shader files.

Compiling


A shader does not get compiled until it is used with the SetShader command (This might be done manually for post processing effects on images, or internally when objects get drawn). If a shader fails to compile, an error message will be added to the log containing information from the compile process. Unless there is a problem with the shader or the driver, shaders should always compile successfully. If a shader fails to compile, it is best to display a critical error immediately, rather than leave the programmer guessing which shaders might not be working correctly.

Post-processing Effects


Shaders can be used to render post-processing effects like bloom and depth of field. This is accomplished by render the scene to a texture-based buffer and then drawing the color texture onscreen with a shader applied.
Some shader post-processing effects include:

Non-Shader Based Post Processing Effects:

Built-in Uniforms



The following values will always be passed to a shader if they are declared as uniforms in the shader source code:
float apptime
Application time.

float terrainsize
The total terrain size in units (width = height).

vec3 terrainscale
The terrain scale.
This can be used to get the terrain resolution (128,256,512,1024, etc.): terrainsize/terrainscale.X = Terrain Resolution.

vec4 ambientlight
The ambient light color of the current world (while rendering).

float rnd
A random value between 0 and 1.

float bumpscale, float gloss, float specular
Bumpscale, gloss and specular. These are set based on the current material's "bumpscale", "gloss" and "specular" keys and are used (in the default shaders) to change the intensity of these effects. See also Materials.

vec2 buffersize
Width and height of the current buffer.

float bufferaspect
The current buffer's width divided by height.

float camerazoom
The zoom of the current camera.

vec2 camerarange
The near and far range of the current camera.

vec3 cameraposition
The global position of the current camera.

mat3 cameramat3
The 3x3 matrix of the current camera.

mat4 cameramat4
The 4x4 matrix of the current camera.

mat3 camerainversemat3
The inverse 3x3 matrix of the current camera.

mat4 camerainversemat4
The inverse 4x4 matrix of the current camera.

Commands

FreeShader
LoadShader
SetShader
SetShader...
  • You cannot add records