2016-05-21 22 views
0

Ich möchte mein Gelände ohne vorgegebene Texturkoordinaten texturieren. Ich möchte die Koordinaten im Vertex- oder Fragmant-Shader mithilfe von Eckpunktkoordinaten bestimmen. Ich verwende jetzt Position ‚XZ‘ Koordinaten (nach oben = (0,1,0)), aber wenn ich eine zum Beispiel Wand aufweisen, die 90 Grad mit dem Boden ist die Textur wird so sein:Wie kann ich mit Eckpunktkoordinaten texturieren? openGL, C++

enter image description here

Wie kann ich diese Position umwandeln, damit diese Koordinaten gut funktionieren?

Hier ist meine Vertex-Shader:

#version 430 

in layout(location=0) vec3 position; 
in layout(location=1) vec2 textCoord; 
in layout(location=2) vec3 normal; 

out vec3 pos; 
out vec2 text; 
out vec3 norm; 


uniform mat4 transformation; 

void main() 
{ 
    gl_Position = transformation * vec4(position, 1.0); 
    norm = normal; 
    pos = position; 
    text = position.xz; 

} 

Und hier ist mein fragmant Shader:

#version 430 

in vec3 pos; 
in vec2 text; 
in vec3 norm; 

//uniform sampler2D textures[3]; 

layout(binding=3) uniform sampler2D texture_1; 
layout(binding=4) uniform sampler2D texture_2; 
layout(binding=5) uniform sampler2D texture_3; 

vec3 lightPosition = vec3(-200, 700, 50); 
vec3 lightAmbient = vec3(0,0,0); 
vec3 lightDiffuse = vec3(1,1,1); 
vec3 lightSpecular = vec3(1,1,1); 

out vec4 fragColor; 
vec4 theColor; 



void main() 
{ 
    vec3 unNormPos = pos; 
    vec3 lightVector = normalize(lightPosition) - normalize(pos); 
    //lightVector = normalize(lightVector); 

    float cosTheta = clamp(dot(normalize(lightVector), normalize(norm)), 0.5, 1.0); 

    if(pos.y <= 120){ 
     fragColor = texture2D(texture_2, text*0.05) * cosTheta; 
    } 
    if(pos.y > 120 && pos.y < 150){ 
     fragColor = (texture2D(texture_2, text*0.05) * (1 - (pos.y-120)/29) + texture2D(texture_3, text*0.05) * ((pos.y-120)/29))*cosTheta; 
    } 
    if(pos.y >= 150) 
    { 
     fragColor = texture2D(texture_3, text*0.05) * cosTheta; 
    } 
} 

EDIT: (Fons)

text = 0.05 * (position.xz + vec2(0,position.y)); 

enter image description here

text = 0.05 * (position.xz + vec2(position.y,position.y)); 

Jetzt funktioniert die Wand aber Gelände nicht. enter image description here

Antwort

1

Das Problem ist eigentlich ein sehr schwieriges Thema, da Sie keine Formel für die Texturkoordinaten, die senkrechten Wände korrekt angezeigt ersinnen können, indem nur die XYZ-Koordinaten.

Um dies zu visualisieren, stellen Sie sich einen Hügel neben einem Stück flachem Land vor. Da der Pfad, der über den Hügel führt, länger ist als der, der über das flache Stück Land führt, sollte sich die Textur öfter auf dem Hügel auf dem flachen Stück Land befinden. Im Bild unten umschließt die Textur 5 Mal auf dem Hügel und 4 Mal auf dem flachen Stück.

Hill visualization

Wenn die Texturkoordinaten (0,0) auf der linken Seite sind, sollten sie (4,0) oder (5,0) auf der rechten Seite? Da beide Antworten gültig sind, beweist dies, dass es keine Funktion gibt, die korrekte Texturkoordinaten basierend auf den xyz-Koordinaten berechnet. :(

Allerdings könnten Ihre Probleme mit verschiedenen Methoden gelöst werden:

  • Die Wände sie unabhängig vom Gelände durch die Erzeugung korrigiert werden können, und die korrekte Textur zuzuweisen Koordinaten sie Es macht tatsächlich mehr Sinn nicht.
  • Sie können die Seiten von steilen Hügeln mit normalen Karten, Strukturen höherer Auflösung oder einer Kombination verschiedener Texturen detaillierter hinzufügen.Es könnte eine bessere Lösung geben, von der ich nichts weiß .

Edit:Triplanar mapping lösen Ihr Problem!

+0

Triplanar Mapping löst mein Problem. Ich danke dir sehr :) –

0

Versuchen:

text = position.xz + vec2(0,y); 

Auch ich empfehlen, den *0.05 Skalierungsfaktor in der Vertex-Shader anstelle des Fragment-Shader einstellen. Der endgültige Code wäre:

text = 0.05 * (position.xz + vec2(0,y)); 
+0

"+ vec2 (0, y)" meinst du "vec2 (0, position.y)"? Es sieht gut aus, aber es ist noch nicht perfekt. Ich habe den Beitrag mit neuem Screenshot bearbeitet. –