브라우저에서 오픈 월드 만들기, 27부: 노이즈로 만든 섬, 땅처럼 보이는 땅
글: Oleg Sidorkin, Cinevva CTO 겸 공동 창업자
처음 오셨나요? 시리즈 가이드를 보세요. spike가 무엇인지 설명하고 모든 부분을 링크해 둡니다.
26부는 세계에 물을 올렸습니다. 이번 부분은 그 아래의 땅을 만듭니다. 실제 장소가 만들어지는 과정을 그대로 따라가는 두 단계로요. Spike 54는 지형 그 자체입니다. 손으로 조각한 게 아니라 노이즈에서 키워낸 뒤, 물이 실제로 흘러간 곳이 가질 법한 배수로와 해안선을 가질 때까지 풍화시킨 것이죠. Spike 55는 그 지형 위에 입히는 피부입니다. 거의 모든 절차적 지면을 무너뜨리는 문제, 곧 타일 텍스처가 타일처럼 보인다는 문제를 해결합니다. 둘을 합치면 하나의 질문에 답하게 됩니다. 창작자가 아티스트의 손을 전혀 거치지 않고도 그럴듯한 섬과 땅처럼 읽히는 땅을 얻을 수 있는가, 그리고 답은 올바른 레시피를 베끼면 그렇다 입니다.
노이즈만으로는 얻을 수 없는 해안선
높이맵은 Red Blob Games 레시피를 따릅니다. 이건 작은 변환들을 쌓은 것으로, 각각이 원시 노이즈의 특정 결함 하나를 고칩니다. 프랙탈 브라운 운동은 Perlin 노이즈의 여러 옥타브를 더해서 지형이 넓은 언덕과 미세한 디테일을 둘 다 가지게 합니다. 하지만 순수 FBM은 흐물흐물하고 그리드에 정렬된 것처럼 보이기 때문에 샘플 지점을 먼저 도메인 워프합니다. 각 좌표를 다른 노이즈 필드로 옵셋하는 것이죠.
이렇게 하면 형태가 나오지만, 그건 노이즈 형태입니다. 강도 없고, 물이 깎은 계곡도 없고, 퇴적 부채꼴도 없습니다. 그 위를 흐른 것이 아무것도 없었기 때문이죠. 해결책은 수력 침식으로, Sebastian Lague의 MIT 라이선스 구현에서 이식해 왔습니다. 수천 개의 물방울이 무작위로 생성되어 비탈을 따라 굴러 내려갑니다. 각각 관성을 지녀서 직각으로 꺾지 않고, 빨라지면 퇴적물을 집어 올리고 느려지거나 고이면 내려놓습니다. 미리 계산해 둔 원형 브러시가 각 침식 이벤트를 작은 반경에 펼쳐서 깎인 자국이 1픽셀짜리 긁힘이 아니라 매끄럽게 됩니다. 그리고 증발이 물방울을 수명 동안 은퇴시킵니다. 충분히 많은 물방울을 돌리면 지형은 노이즈가 흉내 낼 수 없는 것을 키워냅니다. 합류하는 배수망, 하류로 갈수록 넓어지는 계곡, 그리고 퇴적물이 가라앉은 평지죠.
GPU 위의 침식, 그리고 자기가 어디 있는지 아는 강
CPU 침식은 정확하지만 느립니다. 그래서 spike는 이것을 WebGPU 컴퓨트 셰이더로도 이식하는데, 흥미로운 부분은 GPU 원자 연산이 무엇을 강제하는가입니다. 높이는 백만 배율의 고정소수점 i32로 저장됩니다. WGSL에는 부동소수점에 대한 atomic add가 없고, 수천 개의 물방울이 같은 셀에 퇴적물을 내려놓고 제거하는 일을 경쟁 상태 없이 병렬로 할 수 있는 유일한 방법이 정수에 대한 atomicAdd와 atomicSub이기 때문입니다. 이 고정소수점 왕복은 셀이 무거운 동시 드래그 아래에서 가끔 살짝 음수가 될 수 있다는 뜻인데, 이건 무해하고 읽어들일 때 클램프됩니다. CPU 버전은 셀마다의 브러시 테이블을 미리 계산하지만
두 패스가 더 있어 풍화된 지형을 읽을 수 있는 지도로 바꿉니다. 배수는 Red Blob D8 흐름 누적 방식을 씁니다. 모든 셀에 비 한 단위를 떨어뜨리고, 모든 셀을 고도 내림차순으로 정렬하고, 각 셀의 누적된 물을 그 셀의 단 하나뿐인 가장 낮은 이웃에게 넘깁니다. 그러면 물이 자연스러운 계곡을 따라 쌓이고, 누적량이 임계값을 넘는 셀은 강으로 표시됩니다. 함정은 침식된 높이맵에 구덩이가 있다는 것입니다. 내리막 출구가 없는 국소 함몰지죠. 구덩이로 들어간 물은 그냥 멈춰서 누적을 깨버립니다. 그래서 배수가 돌기 전에 Planchon-Darboux 구덩이 채우기가 각 구덩이를 가장 낮은 이웃보다 살짝 높게 올립니다.
멈출 줄 모르고 반복되는 타일
지형에는 고작 몇 미터 너비의 텍스처로 수 킬로미터를 덮는 재질이 필요합니다. 그런데 타일을 키워서 땅을 덮는 순간 눈이 그 반복을 딱 붙잡습니다. Spike 55는 같은 지오메트리와 조명 위에서 네 가지 샘플링 모드를 비교하는 A/B 벤치라서, 유일한 변수는 텍스처를 어떻게 읽느냐입니다. 기준선은 plain입니다. 스케일된 UV에서 한 번 샘플링하는 것이죠. 몇 미터마다 명백하게 타일이 보이고, 이길 대상으로서만 존재합니다. 무료 PBR 레이어는 Poly Haven에서 그들의 CDN을 통해 옵니다. diffuse 더하기 패킹된 ARM 맵(앰비언트 오클루전, roughness, metalness) 더하기 GL normal, 전부 CC0이고, 이방성 8과 밉맵으로 로드됩니다.
흥미로운 세 가지는 반복에 대한 서로 다른 공격입니다. hex-linear 모드는 Heitz-Neyret 삼각형 격자입니다. 표면 위에 비스듬한 삼각 격자를 깔면 각 프래그먼트가 하나의 삼각형 안에 놓이고, 그 삼각형의 세 꼭짓점이 각각 무작위로 옵셋된 탭을 가져와 무게중심 가중치로 블렌딩합니다. 그러면 인접한 영역이 텍스처의 서로 다른 부분을 샘플링하고 큰 스케일의 타일링이 녹아 없어집니다. 하지만 세 탭의 순수 선형 블렌드는 삼각형 가장자리에서 색을 평균 내버려서 눈에 보이는 삼각형 무늬를 남깁니다. spike 48이 부딪혔던 바로 그 아티팩트죠. hex-vp 모드는 같은 2018년 논문에서 발표된 해결책입니다. 무게중심 합 이후에 텍스처의 평균 색을 빼고, 제곱 가중치 합의 역제곱근으로 다시 스케일해서 분산을 일정하게 유지한 다음, 평균을 도로 더합니다. 이렇게 하면 블렌드 전체에서 대비가 안정적으로 유지되어 삼각형이 사라집니다. 그래서 이 재질은 로드된 각 텍스처를 1×1로 읽어들여 평균 색을 미리 추정합니다. 네 번째 모드 iq-untiled는 Inigo Quilez의 Texture Repetition 기법 3입니다. 두 개의 옵셋된 탭을 저주파 변화 패턴으로 블렌딩하는데, 세 번이 아니라 두 번만 샘플링하고 애초에 삼각형 구조가 없는, 잘 버티는 저렴한 선택지입니다.
어떤 모드 위에든 선택적인 삼평면 투영을 얹을 수 있습니다. 이것이 같은 재질로 절벽을 늘어남 없이 감쌀 수 있게 해주는 것이죠. UV 하나 대신 셰이더는 세 개의 월드 축 투영을 샘플링합니다. X를 향한 표면은 YZ 평면을 읽고, Y는 ZX를, Z는 XY를 읽고, abs(normalWorld)를 4에서 8 사이의 샤프닝 거듭제곱으로 올려 블렌딩합니다. 그래야 45도 경사가 세 투영을 다 뭉개서 유령처럼 만들지 않습니다. 이 벤치는 절충을 분명하게 보여줍니다. 분산을 보존하는 hex 블렌딩이 품질 승자이고, Quilez의 두 탭이 성능을 의식한 쪽입니다. 둘 다 plain을 충분히 큰 차이로 이기므로, 어떤 창작자도 plain 타일을 출시해서는 안 됩니다.
이 장에서 다룬 기술
레시피를 쌓은 높이맵 생성. Red Blob Games 레시피는 원시 노이즈를 지형으로 조합합니다. 유기적인 능선을 위한 도메인 워프 FBM(
수력 침식, CPU와 GPU. Sebastian Lague의 물방울 모델(관성, 운반 용량, 미리 계산된 원형 퇴적 브러시, 증발)은 노이즈가 흉내 낼 수 없는 실제 배수로를 깎아냅니다. WebGPU 컴퓨트 이식은 높이를 백만 배율의 고정소수점 i32로 저장해서 물방울들이 같은 셀에 병렬로 atomicAdd/atomicSub할 수 있게 하고,
구덩이 채우기를 포함한 D8 배수. Red Blob D8 흐름 누적은 셀마다 비 한 단위를 떨어뜨리고, 셀을 고도 내림차순으로 정렬하고, 물을 각 셀의 가장 낮은 이웃에게 넘기며, 임계값을 넘으면 강으로 표시합니다. Planchon-Darboux 구덩이 채우기가 먼저 모든 국소 함몰지를
텍스처 타일링을 깨는 네 가지 방법. 동일한 지오메트리와 조명 위에서: plain(한 탭, 명백하게 타일이 보임), hex-linear(Heitz-Neyret 삼각형 격자, 선형 블렌드가 삼각형 무늬를 남김), hex-vp(평균을 빼고, 제곱 가중치의 역제곱근으로 다시 스케일하고, 평균을 도로 더하는 EGSR 2018 §3.3 분산 보존 해결책, 텍스처마다 1×1 평균 읽어들이기가 필요), 그리고 iq-untiled(Inigo Quilez 두 탭 기법 3). 삼평면 투영은 세 개의 월드 축 평면을 abs(normalWorld)의 4-8 거듭제곱으로 블렌딩해서 샘플링하므로 절벽이 늘어나지 않습니다. 분산 보존이 품질에서 이기고, 두 탭이 비용에서 이깁니다. 지형 재질을 보세요.
29부 중 27부. 이전: 26부 - 물을 만드는 세 가지 방법 다음: 28부 - 지평선까지 펼쳐진 풀, 그리고 자신을 숨기는 땅 시리즈 가이드: /ko/blog/2026-02-25-open-world-browser-series-guide