I'm currently working on an infinite world, mostly inspired by minecraft.  
A **Chunk** consists of 16x16x16 blocks. A block(cube) is 1x1x1.  

This runs very smoothly with a **ViewRange** of 12 Chunks (12x16) on my computer. Fine.   
When I change the Chunk height to 256 this becomes - obviously - incredible laggy.

**So what I basically want to do** is stacking chunks. That means my world could be [∞,16,∞] Chunks large.  


**The question is now** how to generate chunks on the fly?  
At the moment I generate not existing chunks circular around my position (near to far). Since I don't stack chunks yet, this is not very complex.

As **important side note** here: I also want to have biomes, with different min/max height. So in Biome *Flatlands* the highest layer with blocks would be 8 (8x16) - in Biome *Mountains* the highest layer with blocks would be 14 (14x16). Just as example.

**What I could do** would be loading 1 Chunk above and below me for example.  
But here **the problem** would be, that transitions between different bioms could be larger than one chunk on y.  


<br /><br /><br />
![Transitions between Biomes][1]

<br /><br /><br />

My **current chunk loading** in action

![Chunk Loading Example][2]

<br /><br />

For the completeness here my current chunk loading "algorithm"

    private IEnumerator UpdateChunks(){
        for (int i = 1; i < VIEW_RANGE; i += ChunkWidth) {
            float vr = i;
            for (float x = transform.position.x - vr; x < transform.position.x + vr; x += ChunkWidth) {
                for (float z = transform.position.z - vr; z < transform.position.z + vr; z += ChunkWidth) {

                    _pos.Set(x, 0, z); // no y, yet
                    _pos.x = Mathf.Floor(_pos.x/ChunkWidth)*ChunkWidth;
                    _pos.z = Mathf.Floor(_pos.z/ChunkWidth)*ChunkWidth;

                    Chunk chunk = Chunk.FindChunk(_pos);
                    
                    // If Chunk is already created, continue
                    if (chunk != null)
                        continue;

                    // Create a new Chunk..
                    chunk = (Chunk) Instantiate(ChunkFab, _pos, Quaternion.identity);
                }
            }
            // Skip to next frame
            yield return 0;
        }
    }


  [1]: https://i.sstatic.net/YSczJ.png
  [2]: https://i.sstatic.net/1u5km.gif