Basic Fragment Shader with SFML

Today I had the idea to try and generate some “art” using semi-random vertices, shapes and colors, but to achieve that I knew, I had to finally learn a bit more about shaders, to get nice glow or similar effects. As I started reading through The Book of Shaders I created in parallel an example application in SFML with which I can follow along. That’s what I’m putting out here in addition to having made a pull request so it could be added to the book repository itself.

The Structure

If you want to use the presented code as is, you’ll need the following structure:

│ └─shader.frag

CMake the Builder

As with most of my projects these days, CMake doesn’t let you down in setting up a basic application and it integrates so well with Visual Studio and all sorts of other IDEs.

cmake_minimum_required(VERSION 3.15)

project(TheBookOfShaders LANGUAGES CXX)


find_package(SFML 2.5 COMPONENTS graphics REQUIRED)


target_link_libraries(TheBookOfShaders sfml-graphics)

install(TARGETS TheBookOfShaders
install(DIRECTORY data

The Source

Since we can’t apply the shader directly to the screen/window, we use a sf::RectangleShape with the same dimensions as the window. The code is also written in my (currently) preferred way of almost-always auto and uniform initialization.

#include <SFML/Graphics.hpp>

#include <iostream>

int main()
    auto window = sf::RenderWindow{ { 800U, 800U }, "The Book of Shaders" };

    auto clock = sf::Clock{};

    auto shape = sf::RectangleShape{ sf::Vector2f{ window.getSize() } };

    auto shader = sf::Shader{};
    if (!shader.loadFromFile("data/shader.frag", sf::Shader::Fragment))
        std::cerr << "Couldn't load fragment shader\n";
        return -1;

    auto mouse_position = sf::Vector2f{};

    while (window.isOpen())
        for (auto event = sf::Event{}; window.pollEvent(event);)
            if (event.type == sf::Event::Closed)
            else if (event.type == sf::Event::MouseMoved)
                mouse_position = window.mapPixelToCoords({ event.mouseMove.x, event.mouseMove.y });

        shader.setUniform("u_resolution", sf::Glsl::Vec2{ window.getSize() });
        shader.setUniform("u_mouse", sf::Glsl::Vec2{ mouse_position });
        shader.setUniform("u_time", clock.getElapsedTime().asSeconds());

        window.draw(shape, &shader);

The Magic

This is directly copied from the book and while u_mouse and u_time aren’t used in this example, they are used in other examples and/or allow you to do some fun modifications of your own.

#ifdef GL_ES
precision mediump float;

uniform vec2 u_resolution;
uniform vec3 u_mouse;
uniform float u_time;

void main() {
	vec2 st =;
	gl_FragColor = vec4(st.x,st.y,0.0,1.0);

The Result

If everything works out, you should end up with a window like this:

Hope this can be useful for someone else as well! 🙂

Leave a Comment

Your email address will not be published. Required fields are marked *


This site uses Akismet to reduce spam. Learn how your comment data is processed.