From dfdc7ebf6bd9e1b1b42c235022ae907c8f719f7d Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 20 Dec 2025 23:51:22 +0300 Subject: [PATCH] add 'emission' block wrap property --- src/graphics/render/BlockWrapsRenderer.cpp | 25 +++++++++++++++------- src/graphics/render/BlockWrapsRenderer.hpp | 4 +++- src/graphics/render/ChunksRenderer.cpp | 5 ++--- src/graphics/render/MainBatch.cpp | 14 ++++++------ src/graphics/render/MainBatch.hpp | 2 +- src/voxels/Chunks.cpp | 2 +- src/voxels/Chunks.hpp | 2 +- 7 files changed, 32 insertions(+), 22 deletions(-) diff --git a/src/graphics/render/BlockWrapsRenderer.cpp b/src/graphics/render/BlockWrapsRenderer.cpp index c169bebfb..c286e28ce 100644 --- a/src/graphics/render/BlockWrapsRenderer.cpp +++ b/src/graphics/render/BlockWrapsRenderer.cpp @@ -7,6 +7,7 @@ #include "graphics/core/Shader.hpp" #include "graphics/core/DrawContext.hpp" #include "graphics/render/MainBatch.hpp" +#include "lighting/Lightmap.hpp" #include "objects/Player.hpp" #include "voxels/Block.hpp" #include "voxels/Chunks.hpp" @@ -41,36 +42,45 @@ void BlockWrapsRenderer::draw(BlockWrapper& wrapper, const Texture* texture) { return; } + const voxel* vox = chunks.get(wrapper.position); + if (vox == nullptr || vox->id == BLOCK_VOID) { + return; + } // one frame can be invalid due to texture change but ok const auto& def = - level.content.getIndices()->blocks.require(wrapper.vox->id); + level.content.getIndices()->blocks.require(vox->id); - if (wrapper.modelType != def.getModel(wrapper.vox->state.userbits).type) { + if (wrapper.modelType != def.getModel(vox->state.userbits).type) { wrapper.dirtySides = 0xFF; refreshWrapper(wrapper); } + glm::vec4 light(1, 1, 1, 0); + if (wrapper.emission < 1.0f) { + light = Lightmap::extractNormalized(chunks.getLight(wrapper.position)); + light = wrapper.emission + (1.0f - light); + } switch (wrapper.modelType) { case BlockModelType::BLOCK: batch->cube( glm::vec3(wrapper.position) + glm::vec3(0.5f), glm::vec3(1.01f), wrapper.uvRegions, - glm::vec4(1, 1, 1, 0), - false, + light, + wrapper.emission, cullingBits ); break; case BlockModelType::AABB: { const auto& aabb = - (def.rotatable ? def.rt.hitboxes[wrapper.vox->state.rotation] + (def.rotatable ? def.rt.hitboxes[vox->state.rotation] : def.hitboxes).at(0); const auto& size = aabb.size(); batch->cube( glm::vec3(wrapper.position) + aabb.center(), size * glm::vec3(1.01f), wrapper.uvRegions, - glm::vec4(1, 1, 1, 0), - false, + light, + wrapper.emission, cullingBits ); break; @@ -117,7 +127,6 @@ void BlockWrapsRenderer::refreshWrapper(BlockWrapper& wrapper) { default: break; } - wrapper.vox = vox; } void BlockWrapsRenderer::draw(const DrawContext& pctx, const Player& player) { diff --git a/src/graphics/render/BlockWrapsRenderer.hpp b/src/graphics/render/BlockWrapsRenderer.hpp index ebb4d0e8a..2d14e4a93 100644 --- a/src/graphics/render/BlockWrapsRenderer.hpp +++ b/src/graphics/render/BlockWrapsRenderer.hpp @@ -22,9 +22,11 @@ class DrawContext; struct BlockWrapper { glm::ivec3 position; std::array textureFaces {}; + float emission = 1.0f; + + // --- render cache --- util::TextureRegion texRegions[6] {}; UVRegion uvRegions[6] {}; - const voxel* vox = nullptr; BlockModelType modelType {}; uint8_t cullingBits = 0xFF; uint8_t dirtySides = 0xFF; diff --git a/src/graphics/render/ChunksRenderer.cpp b/src/graphics/render/ChunksRenderer.cpp index 8289967c1..78bf6f2e7 100644 --- a/src/graphics/render/ChunksRenderer.cpp +++ b/src/graphics/render/ChunksRenderer.cpp @@ -128,12 +128,11 @@ const Mesh* ChunksRenderer::render( chunk->flags.modified = false; if (important) { auto voxelsBuffer = prepareVoxelsVolume(*chunk); - inwork[key] = true; auto mesh = renderer->render(chunk.get(), *voxelsBuffer); - meshes[glm::ivec2(chunk->x, chunk->z)] = + meshes[key] = ChunkMesh {std::move(mesh.mesh), std::move(mesh.sortingMeshData)}; - return meshes[glm::ivec2(chunk->x, chunk->z)].mesh.get(); + return meshes[key].mesh.get(); } if (inwork.find(key) != inwork.end()) { return nullptr; diff --git a/src/graphics/render/MainBatch.cpp b/src/graphics/render/MainBatch.cpp index 2cc6e90ca..1498e1537 100644 --- a/src/graphics/render/MainBatch.cpp +++ b/src/graphics/render/MainBatch.cpp @@ -87,7 +87,7 @@ void MainBatch::cube( const glm::vec3& size, const UVRegion(&texfaces)[6], const glm::vec4& tint, - bool shading, + float emission, uint8_t cullingBits ) { const glm::vec3 X(1.0f, 0.0f, 0.0f); @@ -98,42 +98,42 @@ void MainBatch::cube( quad( coord + Z * size.z * 0.5f, X, Y, Z, glm::vec2(size.x, size.y), - (shading ? do_tint(0.8) * tint : tint), + do_tint((1.0f - emission) * 0.8 + emission) * tint, glm::vec3(1.0f), texfaces[5] ); if (cullingBits & 0x10) quad( coord - Z * size.z * 0.5f, -X, Y, -Z, glm::vec2(size.x, size.y), - (shading ? do_tint(0.9f) * tint : tint), + do_tint((1.0f - emission) * 0.9 + emission) * tint, glm::vec3(1.0f), texfaces[4] ); if (cullingBits & 0x8) quad( coord + Y * size.y * 0.5f, -X, Z, Y, glm::vec2(size.x, size.z), - (shading ? do_tint(1.0f) * tint : tint), + do_tint((1.0f - emission) * 1.0 + emission) * tint, glm::vec3(1.0f), texfaces[3] ); if (cullingBits & 0x4) quad( coord - Y * size.y * 0.5f, X, Z, -Y, glm::vec2(size.x, size.z), - (shading ? do_tint(0.7f) * tint : tint), + do_tint((1.0f - emission) * 0.7 + emission) * tint, glm::vec3(1.0f), texfaces[2] ); if (cullingBits & 0x2) quad( coord + X * size.x * 0.5f, -Z, Y, X, glm::vec2(size.z, size.y), - (shading ? do_tint(0.8f) * tint : tint), + do_tint((1.0f - emission) * 0.8 + emission) * tint, glm::vec3(1.0f), texfaces[1] ); if (cullingBits & 0x1) quad( coord - X * size.x * 0.5f, Z, Y, -X, glm::vec2(size.z, size.y), - (shading ? do_tint(0.9f) * tint : tint), + do_tint((1.0f - emission) * 0.9 + emission) * tint, glm::vec3(1.0f), texfaces[0] ); } diff --git a/src/graphics/render/MainBatch.hpp b/src/graphics/render/MainBatch.hpp index 2bb98cae8..da711b075 100644 --- a/src/graphics/render/MainBatch.hpp +++ b/src/graphics/render/MainBatch.hpp @@ -152,7 +152,7 @@ public: const glm::vec3& size, const UVRegion(&texfaces)[6], const glm::vec4& tint, - bool shading, + float emission, uint8_t cullingBits = 0xFF ); }; diff --git a/src/voxels/Chunks.cpp b/src/voxels/Chunks.cpp index 1233f089c..a4b693829 100644 --- a/src/voxels/Chunks.cpp +++ b/src/voxels/Chunks.cpp @@ -100,7 +100,7 @@ bool Chunks::isObstacleBlock(int32_t x, int32_t y, int32_t z) { return indices.blocks.require(v->id).obstacle; } -ubyte Chunks::getLight(const glm::ivec3& pos) const { +light_t Chunks::getLight(const glm::ivec3& pos) const { return getLight(pos.x, pos.y, pos.z); } diff --git a/src/voxels/Chunks.hpp b/src/voxels/Chunks.hpp index 94fac08ce..e185ce584 100644 --- a/src/voxels/Chunks.hpp +++ b/src/voxels/Chunks.hpp @@ -76,7 +76,7 @@ public: return get(pos.x, pos.y, pos.z); } - ubyte getLight(const glm::ivec3& pos) const; + light_t getLight(const glm::ivec3& pos) const; light_t getLight(int32_t x, int32_t y, int32_t z) const; ubyte getLight(int32_t x, int32_t y, int32_t z, int channel) const; void set(int32_t x, int32_t y, int32_t z, uint32_t id, blockstate state);