Blend modes (mal wieder)

  • GM 8

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Blend modes (mal wieder)

    Alsooo.. ich habe wiedermal ein Problem mit Blend modes. Leider bin ich mit denen noch nicht so ganz Vertraut, daher könte es ab und zu dazu kommen dass ich die dämlichsten Fragen dazu stelle. XD
    Also. Viele kennen ja die normalen "blend-masken" die ein Bild beinhalten wo ein Weißer anteil ins Schwarze übergeht.
    z.B: der da:


    Nun, wenn man solch einen Effekt färben möchte, nutzt man eigentlich "bm_add" dazu um einen Farbwert zu dem Weißanteil dazuaddieren.
    Funktioniert alles Prima.

    Das Problem was ich habe ist jedoch dies, dass ich Dunkle Farben (also z.B: Dunkelblau) auf diesen Blendmode anwenden möchte.
    Das Probem hierbei ist aber, das dunkle Farben bei bm_add nicht dunkel erscheinen. Ich nehme mal an, dass der Schwarzanteil die Farbe einfach "verblassen" lässt statt die Dunkelheit bie der Farbgebung zu bewahren.
    Der Übergang zwischen Weiß zu Schwarz soll eigentlich die Transparenz der Farbe darstellen. Die Färbung soll gleich bleiben.


    Hat jemand ne Ahnung wie man das bewrkställigen könnte? Bm_substract subtrahiert ja Farbwerte. Dies fällt weg, da ich den Blend Mode zwischen hellen und dunklen Farben hin und herschalte.
    Sowas simples wie das Färben solch einer "Map" mit einer Farbe (egal welchen Wertes) sollte doch möglich sein.
  • Ich denke ein multiplizierender Blend Mode könnte das sein, was du suchst. Im GM sieht der so aus:

    GML-Quellcode

    1. draw_set_blend_mode_ext(bm_dest_color,bm_zero);

    Auf diese Weise wird dein Bild auf keinen Fall heller. Wenn du es mit weiß blendest bleibt es wie es ist (x*1 = x).
  • Entweder mach ich was falsch, oder das hat genau garkeine Wirkung beim Gm.
    Habe hier mal ein example hochgeladen wie das jetzt aktuell ausschaut...

    Dabei will ich doch nur das der Schwarzanteil im Bild die transparenz darstellt und der Weißanteil einfach mit der jeweiligen Farbe "überzogen" wird.
    Ich blick da bei den Blendmodes nicht durch. XD

    /edit: Könnte ein dass das example an sich schon garnicht funktionieren kann? Hab das schnell mal erstellt um das Prinzip zu zeigen...
    Dateien
    • dunkler bm.zip

      (71,31 kB, 146 mal heruntergeladen, zuletzt: )

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von LEWA ()

  • Ich hatte mir das eher so vorgestellt:

    GML-Quellcode

    1. draw_background(bg,0,0);
    2. draw_set_blend_mode_ext(bm_dest_color,bm_zero);
    3. draw_set_color(make_color_rgb(0,66,209));//dunkelbau
    4. draw_rectangle(0,0,256,256,false);
    5. draw_set_blend_mode(bm_normal);

    Also erst alles normal zeichnen und am Ende mit der gewünschten Farbe multiplizieren.
  • Okeyy... das funktioniert schonmal ganz gut.
    Jedoch noch eine einzige Frage (die ich eigentlich bei meiner Selbsteinschätzung über GML nicht fragen sollte...)

    Wie soll ich hier jetzt die Transparenz implementieren? Die Schwarze Farbe sollte eigentlich transparent sein. (Also je dünkler der jeweilige Pixel des Background Sprites, desto durchsichtiger wird am ende das Pixel.)
    Oder wäre die einfachste und simpelste Lösung einfach einen Blend Mode mit alphachannel zu benutzen?

    /Edit: Genauer gesagt kann ich mit Alphachanneln BEI Blendmodes auch nicht wirklich umgehen. Ich habe keinen Plan wie man dies hinbekommen könnte...

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von LEWA ()

  • Du möchtest alles schwarz haben, nur den lichtkegel sehen?

    Create-Event:

    GML-Quellcode

    1. surf_id = surface_create(0,0,room_width,room_height)


    Draw-Event:

    GML-Quellcode

    1. surface_set_target(surf_id)
    2. draw_set_color(c_white)
    3. draw_rectangle(0,0,room_width,room_height,false)
    4. draw_set_blend_mode(bm_normal)
    5. draw_sprite(bg,0,20,20)
    6. surface_reset_target()
    7. draw_set_blend_mode(bm_subtract)
    8. draw_surface(surf_id,0,0)
    9. draw_set_blend_mode(bm_normal)
    Alles anzeigen


    Erst wird die Surface weiß angestrichen, das licht schwarz draufgemalt (dazu musst du es invertieren) und dann das ganze von der szene abgezogen. Damit bestimmt die Helligkeit des Lichts die "Transparenz"

    Ich hab mal ne zeit lang daran gearbeitet, das möglichst komfortabel zu machen, vielleicht lad ichs mal hoch


    EDIT: Funktioniert mit 8.1 nicht mehr... Vielleicht lass ich mich dazu überreden, es nochmal zu schreiben, aber eigentlich sollte es zu schaffen sein
  • Du möchtest alles schwarz haben, nur den lichtkegel sehen?


    Ich möchte nicht unbedingt alles Schwarz haben.
    Der Schwarzanteil soll transparent werden. Die Weiße Farbe soll mit einer !BELEBIGEN! Farbe gefärbt werden können (sei sie nun hell oder dunkel.)
    Im Spiel soll das sozusagen wie ein Lichtkegel ausschauen (der nach außen hin transparenter wird.)

    Stimmt dass dies mit dem GM 8.1er nicht funktioniert. Bin mir aber jetzt auch nicht 100%ig sicher wie das funktioniert. XD

    Muss mal schauen wie ich das lösen kann. (Blendmodes treiben mich zum Wahnsinn.9 Wies muss das alles nur so kompliziert sein? Ich will den Weißanteil doch nur Färben.

    Das Bild kann von mir aus auch so ausschauen: (Einfach in einem Bildbearbeitungsprogramm öffnen wo man den Transparenten Hintergrund sieht.)


    Das ergebniss sollte auf jedenfall etwa so ausschauen: (Beachtet den Transparenten Hintergrund.)


    Das Problem ist auch kein neues für mich. Ich habe immerwieder mit genau diesem Problem zu kämpfen. Nie habe ich es wirklich lösen können.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von LEWA ()

  • Du willst farbige Lichter und eine (farbige, nicht schwarze) umgebungshelligkeit?


    Kommt zjetzt darauf an ob du Lichter und umgebungshelligkeit als 2 verschiedene Sachen ansiehst. XD
    Diese "Lichtquellen" sollen nicht schwarz, sondern in allen möglichen Farben (die man mit RGB angaben darstellen kann) angezeigt werden. Mir ist es wichtig Helle als auch dunkle Farben anzeigen zu können. (dunkelgrün, dunkelblau, etc..)
    Der Hintergrund soll (wie bei den Bildern im letzten Post) transparent sein, sodass die Objekte/Sprites die dahinter sind noch sichtbar sind. (je nach Alphatransparenz natürlich.)

    Wäre super wenn du eine Lösung parat hättest. :)
  • Die hab ich, ich bin grad beim Kommentieren der gmk Datei

    Läuft doch auf 8.1, die Version die ich vorhin hatte ging mysteriöser Weise garnicht.

    Im Prinzip muss man nur beim Reinigen der surface die gewünschte farbe invertiert angeben, da sie ja dann abgezogen wird.

    Wenn du also RGB 255 127 0 haben willst, schreibst du:
    draw_clear(0,128,255)
    (meine Rechtecklösung ist umständlich, ich vergaß den Befehl draw_clear)


    Gut, ich hoffe man versteht alles.

    Vom Prinzip her: Man hat eine Schattensurface, die von der Szene abgezogen wird. Deshalb müssen die farben invertiert werden: bei absoluter Finsternis muss die Surface weiß sein,
    denn dann werden beim abziehen (RGB = 255 255 255) alle Farben getilgt.
    Wenn ich von der Surface ein graues Licht abziehe (RGB 200 200 200) ist die Surface an dieser Stelle dunkler (RGB 55 55 55) und demnach wird nicht so viel von der Szene getilgt.

    In meinem Beispiel sollte alles möglich sein, Views kannst du verwenden, wie du willst, die Surface passt sich automatisch an (nur mit drehen von Views hab ichs noch nicht probiert)


    Ich hoffe ich konnte helfen, damals saß ich da seeeeeeehhhhhhrrrrr lange dran, damit farbige lichter gehen, man sich mehrere Lichter korrekt überdecken etc.
    Dateien
    • Licht.zip

      (903,15 kB, 155 mal heruntergeladen, zuletzt: )

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von Chaos Creator ()

  • Echt nice! Scheint soweit zu funktionieren.

    Jedoch funktionieren diese Lichter nur, wenn das Umgebungslicht "dunkel" ist.
    Sprich: Lichter in einer "normal" beleuchteten Umgebung sind nicht möglich. oder übersehe ich da etwas?

    Mein Verwendungszweck sieht jedoch keine Background-verdunkelung vor. Sprich: Ich will einfach nur sprite x mit der Färbung y zeichnen.

    Sprich: Alles im Exampel passt eigentlich, nur die Backgroundverdunkelung ist nicht gewünscht.
  • Ich bin mir immer noch nicht so ganz sicher, was du genau haben willst. Ich vermute mal so ähnlich wie im Anhang. Das Problem beim multiplizierenden Blend Mode ist einfach, wenn man beispielsweise blau färben will, werden Teile, die kein bisschen blau enthalten, einfach schwarz. Bei einem s/w Bild wie im Anhang tritt sowas aber nicht auf, da jeder Pixel, der nicht schwarz ist, automatisch auch blau enthält.

    Wenn man das umgehen will und z.B. grün in blau färben will, könnte man das über die Helligkeit der Farbe machen. Dann sind aber keine Fades mehr wie im Beispiel möglich.
    Dateien
    • bm.zip

      (388,86 kB, 148 mal heruntergeladen, zuletzt: )
  • Eigentlich ist genau dass was du in deinem Anhang hast, genau was ich suche. Der Blendmode soll genau so gezeichnet werden.

    Dann sind aber keine Fades mehr wie im Beispiel möglich.

    Fades (sprich: dem Blendmode eine andere Farbe in echtzeit angeben) sollten mit deinem Beispiel doch auch möglich sein.?


    Bezüglich des Examples: Mir ist aufgefallen dass man den Blend mode nicht ganz normal in Weiß zeichnen kann. Ist das aus technischer Sicht nicht möglich?
    Ich würde gerne die ganze Pallete so zeichnen können. Von Schwarz zu weiss über Grün zu dunkelrot, usw...
  • Fades (sprich: dem Blendmode eine andere Farbe in echtzeit angeben) sollten mit deinem Beispiel doch auch möglich sein.?

    Ja, die Farbe in Echtzeit zu wechseln ist möglich. Ich meinte mit Fade auch eigentlich, dass der Kreis nach außen hin immer weniger färbt. Also dieser fließende Übergang.

    Mir ist aufgefallen dass man den Blend mode nicht ganz normal in Weiß zeichnen kann. Ist das aus technischer Sicht nicht möglich?

    Wie schon in meinem ersten Post erwähnt, bleibt es mit Weiß einfach wie es ist, da das einem Multiplizieren mit 1 entspricht. Die Frage ist ja, wie stellst du dir vor, wie es mit Weiß aussieht? Oder allgemeiner: Nach welcher Formel soll ein Pixel (R1,G1,B1) mit einer Farbe (R2,G2,B2) gefärbte werden (Kanäle jeweils zwischen 0 und 1)? In meinem Beispiel ist die resultierende Farbe eben einfach (R1*R2,G1*G2,B1*B2), was ich zum Färben durchaus für sinnvoll halte.
  • Ich meinte mit Fade auch eigentlich, dass der Kreis nach außen hin immer weniger färbt. Also dieser fließende Übergang.

    Dieser funktioniert ja auch. Sollte er etwa nicht?

    Wie schon in meinem ersten Post erwähnt, bleibt es mit Weiß einfach wie es ist, da das einem Multiplizieren mit 1 entspricht. Die Frage ist ja, wie stellst du dir vor, wie es mit Weiß aussieht? Oder allgemeiner: Nach welcher Formel soll ein Pixel (R1,G1,B1) mit einer Farbe (R2,G2,B2) gefärbte werden (Kanäle jeweils zwischen 0 und 1)? In meinem Beispiel ist die resultierende Farbe eben einfach (R1*R2,G1*G2,B1*B2), was ich zum Färben durchaus für sinnvoll halte.


    Dieser kreis mit weißer Färbung soll dann einfach "weiß geblendet" angezeigt werden. So wie bei allen anderen Farben auch, blos dass dann die Farbe eben Weiss ist.
    Ich habe es mir einfach so vorgestellt, dass der Blendmode die Pixel des "Lichtsprites" prüft. Weiße Pixel werden nun einfach mit der Farbe geblendet die man Angegeben hat. Sei es nun scharz, weiss, rot oder grün.

    Die Farbe wird einfach übernommen. JEDOCH: Je dünkler das Pixel ist (Sprich: mit dem erhöhen des Schwarzanteiles/Wertes des pixels) steigt die Transparenz, was bei dem obrigen Spriteebeispiel für einen "Fading-out-Effekt" nach außen sorgen sollte.
    Komplett schwarze Pixel sollten also nach dem anwenden des Blend modes (oder Scripts, je nachdem) auch komplett transparent sein.

    Kurzgesagt: auf alle Pixel des "schwwarzweiss Lichtkegels" wird eine Farbe übernommen. Je dünkler das Pixel aber ist, desto transparenter wird der Finale Farbpixel.
    z.B:Roter Pixel auf grauen Pixel (grau = 50% Schwarzantei)l > Ergebniss: Roter Pixel mit 50% Alphatransparenz.
  • Ok, neuer Versuch (siehe Anhang).

    Im Create-Event kann man mit der Variable light bestimmen, wie stark aufgehellt werden soll. Sie muss zwischen 0 und 1 liegen, wobei 0 überhaupt nicht aufhellt, also man bei Weiß nichts sieht. Wahlweise könnte man zur Aufhellung auch den additiven Blend Mode verwenden, damit auch schwarze Flächen aufgehellt werden. Kannst du ja probieren, ob das eher deiner Vorstellung entspricht.

    Dieser funktioniert ja auch. Sollte er etwa nicht?

    Doch, doch. Ist schon richtig so. Ich hatte ja geschrieben "Wenn man das umgehen will...", aber wenn dir das Beispiel im Anhang so in der Art passt, ist das ja irrelevant.

    Die Farbe wird einfach übernommen.

    Also wenn es so wie in meinem Beispiel sein soll, dann wird die Farbe eben nicht einfach nur übernommen, sondern sie hängt schon noch davon ab was drunter ist. Sonst würde man ja eine einfarbige Fläche in der entsprechenden Farbe erhalten, wenn man sie einfach "übernimmt". D.h. ganz so einfach ist das in der Praxis nicht. Man muss schon irgendwie zwei Farben geschickt blenden.
    Dateien
    • bm.zip

      (388,95 kB, 139 mal heruntergeladen, zuletzt: )
  • Also ich sehe 2 Möglichkeiten:

    So wie ich zuerst dachte, dass du es meinst, entspricht es am ehesten echtem Licht (nur dass die Methode mit bm_subtract zwar ähnlich aussieht, aber nicht das gleiche ist wie das eigentlich "natürliche" multiplizieren [draw_set_blend_mode_ext(bm_dest_color,bm_zero)], ändere ich noch)

    Aber wenn du keine Verdunklung der Umgebung haben willst, sieht man normales licht nicht - wenn du nur überblenden willst zeichne doch ein nach außen hin transparenter werdenden Sprite mit draw_sprite_ext, dann kannst du ganz einfach die Farbe einstellen.

    Passender Lichtkegel im Anhang (Weißes Bild, Load Alpha from File, s/w Bild auswähln, fertig)
    Sieht weiß aus, hat aber nen Alphaübergang
    Bilder
    • Lichtkegel.png

      18,61 kB, 256×256, 547 mal angesehen
  • @Bl@ckSp@rk:
    WOW! Echt gute example. Ist im GM anscheinend doch komplizierter als man es sich vorstellen kann.
    Wäre es ok, dass ich den Thread nochmals rauskrame falls ich wieder irgendein "Problem" bekomme? ^^

    Danke auf jedenfall.


    @Chaos Creator:
    Der Punkt ist ja, dass ich diese "Spriteverläufe" nicht als Lichter ins Spiel einbauen möchte. Ich will diese nur unterschiedlich Färben können um den Hintergrund des Spiels mit der Zeit anders Färben zu können.
    Genauer gesagt: Ich habe eine Skybox mit 2 Weiß-Verläufen dieser Art gemacht. Diese sollen von mir in allen möglichen Farben "Färbbar" sein.
    Also kein Umgebungslicht, keine richtigen "Lichteffekte", blos das Färben dieses Weißen Verlaufes in unterschiedlichen Farben.
    Alles hat wunderbar funktioniert, bis auf die implementierung der "dunklen" farben.

    Das Example von Bl@ckSp@rk bewerkställigt genau dies.(Helle als auch dunkle Farben möglich > Tag und Nacht)

    Aber wenn du keine Verdunklung der Umgebung haben willst, sieht man normales licht nicht - wenn du nur überblenden willst zeichne doch ein nach außen hin transparenter werdenden Sprite mit draw_sprite_ext, dann kannst du ganz einfach die Farbe einstellen.


    Natürlich kann ich das auch so machen. Jedoch trat hier das Problem auf, dass dunkle Farben nicht dunkel erschienen. (Schwarzwert wurde ignoriert.) Daher suchte ich hier im Thread nach einem "Workaround".
    Bei Nacht muss der Himmel nähmlich auch dunkel sein und nicht Blau erscheinen.

    Aber ebenso danke für deine Hilfe. Ein wenig "Fachwissen" konnte ich immerhin aus dem Topic gewinnen. XD
  • Wäre es ok, dass ich den Thread nochmals rauskrame falls ich wieder irgendein "Problem" bekomme? ^^

    Klar, warum nicht :)
    Ich helfe gerne.

    Kannst ja mal die Grafiken zeigen, die du da färben willst. Dann sieht man mal am konkreten Beispiel wie es mit verschiedenen Färbungen aussehen soll.
  • Oke, ich habe verstanden, was du erreichen willst, wenn auch nicht wofür

    Wegen dem Beispiel: Ist draw_background_ext + eine Färbung so unperformant, dass sich eine Surface lohnt? Ohne wäre es ja genauso möglich.

    EDIT: Ohne Surface ~8020 fps, mit ~9000 fps, lohnt sich also schon
    Und man hat ja mit der Surface den Vorteil, dass man bei keiner änderung der Lichter sie einfach wiederverwenden kann. Nur bei älteren PC's, die keine Surfacen unterstützen, wirds problematisch