3

Im making a voxel game, and i have designed the water as cubes with 0.5 alpha. It works great if all the water is at the same height, like in the image below:

Water at the same height

But, if the water is not at the same height, alpha overlapping happens:

Alpha overlapping at different heights

How can I prevent this overlapping to occur? (For example, only drawing the nearest water body for each pixel, discarding the remaining). Should I need to use FrameBuffers, drawing the scene with multiple passes, or it would be enough by using a alternate blend function, or taking another less GPU expensive approach?

Kromster
  • 7,181
  • 7
  • 63
  • 111
Ivelate
  • 298
  • 2
  • 10

1 Answers1

4

I found an answer without drawing the scene with multiple passes. I hope it helps somebody:

We are going to draw the nearest water body for each pixel, discarding the remaining, and so, avoiding the overlapping.

  1. First, you draw the solid blocks normally.
  2. Then, you draw the water after disabling writing in the color buffer glColorMask(false,false,false,false). The Z-buffer will be updated as desired, but no water will be drawn yet.
  3. Finally, you enable writing in the color buffer (glColorMask(true,true,true,true) ) and set the depthFunc to LEQUAL ( glDepthFunc(GL_LEQUAL) ). Only the nearest water pixels will pass the depth test (Setting it to LEQUAL instead of EQUAL deals with some rare but possible floating point approximation errors). Enabling blending and drawing the water again will produce the effect we wanted:

enter image description here

Ivelate
  • 298
  • 2
  • 10