Interessante Fragestellung!

Nehmen wir an, dass du eine RGB 512x512 Textur im TGA Format hast und du hast mip_levels standardmäßig auf 4 stehen, dann generiert die engine für dich die mipmaps 256x256, 128x128 und 64x64 für dich. Die zweite 64x64 Textur erhält dann die mipmaps 32x32, 16x16 und 8x8. Das würde grob gerechnet bei 24bit pro Pixel fast genau 1 MB für beide Texturen bedeuten, ohne dass sich mipmap Stufen überlappen. Bei einer 256x256 Textur hingegen hast du bei mip_levels = 4 die Texturen 256x256, 128x128, 64x64, 32x32 und 32x32, 16x16, 8x8 und 4x4. Das wäre zusammen 259 KB und genau 3 KB mehr als notwendig, da die 32x32 Stufe doppelt vorhanden ist. Problem ist, dass bei großen Landschaften mit weiter Sicht sowieso ein mip_level Wert von > 4 vorteilhaft ist und du dann bei einer Textur und der Ersatztextur dann mehrere überlappende mipmaps hast.

Du kannst zwar durch den Einsatz von DDS und einer Einschränkung auf bestimmte mipmap Stufen die Generierung dieser reduzieren (also z.B. für 512x512 nur die 256x256 mipmap und für die 64x64 nur die 32x32 mipmap) und so dann wieder Speicher zu sparen, nur ist das vom Aufwand her natürlich erheblicher. Zwar kannst du das durch Batch-orientierte Programme wie die NVidia Texture Tools automatisieren, aber dann müsstest du vor jedem build ein update fahren, weil sich ja evtl die Grafiken verändert haben.

Ich weiß ja auch nicht, ob du shader mit Normalmaps usw. verwendest, da multipliziert sich der Aufwand dann nochmal enstprechend der Texturen, die du für jede Diffuse-Textur brauchst.

Ein weiteres Problem ist auch, dass die engine dann immer zwei Texturen führen muss und zusätzlichen overhead hat. Ich kann mir vorstellen, dass gerade bei statischen Entities, die dann damit ja nicht mehr statisch sind, zusätzliche Performance benötigt wird, die man somit verschwendet.

Eine viel einfachere, zugleich aber auch mächtigere Lösung wäre es, wenn du einen Shader verwendest, der beim Lookup tex2Dbias verwendet und du mit dem bias-Wert die Grenze, wann eine nächste Mipmap verwendet wird, entsprechend änderst. Du kannst auch theoretisch das Gamestudio-feature ausnutzen und techniques "lod0", "lod1", "lod2", or "lod3" ausnutzen, um die shader schrittweise abzuschalten und dann pro LOD Stufe z.B. den bias je nach LOD Stufe einzustellen. Die DIstanz der LOD Stufen stellst du dann über die d3d_lodfactor Variablen ein.

Wenn dir das zu kompliziert ist, kannst du auch einfach pro Entity die LOD0/LOD1 flags auswerten um den lod-step 0..3 zu berechnen und den dann über einen entity skill an den shader zu senden. Aufjedenfall ist es dann so oder so lohnenswert einfach mip_levels auf 8 oder sowas zu stellen und dann mit bias den miplevel im shader zu verwenden.

Du kannst mit den NVidia Texture Tools aus Einzelbildern komplett gemipmappedte Texturen zusammenstecken, allerdings weiß ich nicht wie sich das Tool verhält, wenn in der Kette welche fehlen und wie das aussieht, wenn dann im Shader darauf zugegriffen wird - ist das dann schwarz, wird die letzte mipmap-Stufe verwendet oder was? Naja, aber theoretisch könntest du dann selektiv deine Texturen ausdünnen (also mipmap Stufen rausnehmen), als DDS speichern (lädt schneller und ist komprimiert) und über den shader den bias-Wert verändern (nur eine Textur im Speicher und kein zusätzlicher overhead).

So würde ich das mal ausprobieren und testen. Auf jedenfall musst du dann mal einen Stresstest fahren, um zu gucken was sich performancemäßig ergibt. Es kann auch sein, dass das sprichwörtlich so matschig und kacke aussieht, dass du relativ schnell den Schluss ziehst, dass ihr das nicht macht wink

In jedem Fall empfehle ich, dass ihr euch für die Produktion des Spiels dafür eigens Kommandozeilentools schreibt, die die Modelle und deren Texturen automatisch aktualisieren und so weiter. Wenn Ihr da Hilfe braucht, kann ich euch gerne weiterhelfen.

Viel Erfolg,
-Christian

[EDIT] Achja, und es ist äußerst wichtig, dass Texturen, die mehrfach auf anderen Modellen benutzt werden, als externe Texturen verlinkt werden, damit die nur einmal in den Speicher geladen wird. Texturen die nur einmal im ganzen Spiel auf einem Modell vorkommen (oder nur einmal im ganzen Level), sollten hingegen intern abgespeichert werden, weil man sich dann den zusätzlichen Dateizugriff auf die Festplatte und die Dekompression bei WRS Archiven erspart - das Modell wird dann nur einmal geladen.

Last edited by HeelX; 07/02/12 13:00.