基于FFT的大规模海面的实现方法(上篇)
porry20009
porry20009 10913 252
精华热门加亮 Shader 着色器 2016-04-18 11:42
简介
   为了构建动态海浪,利用Phillips频谱计算海浪频域的振幅值,通过IFFT将频域的振幅值变换到时域的高度值,从而构建海面高度场。因为Phillips频谱是从真实海洋中得到的统计数据,所以能够模拟出较高真实感的深海海浪。为了实现无限海面,本文采用投影网格的方式。

图片:1.png


投影网格
一、大致算法:
1、 在投影空间创建一个规则的网格Grid(坐标在[-1,1])。
2、 将上一步骤创建的网格Grid投影到一个水平面Plane上。
3、 对网格Grid进行Displace(置换)。
4、 然后再将Grid变换回投影空间,输出屏幕。

图片:2.png



二、具体细节
1、怎么在投影空间创建一个规则的网格Gird呢?
我们知道一个模型要显示到屏幕上,需要经过世界变换->视图变换->投影变换->视口变换。我们创建的Grid是不需要经过世界变换和视图变换,因为它的x,y坐标是在[-1,1]z坐标值为0,已经是在投影空间了。
2、怎么将Grid投影到世界空间的一个水平面上呢?
   这个问题其实可以分为两个:
A、 怎么构建以网格的顶点坐标为起点,方向是指向水平面的射线(世界空间)?
B、 怎么求空间射线和平面的交点?

图片:9.png


               其中dir.y不能等于0,若是等于0,射线就平行或是在水平面Plane上。


下面给出求空间线段与水平面Plane交点的代码:

图片:3.png



三、算法的缺陷
 1Camera朝向水平面Plane的时候,该算法能很好地工作,但是当CameraLook方向平行于水平面Plane或是夹角大于90°的时候,该算法就崩溃了,没法求出正确的交点,投影网格也就失效了。
  2Camera的高度小于水平面Plane时,算法也出现问题。


  3、当投影网格用DisplacementMap进行偏移时,可能边缘会出现间隙

图片:4.png



四、改进的方法


       我们必须想办法将投影网格固定在视截体内。并且投影网格要适当增大一些,以防止进行Displace时,边缘出现间隙。

图片:5.png



   设定一个DisplaceableDisplaceableCamera的视截体与平面baseUp和平面baseDown的交集(图中以蓝线标记的区域)。为水平面Plane设定一个上限baseUp和一个下限baseDownbaseUp>=水波的波峰,baseDown
<=水波的波谷,否则边缘会出现间隙。创建一个新的Camera,我们称之为Projector,我们为这个Projector制定一些约束条件:
1、  Projector始终朝向水面。
2、  Projector始终处在baseUp的上面。


上面提到的两个约束条件都很容易实现,这里就不再复述了。比较难的是,要求出投影空间网格Grid与水平面Plane的交点,就需要先得到ProjectorViewMatrixProjectMatrixViewMatrix可以很容易得到,那么怎么得到ProjectMatrix呢?算法如下:

图片:6.png



如上图所示,
1、  求出ABCDEFGH八个交点,并且加入到列表List
2、  判断Camera的视截体NearClipFarClip的八个顶点是否在BaseUpBaseDown之间,是的话,也加入列表List中。
3、  此时List中的顶点就是Displaceable的顶点。
4、  List表中的顶点投影到水平面上Plane(其实就顶点的y坐标值等于水平面Planey坐标值)。


5、  将上述4步骤得到的顶点坐标变换到一个投影空间

图片:10.png




    然后得到最大的MaxProj和最小的MinProj,如果是以水平面Plane计算交点的话, MaxProjMinProj都会是在[-1,1]的范围,但是以BaseDownBaseUp计算的交点的话,那么MaxProjMinProj的值域会稍稍超出[-1,1]。那么我们下一步就是要做一个修正,就是要将Camera投影空间的Grid坐标变换到[MinProj,MaxProj]这个范围内,这样我们构建的射线就由RayOri变成了RayNew,这样就能可控地(设定baseUpbaseDown)扩大了投影网格的范围。如下图所示:

图片:7.png



图片:11.png

图片:8.png



相关文献:
http://fileadmin.cs.lth.se/graphics/theses/projects/projgrid/projgrid-hq.pdf
源码链接:


本部分内容设定了隐藏,需要回复后才能看到








1条评分, 鲜花+500
  • 鲜花500
    就看懂图片了
分享:
游客
要评论请先登录 或者 注册
252条回应 只看楼主 最新
xie744428439 学徒 2016-04-18 13:02 1楼
牛牛牛牛牛牛牛牛牛牛牛牛牛
solo2b 学徒 2016-04-18 13:44 2楼
不错不错        
sanxiabb 学徒 2016-04-18 15:38 3楼
牛牛牛,谢谢分享
ddyee 学徒 2016-04-18 19:18 4楼
棒棒棒 学习了
noflyzone 学徒 2016-04-19 08:46 5楼
不错,天空盒子作好了,效果都不会差的
dreamfairy 学徒 2016-04-19 15:52 6楼
我只想说,楼主牛逼
Alkut120 新手 2016-04-19 20:55 7楼
牛牛牛牛牛牛牛牛牛牛牛
seaplay 学徒 2016-04-20 02:36 8楼
while(1){Console.Write("牛逼");}
yxriyin 师者 2016-04-20 14:26 9楼
666666
1 2 3 4 ...26
返回顶部