(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?
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);
}
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;