AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Licht-Masken

Ein Thema von Valle · begonnen am 3. Sep 2010 · letzter Beitrag vom 3. Sep 2010
Antwort Antwort
Benutzerbild von Valle
Valle

Registriert seit: 26. Dez 2005
Ort: Karlsruhe
1.223 Beiträge
 
#1

Licht-Masken

  Alt 3. Sep 2010, 21:27
Hi DPler,

ich bin seit ein paar Tagen dabei, eine kleine 2d-Simulation zu erstellen. Was ich dabei schon immer toll fand, war Licht. Nach einigem googlen und experimentieren habe ich es sogar geschafft, eine Maske zu erstellen, die eine Art Licht auf der Oberfläche erzeugt. Farbige Bereiche auf der Maske machen die darunterliegende Szene durchsichtig, durchsichtige Bereiche der Maske überblenden die Szene mit Schwarz.

Der Effekt sieht schon sehr interessant und nicht schlecht aus - aber das reicht mir noch nicht. Was ich noch gerne hätte, wäre farbiges Licht. Leider ist es mit meiner aktuellen Methode völlig egal, welche Farbe ich benutze, was zählt ist immer nur die Transparenz. Im Anhang ist eine Maske, die eigentlich rotes Licht erzeugen sollte (oder rotes Licht filtern... Mir fehlt da leider grundsätzlich die Theorie was Farbmischung mit dem PC angeht ). Alles was diese Maske aber tut, ist einen Gegenstand der sich aus dessen Mitte hinausbewegt langsam auszublenden.

Meine Frage ist jetzt, wie ich sowas in der Theorie am besten anstelle. Meine Grafikbibliothek unterstützt von sich aus keine Lichteffekte. Da ich mit Python arbeite, sind Codebeispiele wahrscheinlich auch nicht hilfreich. Ich würde mich freuen, wenn ihr mir erklären könnt, wie man mit farbigem Licht umgeht oder eventuell auch gute Quellen kennt.

Liebe Grüße,
Valle
Miniaturansicht angehängter Grafiken
light.png  
Valentin Voigt
BOFH excuse #423: „It's not RFC-822 compliant.“
Mein total langweiliger Blog
  Mit Zitat antworten Zitat
Benutzerbild von igel457
igel457

Registriert seit: 31. Aug 2005
1.622 Beiträge
 
FreePascal / Lazarus
 
#2

AW: Licht-Masken

  Alt 3. Sep 2010, 21:38
Licht musst du immer additiv zeichnen, spricht die Pixelwerte der Lichter müssen einfach addiert werden:
Code:
Rot_Neu = Rot_Licht + Rot_Alt;
Blau_Neu = Blau_Licht + Blau_Alt;
Grün_Neu = Grün_Licht + Grün_Alt;
Dies ist ja auch logisch - stell dir mal zwei Taschenlampen vor, die sich gegenseitig überschneiden - in der Mitte wird es entsprechen heller, da sich die Lichtintensität aufaddiert hat.

Problem bei der "Simulation" ist jedoch, dass deine Szene ohne Licht komplett schwarz ist - und wenn du auf komplett schwarz die Lichtwerte aufaddierst, wird sie dadurch nicht sichtbar. Deshalb musst du die Pixelwerte der Lichter mit denen der Szene multiplikativ verrechnen. Sprich:
Code:
Rot_Ziel = Rot_Lichter * Rot_Szene;
Blau_Ziel = Blau_Lichter * Blau_Szene;
Grün_Ziel = Grün_Lichter * Grün_Szene;
Das ist auch logisch - stell dir vor, kein Licht ist an, also RGB(0, 0, 0), so ist auch kein Pixel der Szene sichtbar. Ist rotes Licht an, so sind auch nur die roten Pixel sichtbar.

Also ist die Vorgehensweise:
  1. Zeichne alle Lichter additiv getrennt in einen zunächst schwarzen Off-Screen buffer
  2. Zeichne deine Szene ganz normal und zeichne den Lichter-Off-Screen-Buffer multiplikativ auf deine Szene oben drauf und schon bist du fertig

PS: Die Lichter sollten keine transparenz haben sein, sondern einfach nach schwarz überblenden, durch das additive Zeichnen bedeutet schwarz ja einfach "keine Änderung"
PPS: Hier gab es letztens einen Thread wo jemand das Ganze mit Andorra 2D umgesetzt hat, also schau mal danach
Andreas
"Sollen sich auch alle schämen, die gedankenlos sich der Wunder der Wissenschaft und Technik bedienen, und nicht mehr davon geistig erfasst haben als die Kuh von der Botanik der Pflanzen, die sie mit Wohlbehagen frisst." - Albert Einstein

Geändert von igel457 ( 3. Sep 2010 um 21:41 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.153 Beiträge
 
Delphi 12 Athens
 
#3

AW: Licht-Masken

  Alt 3. Sep 2010, 21:44
Zitat:
Delphi-Quellcode:
Rot_Ziel = Rot_Lichter * Rot_Szene;
Blau_Ziel = Blau_Lichter * Blau_Szene;
Grün_Ziel = Grün_Lichter * Grün_Szene;
Ich hätte es eher so erwartet:
Delphi-Quellcode:
Rot_Ziel = Min(Rot_Lichter, Rot_Szene);
Blau_Ziel = Min(Blau_Lichter, Blau_Szene);
Grün_Ziel = Min(Grün_Lichter, Grün_Szene);
[edit]
obwohl ... hast irgendwie Recht, also so?
Delphi-Quellcode:
Rot_Ziel = Rot_Szene * (Rot_Lichter / 255{Rot_Lichter_Max});
Blau_Ziel = Blau_Lichter * (Blau_Szene / 255{Blau_Lichter_Max});
Grün_Ziel = Grün_Lichter * (Grün_Szene / 255{Grün_Lichter_Max});
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu ( 3. Sep 2010 um 21:48 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von igel457
igel457

Registriert seit: 31. Aug 2005
1.622 Beiträge
 
FreePascal / Lazarus
 
#4

AW: Licht-Masken

  Alt 3. Sep 2010, 21:57
Oh, das habe ich vergessen zu sagen, ich gehe hier wirklich davon aus, dass sich alle Farbwerte im Intervall [0,1] befinden, sonst sind die Berechnungen natürlich falsch.
Andreas
"Sollen sich auch alle schämen, die gedankenlos sich der Wunder der Wissenschaft und Technik bedienen, und nicht mehr davon geistig erfasst haben als die Kuh von der Botanik der Pflanzen, die sie mit Wohlbehagen frisst." - Albert Einstein
  Mit Zitat antworten Zitat
Benutzerbild von Valle
Valle

Registriert seit: 26. Dez 2005
Ort: Karlsruhe
1.223 Beiträge
 
#5

AW: Licht-Masken

  Alt 3. Sep 2010, 22:06
Hallo,

vielen Dank für deine tolle Erklärung!

Im Moment habe ich noch Probleme mit der Transparenz, welche jetzt nicht mehr will. Farblich funktioniert es dafür um so besser. Hoffentlich komme ich noch drauf, was hier schief läuft. Du kannst ja mal schnell schauen, ob dir direkt was in's Auge springt, wenn du Lust hast. Vielleicht ist es ja ein grober Fehler.

Code:
def mainloop(self):
    # ...
    self.screen.fill((0, 0, 0))
   self.draw() # draw the szene
   self.draw_lights() # draw lights on offscreen buffer (self.lights)
   self.screen.blit(self.lights, (0, 0), None, BLEND_RGBA_MULT)
   # ...

def draw_lights(self):
   self.lights.fill((0, 0, 0, 0))
   self.lights.blit(self.images['mask'], (0, 0), None, BLEND_RGBA_ADD)
Edit:// Gerade dein PPS gesehen. Jetzt funktioniert's. Vielen Dank nochmal!

Liebe Grüße,
Valle
Valentin Voigt
BOFH excuse #423: „It's not RFC-822 compliant.“
Mein total langweiliger Blog

Geändert von Valle ( 3. Sep 2010 um 22:18 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:53 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz