Search Unity

Voxel Lighting Assistance Needed

Discussion in 'Scripting' started by JasonBricco, Sep 4, 2015.

  1. JasonBricco

    JasonBricco

    Joined:
    Jul 15, 2013
    Posts:
    956
    Hi all,

    I'm having a lot of trouble with voxel lighting. By this, I mean a flood-fill voxel lighting type system in a blocky voxel type game (think Minecraft).

    I don't need help on a code level, but more on a conceptual level. While this isn't directly about Unity, I figured I'd ask here anyway as I know there are several people with experience around here.

    Here's my understanding:

    For sunlight, iterate downward until the surface of the terrain is found. Do this for each x, z column. And once done, use a flood-fill propagation algorithm to scatter the light outwards and around obstacles. This propagation occurs by adding nodes to a list of all locations where there are sources of light (so place a node on each x, z column at the surface). Then flood fill out from these nodes.

    Simple enough. But how in the world do I handle neighbor chunks?

    If I want to load a chunk and draw a mesh for it, I need to know the lighting that enters this chunk from its neighbors. Well, I can run the propagation algorithm on the neighbor chunks and it will propagate into this chunk that I'm generating now. But it will also propagate into other chunks that haven't even been generated yet. And if it does, it won't know which blocks exist to block the light...

    So how can I generate light on a chunk by chunk basis without requiring every chunk in the whole world loaded before I start doing the lighting?

    Thanks for your help.

    (As a note: I had the lighting working before in a finite world where I could indeed have all chunks loaded at once. But now that I'm wanting much larger worlds, I need a new approach...)
     
  2. AdamAlexander

    AdamAlexander

    Joined:
    Jul 24, 2015
    Posts:
    73
    I ran into this same issue awhile back when I was playing around with infinite voxel worlds too. I can't remember entirely but I'm pretty sure this was my approach:

    The voxels had 16 discrete light values, where 0 is pitch black and 15 is maximum brightness. If a voxel was in direct sunlight then it was given a value of 15. If it wasn't then it was given the value of its brightest neighbour minus 1. I believe this is exactly how minecraft lights work as well.

    Since my chunk sizes were also 16x16 on the x-z plane this meant that light from one chunk could only be propagated as far as its adjacent chunks. So I just made sure that all of a chunks neighbours were loaded before calculating lights and polygonising it. For chunks that don't have all their neighbours loaded, just recalculate lights once their neighbours are available.

    Hope that helps!