Unity3D: Wie kann man den Beleuchtungsgrad eines Punktes in einer Szene herausfinden?

Grüße!

Ich weiß, und im Grunde wissen Sie, was Ihre Kartenspiele oder Drei-in-Eins-Spiele fehlen. Stealth-Systeme!

Und natürlich sollte jedes Stealth-System mit Selbstachtung in der Lage sein, die Beleuchtung der Umgebung um den Spieler herum zu berücksichtigen. Ich war erstaunt, das Thema zu vertiefen und eine ungewöhnlich kleine Menge an Informationen zu finden. Deshalb beeile ich mich, die Früchte zu teilen.

Heute werden wir kein vollwertiges Stealth-System für den Spieler entwickeln, sondern nur Interaktionen mit der Beleuchtung betrachten.

Methode 1: Collider


Ein einfacher und nicht sehr ressourcenintensiver Weg.

Wir fügen jeder Lichtquelle einen sphärischen Collider hinzu. Wir machen es zum Auslöser. Wir setzen die Abmessungen ungefähr gleich dem Lichtradius.

Der Rest ist klar wie ein Schatten. Wir schreiben ein einfaches Skript, in dem wir in OnTriggerEnter () die Aktivierung der Lichtberechnung platzieren (damit die Lichtquellen nicht im Leerlauf funktionieren, wenn sich der Player nicht in der Nähe befindet).

Die Beleuchtungsberechnung selbst befindet sich in Update (). Im Wesentlichen ist dies die übliche Physik.Raycast (). Wenn es den Spieler trifft, befindet sich der Spieler in der Lichtzone. Wenn es nicht fällt, bedeutet dies, dass sich der Spieler hinter Hindernissen und damit im Schatten befindet.

Sie können hier auch die Berechnung der Entfernung zwischen dem Player und der Lichtquelle hinzufügen. Um die Beleuchtung zu bestimmen, verwenden wir einen einfachen Schwimmer, der je nach Abstand zu den Lichtquellen variiert. Und Sie können es verwenden, wo immer Ihr Herz es wünscht.

Beispiel

Bei Punkt 1 ist die Beleuchtung nahezu maximal. Bei Punkt 2 ist die Beleuchtung minimal - es gibt ein Hindernis zwischen dem Licht und dem Punkt. Bei Punkt 3 ist die Beleuchtung durchschnittlich.

Und das ist noch nicht alles! Sie können verschiedenen „Schattenzonen“, in denen sich der Spieler verstecken muss, Trigger-Collider hinzufügen. In den besten Traditionen von Manhunt. Ebenso können Sie die hellen Zonen mit dem Collider markieren und beispielsweise das Licht eines Scheinwerfers simulieren.

Vorteile:


  • Einfache Anpassung von Punktlichtern.
  • Sehr sparsam in Bezug auf Ressourcen, wenn Sie keine Lichtquellen spammen.

Nachteile:


  • Das Spotlicht und das Richtungslicht sind stark abgestimmt. Wenn es für das erste ausreicht, den Collider im Lichtfeld zu positionieren (um die Sichtbarkeit des Spielers am Eingang zu erhöhen), ist das zweite ein echtes Grauen. Sie müssen entweder Kollider an jedem Schatten platzieren (um die Sichtbarkeit des Spielers am Eingang zu verringern) oder ständig mit Physics.Raycast () zwischen dem Spieler und der „Sonne“ prüfen - er befindet sich unter den Strahlen oder im Schatten.
  • Eine große Anzahl von Kollidern überfrachtet die Szene und erschwert die Physik.
  • Bei sich kreuzenden Lichtquellen ist Vorsicht geboten.
  • Dynamisches Licht (bewegte oder sich ändernde Intensität) muss separat über Skripte hinzugefügt werden.

Methode 2: RenderTexture


Was machen wir hier? Tatsächlich erhalten wir einen „Screenshot“ von der Kamera und nicht unbedingt von der Hauptkamera. Und dann analysieren wir die Farbe des Screenshots, um herauszufinden, wie hell das Licht auf das Motiv fällt.

Zunächst brauchen wir ein Objekt, von dem wir das Licht "lesen" werden. Erstellen Sie eine regelmäßige Kugel oder Ebene, machen Sie sie klein (Skala 0,1), platzieren Sie sie nahe am Boden, machen Sie sie weiß, entfernen Sie den Collider:

Versteckter Text


Fügen Sie eine Kamera hinzu (entfernen Sie unbedingt den Audio-Listener und stellen Sie sicher, dass sich das MainCamera-Tag nicht lohnt). Binden Sie es an unser Objekt. Wir legen es etwas höher, wir lenken es nach unten. Wir belichten in den Einstellungen nicht die Hauptanzeige. Es orthographisch zu machen ist für Ihren Geschmack.

Am Ende positionieren wir es so, dass es auf unser Objekt und nur auf es schaut.

Versteckter Text


Konfigurieren Sie am Ende die Culling-Maske der primären und sekundären Kamera so, dass die primäre unsere „hellen“ Objekte nicht anzeigt, während die sekundären nur sie sehen, ohne etwas anderes zu überladen.

Und hier beginnt der Spaß. Wir hängen das Skript an die Kamera an:

public Camera cam; //   RenderTexture tex; Texture2D _tex; void Start () { //    "". // ,       -   . // Depth   0   -   . tex = new RenderTexture (1, 1, 8); // RenderTexture "" , //   ,    . _tex = new Texture2D (1, 1, TextureFormat.RGB24, false); } void Update () { //   ""  cam.targetTexture = tex; cam.Render (); //     RenderTexture.active = tex; //   Texture2D _tex.ReadPixels (new Rect (0, 0, 1, 1), 0, 0); _tex.Apply (); Color col = _tex.GetPixel (0, 0); float vis = (col.r + col.g + col.b) / 3; } 

Am Ausgang erhalten wir ein Float Vis, das im Wesentlichen eine numerische Darstellung des auf unser Objekt einfallenden Beleuchtungsniveaus ist. Wenn die Quelle nahe ist - das Objekt ist weiß - vis ist 1. Wenn es dunkel ist - ist das Objekt schwarz - vis ist ~ 0.

Wir müssen die obige Operation nicht in jedem Frame ausführen, daher binden wir einen kleinen zweiten Timer ein:

 float interval = 0; void Update () { interval += Time.deltaTime; if (interval < 1) return; interval = 0; //   } 

Als nächstes binden wir unser gesamtes System an den Spieler, so dass es sich mit ihm bewegt. Und unsere vis-Variable gibt automatisch Licht um den Player zurück!

Dieses System kann nicht nur in Verbindung mit dem Player verwendet werden. Sie können es überall und nach Belieben platzieren und so eine Art Lichtsensor erstellen. In der Regel gibt es effektivere Möglichkeiten, sie umzusetzen, aber ist es immer schön, Alternativen zu haben?

Die Vorteile liegen auf der Hand, lassen Sie uns über die Nachteile sprechen.

Nachteile


  • Jeder „Lichtdetektor“ (wenn es mehr als einen gibt) benötigt eine separate Kamera.
  • Texture2D.ReadPixels () - na ja, extrem langsam. Selbst wenn Sie dies einmal pro Sekunde tun und nicht jedes Bild, auch wenn Sie die Funktionen zum Schreiben und Lesen von Texturen in verschiedene Bilder aufteilen, gibt es immer noch Layouts mit 40 bis 110 ms.
  • Dieses System berücksichtigt einige seltene Fälle nicht. Zum Beispiel leuchtet eine Taschenlampe auf einen Charakter. Der Charakter ist gut beleuchtet, aber das Licht fällt auf ihn und hinter ihn und nicht nach unten. Unser Lichtdetektor zeigt eine geringe Beleuchtungsstärke. Sie können das Problem beispielsweise lösen, indem Sie den Detektor nicht auf dem Boden, sondern auf der Höhe der Brust des Charakters platzieren. Dann müssen Sie zwei Kameras auf gegenüberliegenden Seiten platzieren, um das Licht von beiden Seiten abzulesen. Was wird das System um die Hälfte verlangsamen.

Source: https://habr.com/ru/post/de417135/


All Articles