add PrecipitationRenderer (WIP)

This commit is contained in:
MihailRis 2025-01-12 22:32:41 +03:00
parent fd59aa4f65
commit b4456fdb51
10 changed files with 203 additions and 28 deletions

View File

@ -19,7 +19,9 @@
"gui/cross",
"gui/refresh",
"gui/folder_icon",
"gui/settings_icon"
"gui/settings_icon",
"misc/rain",
"misc/snow"
],
"fonts": [
{

View File

@ -17,7 +17,7 @@ void main() {
float depth = (a_distance/256.0);
float alpha = a_color.a * tex_color.a;
// anyway it's any alpha-test alternative required
if (alpha < (u_alphaClip ? 0.5f : 0.2f))
if (alpha < (u_alphaClip ? 0.5f : 0.15f))
discard;
f_color = mix(a_color * tex_color, vec4(fogColor,1.0),
min(1.0, pow(depth*u_fogFactor, u_fogCurve)));

BIN
res/textures/misc/rain.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 347 KiB

BIN
res/textures/misc/snow.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

View File

@ -6,10 +6,10 @@
#include "assets/assets_util.hpp"
#include "graphics/core/Shader.hpp"
#include "graphics/core/Texture.hpp"
#include "graphics/render/MainBatch.hpp"
#include "window/Camera.hpp"
#include "world/Level.hpp"
#include "voxels/Chunks.hpp"
#include "MainBatch.hpp"
#include "settings.hpp"
size_t ParticlesRenderer::visibleParticles = 0;
@ -179,24 +179,6 @@ void ParticlesRenderer::render(const Camera& camera, float delta) {
}
}
void ParticlesRenderer::gc() {
std::set<Emitter*> usedEmitters;
for (const auto& [_, vec] : particles) {
for (const auto& particle : vec) {
usedEmitters.insert(particle.emitter);
}
}
auto iter = emitters.begin();
while (iter != emitters.end()) {
auto emitter = iter->second.get();
if (usedEmitters.find(emitter) == usedEmitters.end()) {
iter = emitters.erase(iter);
} else {
iter++;
}
}
}
Emitter* ParticlesRenderer::getEmitter(u64id_t id) const {
const auto& found = emitters.find(id);
if (found == emitters.end()) {

View File

@ -40,12 +40,6 @@ public:
u64id_t add(std::unique_ptr<Emitter> emitter);
/// @brief Perform garbage collection (remove extra dead emitters).
/// @note Emitters are deleting without GC when there's no particles with same
/// texture left.
/// @note Currently unused
void gc();
/// @brief Get emitter by UID
/// @return Emitter or nullptr
Emitter* getEmitter(u64id_t id) const;

View File

@ -0,0 +1,155 @@
#include "PrecipitationRenderer.hpp"
#include "assets/Assets.hpp"
#include "assets/assets_util.hpp"
#include "graphics/core/Shader.hpp"
#include "graphics/core/Texture.hpp"
#include "window/Camera.hpp"
#include "world/Level.hpp"
#include "voxels/Chunks.hpp"
#include "MainBatch.hpp"
#include "settings.hpp"
PrecipitationRenderer::PrecipitationRenderer(
const Assets& assets,
const Level& level,
const Chunks& chunks,
const GraphicsSettings* settings
)
: batch(std::make_unique<MainBatch>(4096)),
level(level),
chunks(chunks),
assets(assets),
settings(settings) {
}
PrecipitationRenderer::~PrecipitationRenderer() = default;
int PrecipitationRenderer::getHeightAt(int x, int z) {
int y = CHUNK_H-1;
while (y > 0) {
if (auto voxel = chunks.get({x, y, z})) {
if (voxel->id == 0) {
y--;
continue;
}
}
break;
}
return y;
}
void PrecipitationRenderer::render(const Camera& camera, float delta) {
timer += delta * 1.0f;
batch->begin();
int x = glm::floor(camera.position.x);
int y = glm::floor(camera.position.y);
int z = glm::floor(camera.position.z);
auto& texture = assets.require<Texture>("misc/rain");
texture.setMipMapping(false);
batch->setTexture(&texture, {});
const auto& front = camera.front;
glm::vec2 size {1, 40};
glm::vec4 light(1, 1, 1, 0);
float horizontal = 0.0f;
int radius = 5;
int depth = 8;
float scale = 0.1f;
int quads = 0;
float k = 21.41149;
for (int lx = -radius; lx <= radius; lx++) {
for (int lz = -depth; lz < 0; lz++) {
glm::vec3 pos {
x + lx + 0.5f,
glm::max(y - 3, getHeightAt(x + lx, z + lz)) + 21,
z + lz + 0.5f};
batch->quad(
pos,
{1, 0, 0},
{0, 1, 0},
size,
light,
glm::vec3(1.0f),
UVRegion(
(lx + x) * scale + timer * horizontal,
timer + (z + lz) * k,
(lx + x + 1) * scale + timer * horizontal,
timer + 40 * scale + (z + lz) * k
)
);
}
}
for (int lx = -radius; lx <= radius; lx++) {
for (int lz = depth; lz > 0; lz--) {
glm::vec3 pos {
x + lx + 0.5f,
glm::max(y - 3, getHeightAt(x + lx, z + lz)) + 21,
z + lz + 0.5f};
batch->quad(
pos,
{-1, 0, 0},
{0, 1, 0},
size,
light,
glm::vec3(1.0f),
UVRegion(
(lx + x) * scale + timer * horizontal,
timer + (z + lz) * k,
(lx + x + 1) * scale + timer * horizontal,
timer + 40 * scale + (z + lz) * k
)
);
}
}
for (int lz = -radius; lz <= radius; lz++) {
for (int lx = -depth; lx < 0; lx++) {
glm::vec3 pos {
x + lx + 0.5f,
glm::max(y - 3, getHeightAt(x + lx, z + lz)) + 21,
z + lz + 0.5f};
batch->quad(
pos,
{0, 0, -1},
{0, 1, 0},
size,
light,
glm::vec3(1.0f),
UVRegion(
(lz + z) * scale + timer * horizontal,
timer + (x + lx) * k,
(lz + z + 1) * scale + timer * horizontal,
timer + 40 * scale + (x + lx) * k
)
);
}
}
for (int lz = -radius; lz <= radius; lz++) {
for (int lx = depth; lx > 0; lx--) {
glm::vec3 pos {
x + lx + 0.5f,
glm::max(y - 3, getHeightAt(x + lx, z + lz)) + 21,
z + lz + 0.5f};
batch->quad(
pos,
{0, 0, 1},
{0, 1, 0},
size,
light,
glm::vec3(1.0f),
UVRegion(
(lz + z) * scale + timer * horizontal,
timer + (x + lx) * k,
(lz + z + 1) * scale + timer * horizontal,
timer + 40 * scale + (x + lx) * k
)
);
}
}
batch->flush();
}

View File

@ -0,0 +1,32 @@
#pragma once
#include "typedefs.hpp"
class Level;
class Assets;
class Chunks;
class Camera;
class MainBatch;
struct GraphicsSettings;
class PrecipitationRenderer {
std::unique_ptr<MainBatch> batch;
const Level& level;
const Chunks& chunks;
const Assets& assets;
const GraphicsSettings* settings;
float timer = 0.0f;
int getHeightAt(int x, int z);
public:
PrecipitationRenderer(
const Assets& assets,
const Level& level,
const Chunks& chunks,
const GraphicsSettings* settings
);
~PrecipitationRenderer();
void render(const Camera& camera, float delta);
};

View File

@ -44,6 +44,7 @@
#include "graphics/core/Font.hpp"
#include "BlockWrapsRenderer.hpp"
#include "ParticlesRenderer.hpp"
#include "PrecipitationRenderer.hpp"
#include "TextsRenderer.hpp"
#include "ChunksRenderer.hpp"
#include "GuidesRenderer.hpp"
@ -86,7 +87,10 @@ WorldRenderer::WorldRenderer(
)),
blockWraps(
std::make_unique<BlockWrapsRenderer>(assets, level, *player.chunks)
) {
),
precipitation(std::make_unique<PrecipitationRenderer>(
assets, level, *player.chunks, &engine.getSettings().graphics
)) {
auto& settings = engine.getSettings();
level.events->listen(
LevelEventType::CHUNK_HIDDEN,
@ -188,6 +192,10 @@ void WorldRenderer::renderLevel(
scripting::on_frontend_render();
}
setupWorldShader(entityShader, camera, settings, fogFactor);
entityShader.uniform1i("u_alphaClip", false);
precipitation->render(camera, delta);
skybox->unbind();
}

View File

@ -18,6 +18,7 @@ class LineBatch;
class ChunksRenderer;
class ParticlesRenderer;
class BlockWrapsRenderer;
class PrecipitationRenderer;
class GuidesRenderer;
class TextsRenderer;
class Shader;
@ -71,6 +72,7 @@ public:
std::unique_ptr<TextsRenderer> texts;
std::unique_ptr<ParticlesRenderer> particles;
std::unique_ptr<BlockWrapsRenderer> blockWraps;
std::unique_ptr<PrecipitationRenderer> precipitation;
static bool showChunkBorders;
static bool showEntitiesDebug;