土屋つかさの技術ブログは今か無しか

土屋つかさが主にプログラミングについて語るブログです。

#unity Unity2021.1αのHDRPサンプルシーンでリフレクションプローブを見て動かして焼く

 この記事はUnity HDRP アドベントカレンダー Advent Calendar 2020 - Qiitaの5日目の記事です。

qiita.com
やっぱりHDRPやってる人少ないのかな……土屋がそもそもHDRPやってないからな……今からでもUnityシェーダー全般に範囲拡大してもいいんじゃないかな……。

導入

 Unity2020.2.0(現在β14)から、HDRPのサンプルシーンが一新しました。さやちゃんのブログが詳しいです。どうでもいいけど、さやちゃんぐbotさんの名前、「さやちゃんさん」なのか「さやちゃんぐさん」なのか「さやさん」なのか分からないまま毎回適当に記述してる。
sayachang-bot.hateblo.jp
 土屋は今現在はURPをメインに作業しており、HDRPは触ったことがないんですが、せっかくだからとUnity2021.1αをインストールしてこのサンプルを動かしてみました。HDRPの能力は知っていたつもりですが、実際動いているのを見ると「HDRPだとUnityでこんな絵作りできるんだ!?」と新鮮な驚きがありました。皆さんにもおすすめです。

 さて、上記の記事の中で一個気になる話がありました。ここです。
f:id:t_tutiya:20201205133645p:plain
 確かに、ガラスの反射の中に、スカイボックスの地面と空っぽい風景が写り込んでいるように見えます。それってつまり、リフクレションプローブが正常に機能していないということです。なんだこれ?

 というわけで、調べてみることにしました。

リフレクションプローブについて

 ガラスに限らず、シーン内のオブジェクトへの周辺風景の映り込みは、シーン内に配置された「リフレクションプローブ」というオブジェクトを介して行います。
 リフレクションプローブは、配置された場所から見える周辺風景を上下左右前後6枚のテクスチャにあらかじめ描画しているキューブマップになります。周辺風景を事前にテクスチャに保存しておくことを「ベイクする」と言います。
 オブジェクトに風景を写り込ませたい場合、オブジェクトの近くに配置したリフレクションプローブからテクスチャをサンプリングすることで、近似的に反射の描画が実現できます。
 リフレクションプローブには有効範囲が設定されていて、どのプローブの有効範囲からも外れている場合は、スカイボックスが適用されます(スカイボックスもリフレクションプローブの1種です)。なので、オブジェクトにスカイボックスが写り込んでいる場合、記事のように「設定がおかしいのでは?」と考える必要があるわけです。

ガラスに適用されているリフレクションプローブの確認

 ではシーンを見ていきましょう。サンプルシーンは3つの空間room1/2/3から構成されていて、当該の空間はroom2になります。この部屋にはリフレクションプローブが沢山置かれていて、ガラスに適用されているのはその中の"Reflection Probe Room 2 Main A"になります。
f:id:t_tutiya:20201205133851p:plain
 上図はそのリフレクションプローブを選択した状態。選択するとシーンの中に光沢のある球みたいのが現れます。これがリフレクションプローブです。
 なおroom2には緑色のボリュームが幾つか配置されていて邪魔だったのでオフにしています。なので通常よりも描画クオリティが若干下がってるかもです。
 球はベイクしたテクスチャから生成されたキューブマップを表しています。右下のプレビューにも同じものが描画されているんですが、白トビしてて見えません*1
f:id:t_tutiya:20201205134000p:plain
 プレビューウィンドウの上部ののスライダーを操作して露出を下げると上図のようにキューブマップが可視化されます(ここでは-9に設定しています)。ドラッグで回転させることもできます。
f:id:t_tutiya:20201205134016p:plain
 回転させて、ガラスに写り込んでいる風景と位置を合わせてみました。見た目が左右反転しているのは、リフレクションプローブが反射用にベイクされているからです。こうして見るとわかりますが(そうでもないか?)、地面と空の境界のように見えていたのはスカイボックスではなく、階段の先にあるroom1の外壁と空の境界でした。スカイボックス無罪!

リフレクションプローブの位置を動かして再ベイクしてみる

 とはいえ、見た目に違和感があるのは確かです。というのも部屋の奥から階段の奥にあるroom1を覗くと外壁しか見えないのに、リフレクションプローブから見えるroom1の風景は、上半分が空になっているからです。これは、リフレクションプローブが配置されている座標、つまりベイクの視点となる座標が、階段を下りたすぐの地点になっているためです。
f:id:t_tutiya:20201205134158p:plain
 確かにその場所から階段の奥を見上げると、上半分が空になります。ちなみに無数に浮かんでいるハンコっぽいアイコンはDecal Projectorというコンポーネントで、ビルトインのプロジェクションマッピングに相当する機能と思われます*2
f:id:t_tutiya:20201205134043p:plain
 リフレクションプローブの位置を移動して、違和感を薄めることできるかどうか試してみましょう。インスペクタの十字アイコンをクリックすると、プローブの配置座標を変更できるので、ガラスの横に移動し、高さも調整します。一般に、反射させるオブジェクトの付近に配置してベイクすると描画がより自然になります。逆に言えば、離れたオブジェクトは描画がより不自然になるので、ちょうどいい場所を選ぶ必要があります。
f:id:t_tutiya:20201205134104p:plain
 プローブを移動してbakeボタンを押すと、テクスチャが再ベイクされます。さっきより違和感が減っていると思いますが、いかがでしょうか? とはいえ、先述した通り、この位置がベストというわけでは実はありません。サンプルシーンではroom1からroom2へ移動するようになっているので、階段から降りた地点での描画が、一番違和感出ないようにしているのかもしれません。

終わりに

 今回の記事は、さやちゃんさんのツイートに触発されて検証を始めて、さやちゃんさんと数回DMしているうちに記事が1個できる分だけの結果が発生しました。仲間がいると学習が捗るという事ですかね。HDRP仲間、いっぱい増えるといいね……(遠い目)。
 

*1:リフレクションプローブは大抵こうなってるけどなんでなのかがわからない。HDRだから?

*2:ここではroom1の外壁にうっすら汚れを浮かべるために使用しています