2014-09-27 38 views
0

我正在嘗試使用OpenGL和GLSL渲染帶有普通貼圖的高度圖。 我到目前爲止: 四邊形網格,高度根據高度圖在頂點着色器中更新。 生成正常紋理 實施例OD呈三角之一: http://www.leadwerks.com/wiki/images/0/08/Terr16.JPGOpenGL hieghtmap用法線貼圖進行渲染

地形沒有切線或頂點法線。沒有這些屬性,我無法讓我的燈光系統工作。我猜測我必須使用TBN矩陣來正確生成向量。但如何做到這一點沒有頂點正常或切線?有沒有比複雜的一切複製更簡單的方法? 正常轉型是否真的泄露?或者我的整個光計算方法是錯誤的? 代碼片段:

VS:

vec4 pos=vertex_position;//grid position (only x,z) 
pos.y=((texture(heightmap_tex,uv_coords).x)*scale_height); 
pos.w=1.0;//to be safe 
vec4 P=viewMatrix*pos; 
vec3 L=mat3(MVmatrix)*vec3(worldLightPos)-P.xyz; 
Out.lightDir=L; 
vec3 V=-P.xyz; 
Out.eyeDir=V; 
Out.texCOORD=uv_coords; 
gl_Position = MVPmatrix * pos; 

FS:基於攝像頭

vec3 V=normalize(In.eyeDir); 
vec3 L=normalize(In.lightDir); 
vec2 norm_texture=texture(texturenormal,In.TexCoord).xy*2.0-vec2(1.0); 
vec3 N=normalize(vec3(norm_texture,sqrt(1.0-dot(norm_texture.xy, norm_texture.xy))*2.0-vec3(1.0)));//unpacking from 2 channel 
vec3 R=reflect(-L,N);//phong 
vec3 specular=pow(max(dot(R,V),0.0),shininess)*specularColor;//phong 
vec3 diffuse=max(dot(N,L),0.1)*vec3(texColor);//phong 

眼下地勢越來越亮/暗向左/向右旋轉。所以這很不正確。

+0

現在,基於相機左/右旋轉,地形變得更亮/更暗。所以這很不正確。 – Skides 2014-09-28 13:53:17

+1

除非你正在變形,否則你不應該需要地形法線貼圖的切線。我認爲你在頂點着色器中計算'L'看起來有點可疑。什麼是'MVmatrix',當你從它構造一個'vec3'時會發生什麼? – GuyRT 2014-09-29 08:48:02

回答

0

我已經完成了這一點,通過對相鄰頂點的高度圖進行採樣並計算結果的法線。所以對於頂點(x,y),我在那個點上對高度圖進行採樣。然後,我還在(x + 1,y)和(x,y + 1)處對其進行採樣,並取得結果向量的叉積。所以,我的頂點着色器看起來是這樣的:

vec3 calculateNormal (float y0, float y1, float y2) 
{ 
    vec3 p1 = gl_Vertex.xyz; 
    vec3 p2 = gl_Vertex.xyz; 
    vec3 p3 = gl_Vertex.xyz; 
    p2.x += vertexDelta.x; 
    p3.z += vertexDelta.y; 

    p1.y = y0; 
    p2.y = y1; 
    p3.y = y2; 

    return normalize(gl_NormalMatrix * cross(p3 - p1, p2 - p1)); 
} 

void main() 
{ 
    vec4 heightSample = texture2DRect(heightMap, gl_MultiTexCoord3.xy); 
    vec4 heightSampleX = texture2DRect(heightMap, gl_MultiTexCoord4.xy); 
    vec4 heightSampleY = texture2DRect(heightMap, gl_MultiTexCoord5.xy); 
    ... 
    normal = calculateNormal (heightSample, heightSampleX, heightSampleY); 
} 

這假定頂點在X和Y方向的vertexDelta.xy均勻間隔。它還假定您已設置紋理單元3,4和5的紋理座標。紋理單元3包含高度圖的實際紋理座標。紋理單元4是相同的東西,但移動了x方向頂點之間的距離。紋理單元5與紋理單元3相同,但是座標移動了頂點之間的y距離。 (您可以計算頂點着色器中的距離,但它會變成一個依賴查找,速度較慢。)