Mapboxのハイトマップから地形を生成する

Mapboxからタイル画像を取得して一枚の画像に合成するからのつづき。
衛星画像とハイトマップを使ってHoudiniで立体化する。

ハイトマップを使って立体化

SOP内のネットワーク

cop2net SOP

cop2net SOPでMapboxのTerrain-RGB画像を読み込む。

cop2net内のノードはこのように構成する。

FileノードでMapboxのTerrain-RGB画像を読み込む。32bit浮動小数点に設定する。

Terrain-RGB画像の仕組み
https://docs.mapbox.com/data/tilesets/guides/access-elevation-data/

elevation = -10000 + ((R * 256 * 256 + G * 256 + B) * 0.1)

例えばrgb<1,150,136>の場合、-10000 + ((1 * 256 * 256 + 150 * 256 + 136) * 0.1) = 407.2メートルとなる。

VOPの中身はMapboxのTerrain-RGBを高さに戻す処理を行っている。

HeightFieldFile SOP

SourceはCOPにし、SizeはMapboxの実寸の長さを入力する。Rotateを90にすると、Zマイナスが北になる。

マテリアルを作成し、衛星画像のテクスチャーを貼ったもの。

Web Mercator投影を補正する

Mapboxのタイル画像は、Web Mercator投影が使われている。緯度が高くなるほど歪みが大きくなっている。緯度を均等な間隔にするためにはこれを補正する必要がある。

//
// 緯度を均等にスケールする(ウェブメルカトルの歪みを解消する)
// Run Over: Points
//

// ハイトマップ四方の長さ
float width = `chs("../Coordinates/west")`;
float height = `chs("../Coordinates/height")`;

// 四方の緯度と経度
float west = `chs("../Coordinates/west")`;
float east = `chs("../Coordinates/east")`;
float north = `chs("../Coordinates/north")`;
float south = `chs("../Coordinates/south")`;

// 緯度 → Web Mercator Y座標
float lat_to_web_mercator_y(float lat)
{
    float lat_rad = radians(lat);
    return log(tan((PI/4)+(lat_rad/2)));
}

// Web Mercator Y座標 → 緯度
float web_mercator_y_to_lat(float y_merc)
{
    return degrees(2 * atan(exp(y_merc)) - (PI / 2)); // 緯度に変換
}

// Z座標を0-1にスケールする
float coord = (@P.z*-1 + height/2) / height;
// メルカトル座標に変換する
float south_mer = lat_to_web_mercator_y(south);
float north_mer = lat_to_web_mercator_y(north);
float y_mer = coord * (north_mer - south_mer) + south_mer;

// 緯度が求まる
float lat = web_mercator_y_to_lat(y_mer);

// 緯度から座標を求める
float z = (lat - south) / (north - south) * height - (height / 2);
z *= -1;

@P.z = z;
タイトルとURLをコピーしました