Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   [Andorra] Verschwindende Lücken zwischen Sprites (https://www.delphipraxis.net/153512-%5Bandorra%5D-verschwindende-luecken-zwischen-sprites.html)

Codewalker 5. Aug 2010 19:52

[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.

blackfin 6. Aug 2010 00:19

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:

Die s/t-Koordinate wird auf die Reichweite [0,1] beschränkt und ist nützlich wenn Umwicklungsartifakte beim Mapping eines einzelnen Bildes auf ein Objekt vermieden werden sollen.
Die Standard-Einstellungen für GL_TEXTURE_WRAP_S und GL_TEXTURE_WRAP_T sind GL_REPEAT und genau das kann diese schwarzen Ränder auslösen.

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:
Tiling Textures Without Seams

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.

Codewalker 6. Aug 2010 09:33

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.

igel457 6. Aug 2010 14:37

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:
FParent.Direct3DDevice9.SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
FParent.Direct3DDevice9.SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
Wobei du "WRAP" durch eins von "MIRROR", "CLAMP", "BORDER" und "MIRRORONCE" ersetzen kannst.

Codewalker 6. Aug 2010 15:19

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.

igel457 6. Aug 2010 15:34

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.

blackfin 6. Aug 2010 15:58

AW: [Andorra] Verschwindende Lücken zwischen Sprites
 
Zitat:

Ich schätze das Problem liegt weniger an den Filtereinstellungen (sonst hätten die auch was gebracht), sondern an Rechenungenauigkeiten in der Grafikkarte.
Mhm...das halte ich für unwahrscheinlich, da die Grösse nicht dafür ausreicht, um die Fliesskommapräzision durcheinanderzubringen.
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:

Das Problem ist jedoch definitiv nicht Andorra 2D spezifisch
Das denke ich auch, damit haben wirklich viele zu kämpfen. Ich kenne solche Risse sogar aus z.B. WoW. Aber die hier sind schon extrem...


@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.

Codewalker 6. Aug 2010 16:01

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

blackfin 6. Aug 2010 16:07

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!)

igel457 6. Aug 2010 16:10

AW: [Andorra] Verschwindende Lücken zwischen Sprites
 
Verwendest du eigentlich eine eigene Projektions/Viewmatrix oder verwendest du ausschließlich TAdDraw.Setup2DScene() für das Erstellen dieser Matrizen? Ich bin nochmal meine bisherigen Projekte durchgegangen: Das Problem trat nur dann auf, wenn ich in die Karte reingezoomt/rausgezoomt habe. Solange die Viematrix genau auf die Größe des Viewports eingestellt war gab es dieses Problem nicht.

Edit:
Beispielbild ist hier:
Die einzelnen Kacheln sind durch die dicken weißen Kreuze abgegrenzt. Schwarze Striche gab es dort nicht...

Codewalker 6. Aug 2010 19:19

AW: [Andorra] Verschwindende Lücken zwischen Sprites
 
Zitat:

Zitat von blackfin (Beitrag 1040059)
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!)

Nein, die Quellbilder sind PNGs mit Alphatransparenz.
Zitat:

Zitat von igel457 (Beitrag 1040061)
Verwendest du eigentlich eine eigene Projektions/Viewmatrix oder verwendest du ausschließlich TAdDraw.Setup2DScene() für das Erstellen dieser Matrizen? Ich bin nochmal meine bisherigen Projekte durchgegangen: Das Problem trat nur dann auf, wenn ich in die Karte reingezoomt/rausgezoomt habe. Solange die Viematrix genau auf die Größe des Viewports eingestellt war gab es dieses Problem nicht.
Edit:
Beispielbild ist hier:
Die einzelnen Kacheln sind durch die dicken weißen Kreuze abgegrenzt. Schwarze Striche gab es dort nicht...

Das kann es sein. Ich nutze die SpriteEngineEx um rauszoomen zu können, aber die Fehler treten auch auf bei einem Zoomfaktor von 1. Oder kann es am Resize liegen? Mein Fenster ist in der Größe veränderbar. Im Resize mache ich folgendes:
Delphi-Quellcode:
      AdDraw.Setup2DScene;
      AdDraw.Restore;
Was müsste ich denn tun, damit die Viewmatrix genau passt? (auf den Zoom würde ich nur ungerne verzichten).

Codewalker 8. Aug 2010 21:21

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)

himitsu 8. Aug 2010 21:50

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".

Codewalker 8. Aug 2010 22:12

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.

blackfin 9. Aug 2010 08:32

AW: [Andorra] Verschwindende Lücken zwischen Sprites
 
Zitat:

Das OpenGL-Plugin ist überhaupt nicht nutzbar
Das macht mich jetzt allerdings anderweitig irgendwie stutzig....welche Grafikkarte hast du denn und hast du evtl. einen alten Treiber installiert?
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.

Codewalker 9. Aug 2010 09:13

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 .

Codewalker 9. Aug 2010 09:44

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

blackfin 9. Aug 2010 10:09

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! ;))

Codewalker 9. Aug 2010 10:22

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.

blackfin 9. Aug 2010 11:20

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:
AdTextureOffset := 0 ;
nach
Delphi-Quellcode:
SpriteEngine.Zoom := 1.0;
setze, also:

Delphi-Quellcode:
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;
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 :):
Delphi-Quellcode:
function TDXApplication.GetTextureOffset: single;
begin
  result := 0.5;
end;

Codewalker 9. Aug 2010 11:52

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.

blackfin 9. Aug 2010 12:52

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).

igel457 9. Aug 2010 12:53

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:
http://msdn.microsoft.com/en-us/libr...=VS.85%29.aspx

Edit: Das hier ist das Wichtigste aus dem Artikel:
Zitat:

Zitat von MSDN
The best approach is to use nearest-point filtering only when necessary. When you must use it, it is recommended that you offset texture coordinates slightly from the boundary positions to avoid artifacts.


blackfin 9. Aug 2010 13:39

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:
function TDXApplication.GetTextureOffset: single;
begin
  result := -0.5;
end;
II.
Delphi-Quellcode:
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;
Dann braucht man das AdTextureOffset := 0; nicht mehr und man kann auch bilinear oder anisotropisch filtern.

igel457 9. Aug 2010 13:49

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)

Medium 9. Aug 2010 13:52

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.

blackfin 9. Aug 2010 13:56

AW: [Andorra] Verschwindende Lücken zwischen Sprites
 
Zitat:

-0.5 ist eigentlich sehr seltsam
Mhm, warum macht das dann jeder so?
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:

...If you are using D3DTEXF_POINT (point filtering) to filter your texture, and you video card just happens to round the texture address in the right direction, it’ll work. But it won’t necessarily on every machine, and it won’t if you use bilinear filtering.

How can you tell it’s going wrong? Use a texture the same size as your render target, and observe the top row and left column of rendered pixels. It’s easiest if you use D3DTADDRESS_WRAP texture addressing.You’ll notice they aren’t quite right.

What’s going wrong? It turns out that DirectX addresses surfaces and textures a little bit differently. With a surface, the coordinate (0,0) (not considering any viewport transforms) lies directly in the center of the top-left pixel. With a texture, on the other hand, the coordinate (0,0) lies on the top-left corner of the top-left pixel. So what happens if you map (0,0) on the surface to (0,0) on the texture? You’re actually mapping the upper-left pixel of your rendering surface to a corner of the texture shared by 4 pixels–which means you may get an even blend of the 4 pixels, or if you use point filtering your GPU will choose one of those pixels for you. If you’re lucky, it’ll be the one you want.

How to fix it? Your texture coordinates need to be offset by half a pixel, so that the top-left pixel of the surface maps to coordinate (PWidth/2, PHeight/2), where PWidth and PHeight are the relative height and width of each pixel in texture space. You can make this correction in your vertex buffer’s UV coordinates, but personally I don’t like that solution since it doesn’t automatically scale to different-sized textures. You can also use a transform matrix to move your quad left and up half a pixel in surface space...
Das heisst also, wenn man 0/0 von einer D3D-Textur auf ein D3D-Surface mappt, entstehen links und oben Lücken von einer halben Pixel Breite, da die Grafikkarte sich einen Pixel von 4 Pixeln sucht, der passt. Durch das verschieben der Text-Koordinaten in den negativen Bereich, so dass die beiden wieder direkt aufeinander liegen, stimmts dann wieder.

Medium 9. Aug 2010 14:10

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.

Codewalker 9. Aug 2010 14:14

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