3
\$\begingroup\$

I hope you can help me with the following problem:

I'm developing a 3d game (in XNA) with an ocean. I want it to look semi-realistic. So far, I'm rendering 4 things:

  • The ocean floor (terrain) on the view matrix (refraction)
  • The terrain above water on the mirrored view matrix (reflection)
  • The terrain above water on the view matrix (actual terrain)
  • The water, which is simply a plane, using the refraction and reflection rendertargets, the fresnel term, and a normal map to give the impression of small waves.

Instead of a flat plane, I want to render the water on a mesh, to get some actual waves going. This is where I've been stuck for a while now. It's quite simple to clip the terrain along that plane, but is it possible to clip a mesh along another mesh? Or am I going about this the wrong way?

\$\endgroup\$

3 Answers 3

1
\$\begingroup\$

Wave generation isn't a simple task.

The easy way is expensive. Right now you're rendering your water as a plane, why not just render all of your textures onto a more complex mesh? You could, with an algorithm, take your water plane and re-buffer it to take on a new shape every frame. It's messy and very intensive but it can work.

Here are some resources for the FFT wave generation algorithm:

https://developer.nvidia.com/sites/default/files/akamai/gamedev/files/sdk/11/OceanCS_Slides.pdf

http://www.edxgraphics.com/blog/simulating-ocean-waves-with-fft-on-gpu

Of course these resources (and many others) are using geometry/compute shaders on the GPU. The GPU can do all this re-buffering MUCH faster than the CPU but XNA is built over DX9 and only DX11 and up supports geometry shaders. Monogame has plans to support geometry shaders but it's not there yet.

If you use an algorithm that's less intensive than FFT like basic sin wave generation it might be less harsh on your CPU cycles. Here's a report on wave generation using DX9 (no geometry shaders) http://www.jamesgamlin.com/oceanwaves%20report.pdf

\$\endgroup\$
1
  • \$\begingroup\$ Thanks a ton! I'm working on a solution for the clipping problem right now, but for the waves, I'll definitely look at your examples. \$\endgroup\$
    – Peethor
    Jul 9, 2015 at 12:21
1
\$\begingroup\$

Honeybunch supplied quite a bit of information on creating waves. It's something I can definitely use, but not exactly what I was looking for. I'm posting an answer to my own question because I figured out how to do it. For future reference:

Before rendering anything, I render the water to a rendertarget (let's call it RT_WaterHeight) using a custom shader. The height of the water determines the output color. Let's say my base water level is at 15 units high, and my haves have a maximum amplitude of 5. That means at any point, the height of the water is between 10 and 20. The custom pixel shader calculates this (It's probably better performance-wise to precalculate a multiplier and pass that into the shader as an argument). and renders everything from black to white. 10 = black. 20 = white.

Then, with everything I render, I determine if it's above or below water by comparing its height to the same pixel on RT_WaterHeight. Everything is drawn using custom shaders, so in the pixel shader I can call "discard" if it shouldn't be drawn.

EDIT: This is what I used to do. It results in strange artefacting when looking at a terrain with the camera just above the water. Instead of rendering everything to a target and using that in the terrain shader.... I just sample the water's height map in the terrain shader.

\$\endgroup\$
-1
\$\begingroup\$

I would use a bump map - a texture of the waves, and then use some shader magic to make it look like there are waves. This is relatively cheap compared to creating custom meshes. The downside is that there are some edge artifacts and you need to make sure to resize all your render targets when you resize the viewport.

There's a Riemers page on this:

http://www.riemers.net/eng/Tutorials/XNA/Csharp/Series4/Moving_water.php

The situation you described is very similar to what they are making there and should integrate into your water plane easily.

\$\endgroup\$
2
  • \$\begingroup\$ That's precisely what I had. I asked if there is a way to clip a mesh along another mesh, stepping away from a simple plane. \$\endgroup\$
    – Peethor
    Apr 23, 2016 at 6:54
  • \$\begingroup\$ The original question stated that this is needed to get some actual waves going, as well as asking if there are alternatives. I suggested the bump map since it can create fairly realistic looking waves while not requiring any special clipping. \$\endgroup\$ Apr 26, 2016 at 11:12

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .