add particles lighting
This commit is contained in:
parent
b944f257f7
commit
7abb1a88c7
@ -39,11 +39,14 @@ void Emitter::update(float delta, std::vector<Particle>& particles) {
|
||||
// spawn particle
|
||||
Particle particle = prototype;
|
||||
particle.emitter = this;
|
||||
particle.random = rand();
|
||||
particle.position = position;
|
||||
particle.velocity += glm::ballRand(1.0f) * explosion;
|
||||
particles.push_back(std::move(particle));
|
||||
timer -= spawnInterval;
|
||||
count--;
|
||||
if (count > 0) {
|
||||
count--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -14,6 +14,7 @@ struct Particle {
|
||||
/// @brief Pointer used to access common behaviour.
|
||||
/// Emitter must be utilized after all related particles despawn.
|
||||
Emitter* emitter;
|
||||
int random;
|
||||
/// @brief Global position
|
||||
glm::vec3 position;
|
||||
/// @brief Linear velocity
|
||||
@ -28,6 +29,7 @@ class Texture;
|
||||
|
||||
struct ParticleBehaviour {
|
||||
bool collision = true;
|
||||
bool lighting = true;
|
||||
glm::vec3 gravity {0.0f, -16.0f, 0.0f};
|
||||
};
|
||||
|
||||
|
||||
@ -3,6 +3,8 @@
|
||||
#include "graphics/core/Texture.hpp"
|
||||
#include "graphics/core/Mesh.hpp"
|
||||
#include "graphics/core/ImageData.hpp"
|
||||
#include "voxels/Chunks.hpp"
|
||||
#include "voxels/Chunk.hpp"
|
||||
|
||||
static const vattr attrs[] = {
|
||||
{3}, {2}, {3}, {1}, {0}
|
||||
@ -62,3 +64,19 @@ void MainBatch::prepare(int vertices) {
|
||||
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
|
||||
);
|
||||
}
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
|
||||
class Mesh;
|
||||
class Texture;
|
||||
class Chunks;
|
||||
|
||||
class MainBatch {
|
||||
std::unique_ptr<float[]> const buffer;
|
||||
@ -36,6 +37,10 @@ public:
|
||||
void setTexture(const Texture* texture, const UVRegion& region);
|
||||
void flush();
|
||||
|
||||
static glm::vec4 sampleLight(
|
||||
const glm::vec3& pos, const Chunks& chunks, bool backlight
|
||||
);
|
||||
|
||||
inline void vertex(
|
||||
const glm::vec3& pos,
|
||||
const glm::vec2& uv,
|
||||
|
||||
@ -65,17 +65,7 @@ void ModelBatch::draw(const model::Mesh& mesh, const glm::mat4& matrix,
|
||||
bool backlight) {
|
||||
glm::vec3 gpos = matrix * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
gpos += lightsOffset;
|
||||
light_t light = chunks->getLight(
|
||||
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
|
||||
);
|
||||
glm::vec4 lights = MainBatch::sampleLight(gpos, *chunks, backlight);
|
||||
setTexture(mesh.texture, varTextures);
|
||||
size_t vcount = mesh.vertices.size();
|
||||
const auto& vertexData = mesh.vertices.data();
|
||||
|
||||
@ -8,16 +8,20 @@
|
||||
#include "window/Camera.hpp"
|
||||
#include "world/Level.hpp"
|
||||
#include "voxels/Chunks.hpp"
|
||||
#include "settings.hpp"
|
||||
|
||||
size_t ParticlesRenderer::visibleParticles = 0;
|
||||
size_t ParticlesRenderer::aliveEmitters = 0;
|
||||
|
||||
ParticlesRenderer::ParticlesRenderer(const Assets& assets, const Level& level)
|
||||
: batch(std::make_unique<MainBatch>(1024)), level(level) {
|
||||
|
||||
auto region = util::get_texture_region(assets, "blocks:bazalt", "");
|
||||
emitters.push_back(std::make_unique<Emitter>(glm::vec3(0, 100, 0), Particle {
|
||||
nullptr, glm::vec3(), glm::vec3(), 5.0f, region.region
|
||||
ParticlesRenderer::ParticlesRenderer(
|
||||
const Assets& assets, const Level& level, const GraphicsSettings* settings
|
||||
)
|
||||
: batch(std::make_unique<MainBatch>(1024)),
|
||||
level(level),
|
||||
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));
|
||||
}
|
||||
|
||||
@ -42,6 +46,9 @@ void ParticlesRenderer::renderParticles(const Camera& camera, float delta) {
|
||||
const auto& right = camera.right;
|
||||
const auto& up = camera.up;
|
||||
|
||||
const auto& chunks = *level.chunks;
|
||||
bool backlight = settings->backlight.get();
|
||||
|
||||
std::vector<const Texture*> unusedTextures;
|
||||
|
||||
for (auto& [texture, vec] : particles) {
|
||||
@ -57,14 +64,21 @@ void ParticlesRenderer::renderParticles(const Camera& camera, float delta) {
|
||||
while (iter != vec.end()) {
|
||||
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(
|
||||
particle.position,
|
||||
right,
|
||||
up,
|
||||
glm::vec2(0.3f),
|
||||
glm::vec4(1),
|
||||
light,
|
||||
glm::vec3(1.0f),
|
||||
particle.region
|
||||
);
|
||||
|
||||
@ -11,16 +11,22 @@ class Assets;
|
||||
class Camera;
|
||||
class MainBatch;
|
||||
class Level;
|
||||
struct GraphicsSettings;
|
||||
|
||||
class ParticlesRenderer {
|
||||
const Level& level;
|
||||
const GraphicsSettings* settings;
|
||||
std::unordered_map<const Texture*, std::vector<Particle>> particles;
|
||||
std::vector<std::unique_ptr<Emitter>> emitters;
|
||||
std::unique_ptr<MainBatch> batch;
|
||||
|
||||
void renderParticles(const Camera& camera, float delta);
|
||||
public:
|
||||
ParticlesRenderer(const Assets& assets, const Level& level);
|
||||
ParticlesRenderer(
|
||||
const Assets& assets,
|
||||
const Level& level,
|
||||
const GraphicsSettings* settings
|
||||
);
|
||||
~ParticlesRenderer();
|
||||
|
||||
void render(const Camera& camera, float delta);
|
||||
|
||||
@ -63,7 +63,9 @@ WorldRenderer::WorldRenderer(
|
||||
&engine->getSettings()
|
||||
)),
|
||||
particles(std::make_unique<ParticlesRenderer>(
|
||||
*engine->getAssets(), *frontend->getLevel()
|
||||
*engine->getAssets(),
|
||||
*frontend->getLevel(),
|
||||
&engine->getSettings().graphics
|
||||
)) {
|
||||
renderer = std::make_unique<ChunksRenderer>(
|
||||
level, frontend->getContentGfxCache(), &engine->getSettings()
|
||||
|
||||
@ -112,7 +112,7 @@ bool Chunks::isObstacleBlock(int32_t x, int32_t y, int32_t z) {
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
|
||||
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) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -60,8 +60,8 @@ public:
|
||||
return get(pos.x, pos.y, pos.z);
|
||||
}
|
||||
|
||||
light_t getLight(int32_t x, int32_t y, int32_t z);
|
||||
ubyte getLight(int32_t x, int32_t y, int32_t z, int channel);
|
||||
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);
|
||||
|
||||
/// @brief Seek for the extended block origin position
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user