Clayman的专栏

It's all about XNA & GPU Programming

用户操作
[即时聊天] [发私信] [加为好友]
claymanID:soilwork
193019次访问,排名382好友0人,关注者13
soilwork的文章
原创 85 篇
翻译 15 篇
转载 0 篇
评论 330 篇
clayman的公告
嘿嘿 ^o^....
最近评论
ffffk:研究到这的都是高手
jym5596337:我也不知道我怎么就走到了你的路上来了呵呵...
太晕了,我们专业就学的C#... 那我就凑合着用它学习MDX喽,但到了2008你的这个时期,感觉形式有点尴尬,以前的人说 在中国搞软件是 前有微软,后有盗版。
现在是 前有XNA后有C++ ... MDX 学习资料太太太难找了。。太太太少了。 师兄给介绍下你学历路途中的资料目录咯。。。我好找来学习咯。。 感谢哦感谢。。
jym5596337:好象没有继续哇 ...
shapin:ATI的网站有个支持HLSL语法高亮的vs插件,可以支持其他版本,只要修改相应的那个注册表就行
flip:To linxv :
貼圖座標有用投影嗎?
文章分类
收藏
    相册
    blogs
    David Weller
    nVidia Developer blog
    Rico Mariani
    Shawn Hargreaves
    XNA Team blog
    XNA资源
    XNA Creators Club
    ZBuffer
    Ziggyware XNA Resources
    中国XNA开发网
    存档
    软件项目交易
    订阅我的博客
    XML聚合  FeedSky
    订阅到鲜果
    订阅到Google
    订阅到抓虾
    订阅到BlogLines
    订阅到Yahoo
    订阅到GouGou
    订阅到飞鸽
    订阅到Rojo
    订阅到newsgator
    订阅到netvibes

    原创 水面渲染小结收藏

    新一篇: 关于在amazon买书 | 旧一篇: XNA Kick Start (五)

    水面渲染小结

     

    本文版权归我所有,仅供个人学习使用,请勿转载,勿用于任何商业用途。
    由于本人水平有限,难免出错,欢迎大家和我交流。
    作者:clayman
    Blog:
    http://blog.csdn.net/soilwork
    clayman_joe@yahoo.com.cn


           从几何模型上来看,水面其实和地面是一样的,可以看做普通的均匀网格,不同点在于地形中,顶点高度是固定的,而水面是动态的。此外,对于水面来说,还有许多特殊的光学效果。为了更好的描述渲染效果,下面借用了《Water Effect》一文中的部分图片。

     

    一.           水面动画

           当然,第一步就是让水面运动起来。对均匀网格来说,需要计算出每个顶点的位置和法线。实际上,如果仅模拟比较平静的水面,甚至只需计算法线就行了,这也是目前游戏中常见的做法。

           仅使用法线来模拟水面的好处是可以极大的简化几何模型,最简单的情况下,一个网格就能代表整个水面,你甚至不必担心如何处理LOD计算。它的实现思想就是bump mapping,区别在于这里我们使用动态的normal map。可以实时计算出每条法线的位置,也可以从预先处理好的normal map中获得这些信息。显然,适用后者计算量可以减少很多。在Farcry中,水面实际上只使用了一张normal map,在vertex shader中,对纹理坐标进行不同的缩放和偏移,从而获得动态水面。对这种方法来说,normal map质量的好坏对最终效果有很大影响。下面的代码显示了通过混合三层不同的波来模拟水面的情况:

         bumpCoord1 = texCoord + time*0.02;

         bumpCoord2 = texCoord * 2.0f + time * 0.02;

         bumpCoord3 = texCoord / 2.0f + time * 0.01;

         half3 vBumpTexA = tex2D(tex0, bumpCoord1).xyz;

         half3 vBumpTexB = tex2D(tex0, bumpCoord2).xyz;

         half3 vBumpTexC = tex2D(tex0, bumpCoord3).xyz;

         half3 vBumpTex = normalize(2.0 * (vBumpTexA.xyz + vBumpTexB.xyz+vBumpTexC.xyz) - 3.0);

     

        上述方法最大的缺点就是对于起伏较大的水面来说,就无能为力了,由于仅仅使用法线来表示水面起伏,因此,当近距离观察时,可以看到水面实际是静止的。为了进一步增加真实性,让顶点真正运动起来是必须的。如何来计算水面运动呢?简单来说,可以把水面运动看作一系列正弦或余弦波的叠加。根据不同的时间和顶点坐标位置,计算出当前顶点的高度。然而,实践中我们却更偏向于适用Gerstner Wave。以下是3D Gerstner Wave3D波动方程,注意这里的x是一个矢量xxz),代表顶点的坐标位置,w为角速度,k为波矢量,k为波数,x0为顶点的初始位置。

         从数学角度来看,Gerstner Wave并不比普通的正余弦波动方程复杂,但他的波形却更像水波。对于正余弦波来说,波峰和波谷波的弧度都是均匀的,而实际上水波的波峰要尖一些,波峰则要圆滑。注意上述方程中对给定顶点x0来说,不同时刻,水平位置也是不同的,因此可以正确模拟出这种效果。多个Gerstner Wave相互叠加,就能模拟出相当不错的水面。有了水面高度,进一步对方程求导,就能计算出法线。

        有时,你也许需要渲染电影级真实度的水面,那么这种简单波形叠加的方法也许就有些力不从心。可以适用FFT来模拟更真实的水面,它使用了统计波的模型(statistical wave model),通过快速傅立叶(FFT)变换求值。基本的思想是创建一个类似海面的,具有相同频谱的波形域,然后通过傅立叶变换转换到空间域。因此,水体表面实际上就是由许多由风产生的正弦波线性叠加而成。以下是所使用的波形方程:

        公式中,h表示t时刻在网格位置 处的水面高度。 表示波矢(wave vector, 的计算公式如下

              空间谱(spatial spectrum 通过过滤复数形式的白噪声(complex white noise)获得:

        FFT生成水面的细节超出了本文讨论范围,但总的来说和Gerstner Wave是类似的,只不过方程更复杂而已。

        还值得一提的是用shader mode3中的vertex texture技术,可以把以上两种计算高度的方法放到程序的预处理阶段,运行时直接使用计算好的水面高度图,这样可以大大提高效率。

    (混合多个Gerstner wave得到的水面)

     

    水面颜色

           计算水面颜色的方法很多,这里介绍一种简单高效的方法。假设水的颜色只与水面高度和观察着角度有关,那么可以这样计算颜色:

           half facing = saturate(dot( eyeVect,normal));

         half3 waterColor = lerp(shallowWaterColor,deepWaterColor,facing);

           下面是添加了水面颜色的渲染效果:

     

    三. Bump Mapping

           仅仅靠的第一部分所说的方法来计算水面顶点位置和法线还不够,它们受到网格间距精度限制,只能模拟波长较长的波。这样的水面太过于平和,而显得不够真实。因此,需要添加Bump Mapping来增加细节和高频波浪。这里可以使用的第一部分仅仅使用normal map模拟水纹的方式,来获得动态bump mapping效果。注意转换到tangent space下进行光照计算。

    四. 反射和折射

           反射和折射的思想都一样,以水面为裁减平面,分别把场景渲染为折射和反射帖图,然后投影到水面上。在渲染反射帖图时,需要以水平面为参考面,把摄像机镜像翻转到水面之下。投影纹理时,这里需要用到顶点位置作为参数,来动态调整纹理坐标,反映出水波的流动效果。下图是添加了反射帖图的水面:

    五. 菲捏尔效果(Fresnel term

           对水面来说,当观察者和水面的角度越小时,反射效果越明显,角度越大时,折射效果越明显,称为菲捏尔效果。所以需要更具观察者的角度来计算反射,折射帖图,以及水面颜色的混合方式。物理上正确的菲捏尔向计算比较复杂,通常使用近似的计算方法就可以了:

           fastFresnel = r + ( 1-r ) * pow ( 1.0 – dot ( viewDir, normal ), 5.0);

           这里,空气到水面的反射系数约为0.02037

           最终水面颜色为

           finalColor = waterColor + reflectionColor * fastFresnel + reftractionColor *  ( 1 – fastFresnel );

     

     

    六.参考

    Deep-Water Animation and Rendering

    Simulating Ocean Water

    Animation and Display of Water

    Effective Water Simulation form Physical Models

    Using Vertex Texture Displacement for Realistic Water Rendering

    Animation and Rendering of Underwater God Rays

    An Efficient Method for Rendering Underwater Optical Effects Using Graphics Hardware

    Interactive Animation of Ocean Waves

    Generic Refraction Simulation

    Water Effect

     

     

     

      

     


     


    发表于 @ 2007年04月01日 18:48:00|评论(loading...)|编辑

    新一篇: 关于在amazon买书 | 旧一篇: XNA Kick Start (五)

    评论

    #JT 发表于2007-04-05 17:03:48  IP: 60.178.163.*
    你有这些材质资源吗?
    我也想做做试下,呵呵。
    麻烦了。
    #文盲 发表于2007-04-06 21:14:25  IP: 58.17.145.*
    可以请教你程序的问题么?
    能加我的QQ么?150274196
    我对XAN很感兴趣可是无奈我是美工又是程序盲所以想请你帮忙
    可以吗?
    #soilwork 发表于2007-04-08 23:38:32  IP: 58.60.213.*
    to JT:
    你看到的这些效果基本都是用程序参数写出来的,至于反射和折射帖图,如果你做试验的话,可以直接找两张图片天空和水底的图片来代替
    #chloe 发表于2007-05-17 15:40:11  IP: 203.110.162.*
    太烂了...
    #alexandercer 发表于2007-12-06 18:59:21  IP: 61.170.180.*
    看不到图阿
    发表评论  


    登录
    Csdn Blog version 3.1a
    Copyright © clayman