【问题标题】:OpenGL hieghtmap rendering with normal map使用法线贴图渲染 OpenGL hieghtmap
【发布时间】:2014-09-27 17:41:03
【问题描述】:

我正在尝试使用 OpenGL 和 GLSL 使用法线贴图渲染高度图。 到目前为止我所拥有的: 基于高度图在顶点着色器中更新高度的四叉树网格。 生成的法线纹理 类似的示例: http://www.leadwerks.com/wiki/images/0/08/Terr16.JPG

地形没有切线或顶点法线。没有这些属性,我无法让我的灯光系统正常工作。我猜我必须使用 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

根据相机左/右旋转,现在地形变得更亮/更暗。所以它远非正确。

【问题讨论】:

  • 根据相机左/右旋转,现在地形变得更亮/更暗。所以这远非正确。
  • 除非您对其进行变形,否则您的地形法线贴图不需要切线。我认为您在顶点着色器中对L 的计算看起来有点可疑。 MVmatrix 是什么,当你从它构造 vec3 时会发生什么?

标签: c++ opengl glsl terrain normals


【解决方案1】:

我通过对相邻顶点的高度图进行采样并使用结果计算法线来完成此操作。所以对于顶点(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 距离。 (你可以在顶点着色器中计算距离,但它变成了一个更慢的依赖查找。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多