Warum werden PNGs konvertiert?
Warum werden PNGs konvertiert?
Warum werden beim Erstellen des Spiel eigentlich alle PNGs nach JPEG konvertiert? Hat das einen speziellen Grund, dass die Engine nur JPEGs laden kann?
Der Grund, warum es mich etwas stört ist, dass ich in meinem Spiel ausschließlich PNGs verwende (ich zeichne mit Inkscape) und das Erstellen mittlerweile eine ganze Weile dauert - und das auf einem doch recht aktuellen System . Außerdem erkennt man an einigen Stellen doch recht deutlich unschöne JPEG-Kompressionsartefakte.
Der Grund, warum es mich etwas stört ist, dass ich in meinem Spiel ausschließlich PNGs verwende (ich zeichne mit Inkscape) und das Erstellen mittlerweile eine ganze Weile dauert - und das auf einem doch recht aktuellen System . Außerdem erkennt man an einigen Stellen doch recht deutlich unschöne JPEG-Kompressionsartefakte.
Sie kann schon nur würde damit dein Spiel In-Game locker 3x solange zum Laden der Grafiken und Räume brauchen. Und da ist es doch besser lieber du wartetest als das deine Spieler die Wartezeit abbekommen.Hat das einen speziellen Grund, dass die Engine nur JPEGs laden kann?
BTW : In einer laufenden PaC-DK Session werden die PNGs nur dann umgewandelt wenn du etwas an der Grafik Bibliothek geändert hast. Sonst wird die datei gfx.dat nicht extra neu erstellt. Wenn du also nur Skripte erstellst sollte das Erstellen nicht so lange dauern ab dem 2. Mal.
Und wegen der Artefakte... joa.. man kann super deutlich hingucken... man kann aber auch einfach spieler und sowas nie und nimmer bemerken
Die JPG Kompression bei der PNG Umwandlung liegt bei 85%.
Du meinst, weil PNGs größer sind als JPEGs? Das ist bei Fotos und Bildern mit vielen Mustern und Farbverläufen sicher der Fall. Wenn man hingegen ein Spiel im Comic-Stil zeichnet, mit vielen großen einfarbigen Flächen, ist PNG hingegen kleiner. Bei meinem Spiel sind alle Grafiken zusammen als PNG 1,81 MB groß. Die gfx.dat, die genau die gleichen Grafiken als umgewandelte JPEGs+Alphakanal enthält, ist hingegen 2,94 MB groß.
Welches Format besser ist (also kleiner und somit schneller lädt) hängt stark vom verwendeten Grafikstil ab. Darum fände ich es gut, wenn man im Editor einstellen könnte, ob die Grafiken konvertiert werden sollen oder nicht. Ich bin mir sicher, dass die meisten mit Paint oder Inkscape gezeichneten Spiele als PNG eher kleiner wären und schneller laden.
Bei der Konvertierung selbst könntest du in Erwägung ziehen, mehrere Dateien gleichzeitig zu konvertieren. Besondere Multithreading-Probleme dürften dabei nicht auftreten, weil die Konvertierungen ja völlig unabhängig voneinander laufen. Auf einem Quad-Core sollte die Konvertierung somit auch bis zu viermal so schnell laufen.
Über die Kompressionsartefakte würde ich mich übrigens auch nicht beschweren, wenn sie nicht ziemlich ins Auge fallen würden. Ich weiß, dass das bei anderen Grafikstilen nicht der Fall ist - für Fotos sind JPEGs super - aber hier ist es einfach nur hässlich. Ein Beispiel aus einer Comic-Zwischensequenz:
Der JPEG-Teil ist direkt aus der gfx.dat entnommen. Man sieht deutlich, dass die Buchstaben vor allem am Rand richtig dreckig aussehen.
Ich werde es in meinem Spiel jetzt einfach so belassen, aber es wäre schon ganz gut für die Zukunft, PNGs ohne Umwandlung zu unterstützen. Wenn jemand Fotos als PNG speichert, ist er schließlich selbst Schuld. Wenn du es richtig cool machen willst, kannst du natürlich auch zuerst konvertieren, dann bei jedem Bild checken ob die Dateigröße als PNG oder als PNG größer ist und das jeweils kleinere tatsächlich verwenden. Allerdings würde das bei der Erstellungszeit natürlich keinen Vorteil bringen.
Welches Format besser ist (also kleiner und somit schneller lädt) hängt stark vom verwendeten Grafikstil ab. Darum fände ich es gut, wenn man im Editor einstellen könnte, ob die Grafiken konvertiert werden sollen oder nicht. Ich bin mir sicher, dass die meisten mit Paint oder Inkscape gezeichneten Spiele als PNG eher kleiner wären und schneller laden.
Bei der Konvertierung selbst könntest du in Erwägung ziehen, mehrere Dateien gleichzeitig zu konvertieren. Besondere Multithreading-Probleme dürften dabei nicht auftreten, weil die Konvertierungen ja völlig unabhängig voneinander laufen. Auf einem Quad-Core sollte die Konvertierung somit auch bis zu viermal so schnell laufen.
Über die Kompressionsartefakte würde ich mich übrigens auch nicht beschweren, wenn sie nicht ziemlich ins Auge fallen würden. Ich weiß, dass das bei anderen Grafikstilen nicht der Fall ist - für Fotos sind JPEGs super - aber hier ist es einfach nur hässlich. Ein Beispiel aus einer Comic-Zwischensequenz:
Der JPEG-Teil ist direkt aus der gfx.dat entnommen. Man sieht deutlich, dass die Buchstaben vor allem am Rand richtig dreckig aussehen.
Ich werde es in meinem Spiel jetzt einfach so belassen, aber es wäre schon ganz gut für die Zukunft, PNGs ohne Umwandlung zu unterstützen. Wenn jemand Fotos als PNG speichert, ist er schließlich selbst Schuld. Wenn du es richtig cool machen willst, kannst du natürlich auch zuerst konvertieren, dann bei jedem Bild checken ob die Dateigröße als PNG oder als PNG größer ist und das jeweils kleinere tatsächlich verwenden. Allerdings würde das bei der Erstellungszeit natürlich keinen Vorteil bringen.
Habe erst beim dritten Hinsehnen erkannt, wo denn jetzt eigentlich der Unterschied ist zwischen den beiden Bildern. Aber ich weiß was du meinst: bei meinem Spiel mit 320*240er Auflösung sah es durch die Kompression plötzlich so aus, als hätte mein zusammengepixelter Charakter plötzlich Akne bekommen.
Würde diesbezügliche Einstellmöglichkeiten also auch begrüßen.
Würde diesbezügliche Einstellmöglichkeiten also auch begrüßen.
[img]http://img269.imageshack.us/img269/4060/enjoylachibalken.png[/img]
die es aber nicht geben wird.. ich dachte eigentlich das Argument der 3-fachen Ladezeiten würde für sich sprechen völlig unabhängig von Dateigrößen und Unterschieden die man nur wahrnimmt wenn man längere Zeit und sehr Nahe sich die Grafiken anguckt... KEIN NORMALER Spieler wird das aber tun. Aber überlange Ladezeiten DAS fällt Leuten auf.Würde diesbezügliche Einstellmöglichkeiten also auch begrüßen.
Und nein, ich kann jetzt auch nicht hingehen und mir sagen : Müsst ihr ja wissen was euch wichtiger ist, weil : Der direkte PNG support ist in der Spieleengine nicht einfach nur durch einen Schalter ausgestellt. Da müsste ich schon etwas mehr dran machen und das würde ich nur wenn MIR der Nutzen dieser Arbeit wirklich einleuchten würde.
Du sprichst immer von einer längeren Ladezeit. Womit hast du die denn gemessen? Bist du sicher, dass der Grund nicht eine höhere Dateigröße war? Ich hab gerade danach gegoogelt, aber ich konnte nur einen Vergleich zwischen Lossless JPEG und PNG finden und dabei war PNG ca fünfmal schneller zu dekodieren. Ich kann mir irgendwie nicht vorstellen, dass normales JPEG so viel schneller sein sollte.
Es würde mich nicht wundern, wenn der Flaschenhals tatsächlich das Lesen von der Festplatte ist. Ich habe gerade versucht, es mit Hilfe von Irfan View zu testen, weil dort ja auch die benötigte Zeit zum Laden des Bildes angezeigt wird, aber das war sowohl beim PNG als auch beim JPEG 16 Millisekunden für mein 800x600 Testbild. Es ist aber auch gut möglich, dass diese Zahl einfach ungenau ist. Beim (komplett weißen) Alphakanal-JPEG zeigt er mir z.B. 0 ms an. Für eine wirklich sinnvolle Aussage kommt man wohl nicht darum herum, eine größere Menge Bilder zu verwenden und sie direkt mit den Funktionen zu dekodieren, die du verwendest.
Wenn ich Recht habe, und es tatsächlich in erster Linie von der Dateigröße abhängt, würde die Ladezeit bei meinem Spiel (und anderen in einem ähnlichen Stil gehaltenen) durch Verwendung von PNGs sinken. Denn wie bereits erwähnt brauchen die Grafiken meines Spiels als JPEG über 50% mehr Speicherplatz (bei manchen einzelnen Bildern ist es sogar fast das Doppelte).
Es würde mich nicht wundern, wenn der Flaschenhals tatsächlich das Lesen von der Festplatte ist. Ich habe gerade versucht, es mit Hilfe von Irfan View zu testen, weil dort ja auch die benötigte Zeit zum Laden des Bildes angezeigt wird, aber das war sowohl beim PNG als auch beim JPEG 16 Millisekunden für mein 800x600 Testbild. Es ist aber auch gut möglich, dass diese Zahl einfach ungenau ist. Beim (komplett weißen) Alphakanal-JPEG zeigt er mir z.B. 0 ms an. Für eine wirklich sinnvolle Aussage kommt man wohl nicht darum herum, eine größere Menge Bilder zu verwenden und sie direkt mit den Funktionen zu dekodieren, die du verwendest.
Wenn ich Recht habe, und es tatsächlich in erster Linie von der Dateigröße abhängt, würde die Ladezeit bei meinem Spiel (und anderen in einem ähnlichen Stil gehaltenen) durch Verwendung von PNGs sinken. Denn wie bereits erwähnt brauchen die Grafiken meines Spiels als JPEG über 50% mehr Speicherplatz (bei manchen einzelnen Bildern ist es sogar fast das Doppelte).
Ich arbeite auch mit 320*240, konnte aber derartige Effekte noch nie beobachten. Ich verwende für Objekte und sowas immer PNG, aber wenn die PNG vorher scharfkantig war, ist sie das auch nachher und wenn sie nen Verlauf hatte, hat sie den auch nachher. Mir ist nichts aufgefallen.Lachi wrote:bei meinem Spiel mit 320*240er Auflösung sah es durch die Kompression plötzlich so aus, als hätte mein zusammengepixelter Charakter plötzlich Akne bekommen.
@Benni: Natürlich gibt es einen Unterschied zwischen dem JPEG und PNG bei deiner Beispielgrafik, aber der ist so gering, dass ich als Spieler das wirklich nie bemerkt hätte.
Und hättest du nicht gesagt, dass da ein Unterschied ist, hätte ich ihn auch hier nicht bemerkt. Vielleicht habe ich einfach kein so scharfes Auge für sowas, aber ich denke, dass das bei 80% der Spieler ebenso ist. Deshalb würde ich mir nicht allzugroße Sorgen machen.
Tut mir leid, ich habs wirklich versucht. Aber ich sehe keinen Unterschied!Benni wrote:Über die Kompressionsartefakte würde ich mich übrigens auch nicht beschweren, wenn sie nicht ziemlich ins Auge fallen würden. Ich weiß, dass das bei anderen Grafikstilen nicht der Fall ist - für Fotos sind JPEGs super - aber hier ist es einfach nur hässlich. Ein Beispiel aus einer Comic-Zwischensequenz:
MfG
HeXoR
[img]http://www.hexorarts.de/gifs/Gifs/smily629.gif[/img][img]http://www.hexorarts.de/gifs/Gifs/smily630.gif[/img]
HeXoR
[img]http://www.hexorarts.de/gifs/Gifs/smily629.gif[/img][img]http://www.hexorarts.de/gifs/Gifs/smily630.gif[/img]
Danke...Schiman wrote: @Benni: Natürlich gibt es einen Unterschied zwischen dem JPEG und PNG bei deiner Beispielgrafik, aber der ist so gering, dass ich als Spieler das wirklich nie bemerkt hätte.
Und danke...Tut mir leid, ich habs wirklich versucht. Aber ich sehe keinen Unterschied!
Und nein, es liegt nicht an der Dateigröße. Die lange Zeit entsteht durch das trennen vom normalem Bild zum Alphakanal, die, um als Textur geladen werden zu können, einzeln geladen werden müssen. Die Dateigröße ist dabei wurscht, da zählt nur die Auflösung und die ist Formatunabhängig gleich beim selben Bild. Deswegen wird ja beim Spielerstellen getrennt und die beiden Teile (RGB + Alpha) als zwei JPGs gespeichert die zusammen IMMER sehr viel schneller laden als ein PNG.
Und ich habs tatsächlich in Sekunden gemessen mit einem absichtlich überfüllten Raum.
@ Hexor : Das Rot des linken Krachs ist gaaaanz leicht weniger kräftig und es gibt eine haaaaaaaauchzarte Outline linie die bei JPGs bei krassen direkten Farbübergängen entsteht... was aber kein Schwanz sieht. Zumal dieses KRACH wahrscheinlich ohnehin nur 1 Sekunde oder so zu sehen ist. Bei den Dingern unten links seh ich nämlich nichts!
ich sehe den unterschied in den bilder zwar, finde ihn aber nicht so drastisch.
ich selbst hatte auch noch nie darstellungsprobleme. meine pngs sehen im erstellten spiel immer gut aus und so, wie ich sie mir wünsche
ich selbst hatte auch noch nie darstellungsprobleme. meine pngs sehen im erstellten spiel immer gut aus und so, wie ich sie mir wünsche
[img]http://img268.imageshack.us/img268/8757/bannerkke.gif[/img]
Feed the flames and set them dancing!
Feed the flames and set them dancing!
Ich finde, man sieht recht deutlich an den Rändern, vor allem beim A und beim Ausrufezeichen, dass dort ein dunkler ausgefranster Rand entsteht und außerdem ist das Rot insgesamt dunkler und mit hellen und dunklen Flecken übersät. Aber da es außer mir hier niemandem sonderlich aufzufallen scheint, ist es wohl wirklich nicht so schlimm.Hexor wrote:Tut mir leid, ich habs wirklich versucht. Aber ich sehe keinen Unterschied!
Ah, danke für die Erklärung! Ich wusste nicht, dass man den Alphakanal erst trennen muss. Ich dachte immer, RGBA würde direkt von OpenGL unterstützt werden. Aber wahrscheinlich machst du noch von der Engine selbst her Abfragen auf den Alphakanal, um durch transparente Teile eines Objekts hindurchklicken zu können, da hatte ich nicht dran gedacht.Zimond wrote:Und nein, es liegt nicht an der Dateigröße. Die lange Zeit entsteht durch das trennen vom normalem Bild zum Alphakanal, die, um als Textur geladen werden zu können, einzeln geladen werden müssen. Die Dateigröße ist dabei wurscht, da zählt nur die Auflösung und die ist Formatunabhängig gleich beim selben Bild. Deswegen wird ja beim Spielerstellen getrennt und die beiden Teile (RGB + Alpha) als zwei JPGs gespeichert die zusammen IMMER sehr viel schneller laden als ein PNG.
Und ich habs tatsächlich in Sekunden gemessen mit einem absichtlich überfüllten Raum.
Könntest du aber vielleicht über einfaches Multithreading beim Konvertieren nachdenken? Das sollte sich wirklich mit wenig Aufwand umsetzen lassen. Das Konvertieren passiert ja jedes Mal, wenn man das PacDK neu öffnet und das Spiel erstellt. Ein Update des bereits erstellten Spiels ist ja nur möglich, wenn das Programm in der Zwischenzeit nicht geschlossen wurde. Mein Spiel ist noch vergleichsweise klein und da dauert es schon ca. 3 Minuten. Ich will nicht wissen, wie lange das bei größeren Projekten dauert.
Eine andere Möglichkeit wäre, die konvertieren Bilder irgendwo im gleichen Ordner wie die Projektdatei zwischenzuspeichern, zusammen mit der Änderungszeit des Originalbildes. Dann kannst du einfach nur die Bilder neu konvertieren, die sich tatsächlich geändert haben. Das wäre dann aber glaube ich etwas mehr Aufwand.
wollt ich auch nur noch mal bestätigen.HeXoR wrote:
Tut mir leid, ich habs wirklich versucht. Aber ich sehe keinen Unterschied!
Man brauch hier wohl wirklich einen ultrahochauflösenden Bildschirm und Augen wie ein Adler, dass man die Makel entdeckt.
Wirklich der Rede nicht Wert.
Wenn man den PaC DK sonst auch als nicht 101% Pixelgenaues Programm (etwa bei den Walkmaps) akzepieren kann, sollte man das in dem Fall erst recht. Ich bin eh immer wieder erstaunt, wie gut letztendlich die Sachen aussehen können.
Einfach? OK. nehmen wir mal an das Spielerstellen läuft in einem eigenem Thread.. und während dessen änderst du was im Spiel und zack ist das erstellte Spiel durcheinander. Dazu müsste man schon eine komplette Kopie aller Spieldaten erstellen aus denen dann das Spiel erstellt wird womit dann aber jede Zeitersparniss hinfällig wäre. Dein zweiter Vorschlag is eher denkbar aber wie du sagtest nicht mal eben gemacht.Könntest du aber vielleicht über einfaches Multithreading beim Konvertieren nachdenken?
Nein, nicht das komplette Spiel-Erstellen in einen eigenen Thread auslagern.
Bisher hast du doch bestimmt irgendwo in einem Programm eine Schleife, die über alle Grafiken iteriert und für jede einzelne Grafik deine Konvertierungsfunktion aufruft. Und am Schluss packst du die ganzen konvertierten Grafiken dann in das Archiv.
Um das ganze mit Multithreading zu beschleunigen, musst du nur an dieser einen Schleife ansetzen. Ich kenne die Delphi-Syntax nicht, aber als Pseudocode würde es etwa so aussehen:
Deine eigentliche Funktion zum erstellen des Spiels läuft also immer noch im selben Thread wie der Editor. Es ist nicht möglich, während des Erstellens was am Spiel zu verändern. Die Funktion startet aber mehrere Hilfsthreads, die die Konvertierung erledigen und wartet bis die alle fertig sind. Das einzige, was du beachten musst, ist dass der Zugriff auf die Liste der zu konvertierenden Grafiken durch einen Mutex geschützt wird.
Bisher hast du doch bestimmt irgendwo in einem Programm eine Schleife, die über alle Grafiken iteriert und für jede einzelne Grafik deine Konvertierungsfunktion aufruft. Und am Schluss packst du die ganzen konvertierten Grafiken dann in das Archiv.
Um das ganze mit Multithreading zu beschleunigen, musst du nur an dieser einen Schleife ansetzen. Ich kenne die Delphi-Syntax nicht, aber als Pseudocode würde es etwa so aussehen:
Code: Select all
Mutex m
List images
function worker()
{
loop forever
{
m.lock()
if (images.empty)
{
m.unlock()
return
}
img = images.getFirstEntry()
images.removeFirstEntry()
m.unlock()
convertToJPEG(img)
}
}
function createGame()
{
List threads;
for i=1 to num_threads
{
Thread t = startThread(worker)
threads.add(t)
}
for each t in threads
{
joinThread(t)
}
}
die idee, die dateien zu überpüfen ob sie denn schon mal gespalten wurden und ob sie sich geändert haben halte ich aber für ganz gut. Kann ich aber wie gesagt auch nich mal eben reinmachen. Dazu muss ich auf jeden Fall ne neue Option einbauen damit jeder selber entscheiden kann ob er einen dauerhaften Temp Ordner behalten möchte.
Die Sache ist die. PNG's in JPEG's umwandeln lassen funktioniert nur dann gut für ein hochwertiges Adventure, wenn die Kompressionsrate nicht allzu stark ist. Wenn ich mir den PNG/JPEG-Vergleich von Benni anschaue, dann muss die Kompressionsrate (Qualität) bei ca. 50% liegen, damit man den Unterschied so stark sieht.
Vielleicht ist es möglich die Kompression zu verringern, so auf eventuell 20-30% oder die Qualität auf 70-80% (je nachdem wie du das machst), dann sollte man mit blossem Auge keinen Unterschied mehr erkennen.
Ich weiss wovon ich rede, bin seit vielen Jahren Designer.
Vielleicht ist es möglich die Kompression zu verringern, so auf eventuell 20-30% oder die Qualität auf 70-80% (je nachdem wie du das machst), dann sollte man mit blossem Auge keinen Unterschied mehr erkennen.
Ich weiss wovon ich rede, bin seit vielen Jahren Designer.