2017-01-23 5 views
0

Ich habe versucht, eine Heightmap zu meinem Terrain Shader zu implementieren, aber das Terrain bleibt flach. Die Textur wird in dem Vertex-Shader richtig geladen, und ich versuche, die Grauwert der Textur auf der UVS der Masche auf Basis zu verwenden, um die Scheitelhöhe einzustellen:OpenGL: Gelände Deformation mit einer Heightmap im Vertex Shader

//DIFFUSE VERTEX SHADER 
#version 330 

uniform mat4 projectionMatrix; 
uniform mat4 viewMatrix; 
uniform mat4 modelMatrix; 

in vec3 vertex; 
in vec3 normal; 
in vec2 uv; 

uniform sampler2D heightmap; 

out vec2 texCoord; 

void main(void){ 

vec3 _vertex = vertex; 
_vertex.y = texture(heightmap, uv).r * 2.f; 
gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(_vertex, 1.f); 
texCoord = uv; 

} 

Fragment: (die splatmap Werke, die so ignorieren)

uniform sampler2D splatmap; 
uniform sampler2D diffuse1; 
uniform sampler2D diffuse2; 
uniform sampler2D diffuse3; 
uniform sampler2D diffuse4; 

in vec2 texCoord; 
out vec4 fragment_color; 

void main(void) { 
///Loading the splatmap and the diffuse textures 
vec4 splatTexture = texture2D(splatmap, texCoord); 
vec4 diffuseTexture1 = texture2D(diffuse1, texCoord); 
vec4 diffuseTexture2 = texture2D(diffuse2, texCoord); 
vec4 diffuseTexture3 = texture2D(diffuse3, texCoord); 
vec4 diffuseTexture4 = texture2D(diffuse4, texCoord); 
//Interpolate between the different textures using the splatmap's rgb values (works) 
diffuseTexture1 *= splatTexture.r; 
diffuseTexture2 = mix (diffuseTexture1, diffuseTexture2, splatTexture.g); 
diffuseTexture3 = mix (diffuseTexture2,diffuseTexture3, splatTexture.b); 
vec4 outcolor = mix (diffuseTexture3, diffuseTexture4, splatTexture.a); 

fragment_color = outcolor; 

} 

Einige zusätzliche Informationen: Alle Texturen wie dies in meinem Terrain Material und an den Shader geladen werden (funktioniert):

glActiveTexture(GL_TEXTURE0); 
glBindTexture(GL_TEXTURE_2D, heightMap->getId()); 
glUniform1i (_shader->getUniformLocation("heightMap"),0); 
... 

Die Ebene Mesh uvs werden wie folgt abgebildet:

(0,1) (1,1)

(0,0) (1,0)

Ich glaube, ich etwas schrecklich falsch tue , aber ich kann nicht herausfinden, was. Jede Hilfe wird geschätzt!

+0

Was ist der Zweck von '_vertex'? Sie setzen '_vertex.y', aber danach verwenden Sie es nie wieder. –

+0

Es tut mir leid, es soll _vertex statt Vertex bei GL_position sagen. Ich habe vergessen zu bearbeiten – Possimpible

+0

Sie sollten versuchen, eine zufällige Höhe Generation Funktion und versuchen, dass anstelle der Textur Karte. Auf diese Weise können Sie sehen, ob es die Texturkarte oder die 'gl_Position' ist, die das Problem verursacht. –

Antwort

3

Hat Ihr Schreiben dies:

Das Flugzeug Mesh uvs wie folgt abgebildet werden:

(0,1) (1,1)

(0,0) (1, 0)

... bedeutet, dass Ihr Mesh aus nur 4 Ecken besteht? Wenn ja, dann ist das dein Problem genau dort: Der Vertex-Shader kann keine magischen "neuen" Scheitelpunkte erzeugen, so dass deine Heightmap-Textur nur an 4 Punkten (und nichts dazwischen) gesampelt wird.

Und weil Sie die Texturkoordinaten bei ganzzahligen Werten und Ihren Texturkoordinaten abtasten und bei 0 und 1 sind, werden Sie effektiv die gleiche Texturkoordinate abtasten, so dass Sie die gleiche Verschiebung für alle vier Ecken sehen .

Lösung: Tesselate Ihr Basisnetz, so dass tatsächlich Vertices vorhanden sind, um zu verschieben. Ein Tesselation Shader ist dafür völlig in Ordnung.

EDIT:

BTW, können Sie Ihren Vertex-Shader ein wenig simplyfiy: Für die Attribute es eine

in vec2 vertex; 

machen, die nur 2/3 des Raumes der vec3 erfordert, da Sie verwende die z-Komponente sowieso nicht.

float y = texture(heightmap, uv).r * 2.f; 
gl_Position = 
    projectionMatrix 
    * viewMatrix 
    * modelMatrix 
    * vec4(vertex.x, y, vertex.y, 1.f); 
+0

Vielen Dank für Ihre ausführliche Antwort! Sie hatten Recht bezüglich der Anzahl der Scheitelpunkte des Netzes. Ich habe das Flugzeug so aktualisiert, dass es nun 8192 Scheitelpunkte enthält, und es gibt Fortschritte. Sie sind jedoch nicht interpoliert, so dass es aussieht wie ein transparenter Berg. Ist das der Ort, an dem der Tesselation-Shader ins Spiel kommt? – Possimpible

+0

@Possimpible: Nein, ein Tesselation Shader wird dir dabei nicht helfen. Für mich klingt das eher nach einem Texturkoordinatenproblem. Nämlich, dass Sie die gleiche Texturkoordinate verwenden, um die Verschiebung aller 4 Scheitelpunkte in einem Quad zu erfassen. – datenwolf

+0

Ich kam gerade zurück, um zu sagen, dass das Problem durch Mischen der Outcolor im Fragment-Shader verursacht wurde. Wenn ich es in ein neues vec4 mit Alpha auf 1 setze, funktioniert es wie ein Zauber. Danke für die Hilfe! – Possimpible

Verwandte Themen