2011-02-14 2 views
6

C++/openGL에 정적 3d 블록 월드와 같은 Minecraft를 쓰고 있습니다. 나는 framerates를 개선하기 위해 노력하고 있으며, 지금까지 octree를 사용하여 절두체 컬링을 구현했습니다. 이 방법이 도움이 되긴하지만 중도 및 불량 프레임 비율은 여전히 ​​보입니다. 다음 단계는 가까운 큐브로 시점에서 숨겨진 큐브를 제거하는 것입니다. 그러나 나는 이것을 달성하는 방법에 대한 많은 자원을 찾을 수 없었습니다.3d Occlusion Culling

+0

z 버퍼에 대해 읽었습니까? http://de.wikipedia.org/wiki/Z-Buffer –

+2

@ 토마스 : http://en.wikipedia.org/wiki/Z-Buffer를 의미 할 수도 있습니다. –

+0

나는 그들에 관해 잠깐 읽었지만, 충분하지 않습니다. 그들을 사용하는 방법을 알고 있습니다. 나는 더 많이 읽어야 할 것이다. –

답변

7

Z 버퍼 (또는 "깊이 버퍼")가 활성화 된 렌더 타겟을 생성하십시오. 그런 다음 모든 불투명 한 객체가 앞뒤로 렌더링되도록 정렬해야합니다. 즉, 카메라에 가장 가까운 객체를 먼저 렌더링합니다. 알파 블렌딩을 사용하는 모든 것은 불투명 한 모든 객체를 렌더링 한 후에도 계속 앞으로 렌더링되어야합니다.

또 다른 기술은 오 클루 전 컬링입니다. 지오메트리를 저렴하게 "드라이 렌더링"한 다음 얼마나 많은 픽셀이 깊이 테스트에 실패했는지 확인할 수 있습니다. DirectX 및 OpenGL에는 모든 GPU가이를 수행 할 수있는 것은 아니지만 폐색 쿼리 지원이 있습니다.

단점은 렌더링과 결과 페치 사이에 지연이 필요하다는 것입니다. 예를 들어 프리디 케이트 타일링을 사용할 때와 같이 설정에 따라 전체 프레임 일 수 있습니다. 즉, 개체 자체보다 큰 테두리 상자를 렌더링하고 카메라를 잘라낸 후에 결과를 닫는 등 창의적이어야합니다.

그리고 한 가지 더 : 기존의 솔루션 (교합 소거와 동시에 사용할 수 있음)은 "포털"을 통해 연결된 영역을 "회의실"로 정의하는 회의실/포털 시스템입니다. 포털이 현재 회의실에서 보이지 않으면 연결된 회의실을 볼 수 없습니다. 또한 포털을 통해 볼 수있는 부분까지 뷰포트를 클릭 할 수도 있습니다.

+1

z- 버퍼링은 불필요한 조각 (픽셀) 작업 (조각의 색상 계산, 텍스처 조회, 조명 등)을 피하는 좋은 방법이지만 가능한 경우 불가능한 지오메트리를 건너 뛰는 것이 좋습니다 최종 뷰 이미지에 기여하지 않을 정점에 대한 변형을 피하십시오. 뷰 프러스 텀 컬링으로 수행하는 것처럼. –

+0

그 때문에 교합 소행이 있습니다. 나는 그 주제를 만지기 위해 나의 대답을 편집해야한다. – EboMike

3

카메라에 가까운 서페이스가있는 경우 보이지 않는 영역을 나타내는 절두체를 생성하고 해당 절두체에 완전히 포함 된 개체를 제거 할 수 있습니다. 아래 다이어그램에서 C은 카메라이고 |은 카메라 근처의 평평한 표면이며 .으로 구성된 frustum 모양의 영역은 차단 된 영역을 나타냅니다. 표면을 antiportal이라고합니다.

+0

이것은 훌륭한 기술이 될 수 있지만, 미리 알고있는 모호한 물체가 절두체에서 많은 양의 세계를 가릴 가능성이있는 경우에만 수행해야한다고 덧붙이는 것이 중요하다고 생각합니다. 대뇌 피질에 몸을 담그면 더 느려질 수 있습니다. – Alan

4

얼마나 많은 블록 당신은 렌더링에있다 -

 . 
     .. 
     ... 
    .... 
    |.... 
    |.... 
    |.... 
    |.... 
C |.... 
    |.... 
    |.... 
    |.... 
    .... 
     ... 
     .. 
     . 

(가 OpenGL을에서 할 매우 간단합니다. 다른 답변과 의견에 언급 물론 당신도 깊이 테스트와 깊이 기록을 설정해야합니다) 무슨 하드웨어? 현대 하드웨어는 매우 빠르며 지오메트리에 압도하기가 어렵습니다 (휴대용 플랫폼에 대해 언급하지 않는 한). 적당히 최근의 데스크탑 하드웨어에서 초당 60 프레임으로 수십만 큐브의 프레임을 렌더링 할 수 있어야합니다.

개별 그리기 호출 (glDrawElements/Arrays, glBegin/glEnd 등)을 사용하여 각 블록을 그리는 경우 (보너스 포인트 : glBegin/glEnd를 사용하지 마십시오) 병목 현상이 발생합니다. 이것은 초보자에게 공통적 인 함정입니다. 이 작업을 수행하는 경우 텍스처 및 음영 매개 변수를 공유하는 모든 삼각형을 각 설정에 대해 단일 호출로 함께 배치해야합니다. 지오메트리가 정적이고 프레임마다 변경되지 않는 경우 삼각형의 각 배치에 대해 Vertex Buffer Object을 사용하려고합니다.

일반적으로 한 번에 뷰 절두체에 전체 게임 세계 중 작은 부분 만있는 경우 옥탁과 함께 절두체 컬링과 결합 할 수 있습니다. 버텍스 버퍼는 여전히 정적으로로드되며 변경되지 않습니다. Frustum은 octyl을 컬링하여 절두체의 삼각형에 대한 인덱스 버퍼 만 생성하고 동적으로 각 프레임을 업로드합니다.

+0

현대 시스템 (Gefore 8800 GT, 듀얼 코어, 2GB RAM)에서 절두체 컬링 전에 250,000 개의 1x1x1 큐브를 그리 고 있습니다. 절두체 컬링 (frustum culling)으로, 나는 절두체 컬링없이 ~ 2fps 대 17.83fps의 프레임 속도를 얻고 있습니다. 큐브의 실제 드로잉은 제공된 인터페이스를 통해 이루어 지지만, 말할 수있는 것부터 glPush/PopMatrix 및 glutSolidCube를 사용하여 그려지고 있습니다. –

+0

glutSolidCube가 문제입니다. 한 번에 하나씩 25 만 개의 큐브를 그리기 위해 모든 주 변경 사항에 구속받습니다. 1000 개가 넘는 물체는 합리적인 속도로 작동하는 전형적인 한계가됩니다. – Alan

5

this minecraft level renderer에서 내가 취한 접근 방식은 본질적으로 절두체가 한정된 홍수 채우기입니다.16x16x128 청크는 16x16x16 청크 렛으로 나뉘며 각각은 관련 기하학이있는 VBO가 있습니다. 플레이어의 위치에서 chunklet 그리드의 floodfill을 시작하여 렌더링 할 chunklet을 찾습니다. 충전은에 의해 제한된다 :

  1. 뷰 프러스 텀
  2. 고체 chunklets - chunklet의 전체면이 경우 불투명 블록 다음 플러드 필 그 방향
  3. 방향을 chunklet 입력되지 - 홍수 현재의 chunklet이 시작 chunklet의 북쪽에 있다면, chunklet에 남쪽으로 넘치지 마시오.

잘 작동하는 것 같습니다. 더 복잡한 분석 (Mike Daniels가 지적한 antiportals)이 더 많은 기하학을 추방하지만, 나는 이미 CPU가 제한되어 있으므로 많은 점이 없습니다.

방금 ​​Alan에 대한 답을 보았습니다. 도려내 기가 문제가 아닙니다. 느리고 느린 OpenGL에 무엇을 보내고 보내는 겁니다.

무엇을 그리는가 : 각 블록에 큐브를 렌더링하지 말고, 불투명 한 블록을 경계로하는 투명 블록의면을 렌더링하십시오. 돌 블록의 3x3x3 큐브를 고려해보십시오. 플레이어가 볼 수있는 방법이 없으므로 센터 블록을 그리는 지점이 없습니다. 마찬가지로 플레이어는 두 개의 인접한 돌 블록 사이의 얼굴을 보지 않으므로 그리지 않습니다.

그리기 방법 : Alan에서 설명한대로 VBO를 사용하여 배치 형상을 만듭니다. 얼마나 빨리 물건을 만드는지 믿지 못할 것입니다.

기존 코드를 최소한으로 변경하면서 더 쉬운 방법은 display lists을 사용하는 것입니다. 이것은 미니 크래프트가 사용하는 것입니다.

-2

Z 버퍼를 사용하면 다각형이 올바르게 중첩됩니다.

깊이 테스트를 사용하면 픽셀을 화면에 배치하기 전에 모든 그리기 작업이 Z 버퍼를 검사합니다.

볼록 개체가있는 경우 성능을 위해 후면 배제를 허용해야합니다!

예제 코드 :

glEnable(GL_CULL_FACE); glEnable(GL_DEPTH_TEST); glDepthMask(GL_TRUE);

당신은 glCullFace의 동작을 (변경) GL_FRONT 또는 GL_BACK 통과 ...

//은 "게임 세계"를 그리기

glCullFace(...);

. ..

관련 문제