Mit den folgenden Best Practices kannst du die Darstellung und Leistung von Texturen in deinem Android-Spiel optimieren.
Texturen sind ein Kernelement Ihrer 3D-Grafik. 3D-Spiele, die auf den meisten Geräten laufen, beginnen mit 3D-Grafiken, die so konzipiert sind, dass Grafikprozessoren optimal genutzt werden. In diesem Leitfaden werden Optimierungen und Best Practices für Texturen auf Mobilgeräten vorgestellt, mit denen du die Leistung deines Spiels verbessern, den Stromverbrauch minimieren und gleichzeitig eine hohe Bildqualität beibehalten kannst.
Texturatlas erstellen
Ein Texturatlas ist eine Textur, die die Bilddaten mehrerer grafischer Objekte enthält, z. B. 3D-Mesh-Netzwerke oder 2D-Sprites. Anstelle, dass jedes Objekt eine eigene Textur hat, wird eine Atlastextur verwendet, um die Bilder der einzelnen Objekte zu kombinieren.
Für optimale Rendering-Leistung ist es wichtig, die Anzahl der Zeichenaufrufe eines Spielframes zu minimieren. Die Verwendung derselben Textur für verschiedene Objekte ist ein Faktor für deren Kombination in einem einzigen Zeichenaufruf. Das Reduzieren von Zeichenaufrufen ist besonders für CPU-gebundene Spiele wichtig, da jeder Zeichenaufruf bei der Verarbeitung durch den Grafiktreiber CPU-Aufwand verursacht. Texturatlasen reduzieren auch die Anzahl der Textur-Asset-Dateien in den Laufzeitdaten Ihres Spiels. Hunderte oder sogar Tausende von Texturen können zu einer viel kleineren Anzahl von Texturatlasdateien konsolidiert werden.
Beim Erstellen von 3D-Mesh-Netzwerken sollten Sie das Layout des Texturatlas planen. Wenn der Atlas vor dem Erstellen des Mesh-Assets erstellt wird, muss das Mesh-Asset gemäß dem Texturatlas UV entpackt werden. Wenn der Atlas nach dem Authoring mithilfe von Integrations- oder Atlas-Erstellungstools in der Malsoftware erstellt wird, muss die UV-Insel entsprechend der Textur neu angeordnet werden.
Suchmaschinenspezifische Batchverarbeitung von Zeichenaufrufen
Die Unity-Spiele-Engine hat eine Stapelverarbeitung von Zeichenaufrufen, die Objekte automatisch kombinieren können. Um für die automatische Batchverarbeitung infrage zu kommen, müssen Objekte ein gemeinsames Material, einschließlich Texturen, verwenden und als statisch gekennzeichnet sein.
Unreal Engine 4 erfordert eine manuelle Einrichtung für die Batchverarbeitung. Sie können Objekte in 3D-Software zusammenführen, bevor Sie sie in Unreal importieren. Unreal umfasst außerdem das Tool UE4 Actor Merging, mit dem Mesh-Netzwerke kombiniert und Texturatlasdateien erstellt werden können.
Mipmaps generieren
Mipmaps sind Versionen einer Textur mit geringerer Auflösung. Eine Sammlung von Mipmaps für eine bestimmte Textur wird als Mipmap-Kette bezeichnet. Jede nachfolgende Mipmap-Ebene in einer Kette hat eine niedrigere Auflösung als die vorherige Ebene. Mipmaps werden verwendet, um Textur-LOD (Detailebene) während des Renderings zu implementieren. Wenn eine angepasste Textur an einen Texturbereich gebunden ist, verwendet die Grafikhardware den von einem Fragment eingenommenen Texturraum, um eine Ebene aus der Mipmap-Kette auszuwählen. Beim Rendern einer 3D-Szene wird für ein weiter von der Kamera entferntes Objekt eine Mipmap mit geringerer Auflösung verwendet als dasselbe Objekt, das sich näher an der Kamera befindet.
Eine Textur, die mit „mipmapp“ geändert wurde, benötigt mehr Speicher als eine Textur, die nicht mit „mipmapp“ bearbeitet wurde. Die zusätzlichen Mipmap-Level erhöhen den Speicherbedarf einer Textur um 33%. Wenn eine Textur in einem festen Abstand von der Kamera gezeichnet wird, verbraucht das Generieren von Mipmaps keinen Arbeitsspeicher.
Die korrekte Verwendung von Mipmaps verbessert die GPU-Leistung. Die Verfügbarkeit von Mipmap-Levels mit niedrigerer Auflösung reduziert die Speicherbandbreite und verbessert den Standort des Textur-Cache.
Mipmapping kann auch die visuelle Qualität verbessern, indem Texturaliasing reduziert werden. Das Kanten der Textur kann als Flimmern in Bereichen auftreten, die weiter von der Kamera entfernt sind.
Engine-spezifische Mipmap-Details
Unreal Engine 4 erfordert für die Verwendung von Mipmapping Texturdimensionen in Zweierpotenzen (z.B. 512 × 1024, 128 × 128). Mipmap-Ketten werden nicht generiert, wenn eine oder beide Texturdimensionen keine Potenz von zwei sind.
Die Unity-Engine skaliert Texturen automatisch mit Dimensionen, die nicht eine Potenz von zwei sind, um Mipmaps zu erstellen. Achten Sie darauf, dass die Quelltexturdateien zwei Dimensionen haben, um eine solche Skalierung zu vermeiden.
Geeignete Modi für Texturfilter auswählen
Texturfilter sind eine Hardware-Renderingfunktion, die die visuelle Darstellung eines gerenderten Dreiecks beeinflusst. Der richtige Einsatz der Texturfilter kann die visuelle Qualität einer Szene verbessern. Es gibt mehrere Modi für die Texturfilterung, jeder mit einem unterschiedlichen Verhältnis zwischen Renderingverbesserung und Kosten. Die Kosten umfassen sowohl die Rechenzeit als auch die Speicherbandbreite. Drei häufig verfügbare Texturfiltermodi sind: nächstgelegener (oder Punkt), bilinear und trilinear. Die anisotrope Filterung ist eine zusätzliche Methode zur Texturfilterung, die mit der bilinearen oder trilinearen Filterung kombiniert werden kann.
Nächstgelegene Veranstaltung
„Nächstgelegene“ ist der einfachste und günstigste Texturfiltermodus. In der Nähe wird ein einzelnes Texel mithilfe der angegebenen Koordinaten in der Quelltextur entnommen. Dreiecke, die mit der nächsten gerendert werden, haben eine blockhafte oder pixelige Darstellung, insbesondere wenn sie nahe der Kamera gerendert werden.
Bilinear
Bei der bilinearen Filterung werden die vier Texel genommen, die die angegebenen Koordinaten in der Quelltextur umgeben. Diese vier Texel werden gemittelt, um die Texturfarbe des Fragments zu bestimmen. Die bilineare Filterung führt zu einem weicheren Farbverlauf zwischen den Pixeln, wodurch die blockartige Darstellung der nächstgelegenen Filterung vermieden wird. Dreiecke, die nahe der Kamera gerendert werden, erscheinen verschwommen statt verpixelt. Bilineare Kosten sind aufgrund der zusätzlichen Texelproben und der Durchschnittsermittlung höher als am nächsten.
Trilinear
Wenn Sie ein Mesh-Netzwerk rendern, bei dem die Entfernung der Eckpunkte von der Kamera variiert, können beim Rendern mehrere Mipmap-Ebenen ausgewählt werden. Die Änderungen zwischen zwei Mipmap-Ebenen können zu einem deutlichen Einschnitt am Übergangspunkt führen. Durch die trilineare Filterung werden diese Übergänge abgeschwächt, indem eine bilineare Filterung auf zwei verschiedenen Mipmap-Ebenen durchgeführt und die Ergebnisse interpoliert werden. Durch die Verwendung mehrerer Minp-Levels und Interpolation ist Trilinearer rechenintensiver als bilinear.
Anisotrop
Die anisotrope Filterung erhöht die visuelle Qualität von texturierten Mesh-Netzwerken, die unter einem extremen Winkel relativ zur Kamera gerendert werden. Eine Bodenebene ist ein gängiges Beispiel für diese Art von Mesh. Damit die anisotrope Filterung funktioniert, müssen Texturen mit angepasster Anwendung verwendet werden. Das Verhältnis oder der Grad der anisotropen Filterung, die während des Renderings angewendet wird, kann konfiguriert werden. Die Kosten für die anisotrope Filterung steigen mit steigendem Niveau.
Strategie zur Modusauswahl
Eine bilineare Filterung ist im Allgemeinen das beste Gleichgewicht zwischen Leistung und visueller Qualität. Die trilineare Filterung erfordert deutlich mehr Speicherbandbreite und sollte selektiv verwendet werden. In vielen Fällen sieht die bilineare Filterung in Kombination mit der 2-fachen anisotropen Filterung besser aus und funktioniert besser als die trilineare Filterung mit einmal anisotroper Filterung. Das Erhöhen der anisotropen Stufe über das Zweifache hinaus ist extrem kostenintensiv und sollte bei wichtigen Spiel-Assets sehr selektiv erfolgen.
Die Texturfilterung kann bis zu der Hälfte des gesamten GPU-Energieverbrauchs ausmachen. Die Auswahl einfacherer Texturfilter ist eine hervorragende Möglichkeit, den Stromverbrauch Ihres Spiels zu reduzieren.
Texturgrößen optimieren
Achten Sie darauf, dass die Texturabmessungen so klein wie möglich sind und dennoch die gewünschte Bildqualität erreichen. Prüfen Sie Ihre Textur-Assets auf falsch große Texturen. Dieses Prinzip gilt sowohl für diskrete als auch für Atlastexturen. Wenn Ihr Spiel viele Geräte mit vielen Auflösungs- und Leistungsfähigkeiten unterstützt, sollten Sie Versionen Ihrer Textur-Assets mit niedriger und hoher Auflösung für die entsprechende Geräteklasse erstellen.
Wenn Sie ein Mesh-Netzwerk rendern, das mehrere Texturen in seinem Material verwendet, sollten Sie die Auflösung einiger Texturen selektiv reduzieren. Wenn Sie beispielsweise eine diffuse Textur von 1.024 × 1.024 verwenden, ist eine Reduzierung der Rauheit oder der metallischen Kartentextur auf 512 × 512 möglich, ohne die Bildqualität zu beeinträchtigen. Überprüfen Sie die Auswirkungen aller solcher Tests, um sicherzustellen, dass sie das gewünschte Qualitätsniveau nicht beeinträchtigen.
Geeigneten Farbraum verwenden
Viele Softwarepakete, die zum Erstellen von Texturen verwendet werden, werden im sRGB-Farbraum exportiert und exportiert. Für diffuse Texturen, die als Farbe verarbeitet werden, kann ein sRGB-Farbraum genutzt werden. Texturen, die nicht als Farbe verarbeitet werden, wie metallische Effekte, Rauheit oder normale Karten, sollten nicht in den sRGB-Farbraum exportiert werden.
Die Textureinstellungen der Spiel-Engine enthalten einen Parameter, der festlegt, ob eine Textur den sRGB-Farbraum verwendet.
Da die Pixeldaten solcher Texturen nicht als Farbdaten verwendet werden, führt die Verwendung des sRGB-Farbraums zu falschen visuellen Elementen.
Texturkomprimierung verwenden
Die Texturkomprimierung ist ein Bildkomprimierungsalgorithmus, der auf nicht komprimierte Pixeldaten angewendet wird. Sie ergibt eine Textur, die während des Renderings von Grafikhardware schnell dekomprimiert werden kann. Der effektive Einsatz der Texturkomprimierung kann die Speichernutzung reduzieren und die Leistung steigern, ohne die visuelle Qualität zu beeinträchtigen. Bei Android werden am häufigsten drei Texturkomprimierungsalgorithmen verwendet: ETC1, ETC2 und ASTC. Für moderne Spiele ist ASTC im Allgemeinen die beste primäre Option, wobei ETC2 eine Fallback-Option ist, wenn Ihr Spiel auf Geräte abzielt, die ASTC nicht unterstützen.
ETC1
ETC1 wird von allen Android-Geräten unterstützt. ETC1 unterstützt nur ein einzelnes 4-Bit- Pixel-Modus von RGB-Farbdaten. ETC1 unterstützt keine Alphakanäle. Viele Spiel-Engines, die ETC1 unterstützen, ermöglichen die Angabe einer zweiten ETC1-Textur zur Darstellung von Alphakanal-Daten.
ETC2
ETC2 wird von über 90% der aktiven Android-Geräte unterstützt. Sehr alte Geräte, die die OpenGL ES 3.0 API nicht unterstützen, können ETC2 nicht verwenden. Im Vergleich zu ETC1 fügt ETC2 Folgendes hinzu:
- Unterstützung von Alphakanälen, acht Bit und Ein-Bit-Punchthrough
- sRGB-Versionen von RGB- und RGBA-Texturen
- Ein- und zwei Kanäle, R11 und RG11, Texturen
Logo: ASTC
ASTC wird von über 75% der aktiven Android-Geräte unterstützt. ASTC verfügt über konfigurierbare Komprimierungsblockgrößen, mit denen Sie das Komprimierungsverhältnis einer bestimmten Textur genau gegen die Bildqualität anpassen können. ASTC ist oft in der Lage, bei gleicher Speichergröße wie ETC2 eine bessere Qualität oder eine ähnliche Menge bei einer kleineren Speichergröße als ETC2 zu erreichen.
Geschwindigkeit der Texturkomprimierung
Wenn Ihr Spiel viele Texturen hat, kann die Texturkomprimierung lange Zeit in Anspruch nehmen. Sowohl ETC als auch ASTC haben eine auswählbare Komprimierungsqualität. Einstellungen mit höherer Qualität erfordern mehr Zeit für die Komprimierung. Während der Entwicklung kann es sinnvoll sein, die Qualitätsstufe vor dem Erstellen wichtiger Builds zu verringern, um die Komprimierungszeit zu verkürzen und die Qualitätsstufe zu erhöhen.
Texturkomprimierung in Spiel-Engines
Wenn Sie eine Spiel-Engine verwenden, müssen Sie möglicherweise das Texturkomprimierungsformat (ETC oder ASTC) auf Projektebene auswählen. Zur Unterstützung mehrerer Komprimierungsformate für maximale Kompatibilität sind möglicherweise zusätzliche Maßnahmen erforderlich. Die Funktion für das Format-Targeting der Texturkomprimierung von Google Play Asset Delivery kann Sie dabei unterstützen, mehrere Formate in Ihr Spiel aufzunehmen und bei der Installation auf einem einzelnen Gerät nur das optimale Format bereitzustellen.
UV-Daten entpacken
Halten Sie die UV-Insel so gerade wie möglich. Dies verbessert die Textur auf folgende Weise:
- Das Packen von UV-Inseln ist einfacher, was weniger Platz verschwendet.
- Glatte UVs verringern den „Treppeneffekt“ auf Texturen.
- Eine gute UV-Strahlung sorgt für eine optimale Auflösung der Textur.
- Texturierung mit besserer Qualität, selbst wenn UVs beim Ausrichten leicht verzerrt sind.
Sichtbare Texturnähte an einem Modell sehen schlecht aus. UV-Nähte sollten an Stellen platziert werden, an denen sie weniger gut sichtbar sind. Teilen Sie die UV-Insel so auf, dass die Kanten scharf sind, und lassen Sie um die Insel herum etwas Platz, um bessere normale Karten zu erstellen.
Nicht wahrnehmbare Details vermeiden
Füge beim Gestalten von Kunstwerken keine Details hinzu, die man nicht sieht, insbesondere bei Spielen, die für Geräte mit kleineren Bildschirmen entwickelt wurden. Eine detailreiche Textur mit 4.096 × 4.096 Pixeln entsteht bei einem kleinen Stuhlmodell, das in der Ecke eines Raums kaum zu sehen ist, verschwendet. In bestimmten Fällen müssen Sie die Kanten (also zusätzliche Markierungen) und Schattierungen übertreiben, um die Wahrnehmung der Form zu verbessern.
Angaben zum Backen
Mobilgeräte haben kleinere Bildschirme und weniger leistungsfähige Grafikhardware als Computer oder Spielekonsolen. Anstatt Effekte wie Umgebungsverdeckung oder spiegelnde Hervorhebung während der Laufzeit zu berechnen, sollten Sie sie nach Möglichkeit in der diffusen Textur „verankern“. Dies verbessert die Leistung und sorgt für die Sichtbarkeit Ihrer Details.
Farbtöne verwenden
Wenn Sie die Möglichkeit haben, benutzerdefinierte Shader zu erstellen und Netze mit einem ähnlichen oder einheitlichen Farbschema zu verwenden, sollten Sie eventuell entsprechende Farbtöne verwenden. Bei der Farbabfärbung wird eine Graustufentextur verwendet, die weniger Texturspeicher benötigt als eine RGB-Textur. Der Shader wendet die Farbdaten pro Scheitelpunkt an, um das Mesh einzufärben. Alternativ können Sie eine RGB-Maske verwenden und die Textur basierend auf dem Farbbereich der Maske anwenden.
Texturkanäle packen
Suchen Sie beim Rendern von Materialien mit mehreren Texturen nach Möglichkeiten, Texturen, die nur einen einzelnen Farbkanal verwenden, zu einer einzigen Textur zu kombinieren, die alle drei Farbkanäle nutzt. Dies reduziert die Arbeitsspeichernutzung und reduziert die Anzahl der vom Fragment-Shader ausgeführten Textur-Sampler-Vorgänge.
Weisen Sie beim Packen die detailliertesten Daten dem grünen Kanal zu. Da das menschliche Auge empfindlicher für Grün ist, weist die Grafikhardware dem Grünkanal in der Regel mehr Bit zu. Beispielsweise weist eine Karte mit Rauheit/Glättung in der Regel mehr Details auf als eine metallische Karte und eignet sich besser für den Grünkanal.
Wenn Sie bei Materialien, die einen Alphakanal verwenden, nur zwei Kanäle in der gepackten Textur verwenden, sollten Sie die Alphakanaldaten anstelle der diffusen Textur in die gepackte Textur einfügen. Je nach Format der diffusen Textur kann dies helfen, ihre Größe zu reduzieren oder ihre visuelle Qualität zu verbessern, indem die Alphakanaldaten weggelassen werden.
Achten Sie darauf, dass Ihre Texturen auf einen linearen RGB-Farbraum und nicht auf sRGB eingestellt sind.
Normale Karten erstellen
Bei der normalen Zuordnung werden einem 3D-Modell Details hinzugefügt, ohne dass zusätzliche Geometrie verwendet wird. Merkmale wie Falten oder Bolzen, für die viele Dreiecke zur Modellierung erforderlich sind, können mit einer normalen Karte simuliert werden. Eine normale Zuordnung kann je nach Grafikstil und Richtung des Spiels angemessen sein oder nicht.
Normale Karten verursachen gewisse Leistungskosten und sollten auf günstigeren Geräten sparsam verwendet werden. Für die normale Karte ist eine zusätzliche Textur erforderlich, die zu zusätzlichen Textur-Sampling und Fragment-Shader-Berechnungen führt.
Normale Best Practices für Karten
Im Folgenden finden Sie einige Best Practices für die normale Kartenerstellung:
Verwende einen Käfig
Ein Käfig ist eine größere oder nach außen geschobene Version Ihres niedrigen Polygonmodells. Sie muss das High-Polygon-Modell umfassen, damit sie während der normalen Kartenverankerung gut funktioniert. Der Käfig wird verwendet, um die Raycast-Entfernung während des normalen Verankerns von Karten zu begrenzen und Probleme mit geteilten normalen Nähten auf der normalen Karte zu vermeiden.
Backabgleich nach Name des Mesh-Netzwerks
Wenn Ihre Backsoftware dies unterstützt, können Sie den Back-End-Abgleich nach Name des Mesh-Netzwerks durchführen. Mit dieser Funktion wird das Problem einer falschen normalen Kartenprojektion verringert. Wenn Objekte zu nah beieinander sind, kann es sein, dass ihre normale Karte unerwartet auf die falsche Fläche projiziert wird. Der Abgleich nach Name des Mesh-Netzwerks sorgt dafür, dass nur auf der richtigen Oberfläche gebacken wird. Weitere Informationen zu dieser Funktion in Substance Painter finden Sie auf dieser Seite. Weitere Informationen zu dieser Funktion der Marmoset Toolbag finden Sie auf dieser Seite.
Das Mesh-Netzwerk explodieren
Wenn Sie beim Backen keine Übereinstimmung mit dem Namen des Mesh-Netzwerks herstellen können, sollten Sie Ihr Mesh-Netzwerk explodieren. Wenn das Mesh-Netzwerk explodiert, werden Teile voneinander wegbewegt, sodass die normale Karte nicht auf die falsche Oberfläche projiziert wird. Wenn Sie auch auf Umgebungsverdeckungen backen, müssen Sie dies möglicherweise separat mit einem nicht explodierten Netz durchführen.
Minimierte Nähte
Kontinuierliche UV-Strahlung an harten Kanten führt zu sichtbaren Nähten. Teilen Sie den UV an harten Kanten auf, um diesen Effekt zu minimieren. Als Faustregel gilt beim Festlegen von Glättungsgruppen, einen Winkel von weniger als 90 Grad zu halten. UV-Nähe müssen auf den Dreiecken eine andere Glättungsgruppe haben.