I am creating a voxel game with OpenGL, and I would like to implement water. My voxel world is divided into chunks of 16x256x16 cubes (or voxels). Each chunk has its own VAO with two VBOs, the first one containing a cube, and the second one being used to store the model matrices and the texture coordinates of the visible cubes. I use the Instancing method from OpenGL to render every cube (or voxels) in a chunk with a single draw call.
Recently I've wanted to implement water. For the sake of simplicity, water in my game is simply a cube with a blueish translucent texture. However, the fact that the texture is not completely opaque nor completely transparent causes issues with the depth buffer. With completely transparent cubes, I can use the discard;
method in the fragment shader. However here, I can't, or my water texture would be completely transparent.
I've looked for solutions to my problem on Internet, and one way I found to achieve proper semi-transparency would be to render the cubes from back to front. But rebuilding the second VBO every frame would absolutely destroy my game's performance. Another solution I found was to first render all the opaque cubes in the world, then render all the translucent cubes. While this solution sounds good on paper, it means I would have to create a second VAO containing only the translucent cubes for every chunk, which again, would be terrible for the performance.
So, what would be the best way to implement water in my voxel game ?