Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Speed up loading visible chunks #125

Open
AlexXZero opened this issue Jan 25, 2024 · 1 comment
Open

Speed up loading visible chunks #125

AlexXZero opened this issue Jan 25, 2024 · 1 comment
Labels
enhancement New feature or request

Comments

@AlexXZero
Copy link
Contributor

Проблема

В данный момент реализация выглядит так:

  1. Сначала грузим все ближайшие чанки
  2. Потом грузим дальние чанки

Таким образом подгрузка чанков происходит не самым оптимальным образом.

Ожидаемое решиние

Я считаю, что подгрузка чанков должна быть приоритезована по следующей схеме:

  1. Грузим самые ближайшие видимые чанки
  2. Грузим дальние видимые чанки
  3. Грузим ближайшие не видимые чанки (опционально)
  4. Грузим дальние не видимые чанки (опционально)

Кроме того, функция, которая определяет подгрузку чанков так и названа ChunkController::loadVisible(), что расходится с реализацией.

Черновой набросок

Я попробовал сделать черновой набросок того, как я думаю должно выглядеть исправление, правда пришлось добавить супер костыль, для доступа к классу WorldRenderer из метода ChunkController::loadVisible(). Вот что у меня примерно получилось:

------------------------ src/frontend/WorldRenderer.cpp ------------------------
index 8ae83df..c5d7d37 100644
@@ -39,6 +39,23 @@ using glm::mat4;
 using std::string;
 using std::shared_ptr;
 
+static WorldRenderer* renderer_;
+bool WorldRenderer::isChunkVisible(int cx, int cz)
+{
+	return renderer_->isChunkVisible_(cx, cz);
+}
+bool WorldRenderer::isChunkVisible_(int cx, int cz)
+{
+	vec3 min(cx * CHUNK_W,
+			 0,
+			 cz * CHUNK_D);
+	vec3 max(cx * CHUNK_W + CHUNK_W,
+			 CHUNK_H,
+			 cz * CHUNK_D + CHUNK_D);
+
+	return frustumCulling->IsBoxVisible(min, max);
+}
+
 WorldRenderer::WorldRenderer(Engine* engine, LevelFrontend* frontend)
 	: engine(engine),
 	  level(frontend->getLevel()),
@@ -57,6 +74,7 @@ WorldRenderer::WorldRenderer(Engine* engine, LevelFrontend* frontend)
 	auto assets = engine->getAssets();
 	skybox = new Skybox(settings.graphics.skyboxResolution,
 						assets->getShader("skybox_gen"));
+	renderer_ = this;
 }
 
 WorldRenderer::~WorldRenderer() {

------------------------- src/frontend/WorldRenderer.h -------------------------
index bb500c3..3f06ef8 100644
@@ -41,6 +41,9 @@ public:
 	void drawDebug(const GfxContext& context, Camera* camera);
 	void drawBorders(int sx, int sy, int sz, int ex, int ey, int ez);
 
+	static bool isChunkVisible(int cx, int cz);
+	bool isChunkVisible_(int cx, int cz);
+
 	static float fog;
 };
 

------------------------ src/logic/ChunksController.cpp ------------------------
index 3f6f006..4997aa2 100644
@@ -17,6 +17,7 @@
 #include "../world/World.h"
 #include "../maths/voxmaths.h"
 #include "../util/timeutil.h"
+#include "../frontend/WorldRenderer.h"
 
 
 const uint MAX_WORK_PER_FRAME = 64;
@@ -61,6 +62,7 @@ bool ChunksController::loadVisible(){
 	int minDistance = ((w-padding*2)/2)*((w-padding*2)/2);
 	for (uint z = padding; z < d-padding; z++){
 		for (uint x = padding; x < w-padding; x++){
+			if (!WorldRenderer::isChunkVisible(x+ox, z+oz)) continue;
 			int index = z * w + x;
 			auto chunk = chunks->chunks[index];
 			if (chunk != nullptr){

image

дополнительный контекст

Стоит отметить, что моя реализация не подгружает чанки за зоной видмости, хотя возможно стоило бы погрузить хотя бы ближайшие к камере чанки (например в радиусе 2 чанков). Кроме того, текущая версия isChunkVisible не корректно возвращает результат для пограничных чанков (см не прогруженные чанки слева и справа на скриншоте).

Результат тестирования

Как резульатат при черновой реализации я отметил существенное ускорение прогрузки чанков, попадающих в зону видимости камеры, что улучшает комфорт. Кроме того, игра стала потреблять кратно меньше количество памяти, т.к. теперь она не подгружает чанки находящиеся за пределами видимости, таким образом мне удалось поднять дальность прорисовки до максимума на моём ноутбуке со встроенной графикой и не слишком большом количестве ОЗУ.

@AlexXZero AlexXZero added the enhancement New feature or request label Jan 25, 2024
@iamcsharper
Copy link

Просьба @MihailRis проработать и выгрузить, потрясающая правка!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants