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

    技术2022-05-11  16

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

     

    如有转载,请注明:http://www.azure.com.cn 

         现在的地形渲染一般都使用高度图来作为数据源,高度图中每一个像素的颜色都代表着一个高度值,就为其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方法动态计算出来的,用来查询反射。

    www.azure.com.cn 

     

    最新回复(0)