add particles lighting
This commit is contained in:
parent
b944f257f7
commit
7abb1a88c7
@ -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) {
|
||||||
|
|||||||
@ -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};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
@ -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,
|
||||||
|
|||||||
@ -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();
|
||||||
|
|||||||
@ -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
|
||||||
);
|
);
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
@ -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()
|
||||||
|
|||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user