ピュアなwebglで描画する3D日本の地形地図

3D日本の地形地図

今回はwebglについて勉強していた時の成果物
日本の地形地図
に関するの内容を書きます。
実際2年も前に作ったものであるため詳細は忘れている部分もありますが、
思い出せるところまで書きます。

また私の勉強不足により、間違っている内容もあるかもしれないので、
間違っているところをTwitterで教えて頂けると嬉しいです。

webglについて

webglはブラウザの上でグラフィックカードを使った3D描画のためのインターフェースになります。
近年モダンなブラウズがほとんど対応しています。

webglをベースにした有名なライブラリはthree.jsになります。しかし本当にwebglを勉強したい方
はthree.jsを介さずに、直javascriptでwebglを基本から練習することをおすすめします。

その理由は、グラフィックカードを動かしているのはGLSL (OpenGL Shading Language) だからです
グラフィックカードで実行されるプログラムはCPUで実行される一般的(C, java, javascript)な言語
と違って、vertex shaderとfragment shaderに書かれて通りに動作します。

OpenGLを触れていないプログラマーにはこの部分はかなりハードルがあると思います。実際私もそうだった。

日本の地形の元データ

地形データは国土地理院の標高タイルタイルを元に作成します。
標高タイルの詳細は下記のサイトを参照してください。

https://maps.gsi.go.jp/development/demtile.html

写真地図は下記のタイルを使います。
https://cyberjapandata.gsi.go.jp/xyz/seamlessphoto/{z}/{x}/{y}.jpg

日本の地形描画の基本的な考え方

3Dの描画はcanvas 2dと違って、円や、四角、ポリゴンを直接描画できません。
webglは基本すべてが三角の頂点データになります。

そのため、下記の手順で描画します。

  1. まず地理院の標高タイルを取得してから、格子状に三角の頂点データを作成します。

  2. その後、各三角頂点データの間のピクセルを写真地図タイルのピースで貼り付けます。

この2つが出来たら、後はデータを渡して、webglで描画させるだけです。

実際描画のコードの抜粋を貼ります。

vertex shader

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
attribute float      gridIndex;
uniform mat4 mvpMatrix;
uniform vec4 gridInfo;
uniform sampler2D demTex;
varying vec2 colorCoord;
void main(void) {
int idx = int(gridIndex - 1.0);
int j = idx / int(gridInfo.z);
int i = idx - j * int(gridInfo.z);
vec2 XY = vec2(float(i) * gridInfo.x - gridInfo.x * gridInfo.z / 2.0, gridInfo.y * gridInfo.w / 2.0 - float(j) * gridInfo.y);
vec2 tp = vec2(float(i)/gridInfo.z + 0.5/gridInfo.z, 1.0 - float(j)/gridInfo.w - 0.5/gridInfo.w);
float Z = getZ(texture2D(demTex, tp));
gl_Position = mvpMatrix * vec4(XY, Z, 1.0);
colorCoord = tp;
}

fragment shader

1
2
3
4
5
6
precision mediump    float;
varying vec2 colorCoord;
uniform sampler2D mapTex;
void main(void) {
gl_FragColor = texture2D(mapTex, colorCoord) * vec4(1.0, 1.0, 1.0, 1.0);
}

座標の計算

webglによる3D描画は座標変換がとても重要です。
しかも3次元の座標変換はても複雑になりがちです。
そこで数学の行列の基礎が問われます。
行き詰まった時は、原点に戻り、座標変換のステップを一つずつ追って見るがいいでしょう。

最後に

ある程度shaderを書けて、座標の計算も慣れてから、three.jsを使うとwebglがとても
楽しくなって来ると思います。

webglに関しては、書きたい内容はは沢山ありますので、また整理出来てから書きたい
と思います。