I'm making a voxel game on OpenGL, and are trying to find a way to render semi-realistic water (At least partially good looking, it doesn't need to be strictly scientific accurate).

All sources written about that topic I find seem to assume that all the water in the scene has the same height, which is not the case on a voxel game, where you can have (And see at the same time) multiple bodies of water, with different height each.

The tricky detail lies in the multi-height part of the problem, which makes really difficult to render the scene in real time using typical water reflection algorithms aimed at single level water surface.

As an example, consider the following image: Different height water levels

The dirt pillar at the left should be reflected on the water at its front, as so should be the mountains near the horizon. The water collindant to the pillar is ~20m higher than the general sea water, so traditional reflection methods (Considering a fixed water level) would simply not work in this case. Considering that a lot of different water levels can be seen in a single scene, performing a traditional water reflection method for each water body height is not an option if we want to achieve a acceptable frame rate execution.

How can I overcome this problem? There is any way to render it in real time? If it isn't actually possible to do, what approximation should I take to get a good looking result, even if reflections aren't 100% realistic?

  • \$\begingroup\$ There's no way, those mountains get reflected on the water in real life, \$\endgroup\$ – Bálint Jan 30 '16 at 18:36
  • 1
    \$\begingroup\$ The last picture was more confusing than useful: I uploaded a new one. Hopefully, the problem can be seen clearly on the actual one. \$\endgroup\$ – Ivelate Jan 30 '16 at 18:53
  • \$\begingroup\$ This is quite complex to do, especially with voxels. Have you ever seen a voxel game with reflections? \$\endgroup\$ – Bálint Jan 30 '16 at 19:00
  • \$\begingroup\$ @Bálint No i havent, its true. I was just curious about if it was some way of doing that, or if it simply was impossible, altough there must be some kind of approximation to that problem wich produces a good looking result (Reflecting the nearest water body and just showing the sky on the others, etc.), even if its not realistic at all. \$\endgroup\$ – Ivelate Jan 30 '16 at 19:15
  • 1
    \$\begingroup\$ Showing only the sky is possible, with a cubemap for example, but in this case, it would destroy the illusion. \$\endgroup\$ – Bálint Jan 30 '16 at 21:00

There are two possibilities I can come up with that don't involve ordinary planar reflection.

The first is to perform screen-space reflection, which is fairly cheap and works for any manner of surface. However, it will be prone to artifacts, and of course it will not be able to reflect objects that are not visible from the regular point of view.

The other way is to go volumetric. You represent the world using voxels, inject lighting into it, and then use ray/cone tracing to perform reflections. An added benefit is that you then have the infrastructure in place to do more general global illumination. There's details pertinent to this method in the Voxel Cone Tracing paper.

  • \$\begingroup\$ Could you add more details on the second approach please? \$\endgroup\$ – Kromster Jan 30 '16 at 20:36
  • \$\begingroup\$ The paper was a really good read. Never thoght it would be possible to achieve such high framerates using "classical" raytracing. Anyways, it looks quite difficult to implement/resource heavy for my particular case (Altough I save it for future projects). Screen-space reflections, on the other hand, looks fast enough, and im fairly confident that the artifacts/not visible reflections can be more or less masked by a wave effect/adjusting fresnel. I'm accepting your answer :) \$\endgroup\$ – Ivelate Jan 31 '16 at 13:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.