ポリゴンメッシュでキャラクタを作成(AO 編)
よりリアルな表現を行うために、影はかかせない存在です。
Shade 3Dでの影はレンダリングを行うことで確認できますが、Unityのようなリアルタイム環境では速度を優先させますので擬似的な再現になります。
リアルタイムでの直接照明による影はシャドウマップが使われることが多く、この場合はShade 3Dのレイトレーシング相当の表現が可能になります。
ただし、反射による写りこみや透過、屈折表現が入るとリアルタイムではそれ相応の処理が必要となってきます。
さて、間接照明があるかのように見せる手段としてAO(Ambient Occlusion)というものが存在します。
今回は、そのAOについて説明していきます。
なお、AOの計算はAOUtilプラグインを使用しますので、Shade 3D Standard/Professionalのみの動作となります。
AOUtilプラグインはBasic版では使用できません。
ここではAOUtilプラグイン ver.1.1を使った説明を行っていきます。
AOUtilプラグインはマーケットプレイスで販売されているプラグインです。
AO(Ambient Occlusion)とは?
ある位置から半球状に複数方向へ走査していき、形状にぶつかったときの割合を求めます。
これは、Occlusion(遮蔽)と呼ばれるものになります。
AOの値としては「1.0 - Occlusion値」を使用し、このAO値を形状の頂点やテクスチャに色情報として乗算することで、擬似的にさえぎられている部分を暗くする効果を出すことができます。
パストレーシングのような正確な光の計算ではないため、あくまでも「それらしい」表現を行うものになります。
指向性のある光を考慮した計算ではないため、AOを適用した形状に光を当ててもそれほど違和感なくマッチする、という利点もあります。
リアルタイムでは、頂点AOの場合は頂点カラーとして、テクスチャの場合はAOマップとして与えることになります。
さて、ここでは例として前回テクスチャを与えたドラゴンと、木や草や岩などの小さな自然を表した新たなシーンでAOを適用させていきます。
キャラクタにAO Mapを割り当て
AOUtilプラグインを使用することで、ポリゴンメッシュごとに「頂点AO」もしくは「AO Map」を与えることができます。
「頂点AO」は、ポリゴンメッシュごとの頂点ごとに頂点カラーとしてAO計算を行います。
ここでは、ドラゴンのキャラクタにAO Mapを割り当てることにします。
AO Mapを使用する場合は、ポリゴンメッシュのUV上の各面が重ならないように配置されている必要があります。
また、足元が暗くなるようにしておきたいため、地面となるダミーの板ポリゴンを配置しました。
groundを地面、dragonをドラゴンのポリゴンメッシュとしています。
ブラウザよりground/dragonを選択し、「情報」コンテキストメニューから「AO : AO計算対象」を選択します。
AO計算対象ダイアログボックスで「AO計算対象」チェックボックスをOnにしてOKボタンを押すと、ブラウザ上では「AO Target」というラベルが表示されました。
このAOの計算対象となったポリゴンメッシュが、AO計算時の遮蔽の判定で使用されます。
次に「ground」形状を選択して、「情報」コンテキストメニューから「AO : AO Mapの作成」を選択します。
AO Mapの選択ダイアログボックスで、AO作成時のパラメータを指定します。
「UV」より参照するUV番号を選択。そんなに解像度は必要がないため、「テクスチャサイズ」は512を選択。
計算方法は後々説明しますが「Ray Trace」を選択。
上記の画像のように指定した状態でOKボタンを押します。すると、ブラウザ上のイメージパート内に「ground_AOMap」という名前の512x512 pixelのテクスチャが生成されました。
これがground形状のAO Mapになります。単なるグレイスケールの画像です。
これをground形状に割り当てているマスターサーフェスのマッピングレイヤに、イメージ/拡散反射として「通常」合成で指定しました。
図形ウィンドウ上のテクスチャでは地面に薄っすらと影が落ちたようになってますね。
地面については別途テクスチャを割り当てていないのでこれまで。
次にdragonのポリゴンメッシュにAO Mapを割り当てます。
ブラウザでdragonを選択し、
「情報」コンテキストメニューから「AO : AO Mapの作成」を選択します。
AO Mapの選択ダイアログボックスで、AO作成時のパラメータを指定します。
「UV」は1、「テクスチャサイズ」は1024を選択。
「バイアス」を20.0と大きくしました。このバイアスは、ポリゴンメッシュ上の各位置よりAOの走査を行う場合にどれだけ面から浮かせて計算するかを指定します。
複雑な形状の場合は、近くの面のデコボコで遮蔽されるためにノイズが出やすいときがあります。形状に合わせてバイアス値を調整するようにします。
「dragon_AOMap」という画像が生成されましたので、これをdragonの形状のマスターサーフェスのマッピングレイヤを追加し「イメージ/拡散反射」で「通常」合成として割り当てます。
これをマッピングレイヤの1つめに移動して、以下のようになりました。
ちょっと羽で黒い部分が目立ちますね。
これを詰めてみましょう。
AO Mapの作成ダイアログボックスの「粗さ」は、AO Map計算時に内部的に細かく分割するための敷居値になっています。
これを小さくしていくことで、時間はかかりますがより精度よくAO Map上のAO計算が行われます。
「粗さ」を0.05にします。
また、羽部分は少しデコボコしてますので、デコボコで影になるのを緩和するため「バイアス」を大きくします。
「バイアス」を40にします。
以下のように、羽部分の黒い影が緩和されました。
Tips : マッピングレイヤでの乗算合成
表面材質のマッピングレイヤで、1レイヤ目「拡散反射(拡散反射用テクスチャ)/通常合成」 、2レイヤ目「拡散反射(AO Map用テクスチャ)/乗算合成」とした場合、
2レイヤ目の適用率を1.0より小さくしてレンダリングしても、影が薄くならず「適用率 * ピクセル色」が乗算される形になります。
これだと、AO Mapの影だけを薄く調整してレンダリングに反映させるということはできません。
この場合、1レイヤ目「拡散反射(AO Map用テクスチャ)/通常合成」 、2レイヤ目「拡散反射(拡散反射用テクスチャ)/乗算合成」とレイヤの順番を逆転させて、1レイヤ目の適用率を変更することでAO Mapの影を調整することが可能になります。
ただ、これはShade 3Dの表面材質での乗算合成の仕様のようですので、他ツールとは異なります。
これでレイトレーシングでレンダリングを行うと、以下のようになりました。
まるで間接照明が考慮されているかのように見えますが、これはAOの効果です。
AOを使う前は以下のようになっています。
環境光について
AO表現で大切な要素として「環境光」があります。
Shade 3Dでは、統合パレットの「無限遠光源」ウィンドウで環境光を指定できますが、これは0にして、環境光オブジェクトを配置してそれで全体の環境光を指定したほうが操作しやすいかと思います。
環境光オブジェクトは、ツールボックスの「作成」-「光源/カメラ」より作成できます。
アイコンを選択後、図形ウィンドウ上をドラッグ。
配置した環境光オブジェクトを選択し、形状情報ウィンドウで「環境光」の値をを少し大きくします。
これは、環境光自身を底上げして、拡散反射に乗算合成されるAOの効果が目立つようにするため。
そして、無限遠光源の明るさを少し下げます。
この場合はシーン全体の環境光が強くなるため、AOを適用しない形状の表面材質については基本設定の「環境光」を下げるようにします。
無限遠光源の明るさが小さい場合や他に光源がない場合は、法線マップによるデコボコや光沢によるハイライトが表現できなくなります。
このあたりの調節はシーンにより異なるのもありますのでどれが適切、とは決めにくい部分になります。
もし、法線マップを指定したのにデコボコが光の向きをいくら変えても出ない場合や直接照明による影が弱い場合は、環境光が強すぎないか、もチェックするようにしてみてください。
今までのシーンを「dragon_modeling_motion_walk_ao.shd」として保存しました。
なお、AO Mapとして作成された画像は単なるテクスチャですので、画像ファイルとして保存して他ツール上で利用することができます。
アニメーションさせるキャラクタの場合のAOの扱いは?
AO Mapや頂点AOは、静止物体に対して割り当てる形になってます。
リアルタイムに計算する理論はあるのですが、今現在はまだまだ負荷が高いというのが実情かと思います。
リアルタイムではスキンアニメーションするキャラクタに対しても静止したときにベイクしたAOを利用する、という場合が多いかもしれません。
AO自身は擬似的な陰影効果であるのと他の光源処理に依存しないので薄く割り当てておき、スキンアニメーションしたときにそれっぽく陰影が見える、程度で妥協することになりそうです。
「dragon_modeling_motion_walk_ao.shd」の形状はモーション情報もついてますので、モーションウィンドウで再生して確認してみてください。
ドラゴンのアニメーションでのAOによる陰影は妥協できそうですが、地面に焼きついている影については厳しいとなります。
この場合にリアルタイムに持っていく際は、地面にはAO Mapによる影は落とさずに直接照明によるシャドウマップに頼るか、半透明であらかじめ用意した影テクスチャをキャラクタの下に描画するか、といった選択が考えられそうです。
頂点AOとAO Mapをともに活用してみる
サンプルを変えて、ここでは以下のようなシーンを考えます。
木や草を表現する場合はAO Mapでのベイクされたテクスチャを使うのがいいかというと、そうでもなかったりします。
先に完成の画像を出します。
以下、AO効果をかける前。レイトレーシングでレンダリングしてます。
環境光を調整して、AO効果をかけたもの。
どちらがリアルに見えるかは一目瞭然ですね。
地面、岩、草、木の幹、木の葉、の要素に分かれています。
このうち、地面はAO Mapを使用。岩、草、木の幹、木の葉は頂点AOを使用しました。
マスターサーフェスとしては、地面、木の幹、草と木の葉、岩の4つを用意しています。
草と木の葉については、マスターサーフェスを1つにまとめて参照するようにしています。ピクセル透過のあるテクスチャを指定しました。
地面より下にダミーのポリゴンメッシュを配置
すべてのポリゴンメッシュをAOの計算対象としますが、ダミーで地面より下に板ポリゴンを配置し、これもAOの計算対象にしています。
地面はデコボコになっており、草の板テクスチャや岩の一部が地面から下にすり抜けてしまってる箇所があります。
このまま地面より下の頂点や面上の一点のAO計算を行うと、衝突がないため地面に接している付近が明るくなってしまいます。
これを回避するために、衝突が発生するようにAO計算対象とする面をダミーで配置しました。
地面のAO Mapを計算
すべてのポリゴンメッシュをAO計算対象として割り当てた後、地面である「ground」名のポリゴンメッシュをブラウザで選択して、情報のコンテキストメニューの「AO : AO Mapの作成」を選択します。
地面のポリゴンメッシュは、拡散反射用テクスチャのマッピングでUV1を参照するようにしています。
UV2は面が重ならないように配置しており、これをAO Map用として参照するようにします。
「UV」は2を選択。
計算方式は「Ray Trace」を選択。透過ピクセルを持つ面が衝突対象として存在する場合は、Ray Traceでないと正しく計算できません。
「サンプリング」を400、「バイアス」を20としてOKボタンを押しました。
作成されたAO Mapテクスチャを、マスターサーフェスgroundに割り当てます。
岩の頂点AO値の計算とマスターサーフェスへの割り当て
頂点AOの計算
ブラウザからrock1とrock2の岩のポリゴンメッシュを選択し、情報のコンテキストメニューの「AO : 頂点AOの計算」を選択します。
頂点AOの計算ダイアログボックスで、計算方式は「Ray Trace」を選択。
「サンプリング数」を400、「バイアス」を10としてOKボタンを押します。
すると、頂点ごとにAO値が計算され、内部的に頂点カラーとして保持されます。
まだこの状態では、頂点カラーはレンダリングに反映されません。
表面材質の「その他」で「ローカル座標系」をOffにする
rockの形状に割り当てているマスターサーフェスの表面材質ウィンドウで「その他」を選択し、「ローカル座標系」をOffにします。
これは、次に指定する「頂点カラー」シェーダーのために必要な操作になります。
頂点カラーシェーダーを割り当て
表面材質のマッピングレイヤから「頂点カラー」を選択します。
これをマッピングレイヤの先頭に持ってきて、拡散反射/通常合成とします。
なお、マッピングの一番下の「位置&サイズ」タブ内はいじらないようにしてください。
いじると、レンダリング時に正しく頂点AOが割り当てられなくなります。
マッピングの2つめのレイヤで拡散反射テクスチャを「乗算」合成として指定することで、頂点AOの計算が行われた拡散反射の表現が可能となります。
頂点カラーシェーダーの設定
頂点カラーシェーダーを割り当てたマッピングレイヤの「その他」のボタンを押すと、頂点カラーを割り当てる際の設定を指定できます。
「影」を1.0から下げることで頂点カラーの影の濃さを薄くできます。ただ、マッピングレイヤの適用率で調整するほうがわかりやすいと思われるため、ここへ変更する必要はないかと思われます。
色補正ウィンドウでレンダリング結果のガンマを2.2とする場合は、頂点カラーの「ガンマ」は1.0/2.2を選択するようにします。
木の幹も同じように、頂点AO計算と表面材質での「頂点カラー」指定で割り当てておきます。
草や木の葉の頂点AO値の計算とマスターサーフェスへの割り当て
草や木の葉は、透過ピクセルを含むテクスチャが割り当てられています。
また、1枚の板ポリゴンで表現していますので、頂点カラー計算で裏面が暗くなるということがないようにする必要があります。
板ポリゴンで頂点AOを計算する際は、「裏面を考慮」チェックボックスをOnにするようにして頂点AOを計算してください。
こうすることで、表と裏の両方のAO計算が行われ、明るいほうの値を頂点AOとして採用することになります。
後は、岩のときと同じように表面材質のマッピングレイヤに「頂点カラー」シェーダーを割り当てるようにします。
以上の設定を行い、レイトレーシングでレンダリングすると、はじめに出したような画像がレンダリングされます。
このシーンを「small_narture2.shd」として保存しました。
頂点AOとAO Mapの使い分け
今まで説明したドラゴンの場合はAO Mapを使用、草や木や岩の場合は頂点AOを使用としました。
AO Mapの利点として、頂点AOよりも精密なAO計算結果を割り当てることができるという点がまず上げられます。
AO Mapの欠点として、テクスチャですのでリソースを消費してしまうという問題があります。また、形状ごとにAO Mapを用意するとなると、それだけマテリアルを増やす必要があります。
頂点AOの場合は頂点カラーを与えているだけなのと、特にUVに依存しないのでリソース面でも速度面でもコストが低いという利点があります。
リアルタイムのゲームなどで地形を作る場合、木や岩や草はシーンに大量に存在するのが想像できるかと思います。
この場合に、木や岩や草は同一のものを複製して配置することになりますが、それぞれにAO Mapを割り当てていると速度面で影響が少なからず出てしまいます。
これらを踏まえた上で、シーン内でそれほど重要でない形状(背景やモブ)は頂点AOを割り当てて、人物キャラクタなどの重要な形状はAO Mapを適用する、という流れになってきます。
AOを割り当てる場合は、個々の形状が重要な立場にあるものかどうかを決めてから、頂点AOを使用するかAO Mapのテクスチャを割り当てるか判断しましょう。
なお、Shade 3D ver.15 + AOUtil ver.1.1の段階では、頂点AOとして計算された頂点カラーはFBXエクスポートなどで外に出すことができません。
AOMapについては、単なるテクスチャですので外にエクスポートできます。
AOの計算方式
AOUtil ver.1.1から、頂点AO/AO MapともにAOの計算方式を選択できるようになりました。
「Ray Trace」はサンプリングを伴う計算となり、精度を上げる場合は時間がかかります。レンダリングでのパストレーシングみたいなものを想像していただければわかりやすいかもしれません。
「Disk-Area Approximation」はAOUtil ver.1.1で追加された方式で、GPUを使った計算を行うことができる近似の方式になります。互いの面の相互の関係から遮蔽を計算する方法で、レンダリングでのラジオシティみたいなものを想像していただければわかりやすいかもしれません。
ただ、近似であるのとGPUに特化した計算であるので、Ray Trace式よりも正しい計算が行われるわけではありません。
計算は速いですが、重なる面が多い箇所ほど影が濃くなります(「減衰距離」「影の濃度」のパラメータで調整可能)。
また、テクスチャの透過ピクセルがある場合に「Disk-Area Approximation」方式でAO計算をすると、AOUtil ver.1.1段階では透過処理は行われません。
透過なしの面として判定されます。
「Disk-Area Approximation」の場合は結果が滑らかであるのと計算時間が短くて済む、という利点がありますので、用途に合わせて使い分けてみてください。
これらのデータのダウンロードはこちら。
今回は、AOについてざっとした説明と、何気にマルチUV、マルチテクスチャを使いました。
長くなりましたのでこれでいったん区切って、次回でUnityにマルチUVとマルチテクスチャの情報を渡してAO Mapを反映させる方法について解説予定です。
文:ft-lab