AndroidでRay Tracingできた
はじめに
ついにAndroidでリアルタイムray tracingできる時代が来た!ということでハローワールド的にray tracingで立方体を8つ描いた図がこちら。
スマホは最近手に取れるようになったGalaxy S22を使っていますが、なんだか地味な画像だなと思われるかもしれません。ray tracingといえば高級なグラフィクスのゲームを連想される方がほとんどでしょうが、本来ray traceとはレンダリング手法のひとつで、反射や屈折といった目に見える景色をそのまま描画することに長けている描画方法のことです。上図はその手法を用いて簡単な図をレンダリングしてみました、ということになります。
Galaxy S22について
注意点ですが、日本で発売されるS22を購入しても(おそらく)ray tracingできません。この記事を見てS22が欲しくなる人はまれでしょうが、間違えて購入しないようにお願いします。
S22は欧州向けとそれ以外の地域向けで載っているSoCが異なっており、欧州向けは「Exynos2200(GPU : Xclipse920)」、それ以外は「Snapdragon」です。Xclipse920がAMDのRDNA2アーキテクチャーなので、ray tracingが可能です。
私はAmazon UKで購入しました。
Android Studioでの注意点
まだ描画に成功しただけで、プログラム的に細かい不備がたくさんある状態です。
開発環境はAndroid Studioです。
色々まとまってくれば、Qiitaにも久しぶりに投稿したいと思ってますが、主な注意点としては以下です。
- 最新のndkが必要。(2022/4/3時点)
これ以上でないと、ray tracing pipelineの作成に必要な拡張機能が入っていないようです。
android { ndkVersion "25.0.8221429-beta2" }
NDK のダウンロード | Android NDK | Android Developers
- main/shaders配下にshaderファイルを置いても自動でコンパイルされない。
glslcで手動でコンパイルし、spvファイルを以下に格納する必要がある。
${PROJECT_DIR}\app\build\intermediates\assets\debug\mergeDebugAssets\shaders
Android の Vulkan シェーダー コンパイラ | Android NDK | Android Developers
${NDK_DIR}\toolchains\llvm\prebuilt\windows-x86_64\sysroot\usr\include\vulkan
今後に向けて
色の持ち方がBGRAになっているので、RGBAに直したいところ。
まだまだ画面に何か描けましたという状態ですが、ここまでくれば色々できるようになると思うので、スマホでどこまでできるか楽しみです。
2022/4/4追記
validation layerを入れると、拡張機能を用いているところのほとんどすべてでエラーのメッセージが出力される。実際にはエラーなしに動いているように見えるが、これはいったい?
調査が必要。
2022/4/5追記
enableしているはずなのに、vkGetDeviceAddressの拡張機能を有効にしろというメッセージが出力される。
Validation Error: [ VUID-vkGetBufferDeviceAddress-bufferDeviceAddress-03324 ] Object 0: handle = 0xea7170000000031, type = VK_OBJECT_TYPE_BUFFER; | MessageID = 0xa641531b | vkGetBufferDeviceAddressKHR: The bufferDeviceAddress feature must: be enabled. The Vulkan spec states: The bufferDeviceAddress or VkPhysicalDeviceBufferDeviceAddressFeaturesEXT::bufferDeviceAddress feature must be enabled (https://www.khronos.org/registry/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkGetBufferDeviceAddress-bufferDeviceAddress-03324)2754439499
ただ、有効化していないとそもそもbuffer addressをとってこれないし、debugで値を見てみるときちんと値が入っていることがわかる。
試しにvkGetBufferAddressEXTの関数を用いると、関数が見つからず使えなかった。
Vulkanのバージョンが上がるかvalidation layerのバージョンが上がるまで、callback関数の中でメッセージをフィルターする方向で進める。
ray tracing関係のextensionは軒並みvalidation errorが出ているように見えるので無視したいが、たまに実装が本当によくないことがあるのが事態をややこしくしている。