Skip to content

Commit

Permalink
optimize PrecipitationRenderer
Browse files Browse the repository at this point in the history
  • Loading branch information
MihailRis committed Feb 9, 2025
1 parent 24b1433 commit 2388596
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 16 deletions.
52 changes: 36 additions & 16 deletions src/graphics/render/PrecipitationRenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@
#include "graphics/core/Texture.hpp"
#include "lighting/Lightmap.hpp"
#include "maths/util.hpp"
#include "maths/voxmaths.hpp"
#include "util/CentredMatrix.hpp"
#include "settings.hpp"
#include "voxels/Chunk.hpp"
#include "voxels/Chunks.hpp"
#include "window/Camera.hpp"
#include "world/Level.hpp"
Expand All @@ -29,12 +32,20 @@ PrecipitationRenderer::~PrecipitationRenderer() = default;

int PrecipitationRenderer::getHeightAt(int x, int z) {
int y = CHUNK_H - 1;
int cx = floordiv<CHUNK_W>(x);
int cz = floordiv<CHUNK_D>(z);
auto chunk = chunks.getChunk(cx, cz);
if (chunk == nullptr) {
return y;
}
y = chunk->top;
x -= cx * CHUNK_W;
z -= cz * CHUNK_D;
while (y > 0) {
if (auto voxel = chunks.get({x, y, z})) {
if (voxel->id == 0) {
y--;
continue;
}
const auto& vox = chunk->voxels[vox_index(x, y, z)];
if (vox.id == 0) {
y--;
continue;
}
break;
}
Expand Down Expand Up @@ -68,12 +79,12 @@ void PrecipitationRenderer::render(const Camera& camera, float delta) {
const auto& front = camera.front;
glm::ivec2 size {1, 16};

float horizontal = 0.5f;
float horizontal = 0.5f * 5;

glm::vec4 light = light_at(chunks, x, y, z);

int radius = 6;
int depth = 12;
const int radius = 6;
const int depth = 12;
float scale = 0.4f;
int quads = 0;
float k = 21.41149;
Expand All @@ -88,16 +99,26 @@ void PrecipitationRenderer::render(const Camera& camera, float delta) {
{{0, 0, 1}, {1, 0, 0}},
};

util::CentredMatrix<int, (depth + 1) * 2> heights;
heights.setCenter(x, z);
for (int z = heights.beginY(); z < heights.endY(); z++) {
for (int x = heights.beginX(); x < heights.endX(); x++) {
heights.at(x, z) = getHeightAt(x, z);
}
}

for (const auto& face : faces) {
for (int lx = -radius; lx <= radius; lx++) {
for (int lz = depth; lz > 0; lz--) {
// Position calculations
glm::vec3 pos = face.right * static_cast<float>(lx) +
face.front * static_cast<float>(lz);
pos += glm::vec3(x, 0, z);
pos.y = glm::max(y - size.y / 2, getHeightAt(pos.x, pos.z)) +
pos.y = glm::max(y - size.y / 2, heights.at(pos.x, pos.z)) +
size.y / 2 + 1;
pos += glm::vec3(0.5f, 0.0f, 0.5f);

// UV coords calculations
float m = glm::sign(face.right.x + face.right.z);
int ux = pos.x;
int uz = pos.z;
Expand All @@ -106,22 +127,21 @@ void PrecipitationRenderer::render(const Camera& camera, float delta) {
std::swap(ux, uz);
}

glm::vec4 light = light_at(chunks, pos.x, y, pos.z);
random.setSeed(uz);
float hspeed = (random.randFloat() * 2.0f - 1.0f) * horizontal;
float u1 = ux * scale + timer * hspeed * -m;
float v1 = timer + pos.y * scale + uz * k;

// Draw
glm::vec4 light = light_at(chunks, pos.x, y, pos.z);
batch->quad(
pos,
face.right,
{0, 1, 0},
size,
light,
glm::vec3(1.0f),
UVRegion(
ux * scale + timer * hspeed * -m,
timer + pos.y * scale + uz * k,
(ux + m) * scale + timer * hspeed * -m,
timer + (size.y + pos.y) * scale + uz * k
)
UVRegion(u1, v1, u1 + m * scale, v1 + size.y * scale)
);
}
}
Expand Down
55 changes: 55 additions & 0 deletions src/util/CentredMatrix.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#pragma once

#include <array>
#include <stdexcept>

namespace util {
template<typename T, int diameter, typename CoordT = int>
class CentredMatrix {
public:
static constexpr CoordT radius = diameter / 2;

CentredMatrix() {}

void setCenter(CoordT x, CoordT y) {
centerX = x;
centerY = y;
}

T& at(CoordT x, CoordT y) {
x -= centerX - (diameter - radius);
y -= centerY - (diameter - radius);
if (x < 0 || y < 0 || x >= diameter || y >= diameter) {
throw std::invalid_argument("position is out if matrix");
}
return arr.at(y * diameter + x);
}

auto begin() {
return arr.begin();
}

auto end() {
return arr.end();
}

CoordT beginX() const {
return centerX - (diameter - radius);
}

CoordT beginY() const {
return centerY - (diameter - radius);
}

CoordT endX() const {
return centerX + radius;
}

CoordT endY() const {
return centerY + radius;
}
private:
std::array<T, diameter * diameter> arr;
CoordT centerX = 0, centerY = 0;
};
}

0 comments on commit 2388596

Please sign in to comment.