Feature guide » Builtin shaders

Overview and basic usage of builtin shaders.

Magnum contains a set of general-purpose shaders for easy prototyping, UI rendering and data visualization/debugging in both 2D and 3D scenes. The following shaders are available, see documentation of each class for sample output and example setup:

All the builtin shaders can be used on unextended OpenGL 2.1 and OpenGL ES 2.0 / WebGL 1.0, but they try to use the most recent technology available to have them as efficient as possible on every configuration.


Shader usage is divided into two parts: configuring vertex attributes in the mesh and configuring the shader itself.

Each shader expects some set of vertex attributes, thus when adding vertex buffer into the mesh, you need to specify which shader attributes are on which position in the buffer. See GL::Mesh::addVertexBuffer() for details and usage examples. Example mesh configuration for Shaders::Phong shader:

struct Vertex {
    Vector3 position;
    Vector3 normal;
    Vector2 textureCoordinates;
Vertex data[60]{
    // ...

GL::Buffer vertices;
vertices.setData(data, GL::BufferUsage::StaticDraw);

GL::Mesh mesh;
mesh.addVertexBuffer(vertices, 0,

Each shader then has its own set of configuration functions. Some configuration is static, specified commonly as flags in constructor, directly affecting compiled shader code. Other configuration is specified through uniforms and various binding points, commonly exposed through various setters. All shader uniforms have a reasonable defaults so you are able to see at least something when using the shader directly without any further configuration, but in most cases you may want to specify at least the transformation/projection matrices. Example configuration and rendering using Shaders::Phong:

Matrix4 transformationMatrix, projectionMatrix;
GL::Texture2D diffuseTexture, specularTexture;

Shaders::Phong shader{Shaders::Phong::Flag::DiffuseTexture};

Generic vertex attributes and framebuffer attachments

Many shaders share the same vertex attribute definitions, such as positions, normals, texture coordinates etc. It's thus possible to configure the mesh for a generic shader and then render it with any compatible shader. Definition of all generic attributes is available in the Shaders::Generic class. Configuration of the above mesh using generic attributes could then look like this:

mesh.addVertexBuffer(vertices, 0,

Note that in this particular case both configurations are equivalent, because Shaders::Phong also uses generic vertex attribute definitions. Then you can render the mesh using Shaders::Phong shader like above, or use for example Shaders::Flat3D or even Shaders::MeshVisualizer with the same mesh reconfiguration. The unused attributes will be simply ignored.

Shaders::MeshVisualizer3D visualizerShader{Shaders::MeshVisualizer3D::Flag::Wireframe};

The MeshTools::compile() utility configures meshes using generic vertex attribute definitions to make them usable with any shader.

Besides vertex attributes, the Shaders::Generic contains generic definitions for framebuffer outputs as well — in many cases a shader has just one (color) output, but some shaders such as Shaders::Flat or Shaders::Phong offer an object ID output as well. A setup equivalent to what's done in Flat shader's Object ID output but using the generic definitions would look like this:

    {Shaders::Generic3D::ColorOutput, GL::Framebuffer::ColorAttachment{0}},
    {Shaders::Generic3D::ObjectIdOutput, GL::Framebuffer::ColorAttachment{1}}});