Last lighting issue almost fixed.

This commit is contained in:
Quentin Bazin 2020-01-20 17:01:14 +09:00
parent ba3dfb3b7e
commit 3a2024d120
7 changed files with 57 additions and 26 deletions

View File

@ -50,7 +50,7 @@ class ChunkBuilder {
Torch
};
float getLightForVertex(Light light, u8 x, u8 y, u8 z, u8 i, u8 j, const glm::vec3 &normal, const ClientChunk &chunk);
u8 getLightForVertex(Light light, u8 x, u8 y, u8 z, u8 i, u8 j, const glm::vec3 &normal, const ClientChunk &chunk);
std::array<std::vector<gk::Vertex>, layers> m_vertices;

View File

@ -28,14 +28,22 @@ DebugOverlay::DebugOverlay(const ClientPlayer &player) : m_player(player) {
}
void DebugOverlay::update() {
s32 pcx = std::floor(m_player.x() / CHUNK_WIDTH);
s32 pcy = std::floor(m_player.y() / CHUNK_HEIGHT);
s32 pcz = std::floor(m_player.z() / CHUNK_DEPTH);
std::stringstream stream;
stream << "x: " << floorf(m_player.x()) << " | ";
stream << "y: " << floorf(m_player.y()) << " | ";
stream << "z: " << floorf(m_player.z());
stream << "x: " << std::floor(m_player.x()) << " | ";
stream << "y: " << std::floor(m_player.y()) << " | ";
stream << "z: " << std::floor(m_player.z());
stream << '\n';
stream << "cx: " << floorf(m_player.x() / CHUNK_WIDTH) << " | ";
stream << "cy: " << floorf(m_player.y() / CHUNK_HEIGHT) << " | ";
stream << "cz: " << floorf(m_player.z() / CHUNK_DEPTH);
stream << "rx: " << int(std::floor(m_player.x()) + std::abs(pcx) * CHUNK_WIDTH) % CHUNK_WIDTH << " | ";
stream << "ry: " << int(std::floor(m_player.y()) + std::abs(pcy) * CHUNK_HEIGHT) % CHUNK_HEIGHT << " | ";
stream << "rz: " << int(std::floor(m_player.z()) + std::abs(pcz) * CHUNK_DEPTH) % CHUNK_DEPTH;
stream << '\n';
stream << "cx: " << pcx << " | ";
stream << "cy: " << pcy << " | ";
stream << "cz: " << pcz;
m_positionText.setText(stream.str());
}

View File

@ -333,7 +333,21 @@ inline u8 ChunkBuilder::getAmbientOcclusion(u8 x, u8 y, u8 z, u8 i, u8 j, const
return 3 - (side1 + side2 + corner);
}
inline float ChunkBuilder::getLightForVertex(Light light, u8 x, u8 y, u8 z, u8 i, u8 j, const glm::vec3 &normal, const ClientChunk &chunk) {
inline u8 ChunkBuilder::getLightForVertex(Light light, u8 x, u8 y, u8 z, u8 i, u8 j, const glm::vec3 &normal, const ClientChunk &chunk) {
std::function<s8(const Chunk *chunk, s8, s8, s8)> getLight = [&](const Chunk *chunk, s8 x, s8 y, s8 z) -> s8 {
if(x < 0) return chunk->getSurroundingChunk(0)->isInitialized() ? getLight(chunk->getSurroundingChunk(0), x + CHUNK_WIDTH, y, z) : -1;
if(x >= CHUNK_WIDTH) return chunk->getSurroundingChunk(1)->isInitialized() ? getLight(chunk->getSurroundingChunk(1), x - CHUNK_WIDTH, y, z) : -1;
if(y < 0) return chunk->getSurroundingChunk(4)->isInitialized() ? getLight(chunk->getSurroundingChunk(4), x, y + CHUNK_HEIGHT, z) : -1;
if(y >= CHUNK_HEIGHT) return chunk->getSurroundingChunk(5)->isInitialized() ? getLight(chunk->getSurroundingChunk(5), x, y - CHUNK_HEIGHT, z) : -1;
if(z < 0) return chunk->getSurroundingChunk(2)->isInitialized() ? getLight(chunk->getSurroundingChunk(2), x, y, z + CHUNK_DEPTH) : -1;
if(z >= CHUNK_DEPTH) return chunk->getSurroundingChunk(3)->isInitialized() ? getLight(chunk->getSurroundingChunk(3), x, y, z - CHUNK_DEPTH) : -1;
if (light == Light::Sun)
return chunk->isInitialized() ? chunk->lightmap().getSunlight(x, y, z) : -1;
else
return chunk->isInitialized() ? chunk->lightmap().getTorchlight(x, y, z) : -1;
};
gk::Vector3i offset = getOffsetFromVertex(i, j);
gk::Vector3i minOffset{
@ -342,15 +356,30 @@ inline float ChunkBuilder::getLightForVertex(Light light, u8 x, u8 y, u8 z, u8 i
(normal.z != 0) ? offset.z : 0
};
if (light == Light::Sun)
return (chunk.lightmap().getSunlight(x + minOffset.x, y + offset.y, z + minOffset.z)
+ chunk.lightmap().getSunlight(x + offset.x, y + minOffset.y, z + minOffset.z)
+ chunk.lightmap().getSunlight(x + minOffset.x, y + minOffset.y, z + offset.z)
+ chunk.lightmap().getSunlight(x + offset.x, y + offset.y, z + offset.z)) / 4.0f;
// Get light values for surrounding nodes
s8 lightValues[4] = {
getLight(&chunk, x + minOffset.x, y + offset.y, z + minOffset.z),
getLight(&chunk, x + offset.x, y + minOffset.y, z + minOffset.z),
getLight(&chunk, x + minOffset.x, y + minOffset.y, z + offset.z),
getLight(&chunk, x + offset.x, y + offset.y, z + offset.z),
};
u8 count = 0, total = 0;
for (u8 i = 0 ; i < 4 ; ++i) {
// Fix light approximation
// if (i == 3 && lightValues[i] > lightValues[0] && !lightValues[1] && !lightValues[2])
// continue;
// If the chunk is initialized, add the light value to the total
if (lightValues[i] != -1) {
total += lightValues[i];
++count;
}
}
if (count)
return total / count;
else
return (chunk.lightmap().getTorchlight(x + minOffset.x, y + offset.y, z + minOffset.z)
+ chunk.lightmap().getTorchlight(x + offset.x, y + minOffset.y, z + minOffset.z)
+ chunk.lightmap().getTorchlight(x + minOffset.x, y + minOffset.y, z + offset.z)
+ chunk.lightmap().getTorchlight(x + offset.x, y + offset.y, z + offset.z)) / 4.0f;
return 0;
}

View File

@ -16,9 +16,8 @@
#include "ClientChunk.hpp"
void ClientChunk::update() {
if (m_hasChanged) {
if (m_lightmap.updateLights() || m_hasChanged) {
m_hasChanged = false;
m_lightmap.updateLights();
m_verticesCount = m_builder.buildChunk(*this, m_vbo);
}

View File

@ -56,6 +56,7 @@ class Chunk : public gk::NonCopyable {
s32 z() const { return m_z; }
Chunk *getSurroundingChunk(u8 i) { return (i > 5) ? nullptr : m_surroundingChunks[i]; }
const Chunk *getSurroundingChunk(u8 i) const { return (i > 5) ? nullptr : m_surroundingChunks[i]; }
void setSurroundingChunk(u8 i, Chunk *chunk) { if (i < 6) m_surroundingChunks[i] = chunk; }
bool areAllNeighboursLoaded() const;

View File

@ -253,9 +253,6 @@ u8 ChunkLightmap::getSunlight(int x, int y, int z) const {
if(z < 0) return m_chunk->getSurroundingChunk(2) ? m_chunk->getSurroundingChunk(2)->lightmap().getSunlight(x, y, z + CHUNK_DEPTH) : 15;
if(z >= CHUNK_DEPTH) return m_chunk->getSurroundingChunk(3) ? m_chunk->getSurroundingChunk(3)->lightmap().getSunlight(x, y, z - CHUNK_DEPTH) : 15;
if (!m_chunk->isInitialized())
return 15;
return (m_lightMap[x][y][z] >> 4) & 0xf;
}
@ -267,9 +264,6 @@ u8 ChunkLightmap::getTorchlight(int x, int y, int z) const {
if(z < 0) return m_chunk->getSurroundingChunk(2) ? m_chunk->getSurroundingChunk(2)->lightmap().getTorchlight(x, y, z + CHUNK_DEPTH) : 0;
if(z >= CHUNK_DEPTH) return m_chunk->getSurroundingChunk(3) ? m_chunk->getSurroundingChunk(3)->lightmap().getTorchlight(x, y, z - CHUNK_DEPTH) : 0;
if (!m_chunk->isInitialized())
return 15;
return m_lightMap[x][y][z] & 0xf;
}

View File

@ -36,7 +36,7 @@ void ServerWorld::update(Server &server, std::unordered_map<u16, ServerPlayer> &
for (auto &client : server.info().clients())
sendChunkData(client, it.second.get());
// DEBUG("Chunk updated at", it.second->x(), it.second->y(), it.second->z());
DEBUG("Chunk updated at", it.second->x(), it.second->y(), it.second->z());
}
}
}