feat: distance-based dense render optimization
This commit is contained in:
@@ -20,6 +20,7 @@ BlocksRenderer::BlocksRenderer(
|
||||
) : content(content),
|
||||
vertexBuffer(std::make_unique<ChunkVertex[]>(capacity)),
|
||||
indexBuffer(std::make_unique<uint32_t[]>(capacity)),
|
||||
denseIndexBuffer(std::make_unique<uint32_t[]>(capacity)),
|
||||
vertexCount(0),
|
||||
vertexOffset(0),
|
||||
indexCount(0),
|
||||
@@ -475,9 +476,10 @@ glm::vec4 BlocksRenderer::pickSoftLight(
|
||||
}
|
||||
|
||||
void BlocksRenderer::render(
|
||||
const voxel* voxels, int beginEnds[256][2]
|
||||
const voxel* voxels, const int beginEnds[256][2]
|
||||
) {
|
||||
bool denseRender = this->denseRender;
|
||||
bool densePass = this->densePass;
|
||||
for (const auto drawGroup : *content.drawGroups) {
|
||||
int begin = beginEnds[drawGroup][0];
|
||||
if (begin == 0) {
|
||||
@@ -494,16 +496,19 @@ void BlocksRenderer::render(
|
||||
if (id == 0 || variant.drawGroup != drawGroup || state.segment) {
|
||||
continue;
|
||||
}
|
||||
if (denseRender != (variant.culling == CullingMode::OPTIONAL)) {
|
||||
continue;
|
||||
}
|
||||
if (def.translucent) {
|
||||
continue;
|
||||
}
|
||||
const UVRegion texfaces[6] {
|
||||
cache.getRegion(id, variantId, 0, denseRender),
|
||||
cache.getRegion(id, variantId, 1, denseRender),
|
||||
cache.getRegion(id, variantId, 2, denseRender),
|
||||
cache.getRegion(id, variantId, 3, denseRender),
|
||||
cache.getRegion(id, variantId, 4, denseRender),
|
||||
cache.getRegion(id, variantId, 5, denseRender)
|
||||
cache.getRegion(id, variantId, 0, densePass),
|
||||
cache.getRegion(id, variantId, 1, densePass),
|
||||
cache.getRegion(id, variantId, 2, densePass),
|
||||
cache.getRegion(id, variantId, 3, densePass),
|
||||
cache.getRegion(id, variantId, 4, densePass),
|
||||
cache.getRegion(id, variantId, 5, densePass)
|
||||
};
|
||||
int x = i % CHUNK_W;
|
||||
int y = i / (CHUNK_D * CHUNK_W);
|
||||
@@ -514,16 +519,19 @@ void BlocksRenderer::render(
|
||||
def.ambientOcclusion);
|
||||
break;
|
||||
case BlockModelType::XSPRITE: {
|
||||
if (!denseRender)
|
||||
blockXSprite(x, y, z, glm::vec3(1.0f),
|
||||
texfaces[FACE_MX], texfaces[FACE_MZ], 1.0f);
|
||||
break;
|
||||
}
|
||||
case BlockModelType::AABB: {
|
||||
if (!denseRender)
|
||||
blockAABB({x, y, z}, texfaces, &def, vox.state.rotation,
|
||||
!def.shadeless, def.ambientOcclusion);
|
||||
break;
|
||||
}
|
||||
case BlockModelType::CUSTOM: {
|
||||
if (!denseRender)
|
||||
blockCustomModel(
|
||||
{x, y, z},
|
||||
def,
|
||||
@@ -552,7 +560,7 @@ SortingMeshData BlocksRenderer::renderTranslucent(
|
||||
bool aabbInit = false;
|
||||
size_t totalSize = 0;
|
||||
|
||||
bool denseRender = this->denseRender;
|
||||
bool densePass = this->densePass;
|
||||
for (const auto drawGroup : *content.drawGroups) {
|
||||
int begin = beginEnds[drawGroup][0];
|
||||
if (begin == 0) {
|
||||
@@ -573,12 +581,12 @@ SortingMeshData BlocksRenderer::renderTranslucent(
|
||||
continue;
|
||||
}
|
||||
const UVRegion texfaces[6] {
|
||||
cache.getRegion(id, variantId, 0, denseRender),
|
||||
cache.getRegion(id, variantId, 1, denseRender),
|
||||
cache.getRegion(id, variantId, 2, denseRender),
|
||||
cache.getRegion(id, variantId, 3, denseRender),
|
||||
cache.getRegion(id, variantId, 4, denseRender),
|
||||
cache.getRegion(id, variantId, 5, denseRender)
|
||||
cache.getRegion(id, variantId, 0, densePass),
|
||||
cache.getRegion(id, variantId, 1, densePass),
|
||||
cache.getRegion(id, variantId, 2, densePass),
|
||||
cache.getRegion(id, variantId, 3, densePass),
|
||||
cache.getRegion(id, variantId, 4, densePass),
|
||||
cache.getRegion(id, variantId, 5, densePass)
|
||||
};
|
||||
int x = i % CHUNK_W;
|
||||
int y = i / (CHUNK_D * CHUNK_W);
|
||||
@@ -703,29 +711,45 @@ void BlocksRenderer::build(const Chunk* chunk, const Chunks* chunks) {
|
||||
vertexCount = 0;
|
||||
vertexOffset = indexCount = 0;
|
||||
|
||||
denseRender = false;
|
||||
densePass = false;
|
||||
|
||||
sortingMesh = renderTranslucent(voxels, beginEnds);
|
||||
|
||||
overflow = false;
|
||||
vertexCount = 0;
|
||||
vertexOffset = 0;
|
||||
indexCount = 0;
|
||||
denseIndexCount = 0;
|
||||
|
||||
denseRender = settings.graphics.denseRender.get();
|
||||
// denseRender = false;
|
||||
|
||||
denseRender = false; //settings.graphics.denseRender.get();
|
||||
densePass = false;
|
||||
render(voxels, beginEnds);
|
||||
|
||||
// denseRender = settings.graphics.denseRender.get();
|
||||
// if (denseRender) {
|
||||
|
||||
// }
|
||||
size_t endIndex = indexCount;
|
||||
|
||||
denseRender = true;
|
||||
densePass = true;
|
||||
render(voxels, beginEnds);
|
||||
|
||||
denseIndexCount = indexCount;
|
||||
for (size_t i = 0; i < denseIndexCount; i++) {
|
||||
denseIndexBuffer[i] = indexBuffer[i];
|
||||
}
|
||||
|
||||
indexCount = endIndex;
|
||||
densePass = false;
|
||||
render(voxels, beginEnds);
|
||||
}
|
||||
|
||||
ChunkMeshData BlocksRenderer::createMesh() {
|
||||
return ChunkMeshData{
|
||||
return ChunkMeshData {
|
||||
MeshData(
|
||||
util::Buffer(vertexBuffer.get(), vertexCount),
|
||||
std::vector<util::Buffer<uint32_t>> {util::Buffer(indexBuffer.get(), indexCount)},
|
||||
std::vector<util::Buffer<uint32_t>> {
|
||||
util::Buffer(indexBuffer.get(), indexCount),
|
||||
util::Buffer(denseIndexBuffer.get(), denseIndexCount),
|
||||
},
|
||||
util::Buffer(
|
||||
ChunkVertex::ATTRIBUTES, sizeof(ChunkVertex::ATTRIBUTES) / sizeof(VertexAttribute)
|
||||
)
|
||||
@@ -739,10 +763,18 @@ ChunkMesh BlocksRenderer::render(const Chunk *chunk, const Chunks *chunks) {
|
||||
|
||||
return ChunkMesh{std::make_unique<Mesh<ChunkVertex>>(
|
||||
vertexBuffer.get(), vertexCount,
|
||||
std::vector<IndexBufferData> {IndexBufferData {indexBuffer.get(), indexCount}}
|
||||
std::vector<IndexBufferData> {
|
||||
IndexBufferData {indexBuffer.get(), indexCount},
|
||||
IndexBufferData {denseIndexBuffer.get(), denseIndexCount},
|
||||
}
|
||||
), std::move(sortingMesh)};
|
||||
}
|
||||
|
||||
VoxelsVolume* BlocksRenderer::getVoxelsBuffer() const {
|
||||
return voxelsBuffer.get();
|
||||
}
|
||||
|
||||
size_t BlocksRenderer::getMemoryConsumption() const {
|
||||
size_t volume = voxelsBuffer->getW() * voxelsBuffer->getH() * voxelsBuffer->getD();
|
||||
return capacity * (sizeof(ChunkVertex) + sizeof(uint32_t) * 2) + volume * (sizeof(voxel) + sizeof(light_t));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user