3d für Anfänger - Beleuchtung

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

    • 3d für Anfänger - Beleuchtung

      Weitere 3d-Anfänger Tutorials gibt's hier:


      Dieses Tutorial befasst sich mit Beleuchtungs Methoden im Gamemaker, unter anderem aber auch mit Nebel.
      Was du in diesem Tutorial lernst:
      • "Was ist Smooth Shading?"
      • Das Benutzen von direktionalem Licht
      • Das Benutzen von Lichtquellen
      • Flackerndes Licht
      • Alternativen zu den eingebauten Funktionen
      Außerdem:
      • Nebel
      • Zwei Wege, Nebel effizient zu nutzen

      1. "Was ist Smooth Shading?"
      Smooth Shading, so wie es der Game Maker nennt, habe ich in meinem Anfänger Tutorial nur kurz erwähnt. Da es nun eine größere Bedeutung bekommt, möchte ich es nocheinmal ausfühlicher erklären.

      Links sieht man das sogenannte "Flat Shading". Es kommt zu stande, wenn man Smooth Shading im Game Maker deaktiviert. Bei dieser Methode wird die Farbe für jedes einzelne Polygon bestimmt. Beim Smooth Shading werden die Werte des Polygons interpoliert (weichgezeichnet), was einen deutlich runderen Effekt bewirkt. Beide Methoden nehmen so ziemlich gleich viel Rechenleistung in Anspruch.

      GML-Quellcode

      1. d3d_set_shading(false); // Deaktiviert Smooth-Shading
      2. d3d_set_shading(true); // Aktiviert Smooth-Shading


      2. Das Benutzen von direktionalem Licht

      Direktionales Licht kann man sehr gut mit Scheinwerfern vergleichen. Sie werden häufig benutzt um Objekten eine gewisse Räumlichkeit zu verleihen.



      Direktionales Licht im Game Maker:

      Direktionale Lichter lässt man mit "d3d_light_definde_direction" Zeichnen. Hier ein Beispiel:

      GML-Quellcode

      1. d3d_light_define_direction(ind, dx, dy, dz, color);
      2. d3d_light_enable(ind, true);

      Gehen wir den Code einmal durch. Mit "ind" ist der Name des Lichts gemeint. Zum Bennenen müssen Zahlen benutzt werden.
      Mit "d3d_light_enable" aktivieren wir das zuvor deklarierte Licht, "ind" ist der Name, dem wir das Licht zuvor zugeordnet haben - z.B. "0". Mit "true" wird das Licht aktviert, mit "false" bleibt es deaktiviert.
      Jetzt wird es etwas komplizierter, ich möchte auf dx, dy und dz eingehen. Dafür habe ich eine Grafik vorbereitet.

      Die Grafiken zeigen einen Raum im Game Maker aus der Topdown Perspektive. Beim ersten Bild scheint aus jeder Richtung jeweils ein Licht.
      Ist der dx-Wert größer als 0, scheint das Licht nach rechts, ist er kleiner als 0 scheint er nach links. So funktioniert es auch beim dy-Wert.
      Man kann jedoch auch dx und dy kombinieren, wie man es im zweiten Bild sieht. Ist ein Wert =0, kommt kein Licht aus dieser Richtung. 1 und -1 sind Standartwerte.
      Möchte man ein Objekt von unten bescheinen lassen, sollte der dz-Wert kleiner als 0 sein, möchte man ihn von oben bescheinen lassen größer als 0.
      Beispiele wären also:

      GML-Quellcode

      1. d3d_light_define_direction(0,1,1, 0, c_white);
      2. d3d_light_enable(0, true);
      3. d3d_light_define_direction(1,-1,-1, 0, c_white);
      4. d3d_light_enable(1, true);


      3. Das Benutzen von Lichtquellen

      Lichtquellen, oder Punktlicher kann man sich wie Glühbirnen vorstellen. Sie scheinen von einer x,y,z Position in alle Richtungen.


      GML-Quellcode

      1. d3d_light_define_point(ind,x,y,z,range,col);
      2. d3d_light_enable(ind,true);

      Auch hier gehen wir den Code Schritt für Schritt druch. "ind" haben wir bereits kennengelernt, hierfür müssen Zahlen benutzt werden.
      X,Y und Z sind die Koordinaten, von denen das Licht ausgeht. "range" gibt an, wie weit das Licht scheinen soll. Die Angabe erfolgt in Pixeln, und das Licht nimmt nach außen hin ab.

      4. Flackerndes Licht

      Licht wird in Spielen meist benutzt, um eine gewisse Atmosphäre zu vermitteln. Oft werden deswegen auch flackernde Lichter. Eine Möglichkeit dies zu realisieren möchte ich kurz vorstellen.
      Am besten wir erstellen dafür ein neues Objekt, nennen wir es einfach "obj_licht". In seinem Create-Event deklarieren wir eine Variable, ich benutzte hier "light".

      GML-Quellcode

      1. light=1;

      Jetzt kommt das entscheidene Step-Event.

      GML-Quellcode

      1. if(light>0.2)
      2. {
      3. d3d_light_enable(0,true);
      4. d3d_light_define_point(0,x,y,50,100,c_lime);
      5. }
      6. else
      7. {
      8. d3d_light_enable(0,false);
      9. }
      10. light=random(5);

      Dieser Code bewirkt, dass jeden Step abgefragt wird, ob die Variable "light" größer als 0.2 ist. Ist das der Fall, wird das Licht "0" aktivert und gezeichnet.
      Sollte es nicht der fall sein (else), wird das Licht "0" deaktivert, es wird dunkel.
      In der letzten Zeile, wird "light" ein zufälliger Wert zwischen 0 und 5 zugeschrieben.
      D.h, die Wahrscheinlichkeit, dass "light" <= 0.2 ist, ist eher unwahrscheinlich, und das Licht flackert eher selten. Würden wir die Zeile

      GML-Quellcode

      1. if(light>0.2)
      in z.B.

      GML-Quellcode

      1. if(light>0.4)
      ändern, würde das Licht deutlich öfter flackern.

      5. Alternativen zu den eingebauten Funktionen


      Game Maker unterstüzt eine Beleuchtungsmethode, die in der Fachsprache Vertex Based Lighting heißt. Was das heißt haben wir vorhin schon gelernt, und zwar dass jedes einzelne Polygon eines Modells beleuchtet wird, und nicht jeder Pixel, wie es zum Beispiel beim Per-Pixel-Lighting der Fall wäre.
      Das zieht einige gravierende Nachteile hinter sich:

      In meinem Beispiel zu meinem Basis 3d Tutorial wären Punktlichter nicht auf den Boden anwendbar. In meinem Beispiel zeichne ich nämlich eine riesige Fläche, die insgesamt aber nur aus 2 Polygonen besteht. Würden wir jetzt Punktlicher benutzen wollen, so wie im ersten Bild, könnte der Game Maker keine entsprechenden Werte für das Polygon erstellen, und die Fäche bliebe unbeleuchtet. Damit Punktlichter auf der Fläche ännahernd gut aussehen würden, müssten wir einen Boden wie im zweiten Bild benutzen. Gut sähe es nach wie vor nicht aus, und wir hätten 70 überflüssige Polygone.

      Doch es gibt einen Weg um all dies zu vermeiden, und der oft sogar bessere Ergebnisse hervorbringt. Das einfachste ist es, Blend Modes zu benutzen.
      Die Vorteile sind:
      • Unabhängig von der Anzahl der Polygone
      • Sehen oft weicher aus als Punktlichter
      • Form lässt sich frei bestimmen
      • Benötigt wesentlich weniger Rechenleistung

      Ein mit Blend Modes erstelltes Licht könnte so aussehen.

      Schauen wir uns einmal den Code an, mit dem dieses Licht gezeichnet wird.

      GML-Quellcode

      1. draw_set_blend_mode(bm_add);
      2. draw_set_color(c_yellow);
      3. d3d_draw_floor(x-10,y-10,0.1,x+10,y+10,0.1,background_get_texture(light),1,1);
      4. draw_set_color(c_white);
      5. draw_set_blend_mode(bm_normal);

      Die erste Zeile aktivert den additiven Blend Mode für alles was danach gezeichet wird. Das heisst, dass alles was schwarz ist transparent wird, und alles dunkele dementsprechend halbtransparent. Mit "draw_set_color()" kann man die Farbe des Lichts bestimmen. In der dritten Zeile wird das eigentliche Licht als normale Fläche gezeichnet. Mit "bm_normal" deaktivieren wir Blend Modes wieder.
      Aber das war noch längst nicht alles, was man mit Blend Modes alles anstellen kann.

      Wenn wir, z.B. mit GIMP, ein Relief aus der Beispiel Textur machen, und es nach außen hin dunkeler werden lassen, kann es so aussehen wie auf dem zweiten Bild. Wende wir den gleichen Code an, sieht es so aus:

      Es fällt sofort auf, dass das Licht deutlich realistischer aussieht, da dass Licht nun eine Struktur bekommen hat.

      6. Nebel

      In vielen Spielen wird auch eine Art Nebel benutzt, welche die Sichtweite einschränkt, und die Spannung erhöhen kann.

      GML-Quellcode

      1. d3d_set_fog(enable,color,start,end)

      enable gibt an, ob der Nebel aktivert werden soll, es werden also true und false genutzt.
      color gibt die Farbe des Nebels an, für gewöhnlich ist es c_black, also schwarz.
      start ist der Startpunkt des Nebels, er ist meist ein kleiner Wert als 1. end ist demnach der Endpunkt des Nebels, zum Beispiel 1024. Alles was weiter als 1024 Pixel von der Kamera entfernt ist, verschwindet hinter dem Nebel.

      7. Zwei Wege, Nebel effizient zu nutzen

      Diese Eigenschaft des Nebels kann man sich zu Nutze machen, indem man alles was hinter dem Nebel verschwindet nicht mehr zeichnen lässt. Dies spart enorm viel Performance, und fällt dem Spieler nicht auf. Dafür benutzen wir in Objekten, die hinter dem Nebel nicht mehr geizeichnet werden sollen diesen Code.

      GML-Quellcode

      1. if (point_distance(x,y,spieler.x,spieler.y) > 1024) exit; //1024 muss mit dem Endounkt des Nebels ersetzt werden.
      2. d3d_draw_block(x-5,y-5,0,x+5,y+5,10,-1,1,1);//Dieser Block wird nur gezeichnet, wenn der Spieler weniger als 1024 Pixel von dem Objekt entfernt ist.


      Manche haben sich bestimmt gefragt, warum man den Nebel aktivieren muss. Ganz einfach, mit dieser Eigenschaft kann man Nebel erstellen der nicht global ist, sondern nur auf einzelne Objekte oder Flächen wirksam ist



      So kann man zum Beispiel bei meinem Example über Spiegeleffekte alles was unter dem Wasser ist mit einem Spiegeleffekt versehen. So kann man nicht mehr bis auf den Grund sehen, was sehr unrealistisch wäre.
      Ein Code-Beispiel wäre:

      GML-Quellcode

      1. d3d_set_fog(true,c_black,1,200);
      2. d3d_draw_block(x-3,y-3,0,x+3,y+3,6,-1,1,1);
      3. d3d_set_fog(false,c_black,1,200);

      Der Nebel wirkt sich insofern auf den Block aus, dass dieser, wenn die Kamera mehr als 200 Pixel vom Objekt entfernt ist, komplett schwarz wird.

      8. Schlusswort

      Da dieses Tutorial, anders als meine restlichen, eher theoretisch ist, sind die Beispiele ausnahmsweise etwas ausführlicher.



      Im ersten Example werden Punktlicher, flackernde Punktlichter und die Alternativen gezeigt.



      Das zweite Beispiel zeigt direktionales Licht.
      Dateien
    • Ein paar kleine Fehler gefunden, hab ich dir im ICQ ja schon gesagt, sonst ist es interessant... Hab sogar noch was gelernt (Nebel an/aus um Objekte ein/auszuschliessen)
      So far, Schattenphoenix~
      _____________________________________________________________________________
      "Who needs a stairway to heaven...
      If there is an elevator to hell... ?
      "
      - Vergessen
      "Auch ein perfektes Chaos ist etwas vollkommenes."
      - Jean Genet
    • Irgendwie kommt bei mir immer dieser Error

      ERROR in
      action number 1
      of Create Event
      for object direktionales_licht:

      File is not opened for reading.

      Kann mir mal jemand erklären wieso das so ist
    • Ich hab jetzt dein Tutorial nicht 100%ig durchgearbeitet, aber ich hab eine Frage, für die ich nicht extra einen neuen Thread öffnen wollte.
      Woran liegt es, dass ich nur eine Lichtquelle nutzen kann? Sobald ich 2 Lichtquellen in meinen 3d room setze,
      bleibt die ältere Quelle dunkel.

      MfG
    • hast du kein WinRar? Du musst die ganze Geschichte im Zip in einen Ordner oder so entpacken (also da rausmachen oder extrahieren wies in windows-zip da heißt) damit dus anständig starten kannst.
      ////////////////////////////////////////////////////////////////////////////////////////////////