はじめに
プロシージャルなHeightMapを用いる方法を解説します。
必要な知識
・Shaderの基礎知識
・Shader Graph(Unity)
シェーダーの概要
ShaderGraphの全体像
ParallaxTangent
グラフの全体像とサブグラフ(ParallaxTangent)です。要点となるParallaxTangentはHeightを与えることで対応するUVオフセットを出力します。
視線方向に応じてサンプル位置を変える
オフセット位置は接空間の視線ベクトル$\vec{V}$と任意のスカラー値$h$によって求めることができます。
説明を簡単にするために$UW$座標で説明します。視線ベクトル$\vec{V}$ と HeightMapによってできた凹凸の高さを$h$とします。求めたいオフセット位置を$x$とすると、成す三角形の相似比によって
$$\vec{V_u}:\vec{V_w} = x : h$$
であることが分かります。
よって
$$x = \vec{V_u} / \vec{V_w} ・ h$$
これで$U$軸におけるオフセット位置が求まりました。同様に$V$座標にも計算を行うことで$UV$のオフセット位置が求められます。
テクスチャのサンプリング
テクスチャのサンプリングについては特別な説明はありません。得られたオフセットを任意のUVに足し合わせ、テクスチャをサンプリングすることで視差効果が得られます。HeightMapからノーマル値を計算して出力することで上記の動画と同じ見た目の結果になります。
視差マップの問題点として、視差によって生じる射影を考慮できていないためHeightが強すぎたり、横から覗き込むように見るとテクスチャが歪んで見えます。
フレネル光で隠したり、ロケーションを限るなど工夫が必要です。
終わりに
視差マッピングは単純な方法ではありますが、雲や宝石といった厚みのある表現に用いられます。それだけでなく複数枚サンプリングして厚みをもたせたりUVスクロールを用いて立体感を与える等々、様々な応用が考えられそうです。