add particles lighting

This commit is contained in:
MihailRis 2024-11-03 02:23:37 +03:00
parent b944f257f7
commit 7abb1a88c7
10 changed files with 66 additions and 26 deletions

View File

@ -39,12 +39,15 @@ void Emitter::update(float delta, std::vector<Particle>& particles) {
// spawn particle // spawn particle
Particle particle = prototype; Particle particle = prototype;
particle.emitter = this; particle.emitter = this;
particle.random = rand();
particle.position = position; particle.position = position;
particle.velocity += glm::ballRand(1.0f) * explosion; particle.velocity += glm::ballRand(1.0f) * explosion;
particles.push_back(std::move(particle)); particles.push_back(std::move(particle));
timer -= spawnInterval; timer -= spawnInterval;
if (count > 0) {
count--; count--;
} }
}
} }
void Emitter::setExplosion(const glm::vec3& magnitude) { void Emitter::setExplosion(const glm::vec3& magnitude) {

View File

@ -14,6 +14,7 @@ struct Particle {
/// @brief Pointer used to access common behaviour. /// @brief Pointer used to access common behaviour.
/// Emitter must be utilized after all related particles despawn. /// Emitter must be utilized after all related particles despawn.
Emitter* emitter; Emitter* emitter;
int random;
/// @brief Global position /// @brief Global position
glm::vec3 position; glm::vec3 position;
/// @brief Linear velocity /// @brief Linear velocity
@ -28,6 +29,7 @@ class Texture;
struct ParticleBehaviour { struct ParticleBehaviour {
bool collision = true; bool collision = true;
bool lighting = true;
glm::vec3 gravity {0.0f, -16.0f, 0.0f}; glm::vec3 gravity {0.0f, -16.0f, 0.0f};
}; };

View File

@ -3,6 +3,8 @@
#include "graphics/core/Texture.hpp" #include "graphics/core/Texture.hpp"
#include "graphics/core/Mesh.hpp" #include "graphics/core/Mesh.hpp"
#include "graphics/core/ImageData.hpp" #include "graphics/core/ImageData.hpp"
#include "voxels/Chunks.hpp"
#include "voxels/Chunk.hpp"
static const vattr attrs[] = { static const vattr attrs[] = {
{3}, {2}, {3}, {1}, {0} {3}, {2}, {3}, {1}, {0}
@ -62,3 +64,19 @@ void MainBatch::prepare(int vertices) {
flush(); flush();
} }
} }
glm::vec4 MainBatch::sampleLight(
const glm::vec3& pos, const Chunks& chunks, bool backlight
) {
light_t light = chunks.getLight(
std::floor(pos.x),
std::floor(std::min(CHUNK_H-1.0f, pos.y)),
std::floor(pos.z));
light_t minIntensity = backlight ? 1 : 0;
return glm::vec4(
glm::max(Lightmap::extract(light, 0), minIntensity) / 15.0f,
glm::max(Lightmap::extract(light, 1), minIntensity) / 15.0f,
glm::max(Lightmap::extract(light, 2), minIntensity) / 15.0f,
glm::max(Lightmap::extract(light, 3), minIntensity) / 15.0f
);
}

View File

@ -9,6 +9,7 @@
class Mesh; class Mesh;
class Texture; class Texture;
class Chunks;
class MainBatch { class MainBatch {
std::unique_ptr<float[]> const buffer; std::unique_ptr<float[]> const buffer;
@ -36,6 +37,10 @@ public:
void setTexture(const Texture* texture, const UVRegion& region); void setTexture(const Texture* texture, const UVRegion& region);
void flush(); void flush();
static glm::vec4 sampleLight(
const glm::vec3& pos, const Chunks& chunks, bool backlight
);
inline void vertex( inline void vertex(
const glm::vec3& pos, const glm::vec3& pos,
const glm::vec2& uv, const glm::vec2& uv,

View File

@ -65,17 +65,7 @@ void ModelBatch::draw(const model::Mesh& mesh, const glm::mat4& matrix,
bool backlight) { bool backlight) {
glm::vec3 gpos = matrix * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); glm::vec3 gpos = matrix * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
gpos += lightsOffset; gpos += lightsOffset;
light_t light = chunks->getLight( glm::vec4 lights = MainBatch::sampleLight(gpos, *chunks, backlight);
std::floor(gpos.x),
std::floor(std::min(CHUNK_H-1.0f, gpos.y)),
std::floor(gpos.z));
light_t minIntensity = backlight ? 1 : 0;
glm::vec4 lights(
glm::max(Lightmap::extract(light, 0), minIntensity) / 15.0f,
glm::max(Lightmap::extract(light, 1), minIntensity) / 15.0f,
glm::max(Lightmap::extract(light, 2), minIntensity) / 15.0f,
glm::max(Lightmap::extract(light, 3), minIntensity) / 15.0f
);
setTexture(mesh.texture, varTextures); setTexture(mesh.texture, varTextures);
size_t vcount = mesh.vertices.size(); size_t vcount = mesh.vertices.size();
const auto& vertexData = mesh.vertices.data(); const auto& vertexData = mesh.vertices.data();

View File

@ -8,16 +8,20 @@
#include "window/Camera.hpp" #include "window/Camera.hpp"
#include "world/Level.hpp" #include "world/Level.hpp"
#include "voxels/Chunks.hpp" #include "voxels/Chunks.hpp"
#include "settings.hpp"
size_t ParticlesRenderer::visibleParticles = 0; size_t ParticlesRenderer::visibleParticles = 0;
size_t ParticlesRenderer::aliveEmitters = 0; size_t ParticlesRenderer::aliveEmitters = 0;
ParticlesRenderer::ParticlesRenderer(const Assets& assets, const Level& level) ParticlesRenderer::ParticlesRenderer(
: batch(std::make_unique<MainBatch>(1024)), level(level) { const Assets& assets, const Level& level, const GraphicsSettings* settings
)
auto region = util::get_texture_region(assets, "blocks:bazalt", ""); : batch(std::make_unique<MainBatch>(1024)),
emitters.push_back(std::make_unique<Emitter>(glm::vec3(0, 100, 0), Particle { level(level),
nullptr, glm::vec3(), glm::vec3(), 5.0f, region.region settings(settings) {
auto region = util::get_texture_region(assets, "blocks:grass_top", "");
emitters.push_back(std::make_unique<Emitter>(glm::vec3(0, 80, 0), Particle {
nullptr, 0, glm::vec3(), glm::vec3(), 5.0f, region.region
},region.texture, 0.002f, -1)); },region.texture, 0.002f, -1));
} }
@ -42,6 +46,9 @@ void ParticlesRenderer::renderParticles(const Camera& camera, float delta) {
const auto& right = camera.right; const auto& right = camera.right;
const auto& up = camera.up; const auto& up = camera.up;
const auto& chunks = *level.chunks;
bool backlight = settings->backlight.get();
std::vector<const Texture*> unusedTextures; std::vector<const Texture*> unusedTextures;
for (auto& [texture, vec] : particles) { for (auto& [texture, vec] : particles) {
@ -57,14 +64,21 @@ void ParticlesRenderer::renderParticles(const Camera& camera, float delta) {
while (iter != vec.end()) { while (iter != vec.end()) {
auto& particle = *iter; auto& particle = *iter;
update_particle(particle, delta, *level.chunks); update_particle(particle, delta, chunks);
glm::vec4 light(1, 1, 1, 0);
if (particle.emitter->behaviour.lighting) {
light = MainBatch::sampleLight(
particle.position, chunks, backlight
);
light *= 0.7f + (particle.random % 300) * 0.001f;
}
batch->quad( batch->quad(
particle.position, particle.position,
right, right,
up, up,
glm::vec2(0.3f), glm::vec2(0.3f),
glm::vec4(1), light,
glm::vec3(1.0f), glm::vec3(1.0f),
particle.region particle.region
); );

View File

@ -11,16 +11,22 @@ class Assets;
class Camera; class Camera;
class MainBatch; class MainBatch;
class Level; class Level;
struct GraphicsSettings;
class ParticlesRenderer { class ParticlesRenderer {
const Level& level; const Level& level;
const GraphicsSettings* settings;
std::unordered_map<const Texture*, std::vector<Particle>> particles; std::unordered_map<const Texture*, std::vector<Particle>> particles;
std::vector<std::unique_ptr<Emitter>> emitters; std::vector<std::unique_ptr<Emitter>> emitters;
std::unique_ptr<MainBatch> batch; std::unique_ptr<MainBatch> batch;
void renderParticles(const Camera& camera, float delta); void renderParticles(const Camera& camera, float delta);
public: public:
ParticlesRenderer(const Assets& assets, const Level& level); ParticlesRenderer(
const Assets& assets,
const Level& level,
const GraphicsSettings* settings
);
~ParticlesRenderer(); ~ParticlesRenderer();
void render(const Camera& camera, float delta); void render(const Camera& camera, float delta);

View File

@ -63,7 +63,9 @@ WorldRenderer::WorldRenderer(
&engine->getSettings() &engine->getSettings()
)), )),
particles(std::make_unique<ParticlesRenderer>( particles(std::make_unique<ParticlesRenderer>(
*engine->getAssets(), *frontend->getLevel() *engine->getAssets(),
*frontend->getLevel(),
&engine->getSettings().graphics
)) { )) {
renderer = std::make_unique<ChunksRenderer>( renderer = std::make_unique<ChunksRenderer>(
level, frontend->getContentGfxCache(), &engine->getSettings() level, frontend->getContentGfxCache(), &engine->getSettings()

View File

@ -112,7 +112,7 @@ bool Chunks::isObstacleBlock(int32_t x, int32_t y, int32_t z) {
return indices->blocks.get(v->id)->obstacle; //-V522 return indices->blocks.get(v->id)->obstacle; //-V522
} }
ubyte Chunks::getLight(int32_t x, int32_t y, int32_t z, int channel) { ubyte Chunks::getLight(int32_t x, int32_t y, int32_t z, int channel) const {
if (y < 0 || y >= CHUNK_H) { if (y < 0 || y >= CHUNK_H) {
return 0; return 0;
} }
@ -132,7 +132,7 @@ ubyte Chunks::getLight(int32_t x, int32_t y, int32_t z, int channel) {
return chunk->lightmap.get(lx, y, lz, channel); return chunk->lightmap.get(lx, y, lz, channel);
} }
light_t Chunks::getLight(int32_t x, int32_t y, int32_t z) { light_t Chunks::getLight(int32_t x, int32_t y, int32_t z) const {
if (y < 0 || y >= CHUNK_H) { if (y < 0 || y >= CHUNK_H) {
return 0; return 0;
} }

View File

@ -60,8 +60,8 @@ public:
return get(pos.x, pos.y, pos.z); return get(pos.x, pos.y, pos.z);
} }
light_t getLight(int32_t x, int32_t y, int32_t z); 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); 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);
/// @brief Seek for the extended block origin position /// @brief Seek for the extended block origin position