dsfml.graphics.shader

Shaders are programs written using a specific language, executed directly by the graphics card and allowing one to apply real-time operations to the rendered entities.

There are three kinds of shaders:

  • Vertex shaders, that process vertices
  • Geometry shaders, that process primitives
  • Fragment (pixel) shaders, that process pixels

$(PARA A $(U Shader) can be composed of either a vertex shader alone, a geometry shader alone, a fragment shader alone, or any combination of them. (see the variants of the load functions). Shaders are written in GLSL, which is a C-like language dedicated to OpenGL shaders. You'll probably need to learn its basics before writing your own shaders for DSFML. Like any D/C/C++ program, a GLSL shader has its own variables called uniforms that you can set from your D application. $(U Shader) handles different types of uniforms:)

  • scalars: float, int, bool
  • vectors (2, 3 or 4 components)
  • matrices (3x3 or 4x4)
  • samplers (textures)

$(PARA Some DSFML-specific types can be converted:)

  • $(COLOR_LINK) as a 4D vector (vec4)
  • $(TRANSFORM_LINK) as matrices (mat3 or mat4)

$(PARA Every uniform variable in a shader can be set through one of the `setUniform()` or `setUniformArray()` overloads. For example, if you have a shader with the following uniforms:)

1 uniform float offset;
2 uniform vec3 point;
3 uniform vec4 color;
4 uniform mat4 matrix;
5 uniform sampler2D overlay;
6 uniform sampler2D current;

$(PARA You can set their values from D code as follows, using the types defined in the `dsfml.graphics.glsl` module:)

1 shader.setUniform("offset", 2.f);
2 shader.setUniform("point", Vector3f(0.5f, 0.8f, 0.3f));
3 shader.setUniform("color", Vec4(color));
4 shader.setUniform("matrix", Mat4(transform));
5 shader.setUniform("overlay", texture);
6 shader.setUniform("current", Shader.CurrentTexture);

$(PARA The old `setParameter()` overloads are deprecated and will be removed in a future version. You should use their `setUniform()` equivalents instead. It is also worth noting that DSFML supports index overloads for setting uniforms:)

1 shader["offset"] = 2.f;
2 shader["point"] = Vector3f(0.5f, 0.8f, 0.3f);
3 shader["color"] = Vec4(color);
4 shader["matrix"] = Mat4(transform);
5 shader["overlay"] = texture;
6 shader["current"] = Shader.CurrentTexture;

$(PARA The special `Shader.CurrentTexture` argument maps the given `sampler2D` uniform to the current texture of the object being drawn (which cannot be known in advance). To apply a shader to a drawable, you must pass it as part of an additional parameter to the `Window.draw()` function:)

RenderStates states;
states.shader = shader;
window.draw(sprite, states);

$(PARA In the code above we pass a reference to the shader, because it may be null (which means "no shader"). Shaders can be used on any drawable, but some combinations are not interesting. For example, using a vertex shader on a $(SPRITE_LINK) is limited because there are only 4 vertices, the sprite would have to be subdivided in order to apply wave effects. Another bad example is a fragment shader with $(TEXT_LINK): the texture of the text is not the actual text that you see on screen, it is a big texture containing all the characters of the font in an arbitrary order; thus, texture lookups on pixels other than the current one may not give you the expected result. Shaders can also be used to apply global post-effects to the current contents of the target. This can be done in two different ways:)

  • draw everything to a $(RENDERTEXTURE_LINK), then draw it to the main target using the shader
  • draw everything directly to the main target, then use Texture.update to copy its contents to a texture and draw it to the main target using the shader

$(PARA The first technique is more optimized because it doesn't involve retrieving the target's pixels to system memory, but the second one doesn't impact the rendering process and can be easily inserted anywhere without impacting all the code. Like $(TEXTURE_LINK) that can be used as a raw OpenGL texture, $(U Shader) can also be used directly as a raw shader for custom OpenGL geometry.)

Shader.bind(shader);
... render OpenGL geometry ...
Shader.bind(null);

Members

Classes

Shader
class Shader

Shader class (vertex and fragment).

See Also

$(GLSL_LINK)

Meta