MapLibreで独自シェーダ使用時に標高が正しく表現できない
解決したいこと
MapLibreで独自シェーダを使用するカスタムレイヤーを作り、地図上に点をプロットさせているのですが、期待した高度で表示されません。
発生している問題
富士山の頂上に点(ドット)を表示させようとしています。
初期表示状態(地図を真上から見た状態)では問題なく点が表示されているように見えます。
しかし俯瞰させると富士山より上に描画され、地図を移動させるとドットの高度が変わるように見えます。
平面座標では正しい位置に描画できているようですが、z座標が正しくないように見えます。
使用しているコード
該当部分のみ記載し、不要と思われる箇所は省略しています。
point.vs.glsl(頂点シェーダ)
#version 300 es
in vec3 aPosition;
uniform mat4 uMatrix;
const float pi = acos( -1.0 ); //円周率
const float radius = 6371008.8; //地球平均半径
const float earthCircumfrence = 2.0 * pi * radius; //地球平均円周
const float invPi = 1.0 / pi; //円周率逆数
const float inv360 = 1.0 / 360.0; //360の逆数
//指定緯度での円周を求める
float circumferenceAtLatitude ( float lat ) {
return earthCircumfrence * cos( lat * pi * inv360 * 2.0 );
}
//経度からx座標を求める
float mercatorXfromLng ( float lng ) {
return ( 180.0 + lng ) * inv360;
}
//緯度からy座標を求める
float mercatorYfromLat ( float lat ) {
return (
180.0 - (
180.0 * invPi * log(
tan( pi * 0.25 + lat * pi * inv360 )
)
)
) * inv360;
//標高(と緯度)からz座標を求める
float mercatorZfromAltitude ( float alt, float lat ) {
return alt / circumferenceAtLatitude( lat );
}
//メイン関数
void main () {
gl_Position = uMatrix * vec4(
mercatorXfromLng( aPosition.x ),
mercatorYfromLat( aPosition.y ),
mercatorZfromAltitude( aPosition.z, aPosition.y ),
1.0
);
gl_PointSize = 16.0;
}
MyLayer.js(カスタムレイヤークラス)
class MyLayer {
constructor () {
this.id = 'MyLayer';
this.type = 'custom';
this.renderingMode = '3d';
}
onAdd ( map, gl ) {
//頂点データ(富士山剣ヶ峰の経度、緯度、標高)
const data = new Float32Array([ 138.72734, 35.360676, 3776 ]);
//省略(シェーダコンパイル、プログラム作成、頂点データの転送)
//this.programに作成したプログラムを代入
}
render ( gl, matrix ) {
gl.useProgram( this.program );
gl.uniformMatrix4fv(
gl.getUniformLocation( this.program, 'uMatrix' ),
false,
matrix
);
gl.drawArrays( gl.POINT, 0, 1 );
}
}
その他
mapLibreとdeck.glの組み合わせによる点の表示では期待通りの描画できることを確認しています。今回はmapLibre単体で実現したいためこのような質問になった次第です。
頂点シェーダ上でなにかパラメータが足りないのでしょうか。
おわかりになる方、いらっしゃいましたらご教示くださいますか。
どうぞよろしくお願いいたします。
0