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.

Usage

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,
    Shaders::Phong::Position{},
    Shaders::Phong::Normal{},
    Shaders::Phong::TextureCoordinates{})
     //...
     ;

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. Example configuration and rendering using Shaders::Phong:

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

Shaders::Phong shader{Shaders::Phong::Flag::DiffuseTexture};
shader.bindDiffuseTexture(diffuseTexture)
    .setLightPosition({5.0f, 5.0f, 7.0f})
    .setTransformationMatrix(transformationMatrix)
    .setNormalMatrix(transformationMatrix.rotation())
    .setProjectionMatrix(projectionMatrix);

mesh.draw(shader);

Generic vertex attributes

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

mesh.addVertexBuffer(vertices, 0,
    Shaders::Generic3D::Position{},
    Shaders::Generic3D::Normal{},
    Shaders::Generic3D::TextureCoordinates{});

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::MeshVisualizer visualizerShader{Shaders::MeshVisualizer::Flag::Wireframe};
visualizerShader
    .setColor(0x2f83cc_rgbf)
    .setWireframeColor(0xdcdcdc_rgbf)
    .setViewportSize(Vector2{GL::defaultFramebuffer.viewport().size()})
    .setTransformationProjectionMatrix(projectionMatrix*transformationMatrix);

mesh.draw(visualizerShader);

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