From: Daniel Karbach Date: Mon, 1 Jun 2015 15:08:45 +0000 (+0200) Subject: slight lighting improvement X-Git-Url: http://git.localhorst.tv/?a=commitdiff_plain;h=bee003d1d375789b6533cfd39c65f6d4478f1966;p=blank.git slight lighting improvement using a combination of interpolation and occlusion --- diff --git a/TODO b/TODO index 29fd94f..411172d 100644 --- a/TODO +++ b/TODO @@ -40,10 +40,9 @@ entity ai (block) lighting - light levels are roughtly implemented. the shader has to be - adjusted so they actually have an impact on the resulting color - - there seems to be a bug with propagating light across chunk borders + occlusion/neighbor light mixing is implemented, but still linear + this could be solved by using a pre-interpolated light texture and + mapping light levels to coordinates on that also: how could block light affect entity lighting? diff --git a/src/block.hpp b/src/block.hpp index 2c26ed7..84efa48 100644 --- a/src/block.hpp +++ b/src/block.hpp @@ -55,6 +55,21 @@ struct Block { return Face(f ^ 1); } + static int Axis(Face f) noexcept { + switch (f) { + case FACE_UP: + case FACE_DOWN: + return 1; + default: + case FACE_RIGHT: + case FACE_LEFT: + return 0; + case FACE_FRONT: + case FACE_BACK: + return 2; + } + } + static glm::tvec3 FaceNormal(Face face) noexcept { return face2normal[face]; } diff --git a/src/chunk.cpp b/src/chunk.cpp index f172143..a0415fd 100644 --- a/src/chunk.cpp +++ b/src/chunk.cpp @@ -333,18 +333,81 @@ float Chunk::GetVertexLight(int index, const BlockModel::Position &vtx, const Mo if (direct_light > light) { light = direct_light; } + } else { + return light; + } + + if (Type(BlockAt(index)).luminosity > 0 || direct.GetType().block_light) { + return light; + } + + Block::Face edge[2]; + switch (Block::Axis(direct_face)) { + case 0: // X + edge[0] = (vtx.y - pos.y) > 0.5f ? Block::FACE_UP : Block::FACE_DOWN; + edge[1] = (vtx.z - pos.z) > 0.5f ? Block::FACE_FRONT : Block::FACE_BACK; + break; + case 1: // Y + edge[0] = (vtx.z - pos.z) > 0.5f ? Block::FACE_FRONT : Block::FACE_BACK; + edge[1] = (vtx.x - pos.x) > 0.5f ? Block::FACE_RIGHT : Block::FACE_LEFT; + break; + case 2: // Z + edge[0] = (vtx.x - pos.x) > 0.5f ? Block::FACE_RIGHT : Block::FACE_LEFT; + edge[1] = (vtx.y - pos.y) > 0.5f ? Block::FACE_UP : Block::FACE_DOWN; + break; } - // cheap alternative until AO etc are implemented - // to tell the faces apart + int num = 1; + int occlusion = 0; + + BlockLookup next[2] = { + direct.Next(edge[0]), + direct.Next(edge[1]), + }; - if (direct_face == Block::FACE_LEFT || direct_face == Block::FACE_RIGHT) { - light -= 0.2; - } else if (direct_face == Block::FACE_FRONT || direct_face == Block::FACE_BACK) { - light -= 0.4; + if (next[0]) { + if (next[0].GetType().block_light) { + ++occlusion; + } else { + light += next[0].GetLight(); + ++num; + } + } + if (next[1]) { + if (next[1].GetType().block_light) { + ++occlusion; + } else { + light += next[1].GetLight(); + ++num; + } + } + if (occlusion < 2) { + if (next[0]) { + BlockLookup corner = next[0].Next(edge[1]); + if (corner) { + if (corner.GetType().block_light) { + ++occlusion; + } else { + light += corner.GetLight(); + ++num; + } + } + } else if (next[1]) { + BlockLookup corner = next[1].Next(edge[0]); + if (corner) { + if (corner.GetType().block_light) { + ++occlusion; + } else { + light += corner.GetLight(); + ++num; + } + } + } + } else { + ++occlusion; } - return light; + return (light / num) - (occlusion * 0.8f); } diff --git a/src/chunk.hpp b/src/chunk.hpp index 24024f9..040a817 100644 --- a/src/chunk.hpp +++ b/src/chunk.hpp @@ -172,6 +172,9 @@ public: const BlockType &GetType() const noexcept { return GetChunk().Type(GetBlock()); } int GetLight() const noexcept { return GetChunk().GetLight(GetBlockPos()); } + // traverse in given direction + BlockLookup Next(Block::Face f) const { return BlockLookup(chunk, pos, f); } + private: Chunk *chunk; Chunk::Pos pos;