Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

26.07.2013, 15:58

SFML 2.0 Licht (und Schatten) mit FragmentShader

Hallo Leute,
ich versuche mich gerade daran ein kleines LichtSystem in SFML zu bauen.
Ich beschreib hier mal wie ich mir das gedacht habe:
1. Alle Objekte (Sprites etc.) auf eine RenderTexture zeichnen. (1)
(2. Daraus eine Textur erzeugen, bei der alle Objekte schwarz sind und freie Flächen weiß, um zu wissen was Schatten wirft. Erstmal soll alles die gleiche Höhe haben und Schatten werfen.) Geklammert weil ich erstmal nur Licht will.
3. Die Lichter nacheinander durchgehen und auf einer schwarzen Textur, die richtigen Stellen/Pixel transparent machen. (2)
4. Die farbige Textur(1) aufs Fenster zeichnen, dann die LichtTextur(2) drüberzeichnen.

Also ich denke so müsste das prinzipiell funktionieren. Ich habe auch schon eine PointLight-Klasse kreiirt. Hier die render-Funktion davon:

C-/C++-Quelltext

1
2
3
4
5
6
7
void PointLight::render(const sf::Texture& diffuse, sf::RenderTexture& texture)
{
    lightShader.setParameter("position", position);
    lightShader.setParameter("range", range);
    lightShader.setParameter("color", color);
    texture.draw(sf::Sprite(), &lightShader);
}

Und so wird die Funktion aufgerufen:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
void Game::render()
{
    sf::RenderTexture diffuse;
    diffuse.clear(sf::Color::White);
    diffuse.draw(rect);
    sf::RenderTexture lights;
    light->render(diffuse.getTexture(), lights);
    window.draw(sf::Sprite(diffuse.getTexture()));
    window.draw(sf::Sprite(lights.getTexture()));
}

Und zum Schluss noch mein vorläufiger LightShader:

HLSL-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
uniform vec2 position;
uniform float range;
uniform vec4 color;
uniform sampler2D texture;

void main()
{
     vec4 pixel = texture2D(texture, gl_TexCoord[0].xy);
     float difference = distance(vec2(gl_FragCoord), position);
     if(difference<range)
     {
        gl_FragColor = vec4(color.xyz, difference/range);
     }
     else
     {
        gl_FragColor = vec4(0,0,0,1);
     }
}

Bisjetzt kommt nur ein komplett weißes Fenster(der Fensterhintergrund).
Könnt ihr mir sagen ob meine Idee schonmal soweit richtig ist, oder wie man das richtigerweise umsetzt? :)

Vielen Dank schonmal :)