remove unnecessary drawGroup-based loops

This commit is contained in:
MihailRis 2026-07-06 01:05:44 +03:00
parent c73b036099
commit 30ab6c2f5e
4 changed files with 180 additions and 195 deletions

View file

@ -10,15 +10,14 @@
#include "frontend/ContentGfxCache.hpp"
const glm::vec3 BlocksRenderer::SUN_VECTOR(0.528265, 0.833149, -0.163704);
const float DIRECTIONAL_LIGHT_FACTOR = 0.3f;
constexpr float DIRECTIONAL_LIGHT_FACTOR = 0.3f;
BlocksRenderer::BlocksRenderer(
size_t capacity,
const Content& content,
const Block* const* blockDefs,
const ContentGfxCache& cache,
const EngineSettings& settings
) : content(content),
vertexBuffer(std::make_unique<ChunkVertex[]>(capacity)),
) : vertexBuffer(std::make_unique<ChunkVertex[]>(capacity)),
indexBuffer(std::make_unique<uint32_t[]>(capacity)),
denseIndexBuffer(std::make_unique<uint32_t[]>(capacity)),
vertexCount(0),
@ -28,7 +27,7 @@ BlocksRenderer::BlocksRenderer(
cache(cache),
settings(settings)
{
blockDefsCache = content.getIndices()->blocks.getDefs();
blockDefsCache = blockDefs;
}
BlocksRenderer::~BlocksRenderer() = default;
@ -482,25 +481,20 @@ glm::vec4 BlocksRenderer::pickSoftLight(
}
void BlocksRenderer::render(
const voxel* voxels, const int beginEnds[256][2]
const voxel* voxels, int totalBegin, int totalEnd
) {
bool denseRender = this->denseRender;
bool densePass = this->densePass;
bool enableAO = settings.graphics.softLighting.get();
for (const auto drawGroup : *content.drawGroups) {
int begin = beginEnds[drawGroup][0];
if (begin == 0) {
continue;
}
int end = beginEnds[drawGroup][1];
for (int i = begin-1; i <= end; i++) {
for (int i = totalBegin; i < totalEnd; i++) {
const voxel& vox = voxels[i];
blockid_t id = vox.id;
blockstate state = vox.state;
const auto& def = *blockDefsCache[id];
uint8_t variantId = def.getVariantIndex(state.userbits);
const auto& variant = def.getVariant(variantId);
if (id == 0 || variant.drawGroup != drawGroup || state.segment) {
if (id == 0 || state.segment) {
continue;
}
if (denseRender != (variant.culling == CullingMode::OPTIONAL)) {
@ -556,10 +550,9 @@ void BlocksRenderer::render(
}
}
}
}
SortingMeshData BlocksRenderer::renderTranslucent(
const voxel* voxels, int beginEnds[256][2]
const voxel* voxels, int totalBegin, int totalEnd
) {
SortingMeshData sortingMesh {{}};
@ -569,20 +562,13 @@ SortingMeshData BlocksRenderer::renderTranslucent(
bool densePass = this->densePass;
bool enableAO = settings.graphics.softLighting.get();
for (const auto drawGroup : *content.drawGroups) {
int begin = beginEnds[drawGroup][0];
if (begin == 0) {
continue;
}
int end = beginEnds[drawGroup][1];
for (int i = begin-1; i <= end; i++) {
for (int i = totalBegin; i < totalEnd; i++) {
const voxel& vox = voxels[i];
blockid_t id = vox.id;
blockstate state = vox.state;
const auto& def = *blockDefsCache[id];
uint8_t variantId = def.getVariantIndex(state.userbits);
const auto& variant = def.getVariant(variantId);
if (id == 0 || variant.drawGroup != drawGroup || state.segment) {
if (id == 0 || state.segment) {
continue;
}
if (!def.translucent) {
@ -669,7 +655,6 @@ SortingMeshData BlocksRenderer::renderTranslucent(
vertexCount = 0;
vertexOffset = indexCount = 0;
}
}
// additional powerful optimization
auto size = aabb.size();
@ -710,19 +695,16 @@ void BlocksRenderer::build(
int totalBegin = chunk->bottom * (CHUNK_W * CHUNK_D);
int totalEnd = chunk->top * (CHUNK_W * CHUNK_D);
bool hasTranslucent = false;
int beginEnds[256][2] {};
for (int i = totalBegin; i < totalEnd; i++) {
const voxel& vox = voxels[i];
blockid_t id = vox.id;
const auto& def = *blockDefsCache[id];
const auto& variant = def.getVariantByBits(vox.state.userbits);
hasTranslucent = def.translucent || hasTranslucent;
if (beginEnds[variant.drawGroup][0] == 0) {
beginEnds[variant.drawGroup][0] = i + 1;
if (def.translucent) {
hasTranslucent = true;
break;
}
beginEnds[variant.drawGroup][1] = i;
}
cancelled = false;
@ -734,7 +716,7 @@ void BlocksRenderer::build(
densePass = false;
if (hasTranslucent) {
sortingMesh = renderTranslucent(voxels, beginEnds);
sortingMesh = renderTranslucent(voxels, totalBegin, totalEnd);
} else {
sortingMesh = {};
}
@ -747,13 +729,13 @@ void BlocksRenderer::build(
denseRender = false;
densePass = false;
render(voxels, beginEnds);
render(voxels, totalBegin, totalEnd);
size_t endIndex = indexCount;
denseRender = true;
densePass = settings.graphics.denseRender.get();
render(voxels, beginEnds);
render(voxels, totalBegin, totalEnd);
denseIndexCount = indexCount;
for (size_t i = 0; i < denseIndexCount; i++) {
@ -762,7 +744,7 @@ void BlocksRenderer::build(
indexCount = endIndex;
densePass = false;
render(voxels, beginEnds);
render(voxels, totalBegin, totalEnd);
}
ChunkMeshData BlocksRenderer::createMesh() {

View file

@ -25,7 +25,7 @@ class BlocksRenderer final {
public:
BlocksRenderer(
size_t capacity,
const Content& content,
const Block* const* blockDefs,
const ContentGfxCache& cache,
const EngineSettings& settings
);
@ -44,7 +44,6 @@ public:
}
private:
static const glm::vec3 SUN_VECTOR;
const Content& content;
std::unique_ptr<ChunkVertex[]> vertexBuffer;
std::unique_ptr<uint32_t[]> indexBuffer;
std::unique_ptr<uint32_t[]> denseIndexBuffer;
@ -145,13 +144,16 @@ private:
);
// Does block allow to see other blocks sides (is it transparent)
inline bool isOpen(const glm::ivec3& pos, const Block& def, const Variant& variant) const {
bool isOpen(const glm::ivec3& pos, const Block& def, const Variant& variant) const {
const auto& vox = voxelsBuffer->pickBlock(
chunk->x * CHUNK_W + pos.x, pos.y, chunk->z * CHUNK_D + pos.z
);
if (vox.id == BLOCK_VOID) {
return false;
}
if (def.rt.id == vox.id && def.rt.solid && variant.culling == CullingMode::DEFAULT) {
return false;
}
const auto& block = *blockDefsCache[vox.id];
const auto& blockVariant = block.getVariantByBits(vox.state.userbits);
uint8_t otherDrawGroup = blockVariant.drawGroup;
@ -178,6 +180,6 @@ private:
float x, float y, float z, const glm::ivec3& right, const glm::ivec3& up
) const;
void render(const voxel* voxels, const int beginEnds[256][2]);
SortingMeshData renderTranslucent(const voxel* voxels, int beginEnds[256][2]);
void render(const voxel* voxels, int totalBegin, int totalEnd);
SortingMeshData renderTranslucent(const voxel* voxels, int totalBegin, int totalEnd);
};

View file

@ -14,6 +14,7 @@
#include "util/listutil.hpp"
#include "util/ObjectsPool.hpp"
#include "settings.hpp"
#include "content/Content.hpp"
static debug::Logger logger("chunks-render");
@ -33,7 +34,7 @@ public:
settings.graphics.denseRender.get()
? settings.graphics.chunkMaxVerticesDense.get()
: settings.graphics.chunkMaxVertices.get(),
level.content,
level.content.getIndices()->blocks.getDefs(),
cache,
settings
) {
@ -92,7 +93,7 @@ ChunksRenderer::ChunksRenderer(
threadPool.setStopOnFail(false);
renderer = std::make_unique<BlocksRenderer>(
settings.graphics.chunkMaxVertices.get(),
level.content, cache, settings
level.content.getIndices()->blocks.getDefs(), cache, settings
);
logger.info() << "created " << threadPool.getWorkersCount() << " workers";
logger.info() << "memory consumption is "
@ -126,7 +127,7 @@ const ChunkMesh* ChunksRenderer::render(
const std::shared_ptr<Chunk>& chunk, bool important, bool lowPriority
) {
glm::ivec2 key(chunk->x, chunk->z);
if (important) {
if (important || true) {
ChunkMesh mesh {};
auto voxelsBuffer = prepareVoxelsVolume(*chunk);
mesh = renderer->render(chunk.get(), *voxelsBuffer);

View file

@ -66,7 +66,7 @@ public:
return lights.get();
}
inline blockid_t pickBlockId(int bx, int by, int bz) const {
blockid_t pickBlockId(int bx, int by, int bz) const {
if (bx < x || by < y || bz < z || bx >= x + w || by >= y + h ||
bz >= z + d) {
return BLOCK_VOID;
@ -75,7 +75,7 @@ public:
}
inline voxel pickBlock(int bx, int by, int bz) const {
voxel pickBlock(int bx, int by, int bz) const {
if (bx < x || by < y || bz < z || bx >= x + w || by >= y + h ||
bz >= z + d) {
return {BLOCK_VOID, {}};
@ -83,7 +83,7 @@ public:
return voxels[vox_index(bx - x, by - y, bz - z, w, d)];
}
inline light_t pickLight(int bx, int by, int bz) const {
light_t pickLight(int bx, int by, int bz) const {
if (bx < x || by < y || bz < z || bx >= x + w || by >= y + h ||
bz >= z + d) {
return 0;
@ -103,10 +103,10 @@ private:
template <int w, int h, int d>
class StaticVoxelsVolume {
public:
static inline constexpr size_t size = w * h * d;
static inline constexpr int width = w;
static inline constexpr int height = h;
static inline constexpr int depth = d;
static constexpr size_t size = w * h * d;
static constexpr int width = w;
static constexpr int height = h;
static constexpr int depth = d;
StaticVoxelsVolume()
: StaticVoxelsVolume(0, 0, 0) {}
@ -142,7 +142,7 @@ public:
return lights;
}
inline blockid_t pickBlockId(uint bx, uint by, uint bz) const {
blockid_t pickBlockId(uint bx, uint by, uint bz) const {
bx -= x;
by -= y;
bz -= z;
@ -153,7 +153,7 @@ public:
}
inline const voxel& pickBlock(uint bx, uint by, uint bz) const {
const voxel& pickBlock(uint bx, uint by, uint bz) const {
bx -= x;
by -= y;
bz -= z;
@ -164,7 +164,7 @@ public:
return voxels[vox_index(bx, by, bz, w, d)];
}
inline light_t pickLight(uint bx, uint by, uint bz) const {
light_t pickLight(uint bx, uint by, uint bz) const {
bx -= x;
by -= y;
bz -= z;