高度图的法线不起作用

时间:2016-11-11 01:29:01

标签: dictionary opengl height terrain normals

我试图为我的身高地图实现法线,但它们似乎不起作用。

看看这些: Normals on slope

enter image description here

enter image description here

请注意,图案沿边缘出现。为什么? 顶点是共享的(索引),法线是顶点所属的所有三角形的顶点的平均值。

法线的算法如下:

 float size=Size;
  int  WGidY=int(gl_WorkGroupID.y);
  int  WGidX=int(gl_WorkGroupID.x);

    vec4 tempVertices[3];
    tempVertices[0]=imageLoad(HeightMap, ivec2(WGidX, WGidY));
    tempVertices[1]=imageLoad(HeightMap, ivec2(WGidX, WGidY+1));
    tempVertices[2]=imageLoad(HeightMap, ivec2(WGidX+1, WGidY));
    vec4 LoadedNormal=imageLoad(NormalMap, ivec2(WGidX, WGidY));
    vec4 Normal=vec4(0.0f);
    Normal.xyz=cross((tempVertices[0].xyz-tempVertices[1].xyz),  (tempVertices[0].xyz-tempVertices[2].xyz));
    Normal.w=1; 
    imageStore(NormalMap, ivec2(WGidX,WGidY),          Normal+LoadedNormal);

2 个答案:

答案 0 :(得分:1)

No need to do averaging like that.您可以按照以下步骤直接计算:

vec3 v[4] = {
    imageLoad(HeightMap, ivec2(WGidX-1, WGidY)).xyz,
    imageLoad(HeightMap, ivec2(WGidX+1, WGidY)).xyz,
    imageLoad(HeightMap, ivec2(WGidX, WGidY-1)).xyz,
    imageLoad(HeightMap, ivec2(WGidX, WGidY+1)).xyz,
};
vec3 Normal = normalize(cross(v[1] - v[0], v[3] - v[2]));
imageStore(NormalMap, ivec2(WGidX,WGidY), vec4(Normal, 1));

此外,您甚至不需要明确存储HeightMap网格。相反,您可以将相同的低分辨率四边形发送到GPU,使用曲面细分着色器对其进行细分,通过从单通道纹理采样将高度贴图应用于生成的顶点,并计算法线上的法线如上所述。

答案 1 :(得分:0)

好的,我发现了一个问题。这是“贪婪的三角测量”的症状。三角形内部的法线通过重心算法进行插值,但边缘线性插值以防止调整三角形之间的颜色差异。再次感谢Paul Bourke: http://paulbourke.net/texture_colour/interpolation/

如果你没有足够的三角形,不要使用Phong Shading(也许正常的映射?)。 调整后:

http://prntscr.com/dadrue

http://prntscr.com/dadtum

http://prntscr.com/dadugf