]> git.localhorst.tv Git - blank.git/commitdiff
slight lighting improvement
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Mon, 1 Jun 2015 15:08:45 +0000 (17:08 +0200)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Mon, 1 Jun 2015 15:08:45 +0000 (17:08 +0200)
using a combination of interpolation and occlusion

TODO
src/block.hpp
src/chunk.cpp
src/chunk.hpp

diff --git a/TODO b/TODO
index 29fd94f455fd3353136ec2758565f383e4a8d195..411172d92ab27909b97fb62fa4c444e17e3539a5 100644 (file)
--- 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?
 
index 2c26ed7d8fbae180c75c757c17fb637bdc612317..84efa4894b0dd9146d6f22b1c1b8e11dd7cffec0 100644 (file)
@@ -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<int> FaceNormal(Face face) noexcept {
                return face2normal[face];
        }
index f172143cbf11180cc650557c900267b2eb5ee707..a0415fd4f8f735072cf92174eb530d6a7c2423eb 100644 (file)
@@ -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);
 }
 
 
index 24024f9710aa803446b850872529396908d3c52b..040a817c87197b39586b867df66262cd5cbd4e61 100644 (file)
@@ -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;