任程的博客

计算机图形、动画、虚拟现实 / 3D Computer Graphics, Computer Animation, Virtual Reality / uStep禹步信息科技
  首页  :: 联系 :: 订阅 订阅  :: 管理
    这是2004年的一个海水实现,速度虽然不算快,但很漂亮,是用D3D写的,原网址:http://fileadmin.cs.lth.se/graphics/theses/projects/projgrid/

    自己用Ogre实现了一下,可以同时跑在OpenGL和D3D下了,但似乎D3D的效果要略好一点,精度更细致,天空盒的采样也没有裂缝,搞不懂为什么:) 在最后的效果上减少了一点,因为我基本不需要折射,只采用了反射,另外还没加太阳光的反射。

    这个实现中作者采用了"projected grid"的方法,此方法的好处是能使海面总能充满整个视野,也就是说海面的网格总是跟着视点在实时扩展的,永远走不到海的边界(这不正是有时候我们需要的吗?)它利用摄像机和海平面的位置来反算出当前为了让海面充满视野所需要的网格顶点位置,这些网格顶点在投影计算后在视口(viewport)内是均匀分布的点。我在程序中使用了128*256的网格,也就是128*256*2个三角形。

    这里是实现步骤的要点:
    1. Use projected grid concept to caculate the 4 corners' positions of the ocean base plane. Through interpolation get all the mesh  vertices's XZ coordinates.
    2. Use 8 octaves of Perlin Noise, sum them up, and sample the noise to generate height field(Y coordinate).
       Render the height to a RTT(Render to Texture).
    3. Sample the heightmap to get the neighbor's height. Generate the normal vector by cross product of neighbors' coordinates.
       Render the normal to a RTT.
    4. Make use of normalmap to get per-pixel normal vec and thus determin the reflection vector,which is used to sample the sky cube.
    It's done!

    实现效果:


    到我做的这一步,肯定有许多可以优化的地方,只是对我自己来说暂时还没有必要,所以先搁下。另外Ogre自带的Ocean_Demo的计算速度很快,用的是GPU Gems中的方法,或许可以将Projected Grid方法和它结合一下。不知可否有人实现,或者大家现在都在用什么方法?

ps:很重要的,感谢滨姐帮忙调程序:)