Zipanguelike

『じぱんぐライク』のつくりかた、または地図タイルの動的プロシージャル生成

『じぱんぐライク』の画面

姉妹サイト『はんけトケ』の記事「クライアントサイド地図タイルサーバー」の、応用実践編です。

目次

  1. RPG風ドット絵日本地図
  2. 原理
  3. 基本の定義
  4. ズーム時の挙動
  5. 座標変換
  6. メッシュデータの粒度
  7. WebGL2.0の制約
  8. 地図タイル生成のからくり
  9. さらに作りこむ
  10. 地形のプロシージャル生成
  11. 町のプロシージャル生成は難しい
  12. 乱数の一貫性・再現性に注意
  13. 小さなままのマップチップ
  14. 自作マップチップ表示機能
  15. おわりに
  16. 用語・注釈
  17. 補遺

RPG風ドット絵日本地図

はんけトケの記事では、簡素なヒートマップの実装を通して、サービスワーカーによるクライアント側での地図タイル生成が目論見どおりに働くことを確認しました。 そこで今度は、その技術を全面的に用いて『じぱんぐライク』なる地図ウェブアプリを作ってみました(このサイトのトップページ)。 この記事の主題なので、まずは一度触ってみてください。

おわかりのとおり、日本地図をRPG風のドット絵で表示するものです。 陳腐なネタではあるものの、案外というかそれゆえにというべきか、正面からまともに取り組んだ実装は見たことがありません。 既存の地図アプリにそれらしい皮をかぶせたものがせいぜいです。 実用性も収益性もなさそうなネタを、わざわざコストをかけて一から開発・運営する酔狂はいなかったわけですね。

しかし、地図タイルをクライアント側で生成することにすれば、最も心配なサーバー関連のコストはかかりません。 機能豊富なウェブ地図ライブラリーを無料で利用でき、十分な範囲と粒度のオープン地理データが出そろっており、複雑な処理を一瞬でこなすGPUもあらゆる端末に備わっている。 かつての「酔狂」を「当たり前」にする機は、今や熟しているのです。

原理

用語が紛らわしいので、とりあえず次のように呼んで区別することにします。

  • 地図タイル … “XYZ形式”でリクエストされる、ウェブ地図ライブラリーの地図表示単位
  • マップチップ … 16×16ピクセル程度の正方形で描かれる、山・川・草原などを表すドット絵
  • メッシュ … 要素が格子状に敷き詰められた地理情報データ

はんけトケの記事では、人口メッシュの内容を色分けした地図タイルをサービスワーカーで生成し、ヒートマップとして表示しました。 それと同じ要領で、メッシュを彩色する代わりにマップチップで表す地図タイルを生成すれば、マス目状のドット絵日本地図になるはずです。

原理はとてもシンプルですね。 ただし、実装にはこまごました工夫を要します。 以下にかいつまんで説明します。

基本の定義

マップチップは16×16ピクセル単位とします。 地図タイルは256×256ピクセルのラスター(ビットマップ)画像とします。 ひとつの地図タイルにマップチップがぴったり16×16個収まることになり、処理しやすく見た目もすっきりします。

ズーム時の挙動

まず考えねばならないのが、地図をズームしたときのマップチップの見え方です。

さっき「ひとつの地図タイルにマップチップが16×16個収まる」と決めました。 しかし、これは奇妙な定義です。 ひとつの地図タイルに描かれるべき範囲は、ズームレベルに応じて変化するはずなのですから。

にもかかわらず、常に「ひとつの地図タイルにマップチップが16×16個」であるとはどういうことでしょう。 それはすなわち、「マップチップはクラスター的に表示が切り替わる」ということ。 具体的な挙動を言葉で説明しようとするとややこしいのですが、じぱんぐライクを触ってみたなら意味は明らかでしょう。

ズームレベルの異なる画面を並べた図
つまりこんな具合に、ズームにしたがってマス目が増減して表示される

もしクラスター的でなかったらどうなるか。 地図アプリのズームの画角変化は極端です。 マップチップを敷き詰めたとして、あるズームレベルでは最適に見えても、ちょっとズーム操作したとたんチップが1ピクセル以下にまで縮小されてしまったり、逆に画面一杯に拡大されてしまったりします。 それはそれでいいとの考えもあるでしょうが、わたしの望む挙動ではありません。

なお実際には、地図タイルあたりマップチップは常に16×16個固定ではなく、8×8個や4×4個になることもあります。 やや不規則ですが、ズーム操作していてなるべく違和感のないよう調整した結果です。

座標変換

基本の定義にはもうひとつ奇妙な点があります。

地図は国土交通省などの地理情報メッシュデータ(地域メッシュ)を原典としますが、それらはXYZ形式の地図タイルに合わせた区切りになどなっていません。 もしメッシュデータの格子をそのままマップチップにしたら、「ぴったり16×16個収ま」ってくれません。 微妙にはみ出したり足りなかったりしてしまいます。

よって、地図タイル側の座標系できっちり整列するようメッシュデータを調整せねばなりません。 具体的な処理としては、まずメッシュの各格子のID(地域メッシュコード)を経緯度に変換し、それをさらにXYZ形式のタイル番号に変換してやります。

地域メッシュコードから経緯度を求めるための計算式は地域メッシュの仕様書(PDF)に、経緯度からタイル番号を求めるための計算式はオープンストリートマップのウィキに詳しく記されています。

メッシュデータの粒度

ところでメッシュの粒度、地域メッシュにおける3次・4次・5次などといった区分はどれを選ぶべきでしょうか。 先に結論をいうと、4次としました。

正確には、XYZ形式タイルにおけるズームレベル16の粒度とします。 この格子の大きさは約500メートル四方で、おおよそ地域メッシュの4次に相当します。 なお原典のデータは必ずしも4次だけとは限らず、もっと細かいデータも適宜変換して使っています。

ではなぜその粒度にしたのかといえば、次に述べる、データを扱う側の都合です。

WebGL2.0の制約

地図タイルの生成(描画)には、WebGL2を利用して高速化を図ります。 したがって、データはWebGL2で扱える形式やサイズにしなくてはなりません。

形式はRGBA8UI(RGBA・各8ビット符号なし整数)テクスチャー画像とします。 そしてその大きさは、4,096×4,096ピクセルを上限とします。

WebGL2が扱えるテクスチャー形式は仕様上は多岐にわたるものの、実際には環境・実装にかなり左右されます。 任意の形式が表面的には受け入れられたように見えても、あまり信用できません(エラーにならないのが曲者)。 その形式にネイティブに対応しておらず、float型が内部で整数化されてしまったり、節約のつもりで輝度のみ(グレースケール)にしてもRGBAに拡張されてしまったりすることがあるのです。 どの環境でも確実に使え、かつ無駄のないテクスチャーはRGBA8UIあたりと考えておくのが無難です。

4,096×4,096ピクセルの上限も同様の配慮によるもので、このサイズはWebGL2で最低限扱えることが保証されています。 いまどきそんな最低要件に合わせる必要があるのかといえば、大ありです。 iOS版Safariがまさにその水準の制約をいまだに課しているので。 最近の機種では多少緩和されているかもしれませんが(?)、古い機種を使っている人もまだたくさんいるでしょう。 毎度足を引っ張るiOS版Safariですが、前向きに考えれば、これで動くよう作っておけば他のほとんどの環境でも動きそうです。

さて、日本全域をおおよそ3千キロメートル四方とすると、4,096×4,096ピクセルにすっぽり収まるのは3次メッシュ(1キロ四方格子)ということになります。 しかし、1つの格子の情報量を1バイトとしてRGBAのそれぞれに格納すれば、その2×2倍の粒度、すなわち4次メッシュが収まります。 データの粒度を4次メッシュ相当としたのはこれが理由です。

グレースケールのピクセルで表したメッシュデータ
輝度テクスチャー化したメッシュデータ。 これを4ピクセルずつRGBAに振り分けたものが最終形

なお実際には、4,096×4,096ピクセルのテクスチャーに、4次メッシュ相当のデータ1つだけでなく、3次メッシュ相当のデータも1つ一緒に詰め込んでいます。 平均すると、4次相当メッシュ1格子あたり10ビットの情報量があるわけです。

そこまでしなくても、テクスチャーを複数枚使えばラクに情報量を増やせるではないか。 そのとおりなのですが、iOS版Safariはテクスチャーサイズだけでなくサイトに割り当てられる総メモリー量そのものが非常に少なく、MapLibre GL JS等ウェブ地図ライブラリーもリソースを相当消費することを考えると、できるだけ節約するに越したことはありません。 また一般論として、リソースを安易に無駄遣いしていると、将来拡張する余地が減ってしまいます。

地図タイル生成のからくり

地図タイルのリクエスト応答にはサービスワーカーを使います。 最大のミソですが、方法ははんけトケの記事と同じため省略。 そして地図タイルの描画には、上のとおりWebGL2を使います。

マップチップの描画ごときにWebGLの1ではなく2を選ぶ理由は、2が普及し尽くしており逆に1を選ぶ理由がないからです。 ……それでは身もフタもないので重要な理由をひとつ挙げると、頂点シェーダー内で入力テクスチャーを参照できるからです(1でもできるがオプション扱い)。

16×16ピクセル単位のマップチップを描画するのに、フラグメントシェーダー側でピクセル毎にいちいち入力テクスチャーつまりメッシュデータを参照して描くべきマップチップを判じるのは無駄でしかありません。 他方、頂点シェーダー側でマップチップを決めてしまえば処理量は圧倒的に少なくなります。 地図タイル1つにつきマップチップは16×16=256個なので、各チップを4頂点の正方形ポリゴンとすれば1024回、1頂点のポイントスプライトとすればたった256回の処理で済むのです。 もしフラグメントシェーダー側で処理したら、256×256ピクセル=65,536回です。

マップチップをポリゴンとするかポイントスプライトとするかは、それぞれ一長一短あるため目的に応じて決めます。 じぱんぐライクでは、始めはポリゴンとして作っていましたが、途中でポイントスプライトに変えました。 ポリゴンなら変形など諸々ラクなうえボクセルへの拡張も容易だったりしますが、じぱんぐライクはシンプルな2D表現に徹します。

さらに作りこむ

目指す挙動とデータ構成と地図タイルの生成方法とが決まったので、あとは粛々と実装するだけ。 たいへん面倒ではありますが、定番のウェブ技術の組み合わせにすぎず、質的に新奇で困難なことはありません(本当に難しいのは、わかりやすく使いやすいユーザーインターフェイス開発のほう)。

ただ、ネタというのは徹底しないと面白くありません。 せっかく地図タイルを動的に生成しているのだから、4次相当メッシュを超える詳細な地形をプロシージャル生成し、いかにもゲームらしい「人間サイズ」にまでズームインできるようにしてみます。

その目標の人間サイズは、約2メートル四方と定めました。 4次相当メッシュ約500メートル四方の格子を、切りよく256×256マスに分割した大きさです。

地形のプロシージャル生成

地理に詳しいかたもプログラマーのかたも、「地形は再帰的な自己相似形(フラクタル)っぽい」ことはご存じでしょう。 再帰処理プログラミングの解説では、必ずといっていいほど地形生成のトピックが紹介されます。

わたしが生まれる前の教科書にさえ載っている古典的な知見・手法ですが、じぱんぐライクにおける地形生成は基本的に、それを素直に応用しているだけ。

具体的には、たとえば基となるメッシュ格子が「森林」だとしたら、それを分割した256×256マスもまずすべて森林であるとして、その四辺を自己相似的に揺らぐ周期と振幅でずらすのです。

なんとも安直な処理ですが、結果はじぱんぐライクをご覧のとおり、けっこうそれらしい感じになりました。 さすが古典だけあり強力な効果ですね。

4次相当メッシュそのままの図と、プロシージャル生成で詳細レベルを上げた図
輪郭をずらすほか、内側もそれらしく手を加えている。 「人」のチップも現れる

なおお察しのとおり、このプロシージャル生成処理は頂点シェーダー内で行っています。 さすがにCPUには重荷なので。 地図タイルの描画にWebGL2を導入し、処理量のより少なく済むポイントスプライトを選んだ最大の理由は、実はこのためでした。 もしプロシージャル生成までしないのなら、はんけトケのヒートマップと同じく2DキャンバスにCPUで描く方法でもとくに問題なかったでしょう。

町のプロシージャル生成は難しい

いっぽう建物用地について、これを村や町や都市らしくプロシージャル生成するのは難しく、いろいろ試行錯誤したものの、素朴なアルゴリズムを一様に適用するにとどまっています。

何が難しいかといって、なにしろ面積があまりに広すぎ、何をどう工夫してみても、結局は単調な景色が延々続いてしまうのです。 また四角いマップチップを並べる表現上、斜めや曲線的な配置をしにくい、つまり俯瞰ふかんではそれらしく見えてもズームインすると破綻してしまう(見苦しかったり無秩序に見えたりする)ことも解決を難しくしました。

L-systemや都市形態学などの知見、ゲーム開発者会議のそれこそ各種ローグライク作者の発表なども参考にはなるでしょうが、一朝一夕にものになるわけもなく、即時応答の動的生成ではそもそも実行できる処理の複雑さに限界があります。 よってこの件は割り切り、むしろより単純にして軽さをとる方針としました。

建物を単色で強調した、町のプロシージャル生成結果
ボロノイ図と簡易迷路のアルゴリズムが透けて見える、生成した町の様子。 人口や地域ごとにパラメーターを変えてみても焼け石に水で、どこまでも同じ調子なのがつらい

乱数の一貫性・再現性に注意

プロシージャル生成の内容は左様に行きあたりばったりで参考にならないかもしれませんが、一般的な注意がひとつあります。 処理に用いる疑似乱数についてです。

乱数・ノイズのたぐいをシェーダー内で生成する際、float型を使うと、環境による型精度の差(?)から異なる値が返ることがあります。 あるいは経験則として、sinなどの組み込み関数が微妙に異なる値を返している気もします。 いずれにしても、特殊効果に使うぶんにはかまいませんが、地形生成においては困りますね。 同じ場所の地形が機器によって違ってしまうことになります。

シェーダーの型精度を指定する仕組みは一応あるものの、実際の効果は例によって当てになりません。 よって主要な地形生成に関わる疑似乱数の生成には、整数の式やあらかじめ用意したノイズテクスチャー(要は乱数表)を使うことにしました。 主要でない部分はこの限りではありませんが、少々なら許容範囲でしょう。

よく知られていることながらついでに触れておくと、JavaScriptの標準乱数にはそもそも再現性がありません(意図的な仕様らしい)。 CPU側処理の乱数にも再現性を求めるなら、適当な疑似乱数式を自前で導入する必要があります。

小さなままのマップチップ

景色の単調さのもうひとつの原因は、マップチップの種類の少なさです。 とはいえ単調さを破るほどのチップ数となると膨大で、簡単に用意できるものではありません(チップ自体をプロシージャル生成する手もあるけれど……)。

昔ながらの次善策として、パレット替えがあります。 じぱんぐライクの内蔵マップチップデータはインデックスカラーで、任意のパレットで描画できる仕組みになっています。 地域や緯度(≒気候)ごとに色を変えてみようと企んだのですが、しかしその程度では結局単調さを免れそうにないのと、次に述べるユーザーの自作マップチップを表示できる機能との兼ね合いで見送りました。

自作マップチップ表示機能

ユーザーの自作マップチップ(タイルセット)で地図を表示するのは、じぱんぐライクにとって重要な機能と考えています。 需要の有無はさておき、それが可能なのは地図タイルのクライアント側生成ならではで、つまりは技術的アイデンティティーを象徴するためです。

ただし、マップチップを一般ユーザーに作ってもらうとなると、あまり複雑な仕様にはできません。 一般的な画像編集ソフトでは、さまざまな独自属性が含まれるゲーム用テクスチャーどころか、パレット替えを見越したインデックスカラー画像すら作るのは難しいでしょう。 よってファイル形式は最もありふれたフルカラーPNGとし、パレット替えの仕様をなくしたのです。

玄人筋には物足りないでしょうが、より多くの人に使ってもらえるよう間口を広げることを優先しました。 マップチップの種類を増やしたくない(むしろできるだけ減らしたい)のも、同じ理由からです。

おわりに

説明は以上です。

こんなものの作り方に正解などなく、たとえばベクターデータを解釈してマップチップを配置したっていいし、そもそもマップチップにこだわらなくてもいいわけです。 書いておいて何ですが、こうした各論は大して重要ではありません。 重要なのは、「クライアントサイド地図タイル生成」や「少ない情報をいかに豊かに見せるか」や「プロシージャル生成による補完」といった考え方をわがものとし、いかに応用するかです。 たとえばサーバー配信とこうしたクライアント側生成とを組み合わせれば、配信情報を大幅に減らしたり、よりリッチで楽しい表現ができたりするかもしれません。

もっといえば、というかわたし本来の志向としては、「非伝統的な地図表現」や「あいまい・架空・役に立たない地図」を作る自由、そうした多様な地図を今や「サーバーレスで簡単・安価に公開できる」ことを示したかったのです。 そんな文句をただ叫んでみたところでだれも見向きもしないので、実証するネタとしてじぱんぐライクを作ってみた次第。 果たして成功しているかわかりませんが、自分ではけっこう気に入っています。

町に人間がたくさんいる様子
メッシュデータに基づく人口が、数値や色ではなく本当に人々の多寡で表される
夜の地図で建物の灯りが輝いている様子
夜間(ダークモード)は建物の灯りで都市が浮かび上がる (「ローグライフ」タイルセットの場合)

用語・注釈

地図タイル,XYZ形式,サービスワーカー
はんけトケの記事「クライアントサイド地図タイルサーバー」を参照。
ちなみに、この記事はもともとはんけトケの開発ノート上に公開していた。 話の自然な流れだが、しかし別アプリの詳細をそこに書くのはやはり変だと思い直し、こちらのサイトに引っ越した。
マップチップサイズについて
じぱんぐライクではマップチップのサイズを最終的に可変とした(地図タイルのサイズを変えてつじつまを合わせる)。 ただし不具合が生じる余地が増えそうなため無段階とはせず、現状16×16、12×12、8×8ピクセルの三種にのみ対応している。
クラスター
地図アプリにおいては、表示・操作に難があるほど多量の情報群を階層的にまとめて代表表示する働きを指す。 具体機能としては別だがわかりやすい例は、たとえば地図上の行政区のラベルがズームレベルに応じて市区町村名・都道府県名・国名に切り替わるなど。
WebGL
GPUを駆動する、ウェブ標準のグラフィックスライブラリー。
WebGLでマップチップのような2D表現をするのは、いきなり数学を強いられずに済み入門にも適するはず。 ちなみに、後継と目される「WebGPU」は最近(2025年末ごろ)ようやく全主要ブラウザーが対応した模様。
頂点/フラグメントシェーダー
「各ポリゴン頂点の画面上スクリーン座標や属性情報を決定し」、「そのポリゴンをピクセルとして描画する」GPUの処理パイプ工程ラインにおける、前者のコードを頂点バーテックスシェーダー、後者のコードをフラグメントシェーダーと呼ぶ。
iOS版Safariについて
何かと厄介。 ブラウザーの多様性は歓迎するものの、ウェブ標準仕様の解釈が“多様”だったり、仕様を取り入れるのが他より数年単位で遅かったり、機器が高価なくせに石器時代のごとき制約があったり、バグが多いのに更新が遅かったり、にもかかわらず他のブラウザーに対して排他的・市場独占的だったりするのは端的に困る。 WebKit(基礎となるオープンソースのブラウザーエンジン)は問題ないのにSafariだけおかしいことも。
プロシージャル(手続き的)生成
データをアルゴリズムで生成する手法。 手作業を省いたり、無数のバリエーションを生み出したりするために用いられる。
有用な反面、数値的にはユニークでもユーザーにとっては単調でしかない“無数のバリエーション”の乱造に陥る危険もある(「プロシージャル・オートミール」問題)。
「256×256マスに分割」について
ファミコン版『ドラクエ』シリーズのフィールドマップは256×256マスらしい。 つまり、4次相当メッシュの格子一つ一つがドラクエの世界並みに広がるわけで、総マス数は膨大になる。 国土だけで1千億マス、海も数えれば現実装のカバー範囲は3兆マスを超える。
どうせプロシージャルなので、『パワーズ・オブ・テン』(あるいは『たまごっちパラダイス』?)のごとくさらに粒度を上げることも理論上は可能だが、ズームレベルが高すぎるとMapLibreの動作が怪しくなってくるようだ。
地形のプロシージャル生成について
プロシージャルな地形生成やディテールの補完は、大規模なマップを持つ現代のコンピューターゲームでは当たり前に行われている。 その先駆けとして知られるのが、1980年ごろアメリカで開発されたダンジョン探索RPG『Rogueローグ』。 ダンジョンが毎度プロシージャル生成され、繰り返し新鮮に遊ぶことができる。 このコンセプトを受け継ぐゲームは「Roguelikeローグライク」と総称され、オリジナルの時代に倣ったレトロな表現のものも多い。
じぱんぐライクの命名はこれに由来し(プロシージャル生成部分は架空の地図となるため「日本もどき」との意味合いもある)、表現もいわゆるJRPGではなくローグライクに寄せている。 そのほうがより素朴で制作・開発しやすく、プロシージャル生成の単調さとも調和する(描写が詳細だとかえって単調さが際立ってしまう)。
「CPUには重荷」について
ターゲットを高性能機器に限ればCPUにさせてもいいかもしれない。 地図タイルの生成処理は常時走るわけではないし、地図タイルサーバーからロードするより目立って遅くならなければ問題ない。 マップチップ個別にではなく包括的に処理するCPU向けプロシージャルアルゴリズムも考え得るし、WebAssemblyで効率化する余地もある。
「即時応答の動的生成」について
「タイル要求時にではなく、事前に(アプリ起動時に)すべてをプロシージャル生成しておけばいいのでは?」と思われるかもしれないが、範囲が広すぎて非現実的。 メモリーと時間を膨大に費やし、サイトのリソース割当とユーザーの忍耐力を超えてしまう。 「すべて」ではなく、大まかなヒント情報や家々のプレハブくらいなら作ってみてもいいかもしれない。
自作マップチップ表示機能について
わが国でドット絵地図に求められているのはむしろJRPG風、言ってしまえば『ドラクエ』風だろう。 しかし権利上そのまま再現するわけにはいかず、また仮にそうしてみたところで、ぱっと見わかりやすい反面いまさら感があり興味に欠けるのではないか(ゲームに非はなくあくまで地図ネタとして)。 よってこちらとしては採用しないが、欲しければユーザーご自身でどうぞ、と委ねるために用意した機能でもあった。
裏返していえば、マップチップの自作をユーザーに動機づけるためにはデフォルトはドラクエ風でないほうがよい(自作の楽しみにとっておくほうがよい)、と考えられなくもない。
自作マップチップのテンプレートを適用した様子
いろいろ言いつつ、用意した自作マップチップのテンプレートはJRPG風
「違う地形が表示されてしまう」について
ここでは否定的だが、ローグのようにあえて千変万化させたい(同一シード値による再現性すらいらない)のなら問題ない。
サーバーレス
サーバーに関する要素や労力を何かしら省けることを誇張したマーケティング用語で、実態はさまざま。 ブラウザーに応答する存在が皆無なわけでは無論ない。 ここでは、「膨大なデータを提供する地図タイルサーバーを用意しなくてよい」との意味で使っている。
「安価に公開」について
じぱんぐライクのファイル一式は現時点で3メガバイト強(MapLibre等含む)、すべて静的ファイルでデータベースシステムも不要、初回ロード後は通信量も少ない(オフライン動作可)。 したがって各種クラウドサーバーや“サーバーレス”CDN類の無料枠に余裕で収まり、固有のサーバーサイド実行環境に依存することもない。 レンタルサーバーを借りるとしてもごく安いプランで充分、小型マイコンでの自己ホスティングも無理なく可能。 独自ドメインで公開するならドメイン費用がかかる程度。

補遺

地図タイルの描画における座標系

地図タイルは16×16個のマップチップで構成されます。 これをWebGLで描くとき、シェーダーはメッシュをどのように参照すればいいのでしょうか。

メッシュは「XYZ形式タイルにおけるズームレベル16の粒度」の配列であり、それを入力テクスチャーとして渡しています。 ならば、このテクスチャーのどこかからどこかまでの16×16テクセルを参照すればいいはずです。

その「どこか」とはどこか。 いま描こうとしている地図タイルの、ズームレベル16におけるXY座標です。 元のXYZ座標をそれに変換(Zが1増えるごとにXY軸の目盛りは倍になる計算)し、ユニフォームすなわち入力変数としてシェーダーに渡してやればいいのです。

シェーダーは、渡された座標をテクスチャー上の起点とし、現在のズームレベルに応じた増分で(つまり飛び飛びに)テクセルを参照していきます。

まとめると要するに、ズームレベルによって異なるXYZ形式地図タイルのXY座標系を、メッシュのXY座標系、言い換えればグローバル(と定めた)座標系に変換・統一してやるわけですね。

プロシージャル生成における地図タイルの連続性

言わずもがな当然のような事柄を前節でわざわざ述べたのは、プロシージャル生成においてもそれが重要だからです。

プロシージャル生成される地形は、メッシュに基づいてはいるものの、その境界に沿ってなどいません。 本文で説明したとおり四辺がフラクタルにずれ、チップが隣のタイルへはみ出したり、隣のタイルからはみ出てきたりします。

いっぽう地図タイルは各々個別に描画され、隣接タイルについて関知しません。 にもかかわらず、境界をまたぐフラクタル地形がちゃんとつながるのはなぜでしょう。 さらにいえば、ズームレベル間でも矛盾なく同じ地形を保つのはなぜでしょう。

答えは簡単、フラクタル関数の引数に「地図タイルないしマップチップのグローバルXY座標」を(適当な係数を掛けて)使っているためです。 入力値により出力値が決まる関数の性質により、地図タイル間の連続性が自然に担保されます。 たとえば入力値0.5までの関数グラフと0.5からの関数グラフは、別々に描いてもぴったりつながる道理でしょう。 乱数を求める際も、グローバルXY座標をシード値として与えます。

 

(最終更新:2026-02-19)