Unityで自作シェーダーで法線マップ(Normal Map)を使うときに注意すること

こんにちは。ヤマヤタケシです。

前回、法線マップの理論は見えた!ということで実装を始めました。
やっぱり、理論と実践は違いますね。
というか、理論だけでは実装ができないという現実・・・。

普通に取得しても、x,y,zの色が同じになったのです。

Unityのテクスチャの設定をNormal map -> Color に戻すとちゃんと、x,y,zが別のものが入ってきました。

???

調べました。
Unity、DirectX環境でのNormalMapの内部的なフォーマットお勉強
「GLESやスマホフラグが立っていない環境ではDirectXモードということでNormalDiffuseの法線サンプリング計算はDXT5nを前提に「YW要素をXYZWのXYに変換し、Z要素をXYから復元して埋める」計算に切り替わってますね。」

な、なんだってー!
どうやら、テクスチャにはXXXYな形で入っているので、tex2Dのxyzは同じ値になるんですね。
知らんがな・・・。

ということで、UnityCG.incにUnpackNormal が定義されています。

結論!
こんな感じで解決です。

それにしても、float3, half3, fixed3 のどれを使えば良いのやら・・・。

ありました。
シェーダーを書く場合のパフォーマンスのヒント
引用します。

ワールド空間の位置とテクスチャ座標には、float 型を使用してください。
上記以外 (ベクトル、HDR カラーなど) には、half で始めます。必要なときだけ、増加します。
テクスチャデータのとても簡易な操作には、fixed を使用します。

なるほど!
と、思った次の行には・・・。
あらゆる現代のデスクトップ GPU は、常にすべての事を完全な 浮動小数点数精度で計算していて、そのため、根底では float/half/fixed の結果はまったく同じになります。

なんてこった。
じゃあ、floatを使うさ!
ただ、モバイルでは影響があるらしいです。

そんじゃまた。