Perlin Noise와 Simplex Noise를 활용한 절차적 지형 생성 연구
펄린 노이즈와 심플렉스 노이즈를 활용하여 복셀 기반의 절차적 맵 생성 시스템을 구현했습니다.
청크 단위로 지형과 동굴을 생성하고 최적화하여 효율적인 렌더링을 달성했습니다.
복셀 기반 절차적 맵 생성을 구현하기 위한 연구 과정들을 설명합니다.
난수처럼 보이는 어떤 수의 나열을 만들어 내는 일을 하는 것을 유사 난수 생성기라고 합니다.
선형 합동법, 메르센 트위스터 등이 있으며, 좋은 난수 생성기를 선택해 무작위성이 높은 난수를 생성합니다.
지형 생성에 많이 쓰는 Perline Noise 전 난수에 대해 먼저 알아보았습니다.
선형 합동법
메르센 트위스터
펄린 노이즈는 완전히 랜덤이 아닌, 자연적인 질서를 가진(부드러운) 일련의 값들을 생성하는 알고리즘입니다.
텍스처 및 지형과 같은 것들을 알고리즘을 통해 생성할 수 있으며, 결과 값은 실수입니다.
Ken Perlin 이 발명한 Perlin Noise 가 대표적인 알고리즘입니다.
불규칙 노이즈
펄린 노이즈
펄린 노이즈는 여러 스케일을 갖도록 노이즈를 만들고, 합산하여 랜덤하게 보이도록 하는 것이 좋습니다.
좀 더 자연스러운 노이즈를 생성할 수 있습니다.
이를 위해 옥타브(octave)라는 개념을 사용합니다.
규칙적인 단계로 주파수(frequency)를 연속적으로 증가시키고, 다양한 노이즈 반복(옥타브)을 추가합니다.
이를 프랙탈 브라운 운동 또는 프랙탈 노이즈라는 기법이라고 합니다.
새로운 언어와 엔진을 사용하고 싶어, Rust 언어로 작성된 Bevy 엔진을 사용했습니다.
또한, 많은 복셀들을 제어하기 위해서 ECS 기반의 엔진을 선택했습니다.
메모리 안전성과 성능 및 편의성에 중점을 둔 프로그래밍 언어입니다.
컴파일 타임에 모든 메모리 안전성을 검사합니다.
Rust로 구축된 데이터 기반 게임 엔진입니다.
Entity Component System 패러다임을 활용한 데이터 중심 아키텍처를 사용합니다.
Rust에서는 하나의 폴더가 모듈로 인식됩니다.
각 복셀들의 속성을 정의합니다.
Grass 타입 블록에 맞는 텍스쳐를 지정하고, 이어 돌, 모래 블록들도 어떤 텍스쳐를 사용해야 하는지 정의합니다.
청크를 생성하고, 거리에 따라 활성화/비활성화하는 최적화 작업, 내부 복셀을 생성합니다.
구체적인 과정은 링크를 참고 부탁드립니다.
복셀들의 Mesh Data를 정의합니다. (버텍스, 인덱스, 텍스쳐 등)
청크 크기(10x20), 월드 크기(30x30), 시야 거리(10청크) 등의 설정값을 상수로 정의합니다.
VOXEL_TRIS는 큐브 6개 면의 삼각형을 구성하는 버텍스 인덱스 배열입니다. FACE_CHECKS는 각 면의 법선 벡터로, 인접 복셀 확인에 사용됩니다. VOXEL_UVS는 텍스처 매핑을 위한 UV 좌표입니다.
생성된 청크들의 복셀 메시 데이터를 가지고 실제로 메시를 생성해주는 역할을 합니다.
World 구조체가 청크들을 HashMap으로 관리하며, 플레이어 위치 기반으로 청크를 동적으로 생성/활성화합니다.
check_view_distance 함수로 시야 거리 내의 청크만 활성화하여 최적화합니다.
setup 함수에서 초기 청크 메시를 생성하고, 텍스처와 조명을 설정합니다.
get_voxel 함수는 Perlin 노이즈를 사용해 지형 타입(풀, 모래, 돌 등)을 결정합니다.
update 함수로 플레이어 이동에 따라 새로운 청크를 실시간으로 스폰합니다.
실제로 구현한 펄린 노이즈 알고리즘을 게임 엔진에 적용해보기 위한 복셀 맵을 제작했습니다.
펄린 노이즈로 복셀의 높이만 조절한다면, 내부에는 비어있고 동굴과 같은 구조도 존재하지 않습니다.
따라서 실제 마인크래프트 같은 맵을 만들기 위해 2차원 표면이 아닌, 3차원의 노이즈가 필요합니다.
그래서 Ken Perlin이 n 차원의 노이즈를 위해서 만든 Simplex Noise를 사용했습니다.
복셀 환경에서 더 빠르고 효율적인 테스트를 위해 청크 단위로 개발 및 최적화를 진행했습니다.
청크를 쓰지 않을 때 프레임이 떨어지는 현상이 크게 있었습니다.
'마인크래프트' 게임에서 왜 청크를 사용했는지 몸소 체험할 수 있었습니다.
청크
청크와 텍스쳐 적용
청크 최적화
청크 구조 안에서 펄린 노이즈를 이용해 지형을 생성합니다.
옥타브 적용 X
2D 펄린 노이즈에서 프랙탈 브라운 운동을 구현하며 적용했던 옥타브를 사용합니다.
좀 더 완만한 지형을 보여줍니다.
옥타브 적용 O
위에서 구현했던 Simplex Noise 를 이용해 동굴을 생성합니다.
Simplex Noise는 라이브러리를 사용했습니다.
측면
동굴 최종 결과