![]() |
[Andorra] Verschwindende Lücken zwischen Sprites
Ich habe ein seltsames Problem mit Andorra und weiß nicht, wo ich nach dem Fehler suchen soll. Ich baue für einen Hintergrund aus einzelnen Pergamentstücken eine Karte zusammen. Die Bilder werden dynamisch zusammengesetzt und sollten eigentlich perfekt passen. Leider zeigt mir Andorra zwischen den Bildern teilweise eine 1-pixel-breite unschafte Lücke an. Sobald ich die Kamera bewege, verschwinden an einigen Nahtstellen die Lücken und an anderen tauchen sie auf.
Was genau ist das? Rundungsfehler meinerseits sollten es nicht sein, weil ich nirgendwo Round verwende und die Koordinaten eigentlich alle ganzzahlig sind. Bin für jeden Hinweis dankbar, was das sein kann und wie man es loswerden kann. |
AW: [Andorra] Verschwindende Lücken zwischen Sprites
Liste der Anhänge anzeigen (Anzahl: 1)
Ich weiss jetzt nicht, wie genau intern Andorra arbeitet, aber ich habe eine Vermutung :glaskugel::
Ich hatte mal ein ähnliches Problem bei einem Shader an den Textur-Grenzen. Sieht dein Problem etwa in etwa so aus wie in meinem angehängten Screenshot? Das Problem bei mir war, dass es an der Präzision der Texturkoordinaten-Interpolation in meinem Shader lag und an den Rändern / Textur-Grenzen sozusagen aus dem "Nichts" gesamplet wurde, vor Allem wenn Mipmaps benutzt wurden. Sprich: An den Rändern werden die Randpixel durch das Filtering mit schwarz (="Nichts") geblendet, wodurch diese unscharfen Schwarz-Ränder entstehen. Bewegst du die Kamera (und du verwendest Mipmapping), kann es sein, dass der Effekt bei Nahen Tiles nicht auftritt, dafür bei entfernteren, oder umgekehrt, je nachdem wie du Filtering / Mipmapping usw. eingestellt hast. (Da ist die Variabilität ja gross :)) Um die Ursache des Problems bei dir herauszufinden, musst du wahrscheinlich in den Code von Andorra rein oder überprüfe mal deine Textur-Parameter. Das Problem kann generell an folgendem liegen: 1) Falsche Mipmap-Erstellung 2) Die Textur-Kompression hakt dazwischen 3) Du hast Wrapping für deine Textur an bzw. sie wird nicht geclampt. Dadurch entstehen an den Textur-Grenzen Sampling- /Blending-Fehler. Falls du mit OGL renderst: GL_TEXTURE_WRAP_S und GL_TEXTURE_WRAP_T bei der Funktion glTexParameter() auf GL_CLAMP setzen: Zitat:
Wie gesagt, das Problem muss man im Einzelfall runtertracken, und ich schätze mal, da läuft etwas mit der Texturbindung bzw. der Erstellung der Textur-Parameter in Andorra nicht ganz richtig oder du hast es falsch gesetzt, falls man das in Andorra pro Texture via dessen API einstellen kann. Eventuell hilft auch folgender Artikel dazu: ![]() Edit: Was du auch machen kannst: Erstelle doch mal ein kleines Testprojekt, bei dem der Fehler auftritt und lade es hoch. Ich kanns mir dann bei Gelegenheit mal ansehen und vielleicht finde ich den Fehler ja. |
AW: [Andorra] Verschwindende Lücken zwischen Sprites
Ja, das sieht meinem Problem sehr ähnlich. Danke für die ausführliche Erklärung, ich glaube ich weiß jetzt auch, wo mein Problem liegt. Leider kann ich das Andorra OpenGL Plugin derzeit nicht nutzen, weil dann nur noch Blödsinn angezeigt wird. Aber auch da muss man das ja einstellen können ... ich werde mich da mein einlesen.
|
AW: [Andorra] Verschwindende Lücken zwischen Sprites
Bei DirectX heißen die Parameter ganz ähnlich.
Du musst im DirectX-Plugin (DX3DMain) in der Funktion TDXBitmapTexture.SetFilter einfach mal folgendes einbauen:
Delphi-Quellcode:
Wobei du "WRAP" durch eins von "MIRROR", "CLAMP", "BORDER" und "MIRRORONCE" ersetzen kannst.
FParent.Direct3DDevice9.SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
FParent.Direct3DDevice9.SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP); |
AW: [Andorra] Verschwindende Lücken zwischen Sprites
Liste der Anhänge anzeigen (Anzahl: 2)
Habe alles durchprobiert inkl. verschiedener Filtereinstellungen - hat nicht wirklich geholfen. Anbei mal zwei Screenshots. Die Linien entstehen und verschwinden nur bei Kamerabewegung.
|
AW: [Andorra] Verschwindende Lücken zwischen Sprites
Ich schätze das Problem liegt weniger an den Filtereinstellungen (sonst hätten die auch was gebracht), sondern an Rechenungenauigkeiten in der Grafikkarte.
Ich glaube ich hatte dieses Problem auch mal irgendwo und bin letztendlich dazu übergegangen alle Kacheln einen Pixel überlappen zu lassen - ich gebe zu, dass das jedoch keine optimale Lösung ist. Das Problem ist jedoch definitiv nicht Andorra 2D spezifisch, sondern solche "Risse" treten auch bei Spielen immer wieder auf. |
AW: [Andorra] Verschwindende Lücken zwischen Sprites
Zitat:
Ich kenne solche Präzisionsfehler in derartiger Ausführung eigentlich nur dann, wenn man sich wirklich extrem vom Ursprung des Koordinatensystems entfernt. Die Striche gehen aber auch nicht durch, sondern sind teilweise geblendet. Das sieht man gut, wenn man mal in die Grafik reinzoomt. Deswegen denke ich schon, dass da ein Filtering zwischenpfuscht. Zitat:
@Codewalker: Was für eine Grafikkarte hast du denn? Und...kannst du nicht ein kleines Demo-Projekt erstellen, bei dem nur ein paar Tiles angezeigt werden? Dann könnte man mal gemeinsam auf Fehlersuche gehen. |
AW: [Andorra] Verschwindende Lücken zwischen Sprites
Ich schau mal, ob ich die Tage das ganze aus aus dem Projekt "raussezieren" und eine Mini-Demo erstellen kann, die das ganze reproduziert.
Grafikkarte ist eine Nvidia GeForce 9600 GT |
AW: [Andorra] Verschwindende Lücken zwischen Sprites
Was mir noch gerade auffällt: Sind deine Ursprungs-Bilder vielleicht JPEG's?
Wenn ja, nimm mal Bitmaps, sofern das geht und schau mal, ob sich da was ändert. (aber nicht einfach ein JPEG in ein Bitmap umwandeln, sondern es darf noch nicht komprimiert worden sein!) |
AW: [Andorra] Verschwindende Lücken zwischen Sprites
Zitat:
Zitat:
Delphi-Quellcode:
Was müsste ich denn tun, damit die Viewmatrix genau passt? (auf den Zoom würde ich nur ungerne verzichten).
AdDraw.Setup2DScene;
AdDraw.Restore; |
AW: [Andorra] Verschwindende Lücken zwischen Sprites
Liste der Anhänge anzeigen (Anzahl: 1)
Ich habe testweise mal die zoomfähige TSpriteEngineEx durch die normale TSpriteEngine ersetzt und den Quellcode entsprechend angepasst. Kostete Nerven und überhaupt nichts gebracht, die Lücken sind nach wie vor da :kotz:.
Das OpenGL-Plugin ist überhaupt nicht nutzbar (nur Fehlermeldungen mit Speicheradressen, nichts verwendbares bis jetzt), so dass ich Fins OpenGL-Befehle nicht testen kann. Immerhin habe ich etwas neues gefunden: Beim Scrollen fällt auf, dass selbst bei einem Zoom von 1.0 - also eigentlich keinem Zoom - es eine Art "Linie" gibt, entlang derer die Texturen verzerrt werden, so als ob die Projektion doch nicht 1:1 ist. Ich habe mal einen Screenshot angehangen und die Stellen markiert. Bewege ich die Kamera wandern diese Verzerrungen entsprechend mit. Ich hoffe das sagt Euch mehr als mir. Edit: Habe gemerkt, dass es mehrere solcher Linien gibt, die alle einen festen Abstand haben (der in etwa den Lücken zwischen den Sprites entspricht und daher immer nur eine Linie auf eine diagonale Feldkante Feld und sichtbar ist) |
AW: [Andorra] Verschwindende Lücken zwischen Sprites
Und der Vorschlag die Sprites ein Pixel überlappen zu lassen .. kann da was schlimmes bei rauskommen?
Wenn man den Bildern die selben Randpixel verpaßt, sollte es doch nicht auffallen. PS: Bei dem einen Beispielbild da oben wo es einmal mit und dann ohne diese Linien sein soll. Wenn man ganz genau hinsieht, dann sieht man in beiden Bildern diese Linie ... in der einen halt nur als "schwacher Schatten". |
AW: [Andorra] Verschwindende Lücken zwischen Sprites
Das Überlappen ist eine Lösung, aber keine schöne. Ich würde schon gerne wissen, wo das Problem liegt. Beim Hintergrund kann ich mit der Überlappung leben, auch wenn dann die Randanpassung der Texturen nahezu unnötig war. Aber was ist, wenn ich diese Streifen wieder in einer Situation habe, wo ich nicht überlappen lassen kann. Außerdem würde ich auch gerne diese Verzerrung loswerden und ich vermute, es ist beides das gleiche Problem.
|
AW: [Andorra] Verschwindende Lücken zwischen Sprites
Zitat:
Treiber-Schweinereien können teilweise auch sowas auslösen :D Bei mir laufen auf allen Rechnern, auf denen ich es bisher getestet habe (6 Stück) die Andorra-Demos einwandfrei mit OpenGL. (GeForce-, ATI-, Intel-Karten..ok, auf den Intel gehen die Shader-Demos nicht, aber das ist ja klar :)) Ansonsten...leider stecke ich in Andorra nicht drin, sprich ich habe noch nie damit gearbeitet / programmiert. Bevor ich mich jetzt da aber komplett auf die Schnelle einlese, wäre ein kleines Demo-Projekt wohl das Beste, um gemeinsam auf die Fehlersuche gehen zu können. Wenn ein Projekt läuft und ich es kompilieren kann, dann kann ich auch zum "Unit-Diving" übergreifen :D Edit: Ich habe auch schon öfters feststellen müssen, dass auf manchen Grafikkarten der VSync schuld ist, wenn Texturen so ähnlich verzerrt werden, wie es in deinem Screenshot sichtbar ist. Man sieht z.B. bei der GeForce 8er-Serie ziemlich oft bei Shootern / MMOs, wie sich Texturen während des Laufens in der vertikalen Bildschirmmitte zusammenschieben und auseinanderreissen, wenn der VSync aktiviert ist, gerade bei DirectX ist mir das besonders aufgefallen. Zwar halte ich es in deinem Fall für unwahrscheinlich, da die äusseren Umstände dafür in deinem Projekt nicht gegeben sind (nur bei schneller Bewegung sichtbar, Betrachtungswinkel auf die Textur >80°, perspektivische Kamera), aber schalte ihn doch einfach mal aus und schau, ob sich dabei etwas ändert. |
AW: [Andorra] Verschwindende Lücken zwischen Sprites
Der VSync war ein guter Tipp :thumb:. Habe den über die Nvidia-Systemsteuerung mal mit "Immer aus" vorgegeben und *tata*: Die Verzerrungen sind schonmal weg. Die Lücken sind leider geblieben (wäre auch zu einfach gewesen).
Karte ist eine Nvidia Geforce 9800GT, Treiber sind die aktuellsten Nvidia 258.96 . |
AW: [Andorra] Verschwindende Lücken zwischen Sprites
Liste der Anhänge anzeigen (Anzahl: 1)
So, habe das Demoprojekt fertig. Du brauchst natürlich noch die DirectX- bzw. OpenGL-DLLs aus dem Andorra-Paket (und Andorra selbst um es zu kompilieren). Ansonsten müsste alles dabei sein und ich habe versucht es auf das Wesentliche zu reduzieren.
Edit: Im Form-Create ist auch eine auskommentierte Variante für die OpenGL-DLL von Andorra. Wenn ich diese nehme, dann hagelt es Speicherfehler (ohne Exception). Wäre interessant, ob ihr das auch reproduzieren könnt |
AW: [Andorra] Verschwindende Lücken zwischen Sprites
Ok, läuft, und ich habe die Lücken auch!
Eine Frage: Wie bekomme ich die Bilder denn aus der .ail exportiert? Ich würde die gerne exportieren, um sie mir an den Rändern mal und wegen der Bemaßung anzusehen. (keine Sorge, ich brauch deine Bilder nicht! ;)) |
AW: [Andorra] Verschwindende Lücken zwischen Sprites
Liste der Anhänge anzeigen (Anzahl: 1)
Theoretisch mit dem Andorra ImageEditor, aber der exportiert soweit ich weiß nur BMP kein PNG mit Alphakanal. Habe die Bilder mal angehangen.
Wenn es ein Fehler in der Bemaßung wäre, ist das zwar peinlich, aber der wäre ja noch verhältnismäßig leicht zu korrigieren. |
AW: [Andorra] Verschwindende Lücken zwischen Sprites
*wuselwusel*
Aaaalso....irgendwie liegt das an der Konstanten "AdTextureOffset", die von Andorra in der DX3DMain.pas plötzlich beim Initialisieren auf 0.5 statt 0.0 gesetzt wird und deswegen die Texturen "unsauber" skaliert / positioniert werden (in TAdCustomImage.SetSrcRegion) Ich hab den Grund für das 0.5 Offset noch nicht gefunden, allerdings funktioniert es bei mir, wenn ich
Delphi-Quellcode:
nach
AdTextureOffset := 0 ;
Delphi-Quellcode:
setze, also:
SpriteEngine.Zoom := 1.0;
Delphi-Quellcode:
Ich glaube, für die Erklärung muss Igel sich zu Wort melden, warum in der DX3DMain das Texturen-Offset auf 0,5 gesetzt wird, statt auf 0.0, ich bin auch nicht so DirectX-firm :):
procedure TEditorForm.ResizeAndorra(Sender: TObject);
{ Wird ausgelöst, wenn die größe des Fensters verändert wird. Dann muss Andorra neu initialisiert werden, da sonst die Darstellung verzerrt ist } begin if Draw.Initialized then begin Draw.Setup2DScene; Draw.Restore; SpriteEngine.Zoom := 1.0; AdTextureOffset := 0 ; // <----------- HIER! Center := Point(ClientOrigin.X + (Width div 2), ClientOrigin.Y + (Height div 2)); end; end;
Delphi-Quellcode:
function TDXApplication.GetTextureOffset: single;
begin result := 0.5; end; |
AW: [Andorra] Verschwindende Lücken zwischen Sprites
Fin, du bist ein Genie :thumb:
Eine Ergänzung habe ich noch: Das ganze behebt den Fehler nur bzw. wird überhaupt berücksichtigt, wenn der Filter der ImageList auf adPoint steht. Setzt man ihn z.B. auf linear , dann bleiben die schwarzen Linien nach wie vor. |
AW: [Andorra] Verschwindende Lücken zwischen Sprites
Jaaaa, da haben wir eben diese netten Filtering-Fehler :D
Das ist fast klar, sobald du lineare/isotropische oder anisotropische Filterung einschaltest, bekommst du die ganze Wonne der Filtering-Fehler, die auf der ersten Seite besprochen wurden :D Man bekommt sie etwas "milder", wenn du eben das Clamping bei TDXBitmapTexture.SetFilter() aktivierst und die DLL neu kompilierst, allerdings sind sie so noch nicht ganz weg. Die inoffiziellen Lösungen für so etwas lauten, entweder mit dem (nervigen) Overlapping zu arbeiten, oder aber, was in deinem Fall wohl das bessere ist, beim Rendern von Tile-Sprites die Textur-Filterung abzuschalten. Viel bringen tut dir da (bi)lineare Filterung eh nicht und anisotropische gar nichts (ausser langsameres Rendern), da du ja direkt auf die Textur in einem 90°-Winkel schaust und somit der anisotropische Filter eh nichts machen würde (er muss ja keine verzerrte Poly-Form berechnen). |
AW: [Andorra] Verschwindende Lücken zwischen Sprites
Das mit dem Texture-Offset auf 0.5 setzen behebt eigentlich Sampling-Probleme mit der Point-Filterung, die unter anderem bei Font-Texturen sichtbar werden. Dabei bin ich eigentlich einem Tipp aus der MSDN gefolgt:
![]() Edit: Das hier ist das Wichtigste aus dem Artikel: Zitat:
|
AW: [Andorra] Verschwindende Lücken zwischen Sprites
Das Offset für DX3D9 gilt aber soviel ich weiss in die negative Richtung, also -0.5 statt +0.5.
Würde auch mehr Sinn machen, da negative Tex-Coordinaten ja erstmal undeifiniert sind und der Rasterizer dann wirklich bei 0 anfängt anstatt aufzurunden. Aber das übersteigt nun mein DirectX-Wissen wirklich :D Edit: Gerade ausprobiert, mit einem Offset von -0.5 wird es auch richtig gerendert. Edit II: Mit -0.5 geht dann auch der bilineare und der anisotropische Filter ohne Lücken! Allerdings nur, wenn man die Textur auch noch Clamped! Also ist die Lösung wohl denke ich mal, die DX3DMain.pas folgendermaßen zu verändern und dann die DLL neu zu klompilieren: I.
Delphi-Quellcode:
II.
function TDXApplication.GetTextureOffset: single;
begin result := -0.5; end;
Delphi-Quellcode:
Dann braucht man das AdTextureOffset := 0; nicht mehr und man kann auch bilinear oder anisotropisch filtern.
procedure TDXBitmapTexture.SetFilter;
var f: Cardinal; begin f := D3DTEXF_POINT; case FFilter of atPoint: f := D3DTEXF_POINT; atLinear: f := D3DTEXF_LINEAR; atAnisotropic: f := D3DTEXF_ANISOTROPIC; end; FParent.Direct3DDevice9.SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP); FParent.Direct3DDevice9.SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP); FParent.Direct3DDevice9.SetSamplerState(0, D3DSAMP_MAGFILTER, f); FParent.Direct3DDevice9.SetSamplerState(0, D3DSAMP_MINFILTER, f); if FHasMipMap then FParent.Direct3DDevice9.SetSamplerState(0, D3DSAMP_MIPFILTER, f) else FParent.Direct3DDevice9.SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_NONE); end; |
AW: [Andorra] Verschwindende Lücken zwischen Sprites
Hm, das wäre vielleicht wirklich sinnvoll...
Edit: Hmpf, wo war der rote Kasten... Danke für die Lösungen, ich schreibe mir das auf und werde das in Andorra 2D einarbeiten sobald ich mich wieder daran mache (so in spätestens drei Wochen) |
AW: [Andorra] Verschwindende Lücken zwischen Sprites
Der Hintergrund ist dabei der, dass bei Texturen die Koordinate (0,0) den oberen linken Rand des oberen linken Pixels (Texels) bezeichnet, und nicht wie bei Bitmaps die Mitte dieses Pixels. Texturen können ja via floats indiziert werden, und dabei landet man (wenn man die Koordinaten auf die Größe in Pixel skaliert, normal sind die ja immer 0..1) mit (X,0; Y,0) bis (X,999...; Y,999...) auf dem selben Pixel.
Mit Pointsampling ist das immer die selbe Farbe, ab linear schon nicht mehr. Dort ist dann die "eigentliche" Pixelfarbe bei (X,5; Y,5), alles drum herum wird mit den angrenzenden Pixels verrechnet. Und tada, hier ist unser Offset von 0,5. Roter Kasten: -0.5 ist eigentlich sehr seltsam. Spekulationen: Andorra verwendet irgendwo als Koordinatenbasis (1,1) statt (0,0) (unwahrscheinlich, aber so einen macht ja jeder mal), oooder die Obergrenzen sind falsch gesetzt: Eine Textur der Größe 512x512 hat die (skalierten) Koordinaten (0,0) bis (512,512) ABER(!) letzterer ist der unterste rechte Rand vom untersten rechten Pixel! (Genauer genommen schon so gerade eben darüber hinaus, und daher schon vom Wrapping betroffen.) Die Mitte davon wäre bei (511,5; 511,5). Macht man da also nun den beliebten Fehler die Größenangabe mit der Pixelindizierung gleichzusetzen (ein 8x8 Bitmap hat den letzten Pixel ja bei (7,7), nicht (8,8)), kann das auch ein möglicher Grund sein. Sowas passiert mir auch immer mal wieder gern. |
AW: [Andorra] Verschwindende Lücken zwischen Sprites
Zitat:
Google mal ein wenig, in den Quellcodes wird es eigentlich immer abgezogen, nicht addiert. Das Offset steht zwar auf +0.5, aber es wird von den TexCoordinaten immer abgezogen. Ok, hier ist die Erklärung. Es liegt am Unterschied der Koordinaten von D3D-Surfaces und -Texturen: Zitat:
|
AW: [Andorra] Verschwindende Lücken zwischen Sprites
Also ich habe in meinen Shadern bisher IMMER addiert, und da es dabei oftmals um GPGPU Krams ging, wäre das schon sehr aufgefallen, wenn das verkehrt gewesen wäre :). Auf gamedev.net gibts dazu eigentlich auch immer mal wieder einen Thread (ist da schon fast sowas wie unsere Floatvergleiche, die alle paar Wochen wieder mal vorbei schauen :D).
Sekunde! Ich mach es im Shader! Wenn man aber eine Textur so haben will, dass der Rand genau die Pixelmitten trifft, DANN muss man von den TexCoords im eigentlichen Programmcode 0,5 abziehen! Da kann es dann aber sein, dass durch Pointsampling irgendwo in der Textur eine Versatzlinie auftaucht. Und das würde sich mit dem Fall hier decken: Der "Sprung" (der irgendwie durch VSync gelöst wurde!?) sah aus wie ein 1px Zusammenstauchen mit Pointsampling, was bei +0,5 passierte. Mit -0,5 sollte irgendeine Zeile/Spalte gedoppelt vorkommen. Da schlägt dann wieder die Indizierung zu, nur genau anders herum: Wenn man nun vorher irgendwo die Koordinatenmaxima auf Größe-1 gesetzt hat, landet man bei (-0,5; -0,5) bis (510,5; 510,5) bei einer 512x512px Textur, obwohl es bis (511,5; 511,5) sein müsste. |
AW: [Andorra] Verschwindende Lücken zwischen Sprites
Fins Änderungen klappen wunderbar. Steht der Filter noch auf Point, dann entstehen aber die Verzerrungen an den Feldkanten, die ich weiter oben auf einem Screenshot gezeigt habe. Mit der geänderten DLL kann man den Filter problemlos auf linear setzen und es sind sowohl die schwarzen Linien verschwunden als auch die Verzerrungen.
Außerdem habe ich wieder eine Menge gelernt. Danke an alle für Zeit und Mühe :dp: |
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:28 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz