거대한 절차 상 생성 된 '광야'세계


76

난 당신이 모두 드워프 요새와 같은 게임을 알고 있습니다-방대한 절차 적 생성 광야와 땅. 이 매우 유용한 기사 에서 가져온 것입니다 .

그러나 어떻게 이것을 훨씬 더 큰 규모로 적용 할 수 있을지 궁금했습니다. Minecraft의 규모가 떠 오릅니다 (지구 표면의 8 배 크기가 아닌가)? 의사 무한, 나는 가장 좋은 용어라고 생각합니다.

:디

이 기사에서는 프랙탈 펄린 노이즈에 대해 설명합니다. 나는 그것에 대해 전문가가 아니지만 일반적인 아이디어를 얻습니다 (임의의 픽셀 값이 아니라 반 코 히어 런트 인 랜덤 생성 노이즈입니다).

크기로 영역 X를 X로 정의하고 영역로드 유형을 추가하고 영역을 생성하는 1 비트의 노이즈를 가질 수 있습니다. 그러나 이로 인해 엄청난 양의 섬이 생길 것입니다.

다른 극단적 인 경우, 나는 정말로 엄청난 양의 펄린 노이즈를 생성 할 수 있다고 생각하지 않습니다. 그리고 그것은 단지 하나의 큰 섬 일 것입니다.

나는 Perlin의 소음, 또는 어떤 소음이 어떤 식 으로든 답이 될 것이라고 확신합니다. 내말은지도가 정말 멋져 그리고 아스키를 타일로 대체하고 멋진 모습을 얻을 수 있습니다.


9
"거대한 양의 섬으로 이어질 것입니다."-또는 육지 / 물만 교환하면 호수가있는 땅이 생성됩니다.

3
그럼에도 불구하고 상당히 표준적인 패턴으로 많은 양의 호수를 얻게 될 것입니다.
공산주의 오리

3
@Kylotan : Mincraft의 크기는 무한합니다 (실제로는 아니지만 실제로는 큰 것입니다 ... 총 부피 = long.MaxValue x 128 x long.MaxValue). 따라서 한 번에 전 세계를 생성하거나 전체지도를 메모리에 저장하지 않습니다. 16x128x16 블록의 영역은 방문하지 않은 경우 비동기 적으로 디스크에서로드하기 전에 비동기 적으로 생성합니다.
zfedoran

2
@ 공산당 오리 : 네, 사실입니다. 마인 크래프트와 같은 게임은 블록 당 약 2-4 바이트의 데이터를 사용하여 도망 갈 수 있지만 더 이상 보이지 않는 후에는 바이트 만 저장하면됩니다 (1 바이트는 블록 유형을 나타냄) 다른 바이트는 조명 및 나중에 다시 계산할 수있는 다른 데이터를 설명합니다. 여기서 흥미로운 점은 RLE를 사용하여 블록이 다소 일관성이 있기 때문에 저장된 크기를 몇 바이트로 크게 줄일 수 있다는 것입니다.
zfedoran

4
'정말 큰'은 무한과 같지 않으며 두 용어를 서로 바꿔서 사용할 수 없습니다. 지도를 발견 할 때마다, 그리고 발견 될 때지도를 확장하면 무한한 크기와는 전혀 다른 제안 (요청시)으로 커지는 유한 한 크기입니다. 필요에 따라 각 성장 비트를 생성 할 수 있습니다. Minecraft의 지형 데이터는 데이터간에 일관성이 높기 때문에 사소한 압축에 매우 적합합니다. (예 : 언급 된대로 RLE)
Kylotan

답변:


35

나는 당신이 지금 무엇을 요구하는지 더 잘 이해하고 있다고 생각합니다.

노이즈는 무작위가 아닙니다. 무작위로 보이지만 완전히 수학 공식을 기반으로하며 반복 가능합니다. 모든 정보는 공식으로 인코딩됩니다. 즉, 무한 영역을 포괄하는 수식을 가질 수 있고 필요한 영역의 좌표에 수식을 사용할 수 있습니다. 인접한 영역이 필요한 경우 새 좌표에서 수식을 재사용하면 수식이 연속 값을 생성하므로 영역이 매끄럽게 결합됩니다.

다음은 높이 생성을 위해 펄린 노이즈 대신 사인을 사용하는 단순화 된 예입니다. X 축에서는 월드가 무한하지만 Y 및 Z 축에서는 1 단위 만 상상할 수 있습니다.

공식은 다음과 같습니다. height(x,y) = sin(x/20)

게임이 시작되고 근처 지역의 높이를 생성합니다. (0,0) ~ (9,0) :

[0.0, 0.05, 0.10, 0.15, 0.20, 0.25, 0.30, 0.34, 0.39, 0.43]

우리는 오른쪽으로 올라가는 언덕이 있습니다. 끝까지 걸어 가서 (10,0에서 19,0)까지의 값을 생성해야한다고 가정 해 봅시다.

[0.48, 0.52, 0.56, 0.61, 0.64, 0.68, 0.72, 0.75, 0.78, 0.81]

언덕이 꾸준히 상승하고 있으며 (10,0)의 값은 (9,0)의 값과 잘 어울립니다. 사인 함수가 연속적이기 때문입니다. 이는 기본적으로 2 개의 인접 숫자를 입력하면 2 개의 인접 결과를 얻을 수 있음을 의미합니다. 따라서 월드 좌표를 월드를 정의하는 함수의 매개 변수로 사용하면 한 번에 생성하는 양이 많든 적든 상관없이 연속적인 풍경을 얻을 수 있습니다. 새 부품을 생성하면 높이가 이미 미리 결정되어 있기 때문에 기존 부품에서 자동으로 흐릅니다.

세계가 변하지 않는다면 공식에서 주어진 지점의 높이가 정확히 무엇인지 계산할 수 있기 때문에 아무것도 저장할 필요조차 없습니다. 분명히 Minecraft와 같은 것으로 세상은 완전히 변형 가능하므로 각 덩어리를 만들 때 저장하면됩니다. 인접한 청크 사이에 높은 일관성이 있다고 가정하면 (즉, 1 블록이 잔디 인 경우 옆 블록도 잔디 일 것입니다) 데이터를 매우 효율적으로 압축 할 수 있습니다. 런 길이 인코딩이 작동합니다. 그러나 거의 모든 표준 압축 알고리즘도 마찬가지입니다.

가장 명확한 값으로 높이에 대해 이야기했지만, 동일한 시스템을 사용하여 원하는 특성을 생성 할 수 있습니다. 연속적인 속성과 입력 값이 월드 좌표 인 곳에서 수학 함수를 사용하여 랜드 마크, 광물 매장량, 스폰 지점 등 원하는 위치를 결정할 수 있습니다. (분명히 한 공식의 값이 다른 점에 영향을 줄 수 있습니다. 공중에 석탄 퇴적물을 배치하는 데 아무런 의미가 없으므로 세계 높이 맵을 생성 한 다음 지상보다 훨씬 낮은 블록의 석탄 가능성 만 계산하십시오.)


당신은 분명히 물건을 정리하는 데 도움이되었습니다. 감사합니다. :) 그러나 소음 기능과 같은 것은 연속적이지 않습니다. 그리고 AFAICS, 그것이 연속이라면 나는 '무작위'세계를받지 못할 것입니다. 아니면 여기에 뭔가 빠졌습니까?
공산주의 오리

이중 의견에 대해 죄송하지만 위의 내용이 이것과 분리되어 있다고 생각합니다. '펄린 노이즈에 월드 좌표 사용'이라고 말할 때, 이것은 '거대한'노이즈 시트를 생성하는 것과 같은 종류의 효과일까요? 나는 오늘 섭취에 약간 느낀다.
공산주의 오리

글쎄, 당신의 소음 생성은 확실히 연속적 일 수 있으며 일반적으로 부드럽게 만듭니다. 경계를 넘어 부드럽게하려면 경계를 약간 읽어야하지만 원칙은 동일합니다. 해당 노이즈에 의사 난수 데이터가 필요한 경우 알려진 양으로이를 생성합니다. 세계 좌표의 해시. 그러면 출력을 예측할 수 있습니다.
Kylotan

2
임의성에 관해서는, 각 세계는 계산에 사용되는 고유 한 시드 값을 가질 수 있습니다. 예. 위의 예에서 sin (x) 대신 sin (x + seed). 각각의 다른 씨앗은 다른 세계를 생성 할 것입니다. 그리고 거대한 시트에 관해서는 ... 나는 그것이 어떤 관련이 있는지 잘 모르겠습니다. 얼마나 많이 또는 얼마나 적게 생성하는지 또는 언제 그렇게하는지는 중요하지 않습니다. 세계의 초기 상태는 수학 공식으로 정의되며 해당 공식을 사용하여 필요할 때 언제라도 해당 상태를 검색 할 수 있습니다.
Kylotan

32

몇 년 전에 쓴 이 튜토리얼 은 당신이 원하는 것과 같은 것을 줄 것입니다.

대체 텍스트

마지막 단계에서 섬 수정을 수행하면지도의 가장자리에 도달하지 않는 단일 대륙으로 향하는 경향이 있습니다.


7
훌륭한 시각화!
zfedoran

3
자연 현상의 시뮬레이션에 대한 석사 논문을 할 때이 자습서를 사용하는 것을 기억합니다. "hill"예제를 사용하여 3D 세계에 스카이 돔을 만들었습니다. 지형 생성 개념에 대한 훌륭한 소개.
C.McAtackney

1
미친, 대단해! 나는 아무도 그것을 실제로 사용했는지 몰랐다.
munificent

1
세상에! 나는 이전 프로젝트에서도 이것을 사용했다 ... 내가 본 적이있는 지형을 생성하는 가장 간단한 방법!
War

15

큰 섬을 만들려면 한 번에 모두 만들 필요가 없습니다. 방문 할 때 비동기식으로 영역을 작성합니다.

기사에서 설명하는 것처럼 마스크를 사용하여 섬을 만드는 대신 펄린 노이즈 옥타브 파장으로 재생하여 원하는 모양을 얻을 수 있습니다. 일반적으로 첫 번째 옥타브는 지형의 일반적인 모양을 나타냅니다. 그 후 모든 옥타브는 더 미세한 입자 디테일을 추가합니다. 그러므로 첫 옥타브의 파장을 가지고 땅의 크기를 조절하십시오. 육지가 중앙에 오게하려면 중앙에서 멀어 질수록 소음을 높이면서 높이 맵을 간단히 줄일 수 있습니다. 예를 들어이 두 가지를 결합하여 섬을 만들어보십시오.

첫 옥타브 세부

이 기사는 도움이 될 것입니다 : http://freespace.virgin.net/hugo.elias/models/m_perlin.htm

무한 3D 세계와 다양한 트릭에 대해 배우고 싶다면 노이즈 입력 및 출력으로 재생하여 지형의 모양을 변경하는 데 사용할 수 있습니다.이 기사를 참조하십시오 : http://http.developer.nvidia.com /GPUGems3/gpugems3_ch01.html

그래픽 파이프 라인 및 셰이더 프로그래밍에 익숙하지 않은 경우 약간 읽기 어려울 수 있습니다.


내가 달성하고자하는 효과는 Minecraft의 맵에서 2d 하향식 (게임이 아님)과 같은 것입니다. 옥타브를 적게 사용했다면 여전히 엄청난 양의 펄린 노이즈를 생성 할 필요가 없습니까? 아니면 어떻게 든 아주 작은 양을 생성 할 수 있습니까?
공산주의 오리

펄린 노이즈의 작동 방식에 대해서는 여전히 약간 혼란 스러울 수 있습니다. 펄린 노이즈에 대한 x 및 y 좌표 오프셋을 함수에 보내 16x16 블록의 청크를 개별적으로 생성 할 수 있습니다. PerlinNoise_2D (float x, float y) 함수가 x 및 y 좌표를 어떻게 받는지 확인하십시오. 다시 말해 어떤 (x, y) 위치에 노이즈가 발생합니다. 또한 적은 옥타브를 생성하는 것은 옥타브의 파장을 변경하는 것과 다릅니다. 적은 옥타브 => 미세한 입자 디테일. 더 긴 파장 => 더 확대
zfedoran

또한 확대 / 축소 / 장거리 파장을 구현하는 방법을 보여주는 코드가있는 기사가 있습니다. dreamincode.net/forums/topic/66480-perlin-noise
zfedoran


7

Perlin의 소음과 친구는 좋은 출발점이지만 한 걸음 더 나아가고 싶을 것입니다. 널리 사용되는 노이즈 기반 생성기는 대부분 흥미롭지 않은 결과를 제공합니다. 지형을 사실적으로 만들기 위해 침식 효과를 에뮬레이션하는 알고리즘을 살펴보고 싶습니다. 가장 진보 된 게임 세계 시뮬레이터 중 하나 인 Dwarf Fortress는 침식 시뮬레이션을 세계 건설 단계 중 하나로 수행합니다.

내가 본 정말 멋진 솔루션 중 하나에서 그리는 많은 자원이 그래서 인터넷에서 사용할 수 많은 사람들이 있습니다 게임 프로그래밍 보석 7의 "고급 입자 증착"문서에서 설명되었다 (예를 들어, 1 또는 2 ) .

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