Bevor ich etwas anderes sage: Ich verwende duale Lichtkarten, was bedeutet, dass ich sowohl nah als auch fern mischen muss.
Ich arbeite also schon eine Weile daran, ich habe einen ganzen Tag / Nacht-Zyklus für Renderer und Beleuchtung eingerichtet, und alles funktioniert gut und nicht prozessintensiv.
Das einzige Problem, das ich habe, ist herauszufinden, wie ich zwei Lightmaps zusammenmischen kann. Ich habe herausgefunden, wie man Lightmaps wechselt, aber das Problem ist, dass es abrupt aussieht und die Erfahrung unterbricht.
Ich habe stundenlang nachgeforscht, alle Arten von Shadern ausprobiert, Pixel für Pixel gemischt und alles andere ohne wirklichen Erfolg. Pixel für Pixel in C # zu mischen hat sich für meinen Geschmack als ein bisschen prozessintensiv herausgestellt, obwohl ich immer noch daran arbeite, es aufzuräumen und es reibungsloser zu machen. Shader sahen vielversprechend aus, aber ich konnte keinen Shader finden, der zwei Lightmaps richtig mischen konnte.
Hat jemand irgendwelche Hinweise, wie ich dies erreichen könnte? Ich brauche nur einen fließenden Übergang zwischen meiner Tages- und Nachtlichtkarte. Vielleicht könnte ich die beiden Texturen überlagern und einen Alphakanal verwenden? Oder etwas ähnliches?
Graphics.Blit()
um es zu rendern? Ich habe das noch nie gemacht, aber im Handbuch nachzusehen, sollte funktionieren.Antworten:
Also habe ich mich kürzlich daran versucht und bin auf viele der gleichen Probleme gestoßen, die ihr habt. Die Render-Textur-Lösung ist ein bisschen wie ein roter Hering. Ich konnte es mit Multithreading-Pixel-Manipulation auf einem separaten Thread lösen.
https://www.youtube.com/watch?v=T_zpFk1mdCI
graphics.blit()
Normalerweise verwendet man die Render-Textur und übergibt sie dort, wo sie benötigt wird, aber Lightmap-Daten unterstützen keine Texturen, sondern benötigen texture2ds. Der nächste logische Schritt wäre, die Daten in eine texture2d zu kopieren und diese dann in die Lightmap-Daten einzuspeisen. Diese Technik ruiniert die Bildraten, da die GPU blockiert, um Daten an die CPU zu senden, anstatt nur auf die Daten zu verweisen.Die Lösung besteht dann darin, die GPU nicht zu verwenden.
Lichtkartenübergänge finden über einen langen Zeitraum statt, sodass es nicht unbedingt wichtig ist, die Lichtkarte bei jedem Frame zu aktualisieren. In der Tat würden die Spieler wahrscheinlich nicht bemerken, wenn die Lichtkarten nur alle 20-40 Minuten in der Spielzeit aktualisiert würden.
Sie geben die Aufgabe also für jede Light Map in separaten Threads an die CPU aus.
Normalerweise unterstützt Unity kein Multithreading. Aber das ist okay, C # tut es. Dieser Typ macht einen phänomenalen Job, um Multithreading in Unity zu erklären. Wenn Sie noch nie davon gehört haben oder noch nie gewusst haben, wie Multithreading in Unity funktioniert, ist dies das Video:
https://www.youtube.com/watch?v=ja63QO1Imck
Sie müssen lediglich eine Arbeitsthreadklasse erstellen, die Kopien der Lightmap-Pixeldaten in Farbarrays variiert, und anschließend eine Mischfunktion erstellen.
Ein einfaches Lerp von einer Farbe zur nächsten reicht aus.
Dann erstelle den Thread, starte ihn und wenn alle Lightmaps in den separaten Threads fertig sind, kannst du die Pixeldaten zurück in die Lightmap-Daten-Textur2d kopieren.
Ich habe unten einen Beispielcode gepostet. Es ist sicherlich nicht die vollständig implementierte Version, aber sie zeigt Ihnen die wichtigsten Konzepte zum Erstellen der Klasse, zum Erstellen des Threads und zum Festlegen der Lichtdaten.
Das andere, was Sie tun müssten, ist, ab und zu eine Funktion aufzurufen, um die Aktualisierung der Lightmaps auszulösen. Außerdem müssen Sie entweder alle Pixeldaten beim Start oder beim Kompilieren in die Worker-Klasse kopieren. Viel Glück für alle, die das finden. Ich glaube, die Operation hat ihr Leben fortgesetzt, aber ich weiß, dass andere Menschen mit ähnlichen Problemen darüber stolpern könnten.
quelle
Es gibt einen Skybox-Shader, der zwischen zwei Sets von Skybox-Texturen mischt. Denken Sie Tag und Nacht Zyklus!
Wenn Sie die Skybox aus einem Skript erstellen oder animieren möchten
skyboxmaterial.SetFloat("_Blend", yourBlend)
, ändern Sie die Überblendung mit. kann auch verwendenSetTexture
Materialfunktionen zum Einrichten oder Ändern der Texturen verwenden.Video-Tutorial zum Tag / Nacht-Zyklus: http://www.youtube.com/watch?v=FTfv9JhkmIA
Der Beispielcode lautet wie folgt:
quelle
Wenn Sie wissen, wie man umschaltet, warum nicht mit dem Erstellen einer Reihe von Übergangs-Lightmaps im Hintergrund-Thread fortfahren und dann die Übergänge aktivieren, wenn die Lightmaps fertig sind?
Sie können sich auch ein interessantes Asset im AssetStore ansehen: https://www.assetstore.unity3d.com/en/#!/content/5674
Ich denke, es beinhaltet die Überblendung der Lichtkarten, obwohl ich nicht weiß, wie.
quelle