視差シェーダーの作り方
視差(parallax)シェーダーとは
仮想的な前後関係を与えることで視線の変化による位置関係の変化が生じ、奥行きがあるように見せる技術
理論編
目やカメラは広い範囲の光を小さい網膜やセンサーに集めて情報を認識しているので、扇状に広がる視野角というものが存在します。
つまり奥に行くほど広い範囲の情報が目に入ってくるので遠くのものほど小さく見える、いわゆるパースというものになります。
それではどうやって平面上にパースのついた空間を表現するにはどうしたらいいかというと、実はシンプルに「パースのついたテクスチャ」を表示すればいいのです。
しかしただの2Dテクスチャを張っただけでは視線の変化による位置関係の変化がないため奥行き感を感じにくいです。
そこで視線の変化により仮想的に奥にあるものの位置を変化させることにします。
![](https://assets.st-note.com/img/1709517662594-0AbPNXmmpO.png?width=1200)
次にどれだけ表示位置を変化させればいいのか考えます。
上の図でAの位置にあるものを見るとき、ポリゴン上ではBの位置を通過することになります。つまりBの位置にテクスチャをズラせばAの位置にあるように見えるわけです。
![](https://assets.st-note.com/img/1709518371863-V39Qutozi4.png?width=1200)
Shadergraphのノードで表すとこうなります。
単位系をそろえるためのtransformノードを入れていますが、元の位置にあるものからviewベクトル、つまり視線のベクトルを引いてあげるだけです。
viewベクトルに倍率をかけることで奥行き感の強度を変えることができます。
複雑そうに思える視差の計算もとても単純なものだったりします。
2つの方法
viewベクトルの倍率を変化させることで奥行き感を変化させる方法がわかりましたが、このままでは奥方向にスライドして見えるだけです。
球体や立方体など立体を表現する方法を見ていきます。
積層型
これは立体を何層もの輪切り状態にして各層に奥行きの倍率をかけて重ね合わせるというやり方です。
動画は上下左右それぞれ100層に分割し、奥行き方向にグラデーションを付けることで、そこに見かけ上のUV空間を作って、それぞれ別のテクスチャを貼れるようにしています。
つまり上の視差の計算を400回行うことで奥行きのある空間を表現しているのです。
デプスマップ型
輪切りにせず、奥行きの違いをデプスマップで表現するやり方です。
![](https://assets.st-note.com/img/1709522636290-SBXmj7lyKW.png?width=1200)
図のような深度の違いを表したマップを奥行きの倍率にかけ合わせるだけです。
このやり方はシンプルで計算回数も少ないですが、その分歪みが大きくなります。