I've been programming in C++ as a hobby for about 4 months now, and I've really loved creating stuff using voxels. I wrote a "game" (More of just a personal challenge, as I really only did the terrain, no gameplay) that rendered a Minecraft-like world, but recently I've been thinking about trying to write a game/challenge/etc that uses an algorithm such as Marching Cubes or Dual Contouring and reducing the voxel size. When I wrote my Minecraft-like project, I stored each chunk's data in a multidimensional array of unsigned shorts (thus giving me up to 65536 different block types). Additionally, for rendering, I only stored one point (as a GLubyte) and another GLubyte to indicate which of the 6 faces the point represented. I then rendered the face using a geometry shader. All of this was done to save the amount of RAM usage my project required, as I wanted to have the render distance out as far as possible.
With the new project I've been thinking about, the thing I can't wrap my head around is how I can possibly store enough voxel data to have voxels around ~5cm or 10cm compared to the old 1m sized voxels I had. When I rendered a 704x704x704 area of blocks, my old project used around 670MB of RAM. If I shrunk the voxel size to 10cm and kept the same render distance, that would be around 649GB of Voxel data (assuming 2 bytes per voxel and an area of 7040^3 voxels). Is there any way I can store the voxel data in a more efficient manner that still allows me a wide range of different voxel types?