Candle v1.0
2D lighting for SFML
Darkness and ambient light

Fog and darkness

Light sources alone can become somewhat noisy in the scene. They make much more sense when they exist within an area of darkness, which they illuminate. For this, Candle provides the class candle::LightingArea, that operates in two modes: FOG and AMBIENT. We will focus on the first one right now.

A lighting area in FOG mode behaves as a mask, and when objects candle::LightSource are drawn to it, they make transparent the illuminated polygon, taking into account its intensity and the fade flag. You can think of this class as a wrapper to a sf::RenderTexture, as you have to use clear, draw and display functions. Let's see a minimalistic example:

#include <SFML/Graphics.hpp>
int main(){
// create window
sf::RenderWindow w(sf::VideoMode(300, 379), "app");
// create a light source
light.setRange(100);
light.setFade(false);
// load the image
sf::Texture img1;
if(!img1.loadFromFile("sunflowers_van_gogh.png")){
exit(1);
}
sf::Sprite background(img1);
// create the lighting area
sf::Vector2f(0.f, 0.f),
sf::Vector2f(300.f, 379.f));
fog.setAreaColor(sf::Color::Black);
// main loop
while(w.isOpen()){
sf::Event e;
while(w.pollEvent(e)){
if(e.type == sf::Event::Closed){
w.close();
}else if(e.type == sf::Event::MouseMoved){
sf::Vector2f mp(sf::Mouse::getPosition(w));
light.setPosition(mp);
}
}
fog.clear();
fog.draw(light);
fog.display();
w.clear();
w.draw(background);
w.draw(fog);
w.display();
}
return 0;
}
This file contains the LightingArea class.
This file contains the RadialLight class.
void setRange(float range)
Set the range of the illuminated area.
virtual void setFade(bool fade)
Set the value of the fade flag.
Object to manage ambient light and fog.
Definition: LightingArea.hpp:62
@ FOG
Definition: LightingArea.hpp:73
LightSource that emits light from a single point.
Definition: RadialLight.hpp:32
void draw(sf::RenderTarget &t, sf::RenderStates st) const override
Draw the object to a target.

This time the fade flag is set to false to make the contrast stronger. The previous code results in an image hidden by a layer of darkness, revealed under the light of the cursor.

Example preview
Preview

Also, note that the light is not drawn to the window. If we did that, then the light itself could cover the image below. This doesn't mean that there aren't cases when you will want to draw the light both to the lighting area and the window, but you would have to experiment and adjust the range and intensity parameters, to obtain the desired effect.

Texturing fog

In the last example we've used plain color to define the fog. However, it is possible to use a texture, instead. In the previous example, we would have to change the piece of code to create the lighting area by the following:

// create the lighting area
sf::Texture img2;
if(!img2.loadFromFile("starry_night_van_gogh.png")){
exit(1);
}
&img2);
fog.setScale((float)w.getSize().x / img2.getSize().x,
(float)w.getSize().y / img2.getSize().y);

and we would have this result:

Example preview
Preview

This example also allows us to illustrate how to manage size. An object candle::LightingArea uses a sf::RenderTexture internally, and to avoid destroying and creating a potentially heavy resource repeteadly, it is created only upon construction or when using candle::LightingArea::setAreaTexture. So, if we want to change the size of the area (in this case we want to adjust it to the size of the window), the only way is to scale it.

Revealing permanently (fog of war effect)

For now we have been calling candle::LightingArea::clear before any draw call. If we don't do this, then the darkness layer isn't restored. This way, we can have the effect of permanently revealing what is under it.

Ambient light

The second operation mode of candle::LightingArea is AMBIENT. Its behaviour is rather simple, as it acts as a mere additive layer. Be it a plain color or a texture, they are overlayed to the layer below. Drawing lights to it has no effect, but as light sources are also drawn in an additive manner, then lights within the area will appear to have more intensity.


No LightingArea

FOG mode (Color black, medium opacity)

AMBIENT mode (Color yellow, low opacity)