optimize PrecipitationRenderer
This commit is contained in:
parent
64fd5d7504
commit
787011d164
@ -7,7 +7,10 @@
|
|||||||
#include "graphics/core/Texture.hpp"
|
#include "graphics/core/Texture.hpp"
|
||||||
#include "lighting/Lightmap.hpp"
|
#include "lighting/Lightmap.hpp"
|
||||||
#include "maths/util.hpp"
|
#include "maths/util.hpp"
|
||||||
|
#include "maths/voxmaths.hpp"
|
||||||
|
#include "util/CentredMatrix.hpp"
|
||||||
#include "settings.hpp"
|
#include "settings.hpp"
|
||||||
|
#include "voxels/Chunk.hpp"
|
||||||
#include "voxels/Chunks.hpp"
|
#include "voxels/Chunks.hpp"
|
||||||
#include "window/Camera.hpp"
|
#include "window/Camera.hpp"
|
||||||
#include "world/Level.hpp"
|
#include "world/Level.hpp"
|
||||||
@ -29,12 +32,20 @@ PrecipitationRenderer::~PrecipitationRenderer() = default;
|
|||||||
|
|
||||||
int PrecipitationRenderer::getHeightAt(int x, int z) {
|
int PrecipitationRenderer::getHeightAt(int x, int z) {
|
||||||
int y = CHUNK_H - 1;
|
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) {
|
while (y > 0) {
|
||||||
if (auto voxel = chunks.get({x, y, z})) {
|
const auto& vox = chunk->voxels[vox_index(x, y, z)];
|
||||||
if (voxel->id == 0) {
|
if (vox.id == 0) {
|
||||||
y--;
|
y--;
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -68,12 +79,12 @@ void PrecipitationRenderer::render(const Camera& camera, float delta) {
|
|||||||
const auto& front = camera.front;
|
const auto& front = camera.front;
|
||||||
glm::ivec2 size {1, 16};
|
glm::ivec2 size {1, 16};
|
||||||
|
|
||||||
float horizontal = 0.5f;
|
float horizontal = 0.5f * 5;
|
||||||
|
|
||||||
glm::vec4 light = light_at(chunks, x, y, z);
|
glm::vec4 light = light_at(chunks, x, y, z);
|
||||||
|
|
||||||
int radius = 6;
|
const int radius = 6;
|
||||||
int depth = 12;
|
const int depth = 12;
|
||||||
float scale = 0.4f;
|
float scale = 0.4f;
|
||||||
int quads = 0;
|
int quads = 0;
|
||||||
float k = 21.41149;
|
float k = 21.41149;
|
||||||
@ -88,16 +99,26 @@ void PrecipitationRenderer::render(const Camera& camera, float delta) {
|
|||||||
{{0, 0, 1}, {1, 0, 0}},
|
{{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 (const auto& face : faces) {
|
||||||
for (int lx = -radius; lx <= radius; lx++) {
|
for (int lx = -radius; lx <= radius; lx++) {
|
||||||
for (int lz = depth; lz > 0; lz--) {
|
for (int lz = depth; lz > 0; lz--) {
|
||||||
|
// Position calculations
|
||||||
glm::vec3 pos = face.right * static_cast<float>(lx) +
|
glm::vec3 pos = face.right * static_cast<float>(lx) +
|
||||||
face.front * static_cast<float>(lz);
|
face.front * static_cast<float>(lz);
|
||||||
pos += glm::vec3(x, 0, z);
|
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;
|
size.y / 2 + 1;
|
||||||
pos += glm::vec3(0.5f, 0.0f, 0.5f);
|
pos += glm::vec3(0.5f, 0.0f, 0.5f);
|
||||||
|
|
||||||
|
// UV coords calculations
|
||||||
float m = glm::sign(face.right.x + face.right.z);
|
float m = glm::sign(face.right.x + face.right.z);
|
||||||
int ux = pos.x;
|
int ux = pos.x;
|
||||||
int uz = pos.z;
|
int uz = pos.z;
|
||||||
@ -106,9 +127,13 @@ void PrecipitationRenderer::render(const Camera& camera, float delta) {
|
|||||||
std::swap(ux, uz);
|
std::swap(ux, uz);
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec4 light = light_at(chunks, pos.x, y, pos.z);
|
|
||||||
random.setSeed(uz);
|
random.setSeed(uz);
|
||||||
float hspeed = (random.randFloat() * 2.0f - 1.0f) * horizontal;
|
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(
|
batch->quad(
|
||||||
pos,
|
pos,
|
||||||
face.right,
|
face.right,
|
||||||
@ -116,12 +141,7 @@ void PrecipitationRenderer::render(const Camera& camera, float delta) {
|
|||||||
size,
|
size,
|
||||||
light,
|
light,
|
||||||
glm::vec3(1.0f),
|
glm::vec3(1.0f),
|
||||||
UVRegion(
|
UVRegion(u1, v1, u1 + m * scale, v1 + size.y * scale)
|
||||||
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
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
55
src/util/CentredMatrix.hpp
Normal file
55
src/util/CentredMatrix.hpp
Normal file
@ -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;
|
||||||
|
};
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user