OpenGL on Android with Expo


バグフィックスしつつOpenGL仕様のおさらいをする内容です。

 

発端はReact Native(expo)で作ったAndroidアプリをテストしているときです。

ビルド後、複数端末でテストしたところタブレット端末で急にアプリが落ちました。

クラッシュレポートなど出ず、すっと消えるように。

expoをインストールしてデバッグするもログにも全く残りません。困った。

 

どの端末で使える/使えないと知りたかったのでOpenGLのバージョンなどから調べていきます。

バージョンサポート

ディベロッパードキュメントを見るとサポートはこうなっています。

今回動かなかった端末は5.1.1(API 22)。あれ?問題なさそう。

動いた端末は6.0と7.0です。

Open GLのバージョン

OpenGL、OpenGL ES、WebGLの3つを見てみます。

どれもクロノスグループの策定する仕様で(実装ではない)、OpenGLはフルセット、ESはスマホや組み込み向けのサブセット、WebGLはESの派生規格です。

ESとかWebGLとかのバージョンを見てもわからんって状態でしたがわかりやすい図を作ってくれている方がいました。

 

とりあえず、

  • OpenGL 2.0 → OpenGL ES 2.0 → WebGL 1.0
  • OpenGL ES 3.0 → WebGL 2.0

ということを頭に入れておきます。

gl-reactが使用するバージョン

今回使用させていただいたgl-reactは何を前提としているのか見ます。

expoだとGLViewNative.jsexpo-glGLViewを使っていることがわかります。

 

まずexpoのドキュメントを見てみましょう。

expo-gl provides a View that acts as an OpenGL ES render target, useful for rendering 2D and 3D graphics. On mounting, an OpenGL ES context is created. Its drawing buffer is presented as the contents of the View every frame.

OpenGL ESを使っているようなことが書かれています。

ただWebgl APIセクションには「古い端末だとWebGL 2.0に対応してないかもね(意訳)」と書いています。

また、このパッケージのリポジトリを見てもこうあります。

Expo module providing WebGL2 implementation

WebGL 2.0 ≒ OpenGL ES 3.0を実装しているようです。

原因は?

どうもバージョンは怪しく思えるけど、仕様的に全く動かないわけではないはず。

試しにテストで書いたgl-reactアプリを起動してみます。

問題なく動いた。

 

こうなると一部のシェーダーが悪さをしている気がします。

複数のNodeBusで連結していたので1つずつ動作確認。

最後にBlur処理をするGLSLが原因でした。

内容自体は問題ないのですが、1つ0除算の可能性のあるところを潰したら動くようになりました。

いたって単純なバグです。問題は端末によって動いたり動かなかったりすること。

 

そういえばに似たようなことがあって調べたような。

未定義の動作をしたときに環境によって動いたり動かなかったりするやつです。

ちょっと調べたところ0除算はGLSL ES 3.0からundefinedとしているが実装によって動作が異なったりするそうで(参照元)。

正直エラーはエラーとして一貫してほしいです。


コメントを残す

メールアドレスが公開されることはありません。