플레이어가 블록을 보는 방법?


15

Ogre 엔진을 사용하여 Minecraft와 같은 게임을 작성 중이며 문제가 있습니다. 10000 블록을 그릴 때 2 FPS가 있기 때문에 게임을 최적화해야합니다. 따라서 평면의 표시를 차단하고 보이지 않는 블록을 숨길 수 있다는 아이디어를 얻었습니다. 그러나 문제가 있습니다. 플레이어가 한 번에 어떤 블록을 볼 수 있는지 어떻게 알 수 있습니까?

그리고-그러한 게임에 대한 다른 최적화 방법을 알고 있다면 Ogre에서 그 방법을 사용하는 방법과 방법을 쓰십시오.

답변:


16

오우거는 이미 프러스 텀 컬링 (Frustum Culling)을 구현하고 있지만 (기본적으로 카메라에서 볼 수없는 것을 그리는 것은 아님) 문제가 다르다고 생각합니다.

실제로 10000 블록을 표시해서는 안됩니다. 일반적으로 수행 된 작업 (또는 적어도 내가 본 복제본과 같은 일부 Ogre3d 기반 마인 크래프트 및 원본에서)은 메쉬를 생성합니다 ( 청크의 일부 NxNxN 영역의)는 도시 된 큐브의 외부면을 갖는다. 즉, 2 개의 큐브를 나란히 놓으면 2 개의 얼굴이 닿는 것을 볼 수 없으므로 그릴 필요가 없습니다.

이 얼굴들은 다음과 같이 그려야합니다 : http://www.ogre3d.org/tikiwiki/tiki-index.php?page=DynamicGrowingBuffers 현대 비디오 카드는 100000 다각형의 메쉬 하나와 100 다각형의 1000 메쉬를 선호합니다.


10

이 문제에는 몇 가지 측면이 있습니다. 먼저, 10000 개의 블록을 어떻게 그리십니까? 실제로 10000 별도의 객체로 그림을 그리십니까? 그렇다면 이것은 거의 확실하게 병목이며 폐색 컬링의 부족이 아닙니다. 드로우 콜을 줄이기 위해이 블록들을 더 적은 수의 메시 (메시 당 수천 개)로 그룹화해야합니다.

실제 질문에 관해서는, 세 가지 유형의 폐색 컬링이 떠 오릅니다.

1) 뷰 프러스 텀 외부의 블록. 이것은 당신의 뒤에 또는 옆에있는 블록을 의미합니다. 오우거는 이미 뷰 프러스 텀 컬링을 통해 이들을 제거합니다.

2) '지하'이거나 다른 블록으로 완전히 둘러싸인 블록은 어떤 각도에서도 볼 수 없습니다. siz 주변 블록을보고이를 식별 할 수 있습니다. 모두 단단하면 블록이 숨겨집니다. GPU는 이러한 블록에 대해 듣지 말아야합니다. 표면을 나타내는 메쉬를 만들 때 건너 뛰어야합니다.

3) 표면에 있고 레벨의 일부 위치에서 볼 수 있지만 현재 언덕 (또는 무언가)에 의해 숨겨져있는 블록. 이것은 내가 다루지 않은 가장 까다로운 사례이지만이 경우 하드웨어 폐색 쿼리를 사용할 수있는 좋은 기회가 있습니다.

그것은 뻔뻔한 플러그이지만 Ogre를 사용하는 일부를 포함하여 여러 사람들이 Minecraft 클론을 개발하는 데 사용하는 상당히 성숙한 라이브러리가 있습니다. 볼륨의 내용을 정의하면 렌더링 할 수있는 표면 메쉬가 생성됩니다. 여기 홈페이지가 있습니다 :

http://www.thermite3d.org/

다음은 다른 사람의 프로젝트를 사용하는 비디오입니다.

http://www.youtube.com/watch?v=Jju6WRPEK7o


4

후면 컬링을 사용하여 플레이어를 향하지 않는 정점 및 관련 픽셀을 컬링 할 수 있습니다. 깊이 버퍼링은 나머지를 처리해야합니다. 10k 블록은별로 많지 않습니다. 5770은 1500fps에서 100k vert를 렌더링 할 수 있습니다. 나는 당신이 다른 것을 잘못하고 있다고 생각합니다.


나는 동의한다. 이것은 다른 것에 문제가있을 수 있습니다.
Notabene

1

10000 개의 개별 객체가있는 경우 병목 현상은 아마도 정점, 다각형 또는 채우기가 아닌 기본 수입니다. 속도를 높이기 위해 개체를 더 적은 수의 더 높은 다각형 개체로 굽습니다.

Minecraft에는 큐브 블록이라는 개념이 있지만 현재로서는 참조를 찾을 수 없습니다.

다음 은 다양한 기술을 사용하여 수많은 큐브를 그리는 실험입니다. 베이킹은 포함되지 않습니다 (아직).


0

내가하는 일은 블록 배열을 만든 후 정점을 만들기 전에 UpdateBlockVisiblility라는 하위를 실행하는 것입니다.

서브는 단순히 이웃을 블록으로 확인하고 그에 따라 블록이 보이지 않는 부울을 업데이트합니다.

#define BLOCKFACE_NORTH 0

#define BLOCKFACE_SOUTH 1 

etc etc etc

if(IsBlockAt(NorthOfBlock))
  Blocks[Whatever].facevisible[BLOCKFACE_NORTH] = false;

그런 다음 얼굴이 보이는 경우에만 정점을 만듭니다! 단순 :)

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.