2016-05-21 81 views
0

我想紋理我的地形沒有預定的紋理座標。我想使用頂點位置座標確定頂點或碎片着色器中的座標。我現在使用位置「XZ」座標(UP =(0,1,0)),但如果我有一個例如壁是90度與地面的紋理將是這樣的:如何使用頂點位置座標進行紋理化? openGL,C++

enter image description here

如何將這個位置轉換成這些座標以便正常工作?

這裏是我的頂點着色器:

#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; 

} 

這是我的fragmant着色器:

#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; 
    } 
} 

編輯:(馮斯希)

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

enter image description here

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

現在,牆上的工作,但地形不是。 enter image description here

回答

1

這個問題實際上是非常困難的,因爲你不能設計一種正確顯示垂直牆,僅使用XYZ座標紋理座標的公式。

想象這一點,想象一下在一塊平坦的土地旁邊的一座小山。由於經過山丘的路徑比經過平坦的土地的路徑長,所以紋理應該在平坦的土地上的山上包裹更多次。在下面的圖片中,紋理在山上包裹5次,在平坦部分包裹4次。

Hill visualization

如果紋理座標(0,0)在左邊,他們應該在右邊(4,0)(5,0)?由於這兩個答案都是有效的,這證明沒有函數僅基於xyz座標計算正確的紋理座標。 :(

但是,您的問題可能會用不同的方法來解決:

  • 壁可通過從地形獨立生成它們予以糾正,並指定正確的紋理座標他們這其實更有意義沒有。將這些地圖合併到你的地形中
  • 您可以使用法線貼圖,更高分辨率的紋理或不同紋理的組合來爲陡峭的山坡增加更多細節,可能有更好的解決方案,我不知道。

編輯:Triplanar mapping將解決您的問題!

+0

Triplanar映射解決了我的問題。非常感謝 :) –

0

嘗試:

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

另外,我建議您將*0.05比例因子在頂點着色器,而不是片段着色器。最終的代碼如下:

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

「+ vec2(0,y)」您是指「vec2(0,position.y)」?它看起來不錯,但它還不完美。我用新的截圖編輯了這篇文章。 –