Optimizing lighting algorithm for a voxel engine I am creating a Minecraft-like terrain engine in XNA to learn HLSL and more XNA. The problem is my lighting algorithm. Whenever a block which emits light is placed, it takes about half a second to calculate it. I have implemented the lighting in a recursive way.

public void DoLight(int x, int y, int z, float light)
{
    Vector3i xDecreasing = new Vector3i(x - 1, y, z);
    Vector3i xIncreasing = new Vector3i(x + 1, y, z);
    Vector3i yDecreasing = new Vector3i(x, y - 1, z);
    Vector3i yIncreasing = new Vector3i(x, y + 1, z);
    Vector3i zDecreasing = new Vector3i(x, y, z - 1);
    Vector3i zIncreasing = new Vector3i(x, y, z + 1);

    if (light &gt; 0)
    {
        light--;

        world.SetLight(x, y, z, (int)light);
        Blocks.Add(new Vector3(x, y, z));

        if (world.GetLight(yDecreasing.X, yDecreasing.Y, yDecreasing.Z) &lt; light &amp;&amp;
            !world.GetBlock(yDecreasing.X, yDecreasing.Y, yDecreasing.Z).IsSolid &amp;&amp;
            world.InBounds(yDecreasing.X, yDecreasing.Y, yDecreasing.Z))
            DoLight(x, y - 1, z, light);
        if (world.GetLight(yIncreasing.X, yIncreasing.Y, yIncreasing.Z) &lt; light &amp;&amp;
            !world.GetBlock(yIncreasing.X, yIncreasing.Y, yIncreasing.Z).IsSolid &amp;&amp;
            world.InBounds(yIncreasing.X, yIncreasing.Y, yIncreasing.Z))
            DoLight(x, y + 1, z, light);
        if (world.GetLight(xDecreasing.X, xDecreasing.Y, xDecreasing.Z) &lt; light &amp;&amp;
            !world.GetBlock(xDecreasing.X, xDecreasing.Y, xDecreasing.Z).IsSolid &amp;&amp;
            world.InBounds(xDecreasing.X, xDecreasing.Y, xDecreasing.Z))
            DoLight(x - 1, y, z, light);
        if (world.GetLight(xIncreasing.X, xIncreasing.Y, xIncreasing.Z) &lt; light &amp;&amp;
            !world.GetBlock(xIncreasing.X, xIncreasing.Y, xIncreasing.Z).IsSolid &amp;&amp;
            world.InBounds(xIncreasing.X, xIncreasing.Y, xIncreasing.Z))
            DoLight(x + 1, y, z, light);
        if (world.GetLight(zDecreasing.X, zDecreasing.Y, zDecreasing.Z) &lt; light &amp;&amp;
            !world.GetBlock(zDecreasing.X, zDecreasing.Y, zDecreasing.Z).IsSolid &amp;&amp;
            world.InBounds(yDecreasing.X, yDecreasing.Y, zDecreasing.Z))
            DoLight(x, y, z - 1, light);
        if (world.GetLight(zIncreasing.X, zIncreasing.Y, zIncreasing.Z) &lt; light &amp;&amp;
            !world.GetBlock(zIncreasing.X, zIncreasing.Y, zIncreasing.Z).IsSolid &amp;&amp;
            world.InBounds(zIncreasing.X, zIncreasing.Y, zIncreasing.Z))
            DoLight(x, y, z + 1, light);
    }
}


Does anyone see what is costing me so much performance? And if so, could you please suggest any way to fix it?

Especially when I try to update only a single light every frame, I get a depressingly low FPS of 4 (maybe the recursion is the problem).  Does anyone know if a iterative would increase performance ?  If so, how would I implement it?
Building upon Vadym's answer - the vector instantiation could probably be eliminated entirely.  It appears they are only created to provide nice groupings of x,y,z coordinates, as they are only ever referenced by pulling the x,y,z values back out.

If performance is really an issue, I would suggest keeping individual values instead for xincreasing, xdecreasing, etc. and using those.  It saves on the object creation and the property getter calls. (edit: and, to me at least, it is a little easier to read)

public void DoLight(int x, int y, int z, float light)
{
    int xDecreasing = x - 1;
    int xIncreasing = x + 1;
    int yDecreasing = y - 1;
    int yIncreasing = y + 1;
    int zDecreasing = z - 1;
    int zIncreasing = z + 1;

    if (light &gt; 0)
    {
        light--;

        world.SetLight(x, y, z, (int)light);
        Blocks.Add(new Vector3(x, y, z));

        if (world.GetLight(x, yDecreasing, z) &lt; light &amp;&amp;
            !world.GetBlock(x, yDecreasing, z).IsSolid &amp;&amp;
            world.InBounds(x, yDecreasing, z))
            DoLight(x, yDecreasing, z, light);
        if (world.GetLight(x, yIncreasing, z) &lt; light &amp;&amp;
            !world.GetBlock(x, yIncreasing, z).IsSolid &amp;&amp;
            world.InBounds(x, yIncreasing, z))
            DoLight(x, yIncreasing, z, light);
        if (world.GetLight(xDecreasing, y, z) &lt; light &amp;&amp;
            !world.GetBlock(xDecreasing, y, z).IsSolid &amp;&amp;
            world.InBounds(xDecreasing, y, z))
            DoLight(xDecreasing, y, z, light);
        if (world.GetLight(xIncreasing, y, z) &lt; light &amp;&amp;
            !world.GetBlock(xIncreasing, y, z).IsSolid &amp;&amp;
            world.InBounds(xIncreasing, y, z))
            DoLight(xIncreasing, y, z, light);
        if (world.GetLight(x, y, zDecreasing) &lt; light &amp;&amp;
            !world.GetBlock(x, y, zDecreasing).IsSolid &amp;&amp;
            world.InBounds(x, y, zDecreasing))
            DoLight(x, y, zDecreasing, light);
        if (world.GetLight(x, y, zIncreasing) &lt; light &amp;&amp;
            !world.GetBlock(x, y, zIncreasing).IsSolid &amp;&amp;
            world.InBounds(x, y, zIncreasing))
            DoLight(x, y, zIncreasing, light);
    }
}