https://prideout.net/emulating-double-precision の ざっくり翻訳
https://prideout.net/emulating-double-precision の ざっくり翻訳
頂点変換の精度を向上させる
WebGLとOpenGL ESは64ビット演算をサポートしていませんが、頂点シェーダーで少し足掻くだけでエミュレートできます。
まず、この記事に興味を持たれた方は、Patrick CozziとKevin Ringが出版した「3D Engine Design for Virtual Globes」というとても素晴らしい本に興味を持たれたのではないでしょうか。この本には、精度についての章があり、その他にも多くのことが書かれています。
地図画像を読み込むと、以下の2つのインタラクティブなWebGLキャンバスが表示されます。青い十字線は、バークレー・マリーナのすぐ北にあるセザール・チャベス公園の展望台です。ここは、私の2人の子供たちのお気に入りの場所で、十分に拡大すると見ることができます。Googleマップと同じように、ズームやパンをしてみてください。
子供たちが見えるくらいまで拡大すると、左のキャンバスでは十字線が揺れていますが、右のキャンバスでは揺れていないことに気がつくかもしれません。左のキャンバスでは従来のモデル・ビュー・プロジェクション・マトリックスを使用していますが、右のキャンバスでは MVP を計算する際にカメラが (0,0,0) にあるように見せかけ、バーテックスシェーダーで手動で変換を行っています。このためのGLSLを以下に示します。
ハイパートとローパートの2つのユニフォームを使って、目の位置をGPUに送信していることに注意してください。この2つのパーツを抽出するために、以下のCPUサイドのコードを使用することができます:
C言語ではなくJavaScriptを使用している場合、Float32Arrayを使用して、上記のスニペットで見られるdouble-to-floatキャストを行うことができるかもしれません。
64ビット頂点
これまで、64ビットのカメラ位置の扱い方について説明してきましたが、これは上記のデモで十分です。では、64ビットの頂点が必要な場合はどうでしょうか。この場合も、GPUに送る前に各2倍を2つの浮動小数点に分割することができます。この場合、VBOが2倍になり、バーテックスシェーダが少し複雑になるため、よりコストがかかります。
私はこれを完全にテストしたわけではありませんが、ドナルド・クヌース(Donald Knuth)の研究に基づく古い数学精度ライブラリであるDSFUN90で使用されている「ダブル・シングル」ルーチンをGLSLで移植したものがあります!
いくつかの脚注
このページの地図デモは、私が取り組んでいる小さなC99ライブラリを使い、MODULARIZE=1、PRECISE_F32=1のフラグを付けてEmscriptenで実行したものです。PRECISE_F32を使用しない場合、Emscriptenはfloat変数でもdoubleを使用するため、split_doubleのコードが壊れてしまいます。
デモ用のマップテクスチャを得るために、mapbox.comの本当に素晴らしいStatic maps APIを使用しました。