# LWJGL 2.9.2: Seltsamer Effekt beim Rendern (VertexShader Problem?)



## Times (25. Jan 2016)

Hallo - ich bins schonwieder (nicht der schonwieder )

in meinem letzten Thread ging es darum wie ich am besten viele verschiedene TerrainTexturen in einer zufällig generierten Welt darstelle und das funktioniert auch alles soweit.
Ich habe das ganze bereits mit mehreren Texturen und Transparenzwerten getestet und es funktioiniert soweit, zur Veranschaulichung in diesem Thread aber entfernt.
Ich verwende also zurzeit nur 7 verschiedene Grundtexturen welche verschiedene Ariale der Welt ausmachen (OCEAN, SEA, COAST, PLATEU, HILL, MOUNTAIN).

Die Texturdatei sieht in diesem Beispiel also aus (Lila Hintergrund zur Erkennung ob Fehler bei der Zuweisung auftreten!)





(Habe das Bild zur Veranschaulichung verkleinert!)

Die TexturIndex'e werden durch einen Höhenbereich ermittelt. So liegt das Plateu zwischen -0.2f und 0.5f wenn man die Höhe auf einen Bereich von -1 bis +1 umrechnet.

Zur Zeit ist jedes Arial durch eine gerade Trennung vom anderen Arial abgetrennt. Würde das folgende Problem gerne erst beheben bevor ich die Höhenwerte der Trennung noch ein wenig hin und herschiebe sodass es ein bisschen kurvig aussieht.

Wenn ich das ganze nun starte, mich auf einen Berg stelle und nach unten sehe, sieht das wie folgt aus:





Die roten "Blitz-Pfeile" (Mein tolles Bildbearbeitungsprogramm kann keine Pfeile!) zeigen auch schon den Effekt. 
Nun anfangs kann man meinen ich hätte an den Rändern falsche TexturKoordinaten verwendet, da diese so lila mäßig aussehen, der Shader also auf die falsche Koordinate in der Textur zurückgreift, aber das ist es nicht.
Habe die Ränder zunächst einmal herausgefiltert und mir die Index'e ausgeben lassen und die stehen richtig.

Das ganze tritt allerdings nur auf wenn ich mich weit entferne. Wenn ich näher herangehe sieht alles so aus wie es soll.
*ABER: *Wie bereits oben erwähnt habe ich der Textur extra einen lila Hintergrund gegeben.. zu Anfang war ich noch so naiv zu denken das dies nur zufällig so aussieht, aber Pustekuchen.. habe die Farbe auf pink, dann schwarz geändert und die Ränder nehmen genau diese Farbe an, was mich immer mehr verwirrt.

Im nächsten Schritt habe ich meinen TerrainFragmentShader kopiert und auf 1 Zeile dezimiert (Alle Licht, Schatten, Zeit Änderungen an der Farbe entfernt) und bis auf das alles etwas grell aussieht ist das Problem geblieben.

*outColor = texture(terrainTexture, pass_textureCoords);*

outColor = Ausgabewert der Farbe: vec4
terrainTexture = TexturDatei: sampler2D
pass_textureCoords = TexturKoordinaten (x und y jeweils zwischen 0 und 1): vec2 -> Werden vom TerrainVertexShader übergeben, aber dieser macht nichts mit den Koordinaten, also verändert diese nicht. Sie werden einfach nur weitergereicht.

Nun weit umher geredet.. ich würde behaupten liegt an der ViewMatrix im TerrainVertexShader.
Wie komme ich darauf: Je nachdem wie ich die Kamera drehe tritt das Problem auf und dann auch mal wieder nicht. 
Regeln dafür wann die Probleme auftreten:
- Je weiter die Kamera entfernt ist, desto stärker tritt der Effekt auf
- Je weiter Pitch-Rotation gen "Boden" geht, desto stärker tritt der Effekt auf. Wenn ich von oben schaue sieht alles okay aus, egal wie weit die Kamera entfernt ist.
- Über Änderung der Yaw-Rotation kann ich keine genaue Aussage machen, da zum einen die Pitch-Rotation nicht zu weit oben sein darf (2. Punkt) und sich deswegen beim ändern der Yaw-Rotation der Abstand zum "Boden" auch immer ändert und der Effekt mal auftritt und mal nicht (1. Punkt).

In dieser Welt: 
Pitch: Rotation um die X-Achse
Yaw: Rotation um die Y-Achse
_Erklärungen hierfür sind im Internet nicht immer gleich, habe auch mehrere Definitionen gesehen in der bei Pitch von der Z-Achse ausgegangen - also nicht wundern wenn ihr es etwas anders kennt!_

ViewMatrix Erstellung:

```
Matrix4f matrix = new Matrix4f();
        matrix.setIdentity();
        Matrix4f.rotate((float)Math.toRadians(camera.getPitch()), new Vector3f(1, 0, 0), matrix, matrix);
        Matrix4f.rotate((float)Math.toRadians(camera.getYaw()), new Vector3f(0, 1, 0), matrix, matrix);
        Vector3f cameraPos = camera.getPosition();
        Vector3f cameraPosNeg = new Vector3f(-cameraPos.x, -cameraPos.y, -cameraPos.z);
        Matrix4f.translate(cameraPosNeg, matrix, matrix);
```

Den TerrainVertexShader habe ich auch so weit wie möglich dezimiert um die Fehlerquelle schneller ausfindig zu machen.


```
vec4 worldPosition = transformationMatrix * vec4(position, 1.0);
    vec4 relPosCam = viewMatrix * worldPosition;
    gl_Position = projectionMatrix * relPosCam;

    pass_textureCoords = textureCoords;
```

transformationMatrix wird von Java übergeben: Matrix4f
position wird von Java übergeben: Vec3f
viewMatrix  wird von Java übergeben: Matrix4f
pass_textureCoords: Output an den TerrainFragmentShader!


Von nun an weiss ich nicht weiter wie ich es testen soll, da ich diese Zeilen nicht noch weiter dezimieren kann!

Ich hoffe so sehr das es ein simpler einfacher Fehler ist dem schonmal jemand passiert ist 

Falls jemand noch mehr Code braucht oder weitere Informationen möchte, einfach Bescheid geben bitte.

Grüße
Times


----------



## Baldur (13. Mrz 2016)

Wenn ich das jetzt richtig verstanden habe, dann sind bei dir alle Terrains in einer einzelnen Textur zusammengefasst?
Es gibt verschiedene Varianten, wie die GPU die Farbe berechnet, die dir für eine bestimmte Texturkoordinate zurückgegeben werden. Einstellen kann man das bei OpenGL mittels 
glTexParameteri(GL_TEXTURE_MIN_FILTER, x) bzw. glTexParameteri(GL_TEXTURE_MAX_FILTER, x)
Je nachdem, was du für x übergibst, wird eine andere Art Berechnung durchgeführt. Wenn du den Parameter auf GL_NEAREST stellst, wird vermutlich das passieren, was du erwartest und du bekommst direkt die Farbe an der entsprechenden Stelle. Der Nachteil daran ist, daß bei GL_NEAREST die Textur schnell pixelig aussehen kann, wenn man nahe heran geht.
Stellst du die Filteroption auf GL_LINEAR (was bei dir der Fall sein dürfte), dann nimmt sich die GPU jeweils die vier nächsten Pixel und vermischt deren Farben. Dadurch werden die Übergänge etwas weicher, aber es kann z.B. auch passieren, daß dir, wenn du auf eine Texturkoordinate nahe an dem rosa Teil zugreifst, dir auch diese Farbei mit rein gemischt wird und du so diese Kanten bekommst.

Am besten wäre es natürlich, wenn du statt einer Textur mit verschiedenen Terrains für jedes Terrain jeweils eine eigene Textur nimmst, bzw. ggf ein Textur-Array. Falls du später mal "richtige" Texturen für dein Terrain haben willst, also z.B. mit einer Struktur für den Sand, etc., dann willst du die Texturen vermutlich auch kacheln, was mit richtigen Texturen, die von Rand zu Rand durchgängig sind auch einfacher ist.


----------



## Times (30. Mrz 2016)

Hey 

Danke für die Antwort. Ich werde danach schauen wenn ich wieder zuhause bin (Kann noch etwas dauern), aber melde mich dann aufjedenfall nochmal =)

Liebe Grüße
Times


----------



## Times (2. Mai 2016)

Guten Morgen (Mittag)..

wie versprochen wollte ich mich nochmal melden. Es hat soweit alles funktioniert und ich bin glücklich 
Vielen Dank Baldur!

Grüße
Times


----------

