add 'emission' block wrap property

This commit is contained in:
MihailRis 2025-12-20 23:51:22 +03:00
parent 54d1398d1b
commit dfdc7ebf6b
7 changed files with 32 additions and 22 deletions

View file

@ -7,6 +7,7 @@
#include "graphics/core/Shader.hpp" #include "graphics/core/Shader.hpp"
#include "graphics/core/DrawContext.hpp" #include "graphics/core/DrawContext.hpp"
#include "graphics/render/MainBatch.hpp" #include "graphics/render/MainBatch.hpp"
#include "lighting/Lightmap.hpp"
#include "objects/Player.hpp" #include "objects/Player.hpp"
#include "voxels/Block.hpp" #include "voxels/Block.hpp"
#include "voxels/Chunks.hpp" #include "voxels/Chunks.hpp"
@ -41,36 +42,45 @@ void BlockWrapsRenderer::draw(BlockWrapper& wrapper, const Texture* texture) {
return; 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 // one frame can be invalid due to texture change but ok
const auto& def = 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; wrapper.dirtySides = 0xFF;
refreshWrapper(wrapper); 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) { switch (wrapper.modelType) {
case BlockModelType::BLOCK: case BlockModelType::BLOCK:
batch->cube( batch->cube(
glm::vec3(wrapper.position) + glm::vec3(0.5f), glm::vec3(wrapper.position) + glm::vec3(0.5f),
glm::vec3(1.01f), glm::vec3(1.01f),
wrapper.uvRegions, wrapper.uvRegions,
glm::vec4(1, 1, 1, 0), light,
false, wrapper.emission,
cullingBits cullingBits
); );
break; break;
case BlockModelType::AABB: { case BlockModelType::AABB: {
const auto& 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); : def.hitboxes).at(0);
const auto& size = aabb.size(); const auto& size = aabb.size();
batch->cube( batch->cube(
glm::vec3(wrapper.position) + aabb.center(), glm::vec3(wrapper.position) + aabb.center(),
size * glm::vec3(1.01f), size * glm::vec3(1.01f),
wrapper.uvRegions, wrapper.uvRegions,
glm::vec4(1, 1, 1, 0), light,
false, wrapper.emission,
cullingBits cullingBits
); );
break; break;
@ -117,7 +127,6 @@ void BlockWrapsRenderer::refreshWrapper(BlockWrapper& wrapper) {
default: default:
break; break;
} }
wrapper.vox = vox;
} }
void BlockWrapsRenderer::draw(const DrawContext& pctx, const Player& player) { void BlockWrapsRenderer::draw(const DrawContext& pctx, const Player& player) {

View file

@ -22,9 +22,11 @@ class DrawContext;
struct BlockWrapper { struct BlockWrapper {
glm::ivec3 position; glm::ivec3 position;
std::array<std::string, 6> textureFaces {}; std::array<std::string, 6> textureFaces {};
float emission = 1.0f;
// --- render cache ---
util::TextureRegion texRegions[6] {}; util::TextureRegion texRegions[6] {};
UVRegion uvRegions[6] {}; UVRegion uvRegions[6] {};
const voxel* vox = nullptr;
BlockModelType modelType {}; BlockModelType modelType {};
uint8_t cullingBits = 0xFF; uint8_t cullingBits = 0xFF;
uint8_t dirtySides = 0xFF; uint8_t dirtySides = 0xFF;

View file

@ -128,12 +128,11 @@ const Mesh<ChunkVertex>* ChunksRenderer::render(
chunk->flags.modified = false; chunk->flags.modified = false;
if (important) { if (important) {
auto voxelsBuffer = prepareVoxelsVolume(*chunk); auto voxelsBuffer = prepareVoxelsVolume(*chunk);
inwork[key] = true;
auto mesh = renderer->render(chunk.get(), *voxelsBuffer); 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)}; 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()) { if (inwork.find(key) != inwork.end()) {
return nullptr; return nullptr;

View file

@ -87,7 +87,7 @@ void MainBatch::cube(
const glm::vec3& size, const glm::vec3& size,
const UVRegion(&texfaces)[6], const UVRegion(&texfaces)[6],
const glm::vec4& tint, const glm::vec4& tint,
bool shading, float emission,
uint8_t cullingBits uint8_t cullingBits
) { ) {
const glm::vec3 X(1.0f, 0.0f, 0.0f); const glm::vec3 X(1.0f, 0.0f, 0.0f);
@ -98,42 +98,42 @@ void MainBatch::cube(
quad( quad(
coord + Z * size.z * 0.5f, coord + Z * size.z * 0.5f,
X, Y, Z, glm::vec2(size.x, size.y), 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] glm::vec3(1.0f), texfaces[5]
); );
if (cullingBits & 0x10) if (cullingBits & 0x10)
quad( quad(
coord - Z * size.z * 0.5f, coord - Z * size.z * 0.5f,
-X, Y, -Z, glm::vec2(size.x, size.y), -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] glm::vec3(1.0f), texfaces[4]
); );
if (cullingBits & 0x8) if (cullingBits & 0x8)
quad( quad(
coord + Y * size.y * 0.5f, coord + Y * size.y * 0.5f,
-X, Z, Y, glm::vec2(size.x, size.z), -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] glm::vec3(1.0f), texfaces[3]
); );
if (cullingBits & 0x4) if (cullingBits & 0x4)
quad( quad(
coord - Y * size.y * 0.5f, coord - Y * size.y * 0.5f,
X, Z, -Y, glm::vec2(size.x, size.z), 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] glm::vec3(1.0f), texfaces[2]
); );
if (cullingBits & 0x2) if (cullingBits & 0x2)
quad( quad(
coord + X * size.x * 0.5f, coord + X * size.x * 0.5f,
-Z, Y, X, glm::vec2(size.z, size.y), -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] glm::vec3(1.0f), texfaces[1]
); );
if (cullingBits & 0x1) if (cullingBits & 0x1)
quad( quad(
coord - X * size.x * 0.5f, coord - X * size.x * 0.5f,
Z, Y, -X, glm::vec2(size.z, size.y), 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] glm::vec3(1.0f), texfaces[0]
); );
} }

View file

@ -152,7 +152,7 @@ public:
const glm::vec3& size, const glm::vec3& size,
const UVRegion(&texfaces)[6], const UVRegion(&texfaces)[6],
const glm::vec4& tint, const glm::vec4& tint,
bool shading, float emission,
uint8_t cullingBits = 0xFF uint8_t cullingBits = 0xFF
); );
}; };

View file

@ -100,7 +100,7 @@ bool Chunks::isObstacleBlock(int32_t x, int32_t y, int32_t z) {
return indices.blocks.require(v->id).obstacle; 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); return getLight(pos.x, pos.y, pos.z);
} }

View file

@ -76,7 +76,7 @@ public:
return get(pos.x, pos.y, pos.z); 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; 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; 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); void set(int32_t x, int32_t y, int32_t z, uint32_t id, blockstate state);