3

I am about to create a light system for my game and I actually have it setup, but with this "blocky" lightning as seen in the image. I would like to smooth the faces so that two different tiles aren't notable.

I have looked around on the subject and the only real answer I found is to average all 4 surrounding neighbors light and create a gradient from it. The answer was found here, but with no special rules to follow because that is what I need to find out.

The light intensity of each tile is a fixed number between 100-255, where 100 is the darkest and 255 is the brightest(opacity) and each vertex gets this value.

Do I have to find out which neighbors use each tiles vertex point and go on from there? I really have no clue

The current version of my light look like this: EDIT: Now it looks like this. It has some flaws. enter image description here

I tried to collect all the neighbours vertices and take the average of them(see image below). By following this method, I will receive different intensity values on each vertex.

enter image description here

This is a beginning of the algorithm. This function is meant to run for every tile in the light. From my current state of the algorithm I need to find the vertices on the same point. I am stuck here! :'-( I have updated the algorithm, but it's still got some visual flaws. Note how the top left and the bottom right sides are "blocky" when the others aren't. Also if you look very closely at the center, there is a hexagon shape, ~3 wide and high.

void Torch::smoothLight(int pX, int pY)
{
    if (pX == 0 || pX == (mWidth - 1) || pY == 0 || pY == (mHeight - 1)) return;

    // Tile we are smoothing
    Tile *c = mTilesInRange[pY * mWidth + pX];
    if (c == nullptr) return;

    int x_min_1 = pX - 1;
    int x_plus_1 = pX + 1;
    int y_min_1 = pY - 1;
    int y_plus_1 = pY + 1;

    // Get all nearby tiles in all 8 weather directions
    Tile *NW = mTilesInRange[y_min_1 * mWidth + x_min_1];
    Tile *N = mTilesInRange[y_min_1 * mWidth + pX];
    Tile *NE = mTilesInRange[y_min_1 * mWidth + x_plus_1];
    Tile *E = mTilesInRange[pY * mWidth + x_plus_1];
    Tile *SW = mTilesInRange[y_plus_1 * mWidth + x_min_1];
    Tile *S = mTilesInRange[y_plus_1 * mWidth + pX];
    Tile *SE = mTilesInRange[y_plus_1 * mWidth + x_plus_1];
    Tile *W = mTilesInRange[pY * mWidth + x_min_1];

    /*
        - Loop trough all 4 vertices on the tile in the following order

        0 1
        2 3

        - For each vertex, find the 3 other vertices that lies on the same point, example vertex 1:

        0 1  <--
        2 3

                            0 1 0 1
                            2 3 2 3
        Original quad   ->  0 1 0 1
                        ->  2 3 2 3

        Result: 3 2
                1 0
    */
    for (int i = 0; i < 4; i++)
    {
        int intensitySum = 0;

        // This is really ugly but I can't come up with a better algorithm
        if (i == 0) // upper left
        {
            intensitySum += c->getQuad()[0].color.a; // me
            intensitySum += N->getQuad()[3].color.a;
            intensitySum += NW->getQuad()[2].color.a;
            intensitySum += W->getQuad()[1].color.a;

            int alpha = intensitySum / 4;
            c->getQuad()[0].color.a = alpha;
        } 
        else if (i == 1) // upper right
        {
            intensitySum += c->getQuad()[1].color.a; // me
            intensitySum += N->getQuad()[2].color.a;
            intensitySum += NE->getQuad()[3].color.a;
            intensitySum += E->getQuad()[0].color.a;

            int alpha = intensitySum / 4;
            c->getQuad()[1].color.a = alpha;
        }
        else if (i == 2) // lower left
        {
            intensitySum += c->getQuad()[2].color.a; // me
            intensitySum += E->getQuad()[3].color.a;
            intensitySum += SE->getQuad()[0].color.a;
            intensitySum += S->getQuad()[1].color.a;

            int alpha = intensitySum / 4;
            c->getQuad()[2].color.a = alpha;
        }
        else if (i == 3) // lower right
        {
            intensitySum += c->getQuad()[3].color.a; // me
            intensitySum += S->getQuad()[0].color.a;
            intensitySum += SW->getQuad()[1].color.a;
            intensitySum += W->getQuad()[2].color.a;

            int alpha = intensitySum / 4;
            c->getQuad()[3].color.a = alpha;
        }
    }
}
Community
  • 1
  • 1
  • Ummm doesn't minecraft use opengl pixel shaders and Phong shading when set to fancy lighting settings? – luk32 Jun 24 '14 at 18:01
  • I don't think they use shaders. There is a very brief explanation about [Smooth Lightning](http://minecraft.gamepedia.com/Light#Smooth_lighting) from the minecraftwiki, unfortunately without any technical explanation. –  Jun 24 '14 at 18:09
  • Seems you're right but then I'd advise to read up on 2D Ambient Occlusion, something like here: http://codebin.co.uk/blog/fake-ambient-occlusion-part1/ – luk32 Jun 24 '14 at 18:28
  • AO is just one feature in theirs lightning engine. They stated that "interpolating lighting across block faces" is another feature along with AO to make the smooth lightning. So interpolation across tiles is what I want to achieve, but from there I am lost. –  Jun 24 '14 at 18:39
  • How to "get vertices that lie on the same point"? This question is language/library specific isn't it. You should tag those in. I thought you were asking more on the algorithm side. So, I deleted my answer that suggested you look at Gaussian blur. – Apiwat Chantawibul Jun 24 '14 at 20:31
  • @Balliska It isn't really language specific, else I would have tagged it with C++. But I tried to explain the algorithm in the comment. Isn't that clear for you? If not, I have to re-phrase it. –  Jun 24 '14 at 20:51

0 Answers0