我正在为GPU生成景观编写模块。我使用OpenGL和GLSL进行生成和可视化。在我写了一个高度图生成着色器后,我开始考虑照明法线。我为普通地图生成编写了一个简单的着色器,它有点工作,但结果很奇怪。法线贴图中的四边形有一些意外的分割。 请参阅screen capture。
以下是片段着色器:
#version 330
uniform sampler2D heightmap;
uniform float res_x;
uniform float res_y;
in vec4 fragmentColor;
in vec2 tc;
in vec4 pos;
in vec3 normal;
out vec4 color;
void main(void)
{
float x_d = 1.0/res_x; //size of texel
float y_d = 1.0/res_y;
//1024 = resolution of hm
vec3 top = vec3(tc.x*1024.0, texture2D(heightmap, tc + vec2(0.0, y_d)).r, (tc.y + y_d)*1024.0);
vec3 bottom = vec3(tc.x*1024.0, texture2D(heightmap, tc + vec2(0.0, -y_d)).r, (tc.y - y_d)*1024.0);
vec3 left = vec3((tc.x - x_d)*1024.0, texture2D(heightmap, tc + vec2(-x_d, 0.0)).r, tc.y*1024.0);
vec3 right = vec3((tc.x + x_d)*1024.0, texture2D(heightmap, tc + vec2(x_d, 0.0)).r, tc.y*1024.0);
vec3 center = vec3(tc.x*1024.0, texture2D(heightmap, tc + vec2(0.0, 0.0)).r, tc.y*1024.0);
//this 4 vectors are forming 4 triangles
vec3 top_minus_center = normalize(top - center);
vec3 bot_minus_center = normalize(bottom - center);
vec3 left_minus_center = normalize(left - center);
vec3 right_minus_center = normalize(right - center);
//calc 4 normals to 4 triangls
vec3 _normal[4];
_normal[0] = normalize(cross(left_minus_center, top_minus_center));
_normal[1] = normalize(cross(right_minus_center, top_minus_center));
_normal[2] = normalize(cross(right_minus_center, bot_minus_center));
_normal[3] = normalize(cross(left_minus_center, bot_minus_center));
//right direction of normal
for (int i = 0; i < 4; i++)
if (_normal[i].y < 0.0)
_normal[i] = -_normal[i];
color = vec4(((_normal[0] + _normal[1] + _normal[2] + _normal[3]).xzy/4.0)/2.0 + 0.5, 1.0);//packing normal
}
造成这种缺陷的原因是什么?
答案 0 :(得分:1)
纹理坐标为0到1
我会建议一些事情:
// get the heights
float top = texture2D(heightmap, tc + vec2(0.0, y_d)).r;
float bottom = texture2D(heightmap, tc + vec2(0.0, -y_d)).r;
float left = texture2D(heightmap, tc + vec2(-v_x, 0.0)).r;
float right = texture2D(heightmap, tc + vec2(v_x, 0.0)).r;
// The center one is not really important
vec3 n = normalize(vec3(bottom - top, left - right, 2.0));
// viola, pack it and go