2016年8月13日土曜日

BlenderGISでDEMを3Dレンダリング

DEM(標高ラスタ)を高品質な3Dでインタラクティブに描画できるソフトウェアはあまり多くない。商用ソフトでは色々あり、今まで使った中ではSurferが手軽で高品質、また動画作成に関してはFledermausが良かった。しかしやはりOSS(オープンソース・ソフトウェア)で実現したいところである。そこで、3DモデリングソフトBlenderのアドオンであるBlenderGISを試してみることにした。
Blenderはかつて商用だったこともある非常に高機能なソフトウェアで、動画作成機能が統合されている上、ダイナミックライティングなど近代的な描画手法にも対応している。BlenderGISはこのBlenderのPython 3.xで動くコンソールを介し、DEMを始めとしたラスタとShapefileによるベクタデータ、更にはXYZからなる点群データの座標変換を担当する機能を持つ。今回は、GeoTiffからなるDEMデータを読み込み、傾斜図をテクスチャとして貼り付けるまでの操作を行う。

作業の流れ

サンプルデータとして、USGSのセントヘレンズ山のLiDAR(レーザー航空測量)による地形データを使う。
Mosbrucker et al. (2014): https://pubs.er.usgs.gov/publication/ds904

0. BlenderGISのインストール
1. QGISでデータの整形
2. BlenderへのDEMの読み込み
3. テクスチャの作成(QGIS)
4. テクスチャの読み込み(Blender)
5. 完成

0. BlenderGISのインストール

QGISBlender、そしてPython 3.x系列およびpipやNumpy, GDALといったGISに関わるモジュール群は既にコンピューターにインストールされているものとする。
BlenderGISはBlenderのアドオンとして提供されており、まず GitHub - domlysz/BlenderGIS からZIPファイルをダウンロード。

次にBlenderを起動。左上のFile→User Preferencesを開いて、Add-onsタブからInstall from Fileを選択し、先ほどダウンロードしたZIPファイルを指定する。無事追加されれば、Add-Onsに"3DView: BlenderGIS"という項目が表示されチェックが入っている。
しかし実はこれだけではファイルを読み込めない。BlenderGISはGIS関連のPythonモジュールを必要とするが、Blenderが内部的に持っているPythonにはそれが含まれておらず、追加することも困難だからである。解決法は簡単で、Blender外部の通常版Python 3.xを使わせればいい。
するべきことは、Blenderのインストールディレクトリ(C:\Program Files\Blender Foundation\Blender)に行き、BlenderにバンドルされているPythonのフォルダを全削除。これで自動的にBlenderは外部のPythonを参照するようになる。

1. データの整形

サンプルに用いるデータはNAD1983 / UTM Zone 10Nの座標系で作られており、1mグリッドのデータは150メガピクセルもある。幸い低解像度の10Mグリッド版も同梱されているので、これを用いてセントヘレンズ山周辺だけ切り出す。QGISのラスタ→クリッパーで適当に切り抜き、GeoTiffで保存(StHelensLiDAR.tif)。
今回切り出した範囲は30メガピクセルちょっと。非ワークステーションでトライする場合はもう少し小さめに枠を取ったほうが良さそう。

2. BlenderでのDEMの読み込み

まずBlenderを起動する。Blenderは独特のショートカットキー地獄な文化を持つソフトウェアなので、細かい操作はBlender2.5xショートカット集などを適宜参照されたい(因みに2.5で変更があった)。
初期状態の画面は以下のとおりで、立方体が配置・選択されている。邪魔ななのでDELキーを押し、確認操作を経て立方体を消す。
次にFile→Import→Georeferenced Rasterを選択する。ここからは、GDALが対応するあらゆるラスタを読み込むことができる。デフォルトでModeは"On Plane"となっているが、このままだと画像付き板になってしまうので、"As DEM"を選んでおく。
続けて忘れずにCRSを設定する。 EPSGコード: 26910 を与えるか、或いはQueryに"UTM Zone 10N"と入力してEnterキーで検索し、NAD83 / UTM Zone 10Nを選択→OK、そしてCRSに追加された当該項目を選ぶ。
Fill nodata valuesにチェックを入れると、少々時間はかかるが穴埋めもしてくれる。
設定を終えたら、深呼吸して"Import georaster"をクリックして読み込む。
 …化け物みたいなものが出現してしまった。が慌ててはいけない。マウスのホイール(中央ボタン)のドラッグで慎重に向きを変え、Alt+Fキーの組み合わせて視界を移動させると、正しく読み込まれていることが分かる。要はnodata部分がマスクされていないだけである。
しかし、この状態ではDEMは間引いた状態で読み込まれており、ディテールが失われている。
そこで右側のパネルにあるModifier(レンチアイコン)をクリックし、その中のSubdivisionsの数値を増やしてみる。
この値は2^Nの値で、一つ増やすごとに細かさもメモリ使用量も増えていく。現環境では最大値が11で、取り敢えず作業は10で行う事が多い。有り難い事に、現在表示している作業画面である"View" と完成版の出力のための"Render”で異なる値を指定できるようになっている。
またZ軸方向に引き延ばすには、パネルのObject(立方体アイコン)のScaleを1.0から任意の倍率にする。


3. テクスチャの作成(QGIS)

このままでは只の白い面なので、DEMに対応するテクスチャを設定して色を付ける。つける色としては、例えば段彩図(標高に対応したグラデーション)や傾斜図(傾斜度に対応したグラデーション)などが考えられるが、今回は地形の判読性を考えて後者にする。
まずRaster→Analysis→Terrain Modelで図のような傾斜図(StHelensLiDAR_slope.tif)を作る。

これにプロパティで適当な色をつけた(白黒反転作業など)後、レイヤー一覧上で右クリック→Save As..を選択。"Output mode"を"Rendered image"にして保存(→ StHelensLiDAR_texture2.tif)することで、描画済みの画像として保存することができる。

4. テクスチャの読み込み(Blender)

再びBlenderでの作業に戻る。DEMを読み込んだ時と同様に、File→Import→Georeferenced rasterを選択する。今回はModeをAs DEMからOn meshに切り替える。
Objectsが先ほど読み込んだDEMの名前になっているのを確認し、QGISで作成した画像を読みこませる。
手順が合っていれば、以下の図のようにガリーなど地形がくっきりとした3Dオブジェクトに仕上がる。スクロールやAlt+Fによる視点移動で色々観察してみよう。

5. 完成

溶岩流を拡大するとこんな感じ。内部膨張による割れ目がよく分かる。
ステップ3に戻って、標高段彩図をテクスチャにするとこのようになる。起伏がわかりにくくなるので、適切にライトを追加するなど工夫が必要。

BlenderGISのGeoRefrenced Cameraを使うとオルソ画像をレンダリングすることもできるが、その辺はまた別の機会に。航空写真や、尾根谷度など特殊ラスタを与えても楽しそうである。


より高度な情報は、以下のサイトをどうぞ:
BlenderGIS の Wiki
Shaded relief with BlenderGIS - Morgan Hite: Part 1, Part 2

0 件のコメント:

コメントを投稿