XNA에서 대규모 지형을 렌더링하는 효율적인 방법


10

플레이어에게 큰 공간이 필요한 XNA 게임을 만들고 있습니다. 현재 사용중인 테스트 하이트 맵은 4096x4096이며 4 비트 BMP로 저장됩니다.

내가하려고하는 것은 거대한 하이트 맵 파일을 가져 와서 게임에서 렌더링하는 것입니다. 내가 겪고있는 문제는 사용 가능한 메모리의 대부분을 사용하므로 전체 지형을 한 번에 메모리에로드하는 것이 비효율적이라는 것입니다.

내가 겪었던 또 다른 문제는 XNA 내에서 하드 제한 세트 때문에 지형을 하나의 프리미티브로 모두 렌더링 할 수 없다는 것입니다.

그 말로, 나는 여러 가지 솔루션을 발견했으며, 모두 아래에 나열했습니다.

  • 현재 사용자의 위치를 ​​기준으로 렌더링-기본적으로 세계 내에서 방향에 관계없이 사용자 주위에 사각형을 그립니다. 이것은 여전히 ​​사용자가 볼 수없는 공간을 렌더링하기 때문에 내가 원하는 것이 아닙니다.
  • 사용자의 방향과 위치를 기준으로 렌더링-하이트 맵의 픽셀을 렌더링 해야하는 삼각형을 검색하는 수식을 찾았지만 매우 어려웠습니다.
  • 지형을 여러 청크로 분할하고 사용자에게 가장 가까운 것을 렌더링-사람들이 볼 수없는 청크를 여전히 렌더링하므로 여전히 효율적이지 않습니다. 그리고 하이트 맵을 여러 조각으로 분할해야하기 때문에 작업 집약적이며 확장 성이 큰 문제가됩니다.

이러한 솔루션을 시도한 후에는해야 할 일에 대한 아이디어가 부족합니다. 사람들이 이러한 복잡한 알고리즘을 수행하도록 지시하는 몇 가지 답변을 받았지만 어떻게 알고리즘을 접근하는지조차 모릅니다.

기본적으로 저는 XNA에서 엉성한 지형을 최대한 효율적으로 렌더링하는 간단하고 간단한 방법을 요구하고 있습니다.

나는 일반적으로 게임 개발에 익숙하지 않지만 유망한 것으로 보인다면 기꺼이 연구하려고합니다.

업데이트 1 : 지오 클립 매핑 방법을 조사한 후 코드 작성을 시작했습니다. 나는 모든 수학을 마쳤고 게임이 실행됩니다. 그러나 그것은 매우 비효율적입니다. 아마도 내 코딩이 잘못되었을 수 있습니다. 2FPS에서 실행되며 내 CPU의 전체 코어를 사용합니다. 코드를 작성하고 개선하려고하는데 도움이 더 필요하다고 생각합니다. 여기 Terrain manager 클래스 코드의 Pastebin이 있습니다. 더 효율적으로 사용하려면 나중에 더 많은 결과를 게시 할 것입니다.


1
흥미롭게도, 당신이 말하는 기술은 ID Software가 다가오는 게임 Rage에서 사용하는 기술과 비슷합니다. 그들은 '메가 텍스처'를 사용한 다음 필요한 부분을 GPU로 스트리밍합니다. 그는 그것에 대해 이야기를했지만 여기에 wikipedia 기사가 있습니다. en.wikipedia.org/wiki/MegaTexture

답변:


5

청크 접근 방식이 일반적으로 사용됩니다. 렌더링해야하는지 확인하기 위해 수십만 개 중 모든 삼각형을 테스트하는 것이 거의 효율적이지 않습니다. 대신 대부분의 지형 렌더링 알고리즘은 공간 데이터 구조 를 사용하여 지형 의 보이는 부분을 동적으로 렌더링합니다.

데이터 구조를 쉽게 구현하는 것을 쿼드 트리 라고합니다 . 요컨대, 쿼드 트리를 사용하려면 플레이어가 보는 절두체를 찾아 쿼드 트리의 최상위 레벨과 교차 시키며 부분적으로 볼 수있는 덩어리 (즉, 절두체 평면이 덩어리를 가로 지르는 덩어리)에 대해 모든 하위 분류 및 테스트를 수행합니다. 절두체 외부의 것을 생략합니다. 이렇게하면 몇 가지 수준의 재귀만으로 실제 보이는 지오메트리에 매우 근접하게됩니다.

고급 지형 렌더러는 알고리즘을 사용하여 볼 수있는 지오메트리뿐만 아니라 해당 지오메트리의 디테일도 조정합니다. Geomipmapping (및 상대적 geoclipmapping)은 현재로서는 비교적 인기가 있지만 구현하기는 쉽지 않습니다.

편집 : 다음 은 지오 클립 매핑과 절두체 컬링에 대한 적절한 설명입니다.

또한 하이트 맵에 대한 4 비트가 실제로 결과물을 다듬지 않는 한 멋진 지형을 생성하기에 충분한 지에 대해서는 의문의 여지가 있습니다.


이 기사를 살펴본 결과, 지형을 대량으로 표시하는 데 가장 효율적인 지오 클립 매핑 방법을 먼저 사용하기로 결정했습니다. 결과를 다시 게시하겠습니다.

3

GPU에 데이터를로드하기 위해 프레임 단위 작업을 수행해야하는 모든 접근 방식에 결함이 있습니다.

다음은 잘 수행해야하는 한 가지 접근 방식에 대한 대략적인 개요입니다.

터 레인을 (상당히 큰) 청크로 나눠서 해당 청크를 고정 정점 버퍼에로드해야합니다 (높이 맵의 비트 깊이는 중요하지 않습니다!). 이 버텍스 버퍼는 렌더링되기를 기다리면서 GPU 메모리에 앉아있을뿐입니다. 적절한 청크 크기를 실험해야하지만 128x128이 시작하기에 좋은 장소 일 수 있습니다.

4096x4096 지형의 경우 한 번에 GPU에 편안하게로드 할 수있는 한계를 약간 초과합니다. 수백 MB의 정점 데이터 일 것입니다 (하지만 64MB로 줄일 수는 있지만) 영리한). 따라서 백그라운드에서 GPU에서 정점 버퍼를로드 및 언로드해야 할 수도 있습니다.

(청크의 백그라운드 로딩을 ​​구현하면 확장 성이 뛰어납니다!)

후에 당신이 GPU에 정점 데이터를 가지고 그것은에 가시성 컬링을 할 수있는 적절한 시간 당 덩어리 근거는. 청크가 카메라 뒤에 있다는 것을 알고 있다면 청크를 렌더링하기 위해 명령을 보낼 필요가 없습니다.

CPU에서 삼각 당 컬링을 수행해서는 안됩니다 !

GPU는 화면 보다 훨씬 빠른 삼각형을 제거 합니다.

성능에 대한 자세한 내용은 Game Dev 사이트 에서이 답변 을 살펴보십시오 .


0

나는 XNA의 전문가가 아니므로 내가 틀렸다면 바로 정정하십시오. 그러나 실제로 이와 같은 상황에 최적화가 내장되어 있다는 인상을 받았습니다. 렌더 거리를 설정할 수 있으며 그 후에는 아무것도 렌더링하지 않습니다. 여러분의 경우 나머지 지형이 될 것입니다. 그러나 이것은 렌더링 된 세계에 상당히 매력적이지 않기 때문에 대부분의 오픈 월드 게임에있는 안개 같은 것을 구현해야합니다.


솔루션이 내장되어 있지만 내가 겪었던 문제는 하나의 큰 프리미티브를 렌더링하려고 시도했는데 프리미티브의 다각형 제한을 초과했습니다. 따라서 예외는 아닙니다.
sammarks
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.