• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
燃尘的技术博客
博客园    首页    新随笔    联系   管理    订阅  订阅

Slope(斜坡) 法线生成算法,在地形渲染中的应用

原文出处:
http://www.azure.com.cn/article.asp?id=285

 

现在的地形渲染一般都使用高度图来作为数据源,高度图中每一个像素的颜色都代表着一个高度值,就为其y值,其x,z值为程序生成的规格数据。所以将所有这些顶点依次用三角形带绘制出来,即形成一块地形。
      但问题出来了,高度图中没有包含法线信息,无法进行光照,当然你可以说,我可以用张图的R,G,B来储存法线信息,用A来储存高度值。这样当然最好,但这样的话,你得为它写一个完善的地形编辑器了,而且这个法线是不可更改的。
      如果你要做顶点波动的水面,这时又需要用当前顶点的法线去查询cubemap来产生反射效果。你就必须要动态更新法线信息了,如果快速的实时计算,就是我们需要面对的问题了,Slope方法就可以解决此问题。

关于 Slope 计算法线,先见下图:

 

上图为一个网格图,假设有顶点p00,p10,p20.......
首先见图中深色部分。
如果我们要计算p31此点的法线,
Slope法线算法如下:


p[3][1].normal.x = p[4][1].position.y - p[2][1].position.y;
p[3][1].normal.y = -k;
p[3][1].normal.z = p[3][2].position.y - p[3][0].position.y;
p[3][1].normal.normalize();   //归一化
[/code]

 

所以推广到任意点为:
[code]
p[a][b].normal.x = p[a+1][b].position.y - p[a-1][b].position.y;
p[a][b].normal.y = -k;
p[a][b].normal.z = p[a][b+1].position.y - p[a][b-1].position.y;
p[a][b].normal.normalize();   //归一化

关于这个k值:
这个值是个调整值,反复调整才能达到最好的效果,
如果两个顶点的水平距离较大,k值应该大点,反之小点,
在我的地形demo中我取20。

边缘特殊处理:
当顶点为p00, p10, p20, p01 这些边缘顶点的时候,用以上方法计算,必然导致数组越界,
所以我们强制定义边缘处顶点法线为(0, 1, 0).

相关此方法demo的截图:

此地形的法线是用Slope方法预计算出来的,效果还不错吧.

 

 

这个水面的法线是用Slope方法动态计算出来的,用来查询反射。

 

 

 

 

 

 

 

 

 

 

 

 

 

posted @ 2010-06-08 09:31  燃尘  阅读(980)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3