
マイケル
みなさんこんにちは!
マイケルです!
マイケルです!

エレキベア
こんにちクマ〜〜〜〜

マイケル
今日は前回と引き続き、シェーダーライティングを進めていきます!
前回は基本のライティングを進めてきましたが、今回は「テクスチャマッピングによるライティング」編になります!
前回は基本のライティングを進めてきましたが、今回は「テクスチャマッピングによるライティング」編になります!

エレキベア
テクスチャマップというと、法線マップとかのあれクマ??

マイケル
その通り!
法線マップの他にもいろんな種類があるから、概要からシェーダーでのライティングについて解説していきます!
法線マップの他にもいろんな種類があるから、概要からシェーダーでのライティングについて解説していきます!

エレキベア
楽しみクマ〜〜〜

マイケル
なお、今回実装するシェーダーはGitHubにも上げています!
こちらもよければご参考ください!!
こちらもよければご参考ください!!
GitHub – masarito617/unity-lighting-shader-sample

エレキベア
毎度お馴染みクマ〜〜〜〜
参考書籍

マイケル
シェーダー実装や内容をまとめるにあたり、
下記の書籍を参考にさせていただきました!
下記の書籍を参考にさせていただきました!
HLSL シェーダーの魔導書 シェーディングの基礎からレイトレーシングまで

エレキベア
「DirectX 9 シェーダプログラミングブック」は今は手に入りにくいクマが、
どっちも分かりやすくて定番書籍クマ〜〜〜
どっちも分かりやすくて定番書籍クマ〜〜〜
テクスチャマッピングの概要と種類
テクスチャマッピングとは

マイケル
まずテクスチャマッピングとはそもそも何なのか?という点についてですが、
こちらは 「テクスチャを使用して3Dモデル表面に質感を与える手法」になります。
このテクスチャをテクスチャマップといい、普段ただテクスチャを貼り付けて色を描画するだけのテクスチャもカラーマップ(アルベドマップ)と呼ばれるテクスチャマップの一種になります。
こちらは 「テクスチャを使用して3Dモデル表面に質感を与える手法」になります。
このテクスチャをテクスチャマップといい、普段ただテクスチャを貼り付けて色を描画するだけのテクスチャもカラーマップ(アルベドマップ)と呼ばれるテクスチャマップの一種になります。

エレキベア
逆に言えば色情報以外の情報もテクスチャに持たせることでいろんな表現ができるクマね
テクスチャマップの種類

マイケル
代表的なテクスチャマップの種類としては下記のようなものがあります!
名称 | 概要 | 格納情報 |
---|---|---|
カラーマップ | オブジェクトの色を表現するためのテクスチャ | 色情報(RGB) |
ハイトマップ | 高低情報を示したテクスチャ | 高低情報(グレースケール) |
法線マップ | 法線情報を元にディテールを表現するためのテクスチャ | 法線情報(RGB) |
スペキュラマップ | 光沢の量を示したテクスチャ | 光沢量(グレースケール) |
AOマップ | 環境光の影響の強さを示したテクスチャ | 環境光の影響(グレースケール) or 陰影を付与したテクスチャ(RGB) |
ディスプレイスメントマップ | 実際の形状に変形してディテールを表現するためのテクスチャ | 形状を動かす距離(グレースケール) |

マイケル
この中でも得に物体表面に凸凹を付けてディテールを表現する手法をバンプマッピングと呼びます。
バンプマッピングは、初めはハイトマップが使用されていましたが、現在はより細かいディテールを表現できる法線マップの使用が主流のようです。
また、ハイトマップはグレースケールで手軽に作成できるため、法線マップを生成するのにも使用されることがあるようです。
バンプマッピングは、初めはハイトマップが使用されていましたが、現在はより細かいディテールを表現できる法線マップの使用が主流のようです。
また、ハイトマップはグレースケールで手軽に作成できるため、法線マップを生成するのにも使用されることがあるようです。

エレキベア
バンプマッピングも名前はよく聞くクマね

マイケル
スペキュラマップやAOマップはピクセルごとに影響量を持たせることで調整を行うテクスチャです。
以前トゥーンシェーダーを作成した際に使用した、輪郭線の描画量を書き込んだテクスチャもこれらと似た要領になりますね。
以前トゥーンシェーダーを作成した際に使用した、輪郭線の描画量を書き込んだテクスチャもこれらと似た要領になりますね。

【Unity】トゥーンシェーダーを一から自作する(陰影+輪郭線)【シェーダー】
マイケルみなさんこんにちは!マイケルです!エレキベアこんにちクマ〜〜〜マイケル新年一発目の記事は、みんな大好きトゥーンシェーダーの実装だ!エレキベアついに来たクマか・・・マイケ...
↑トゥーンシェーダー作成時にも輪郭線の描画量をグレースケールのテクスチャで用意した

エレキベア
ピクセルごとに追加で必要な情報を載せるのクマね

マイケル
また、AOマップに関してはカラーマップに陰影を付与したものをAOマップと呼ぶことも多いようです。
今回は陰影量のみを抜き出したグレースケールとして扱っていきます。
今回は陰影量のみを抜き出したグレースケールとして扱っていきます。

マイケル
ディスプレイスメントマップに関しては目的は法線マップと同じですが、実際に形状を変形させるすごいやつです!

エレキベア
一番すごそうクマ・・・

マイケル
今回はこの中で
・法線マップ
・スペキュラマップ
・AOマップ
の3種類を使用してライティングを行なっていきます!
ディスプレイスメントマップに関しては、正確に使用するにはテッセレーション等の知識が必要になるため、今回は割愛とさせてください。。(いつかこちらもまとめるかもしれません)
・法線マップ
・スペキュラマップ
・AOマップ
の3種類を使用してライティングを行なっていきます!
ディスプレイスメントマップに関しては、正確に使用するにはテッセレーション等の知識が必要になるため、今回は割愛とさせてください。。(いつかこちらもまとめるかもしれません)

エレキベア
まあまずは基本どころを抑えるクマね
テクスチャマップの生成方法

マイケル
テクスチャマップの生成方法としては、主に下記のような方法があります。
1. WEBツールを活用する
2. 3DCGソフトから出力する
3. ペイントソフトから作成する

マイケル
2.3.はBlenderやPhotoshopといったソフトを使用して生成する方法です。
これらのソフトでの生成方法についてはまた別途記事でまとめることにして、今回は1.のWEBツールを使用して出力したテクスチャを使用して進めます。
これらのソフトでの生成方法についてはまた別途記事でまとめることにして、今回は1.のWEBツールを使用して出力したテクスチャを使用して進めます。

エレキベア
各ソフトでの使い方まで書いてるとかなり多くなりそうクマからね

マイケル
今回、WEBツールは下記の NormalMap-Online というサービスを使用させていただきました。


マイケル
こちらはアップロードしたハイトマップや画像から法線マップやディスプレイスメントマップといったテクスチャを作成するサービスになっています。
今回はデフォルトで設定されているキューブの各面に渦模様が入ったテクスチャを使用させていただきました。
今回はデフォルトで設定されているキューブの各面に渦模様が入ったテクスチャを使用させていただきました。

エレキベア
なんてありがたいサービスクマ・・・
法線マップを使用したシェーダー実装

マイケル
それでは早速法線マップを使用したライティングについて触れていきます!
法線マップの考え方

マイケル
法線マップは前述した通り、法線情報を元に凸凹等のディテールを表現するために使用されます。
イメージとしては、下記のように平面なポリゴン内で凸凹している箇所について法線マップで別途法線情報を書き込んでおくことで、ライティング計算する際に陰影を付けるようなものになります。
イメージとしては、下記のように平面なポリゴン内で凸凹している箇所について法線マップで別途法線情報を書き込んでおくことで、ライティング計算する際に陰影を付けるようなものになります。

エレキベア
なるほどクマ
これでポリゴン数を抑えながら凸凹を表現できるわけクマね
これでポリゴン数を抑えながら凸凹を表現できるわけクマね
オブジェクトスペースとタンジェントスペース

マイケル
法線マップに書き込む情報としては大きく
・オブジェクトスペース
・タンジェントスペース
の2つの座標系で書き込む方法があります。
・オブジェクトスペース
・タンジェントスペース
の2つの座標系で書き込む方法があります。

マイケル
オブジェクトスペースは法線のXYZ座標をそのまま書き込んだもので、
タンジェントスペースは
・法線(normal)
・接線(tangent)
・従法線(binormal)
の3つの軸に分けた法線座標系で書き込んだものになります。
タンジェントスペースは
・法線(normal)
・接線(tangent)
・従法線(binormal)
の3つの軸に分けた法線座標系で書き込んだものになります。

エレキベア
タンジェントスペースは3つの成分に分けて書き込むクマね

マイケル
しかし、オブジェクトスペースで書き込んだ場合には頂点の変形に対応できないという問題点があるため、
一般的に法線マップはタンジェントスペースで書き込まれているものがほとんどです。
一般的に法線マップはタンジェントスペースで書き込まれているものがほとんどです。

マイケル
タンジェントスペースで法線マップを作成した例としては下記のようになります。
RGB成分に対して(tangent, binormal, normal)で書き込むため、基本的には垂直なnormalが大きく、青成分が強く出ているのが特徴です。
RGB成分に対して(tangent, binormal, normal)で書き込むため、基本的には垂直なnormalが大きく、青成分が強く出ているのが特徴です。

エレキベア
法線マップが青みがかってるのはそういう意味だったのクマね
1. 法線情報をワールド座標空間に変換して計算する方法

マイケル
法線マップの情報を使用して法線を計算する方法としては大きく
1. 法線情報をワールド座標空間に変換して計算する方法
2. ライトやカメラを接空間に変換して計算する方法
の2つがあります。
まずは基本の考え方となる1.の方法を見ていきましょう!
1. 法線情報をワールド座標空間に変換して計算する方法
2. ライトやカメラを接空間に変換して計算する方法
の2つがあります。
まずは基本の考え方となる1.の方法を見ていきましょう!

マイケル
計算方法としては、法線マップに書き込まれたタンジェントスペースの法線情報と、
頂点座標の基底軸を掛け合わせることで法線を算出します。
簡単な数式で表すと下記のようになります。
頂点座標の基底軸を掛け合わせることで法線を算出します。
簡単な数式で表すと下記のようになります。

エレキベア
基底軸は頂点シェーダーに渡されてくる情報クマね
これなら頂点が変形しても対応できそうクマ
これなら頂点が変形しても対応できそうクマ

マイケル
最終的にワールド座標の法線が必要となるため、
1. 頂点シェーダー内で基底軸をワールド座標に変換する
2. フラグメントシェーダー内で変換した基底軸と法線マップから取り出した法線座標を掛け合わせる
といった流れになります。
こちらをシェーダーで実装したものが下記になります。
1. 頂点シェーダー内で基底軸をワールド座標に変換する
2. フラグメントシェーダー内で変換した基底軸と法線マップから取り出した法線座標を掛け合わせる
といった流れになります。
こちらをシェーダーで実装したものが下記になります。
↑法線情報をワールド座標空間に変換して計算する

エレキベア
長いので主要部分の解説を頼むクマ

マイケル
よしきた!!

マイケル
まずはプロパティ部分を見てみましょう!
こちらは先ほど解説したnormal、tangentの基底軸を受け取り、ワールド座標に変換したものを渡す流れとなっています。
こちらは先ほど解説したnormal、tangentの基底軸を受け取り、ワールド座標に変換したものを渡す流れとなっています。
↑プロパティの定義

マイケル
実際に基底軸をワールド座標に変換する処理は下記のようになります。
法線、接線しか渡されてこないため、これらの外積を取ることで従法線を算出します。
法線、接線しか渡されてこないため、これらの外積を取ることで従法線を算出します。
↑基底軸をワールド座標に変換

マイケル
最後に変換した基底軸と法線マップの情報から、上述した計算で法線を算出します。
この時、用意されたUnpackNormal関数を使用することで書き込まれた0〜1の値を-1〜1に変換して取得することができるので便利です。
この時、用意されたUnpackNormal関数を使用することで書き込まれた0〜1の値を-1〜1に変換して取得することができるので便利です。

マイケル
ワールド座標の法線座標が算出できたら、後はそれを使用してライティングを行うのみ!
内容としては前回解説したBlinn-Phongモデルのライティングを使用しています。
こちらの詳細について知りたい方は、第一回の記事もご参照ください!
内容としては前回解説したBlinn-Phongモデルのライティングを使用しています。
こちらの詳細について知りたい方は、第一回の記事もご参照ください!

【Unity】第一回 シェーダーライティング入門 〜基本のライティング〜(Lambert、Phong、HalfLambert、Blinn-Phong、リムライト)【シェーダー】
マイケルみなさんこんにちは!マイケルです!エレキベアこんにちクマ〜〜〜マイケルここ最近はずっとシェーダー周りを触っていてある程度慣れてきたので、整理も含めてぼちぼち体系的にまとめていこうかと思います...
↑基本的なライティングについてはこちらを参照

エレキベア
やはり基本のライティングの知識は必要になるクマね

マイケル
こちらのシェーダーに下記のようなカラーマップ、法線マップを適用すると下記のように描画されることが確認できました!

マイケル
法線マップを適用すると、渦マークの部分の陰影が立体的に浮き上がって見えると思います!

エレキベア
これが法線マップの力クマ〜〜〜〜
2. ライトやカメラを接空間に変換して計算する方法

マイケル
次に2つ目の
ライトやカメラを接空間に変換して計算する方法
についてですが、こちらはそのままライトやカメラを接空間情報に変換して、法線マップも接空間情報のまま計算する手法です。
ライトやカメラを接空間に変換して計算する方法
についてですが、こちらはそのままライトやカメラを接空間情報に変換して、法線マップも接空間情報のまま計算する手法です。

マイケル
1の方法では法線の算出をフラグメントシェーダー内で行う必要がありましたが、こちらの方法では頂点シェーダー内で計算を行うために負荷が少ないというのがメリットになります!

エレキベア
処理負荷的にはこちらの方がよさそうクマね

マイケル
シェーダー全文は下記になります。

マイケル
こちらの主要処理を抜粋していきます。
まず、ライト、カメラを接空間に変換する処理は下記になります。
まず、ライト、カメラを接空間に変換する処理は下記になります。
↑ライト、カメラの方向ベクトルを接空間への変換

マイケル
ここではUnity側で用意されているTANGENT_SPACE_ROTATIONを使用しています。
こちらは下記のような内容になっていて、頂点座標と法線情報から接空間変換用の行列を生成してrotation変数に格納しています。
こちらは下記のような内容になっていて、頂点座標と法線情報から接空間変換用の行列を生成してrotation変数に格納しています。
↑変換処理は下記のようになっている

エレキベア
用意されているのはありがたいクマね

マイケル
あとはこれらを使用して接空間情報上でライティング計算を行うのみ!
下記のように法線マップから取り出した情報をそのまま計算に使用することができます。
下記のように法線マップから取り出した情報をそのまま計算に使用することができます。
↑接空間でライティング計算を行う

マイケル
こちらも先ほどと同様テクスチャを設定すると、
下記のように描画されることが確認できます。
下記のように描画されることが確認できます。

エレキベア
いい感じクマ〜〜〜〜
スペキュラマップ、AOマップを使用したシェーダー実装

マイケル
次はスペキュラマップとAOマップを使用したライティングを見てみましょう!
スペキュラマップ

マイケル
まずはスペキュラマップの使用から!
こちらは光沢量をグレースケールで表現したテクスチャで、今回は読み取った値をPhong鏡面反射に乗算することで使用しました。
シェーダー全文は下記になります。
こちらは光沢量をグレースケールで表現したテクスチャで、今回は読み取った値をPhong鏡面反射に乗算することで使用しました。
シェーダー全文は下記になります。

エレキベア
ほぼBlind-Phongモデルのシェーダーsと同じクマね

マイケル
実際に調整を行なっている部分は下記になります。
前述した通り、スペキュラマップから読みこんだ値を鏡面反射量に乗算しているだけですね。
前述した通り、スペキュラマップから読みこんだ値を鏡面反射量に乗算しているだけですね。
↑スペキュラマップから読みこんだ値を鏡面反射量に乗算

マイケル
こちらのシェーダーに下記のようなカラーマップ、スペキュラマップを設定した結果がこちらになります。

マイケル
スペキュラマップで白く指定した箇所が強く鏡面反射が出ていることが確認できます!

エレキベア
やったクマ〜〜〜
AOマップ

マイケル
最後にAOマップを使用した場合の例を見てみましょう!
考え方はスペキュラマップの時と同じですが、こちらは環境光に対して値を乗算しています。
考え方はスペキュラマップの時と同じですが、こちらは環境光に対して値を乗算しています。

マイケル
シェーダー全文は下記になります。

マイケル
実際に調整を行なっている箇所は下記になります。
こちらもAOマップから値を読み込んで乗算しているだけですね
こちらもAOマップから値を読み込んで乗算しているだけですね
↑AOマップによる環境光の調整

エレキベア
簡単クマ〜〜〜

マイケル
こちらのシェーダーに下記のようなカラーマップ、AOマップを適用した結果がこちらになります。

マイケル
AOマップを使用して環境光を制限できていることが確認できました!

エレキベア
やったクマ〜〜〜〜
おわりに

マイケル
というわけで今回はテクスチャマップを使用したライティングについてでした!
どうだったかな??
どうだったかな??

エレキベア
こんなに種類があるとは知らなかったクマ〜〜〜
テクスチャを使用して細かい調整ができるのは便利だと思ったクマ
テクスチャを使用して細かい調整ができるのは便利だと思ったクマ

マイケル
大事なのはテクスチャに追加情報を使用してライティングに使用できることだね!
言ってしまえばRGBA情報に設定できれば何でもいいわけだから、今回紹介したものだけではなく状況に応じて柔軟に活用できるようになりたいね!
言ってしまえばRGBA情報に設定できれば何でもいいわけだから、今回紹介したものだけではなく状況に応じて柔軟に活用できるようになりたいね!

エレキベア
心得たクマ

マイケル
それでは今日はこの辺で!
アデューー!!!
アデューー!!!

エレキベア
クマ〜〜〜〜
【Unity】第二回 シェーダーライティング入門 〜テクスチャマップを使用したライティング〜(法線マップ、スペキュラマップ、AOマップ)【シェーダー】〜完〜