SFML community forums

Help => General => Topic started by: StriderPulse599 on November 07, 2023, 08:55:28 pm

Title: How to implement lightning?
Post by: StriderPulse599 on November 07, 2023, 08:55:28 pm
All topics seems to be heavily outdated and I can't wrap my head around shaders.

My rendering pipeline uses single VertexArray (triangle primitives). Is there a way to blend specific elements of the array, or another method to create a lightning map? I know sf::BlendMode exists but no idea how to use it
Title: Re: How to implement lightning?
Post by: eXpl0it3r on November 08, 2023, 12:11:26 am
Just because something a few years old doesn't necessarily mean that it's outdated. SFML 2.0 came out 10 years ago and what worked back then, will also work today. ;)

What have you tried already?

Have you taken a look at Candle? https://github.com/MiguelMJ/Candle
Title: Re: How to implement lightning?
Post by: StriderPulse599 on November 08, 2023, 02:06:25 pm
Just because something a few years old doesn't necessarily mean that it's outdated. SFML 2.0 came out 10 years ago and what worked back then, will also work today. ;)

What have you tried already?

Have you taken a look at Candle? https://github.com/MiguelMJ/Candle

Building light map from primitives worked great on small scale, but the only problem is drawing darkness to fill everything around. I tried to dig up any manuals/snippets on how to use sf::BlendMode with VertexArray primitives, or other methods that would allow me to simply add transparency to certain points of texture, but can't find anything.

I know about Candle, but I want to pull this off myself since I'm only one problem away from solution
Title: Re: How to implement lightning?
Post by: Hapax on November 08, 2023, 05:02:17 pm
Building light map from primitives worked great on small scale, but the only problem is drawing darkness to fill everything around.

You could use a "post-processing"-style setup and draw to an intermediate step and then draw all the light stuff together at once.
This would be something like:
Title: Re: How to implement lightning?
Post by: StriderPulse599 on November 09, 2023, 06:45:01 pm
Building light map from primitives worked great on small scale, but the only problem is drawing darkness to fill everything around.

You could use a "post-processing"-style setup and draw to an intermediate step and then draw all the light stuff together at once.
This would be something like:
  • create a render texture that covers the entire part you want to draw (likely just the entire window but this can be modified e.g. if you're using double-pixels, you could use a half-size rendertexture)
  • fill it with black (that's all the dark parts sorted right away!)
  • draw your lights to the render texture (can be coloured but white is normal light; can also have transparency and likely should to allow overlapping lights), adding them together (blendmode: add)
  • draw the render texture to the window with some sort of filter (blendmode: multiply is the simplest but a shader may do a better job if you use coloured lights)

Worked like a charm, code is bellow so others can use it. Colors seems to be fine too, but I'll need to create something like campfire to test it for sure. Do you have snippet/manual for that shader so I can compare the results?

int main()
{
    sf::Vector2f resolution = { 500, 500 };

    sf::RenderWindow window(sf::VideoMode(resolution.x, resolution.y), "LightExample", sf::Style::Close);

    sf::RenderTexture texture;
    texture.create(resolution.x, resolution.y);

    sf::CircleShape light(80.f, 8);
    light.setFillColor(sf::Color(250, 250, 250, 250));
    light.setPosition(250, 250);


    while (window.isOpen())
    {
        sf::Event event;
        while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
            {
                window.close();
                return 0;
            }
        }

        texture.clear(sf::Color( 0, 0, 0, 250));
        texture.draw(triangle, sf::BlendAdd);
        sf::Sprite renderTextureSprite(texture.getTexture());
       
        window.clear();

        window.draw(renderTextureSprite, sf::RenderStates(sf::BlendMultiply));

        window.display();
    }
}
 
Title: Re: How to implement lightning?
Post by: Hapax on November 09, 2023, 09:57:28 pm
Excellent news. Glad it worked!

Actually, for lighting, multiplying should do the job decently. I was thinking about some other colour mixing issues.

Anyway, there is a shader you may be interested in. It's a radial gradient shader and could be useful for lighting purposes:
https://github.com/SFML/SFML/wiki/Source%3A-Radial-Gradient-Shader