지형 생성을위한 Octree 구축


9

이전에 IsoSurface를 렌더링하기 위해 행진 큐브 / 사면체를 구현했습니다. 그것은 효과가 있었지만 ( YouTube ), 뷰 거리를 기준으로 가변 레벨의 디테일을 구현하거나 심지어 먼 오래된 청크를 제거하지 않아도 성능이 심각했습니다.

나는 이번에 또 다른 일을하기로 결정했습니다. Build()호출 될 때 다음과 같이 작동하는 OctreeNode를 작성하여 시작했습니다 .

  • 청크가 너무 작아 빌드 할 수 없으면 즉시 반환하십시오.
  • 표면이이 덩어리의 볼륨을 통과하는지 확인하십시오.
  • 그렇다면 LOD를 올릴 것인지 결정하십시오 (카메라가 가까이 있기 때문에)
  • 그렇다면 8 명의 자식을 생성하고 같은 프로세스를 호출하십시오.
  • 그렇지 않은 경우 현재 노드의 치수를 사용하여 메쉬를 작성하십시오

일부 유사 코드 :

OctNode Build() {
    if(this.ChunkSize < minChunkSize) {
        return null;
    }
    densityRange = densitySource¹.GetDensityRange(this.bounds);
    if(densityRange.min < surface < densityRange.max) {
        if(loDProvider.DesiredLod(bounds > currentLoD) {
            for(i 1 to 8) {
                if(children[i] == null) {
                    children[i] = new OctNode(...)
                }
                children[i] = children[i].Build();
            }
        } else {
            BuildMesh();
        }
        return this;
    }
}

¹ 한 지점에서 밀도를 반환 할뿐만 아니라 밀도 소스는 주어진 부피에 대해 가능한 밀도 범위를 결정할 수 있습니다.

² LoD 제공 업체는 경계 상자를 사용하여 카메라 위치 / 절두체, 사용자 설정 등에 따라 원하는 최대 LoD를 반환합니다.

그래서 ...이 모든 것이 상당히 잘 작동합니다. 간단한 구체를 밀도 소스로 사용하고 모든 노드를 표시합니다.

풀 옥트리

그리고 나뭇잎 만 :

잎만 보여주는 옥트리

그러나 몇 가지 문제가 있습니다.

  • 초기 바운딩 볼륨을 정의해야합니다 (그리고 클수록 클수록 처리가 더 필요합니다)
  • 나무의 뿌리에서 나는 잎이 얼마나 깊을 지 모른다. 그래서 LoD 번호는 최저 품질 (루트)에서 시작하여 덩어리가 작아 질수록 증가한다. LoD는 이제 초기 볼륨을 기준으로하기 때문에 특정 크기 / 품질로 작업을 수행 할 때는 많이 사용하지 않습니다.

몇 가지 옵션을 생각했지만 둘 다 결함이있는 것 같습니다.

  • Octrees 컬렉션을 유지하고 거리에 따라 추가 / 제거합니다. 멋지게 메쉬되는 방법을 볼 수 없음 ¹, 특히 임의의 3D 표면을 원할 경우 비어있는 볼륨의 목록이 필요합니다 (빈 볼륨을 반복적으로 다시 계산하지 않기 위해)
  • 현재 루트에 상위 노드를 추가 한 다음 원래 노드에 7 개의 형제를 추가하십시오. 이것은 작동하고 주문형이지만 플레이어가 가로 방향으로 이동할 때 현명하게 축소되는 것은 복잡해 보입니다. 또한 LoD 숫자는 덜 의미가 있습니다.

¹ [아래 Q에 대한 설명에서] 현재 트리에서 물리적으로 인접한 2 개의 노드가 서로 다른 LOD에 있으면 메쉬가 생성 될 때 이음새가 없도록 vert를 강제하는 코드가 있습니다. 여러 주변 노드의 밀도를 알고 있으면이 작업을 수행 할 수 있습니다. 2 개의 독립적 인 옥트리가 나란히있는 시나리오에서는이 정보를 쉽게 검색 할 수 없으므로 이음새가 생깁니다.

이것에 접근하는 가장 좋은 방법은 무엇입니까?

답변:


1

나는 정확한 질문에 대답하고 있는지 확신 할 수 없으므로 세그먼트로 대답하고 특정 질문의 세부 사항에 대한 오해가 있으면 의견에 자유롭게 회신하십시오.

초기 바운딩 볼륨을 정의해야합니다 (그리고 클수록 클수록 처리가 더 필요합니다)

이것은 사실이 아닌 것 같습니다. octree는 기하 급수적으로 기하 급수적으로 증가하기 때문에 맨 위에 몇 수준을 추가하면 성능 적중률이 매우 작아집니다.

나무의 뿌리에서 나는 잎이 얼마나 깊을 지 모른다. 그래서 LoD 번호는 최저 품질 (루트)에서 시작하여 덩어리가 작아 질수록 증가한다. LoD는 이제 초기 볼륨을 기준으로하기 때문에 특정 크기 / 품질로 작업을 수행 할 때는 많이 사용하지 않습니다.

루트 옥트리를 "충분히 큰 값"으로 수정하면 "초기 볼륨에 비해 LoD"는 문제가되지 않습니다. 위에서 언급했듯이 최상위에 추가 수준을 두는 것이 전반적인 성능에 영향을 미치지 않을 것이라고 생각합니다.

Octrees 컬렉션을 유지하고 거리에 따라 추가 / 제거합니다. 잘 맞 물리는 방법을 볼 수 없으며, 특히 임의의 3D 표면을 원할 경우 비어있는 볼륨 목록이 필요합니다 (빈 볼륨을 반복적으로 다시 계산하지 않기 위해)

내가 알기로,이 제안 된 솔루션은 이전에 자세한 영역에서 벗어날 때 LoD를 낮추는 것입니다. "증가 LoD"코드 경로와 매우 유사하게 보입니다.

if (loDProvider.DesiredLod(bounds) <(is a lot less than)< currentLoD) { 
    for(i = 1 to 8) { 
        children[i].Destroy();
    }
    BuildMesh();
}

그런 다음 멀리 떨어져있는 노드를 검사하는 데 너무 많은 시간을 소비하지 않습니다. 멀리있는 동안 너무 많은 "활성"노드가 없다는 사실에 의존 할 수 있기 때문입니다. 모든 고해상도 노드가 제거 되었기 때문입니다.


작은 노드가 가늠자라고 가정하면 대륙을 가로 질러 여행 할 때 수백 레벨이 아니라면 수십을 의미 할 것입니다

옥트리의 로그 스케일이 여전히 가능하다고 생각합니다. 최상위 레벨이 1,000,0000,000m (이것은 실제 지구보다 25 배 넓고 표면적이 625 배일 것)이고 가장 낮은 레벨의 비트가 10cm 인 경우 옥트리의 32 개 레벨입니다. 일 것입니다. 충분히 관리 할 수 ​​있습니다. 지구보다 100 배 더 넓은 행성을 원한다면 (표면적의 10000 배 더 많은), 그것은 옥트리에서 단지 3-4 수준에 불과합니다. 이 시점에서 플레이어는 전 세계를 걷는 데 수백 년이 걸리며 순진 부동 소수점 수학을 사용하면 세계는 정밀 오차를 누적하게됩니다.

Octrees 컬렉션을 유지하고 거리에 따라 추가 / 제거합니다. 멋지게 메쉬되는 방법을 볼 수 없음 ¹, 특히 임의의 3D 표면을 원할 경우 비어있는 볼륨의 목록이 필요합니다 (빈 볼륨을 반복적으로 다시 계산하지 않기 위해)

이것이 기본적으로 10 억 km 너비의 옥트리를 가지고 있지만 1km 블록마다 모든 포인터 목록을 유지하는 것과 같지 않습니까? 그러면 "메싱 오버"는 단순히 2km 크기의 노드에 의존합니다. 각 중간 레벨 "큰 블록"에 대한 로컬 참조를 유지하면 "수십 개의 추가 옥트리 레벨"에 대해 걱정되는 경우 최상위 노드를 반복하지 않아도됩니다.


대답 해줘서 고마워. 지형이 무한하기 때문에 방대한 초기 볼륨을 선택할 수는 없습니다 (저의 목표입니다). 아이디어를 얻으려면 비디오를보십시오. 따라서 내 노드 트리는 점점 높아질 것입니다. 작은 노드가 가늠자라고 가정하면 대륙을 가로 질러 여행 할 때 수백 레벨이 아니라면 수십 개가 될 수 있습니다. 다시 : 메쉬, 질문에 더 자세한 내용을 추가하겠습니다 [완료]
기본

플레이어와 관련하여 "십억 마일"은 "무한"에 가깝습니다. 고정 초기 볼륨에 대한 추가 인수가 답변에 추가되었습니다.
Jimmy

나는 아직도 확신하지 못한다. 쓸모없는 처리 계층이 30 개 이상인 이유는 무엇입니까? 효율적일뿐만 아니라 우아하지도 않습니다. 나는 걸을 시간에 대해 당신의 요점을 취하지 만 우리는 단순히 지형 생성에 대해 이야기하고 있습니다. 내가 원점을 중심에 두어야한다고 말하거나 고속으로 비행하는 것은 불가능합니다. FWIW 저는 정밀 문제를 피하기 위해 내부에서 복식을 사용하고 있습니다.
기본
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.