![]() |
![]() 今回は、リアルタイム・シェーダーについて、第1ページ目として記述しようかと思います。 リアルタイム・シェーダーと聞くと実写的なもので、ノウハウとして敷居が高く、 プログラマーに作ってもらうもの・・・、という印象があるかも知れません。 そこで、このサイトではトゥーンのキャラクターを扱っているので、 RT(リアルタイムの略)もToonShaderを模索し、 グラフィックの人でもここまで作ることができるよ、ということを御紹介したいと考えます。 最終的にはプログラマーさんにソースを見てもらって、 同じ効果をより適正化・高速化したものに修正してもらうことが考えられます。 しかし、プログラマーさんからはどんなRT_Shaderを用意すれば グラフィッカーが絵作りに必要十分なものになるのか理解しづらいとも言えるのです。 まずはグラフィッカーがどういった映像をどのように表現したいのか プログラマーさんに実際に動くもので提示できることは映像開発の上で一歩も二歩も先んじていて、 映像作成の効率化・高品質化につながるのではないか、という思いがあります。 > ウンチク・前準備OpenGL > Softimageでの設定、表示方法 > RT_Toon を作ろう >> 1, 基本色;デフューズ色の設定 >> 2, 輪郭線;シェーダーの複製 >> 3, 影の色;シェード色の設定 >> 4, 色のグラデーション幅とその位置設定 >> 5, テキスチャー設定 パソコンのスペックWindowsXP SP3、Intel Core2Duo 3G、RAM; 3G、NVIDIA Quadro FX1700 |
ウンチク・前準備 最近、良くリアルタイムのトゥーンシェーダーについて耳にするようになって来たように感じませんでしょうか。 それは、みなさんが使っているパソコンの性能がグントとアップしていて、 実は”RTシェーダー”を平気で表示できるような環境を持っている事になっているという点と、 今までのプレレンダーによる映像製作ではレンダリング時間がかかりずぎるのことへ対応として RTを使ってそれらしい映像作りができないだろうか・・・と模索し始めて来ているのではないかと考えます。 その場で表示している絵がその結果であるRTシェーダーは、 表示しているそのままの画像を映像素材として扱えれば、 今までと違った映像製作のワークフローを構築できるのではないか、というアプローチなのです。 もちろん、パソゲーや高性能な家庭用ゲーム機でも使える技でもありますね。
例えば、NVIDIA社さんのデベロッパー・ゾーンに FX Composer があります。 http://developer.nvidia.com/object/fx_composer_home.html(NVIDIA社サイトにリンク) これをインストールし、サンプルがたくさん用意されているライブラリーページからD&Dすることによって 色々な画像効果をその場で見ることができます。 ここでの注意点としては、グラフィックボードをNVIDIA Quadro FX1700を使用していることから NVIDAのボードで再現できるであろうシェーダーの紹介であることと、 最新のDirextX(DirectX エンド ユーザー ランタイム Web インストーラを参照)はインストールしてあるということがあります。 OpenGL そしてもう1つの注意点としては、サンプルとしてココでご紹介する RT_Shaderは.cgfx形式 で行こうと考えます。 つまりOpenGL形式になります。OpenGLに関しては少し知識が要ります。 まず正しく3D描画を動作させる為に、The OpenGL Utility Toolkit (GLUT)が必要です。 Windows版 (95/98/98SE/Me/NT/2000/XP) の最新版がhttp://www.xmission.com/~nate/glut.htmlにあります。 執筆時点でGLUT 3.7.6 for Windows.が最新でした。 Zipを解凍して中にあるglut32.dllをC:\WINDOWS\system32内にコピーします。 <コピーに失敗した場合は、Administrator権限でコピーを行う必要があります。> OpenGL系の3D描画が正しく行えるかテストをしてくれる便利なものとして OpenGL Extention Viewerというものがあります。執筆時点でRelease 3.15(Wed, 18 Nov 2009)が http://realtech-vr.com/home/glviewの[ダウンロード]から得られます。 インストール後、Testタブ内一番下に[Rendering tests] ボタンを押すと、OGL1.1~2.1までをテストしてくれます。 ![]() 注意点!!<メールウェア> ここで御紹介しているFMT Toon Shadingは、色々な既存サンプルを参考にしつつも、自ら作成しているものです。 ですので、FMT Toon Shading をそのまま利用してもらっても結構なのですが、使用に関してはあくまでも自己責任でお願い致します。 また、そのまま利用の際には、特に商業利用に関しては、できればメールにて事前連絡をして頂けたらうれしいです。 作品公開可能な方は作品をお送りいただければ、UsersNotes内のギャラリーページに掲載させていただきますよ! 送り先は、 siun-info@dc.itec.daikin.co.jpです。 ココで紹介するものを参考にしつつ、もっとこんなものが製作できたよ--!!!っていう前向きの姿勢を期待するものであります。 |
Softimageでの設定、表示方法
.cgfxファイルと SoftimageでのOpenGL表示今回、ご紹介していくリアルタイムシェーダーのファイル形式を.cgfxとします。 ここにXSI_00.xというXSIマークの3Dデータを御提供いたします。 >> XSI_00_x.zip FX Composer で上部一番右をOpneGLとしておきます。 ![]() 上部 ![]() ![]() AddEffectページが表示されるので、CgFxにチェックを入れてNextボタンを押すと基本となるマテリアルが表示されます。 Phongを指定してNextボタンを押し、Finishボタンを押すと、マテリアル項目にPhongが表示されます。 それを中央の3Dモデル上までD&Dすると表示がこのようになります。 実はこれで、Phong.cgfxというファイルがどういう状態のシェーダーであるのか確認できた状態になります。 中をテキストエディターで開いて見ると、これだけでも結構な行が書かれたものであることが解ります。 ![]() COLLADAファイルの XSI_00_dae.zipをファイル>Crosswalk >読み込むから画面表示させます。 RenderTree からノード>リアルタイム > Cg > Cgfxノードを出します。 順番1、 Cgfxノードをダブルクリックし、何もまだ設定されていない Cgfx設定画面を表示します。 その一般CgFXファイルの空欄にPhong.cgfxを設定します。 順番2、 CgfxノードをマテリアルのRealtimeに所に接続します。 順番3、 表示しているView画面右上の表示設定のプルダウンメニューからリアルタイムシェーダー>OpenGLを選択します。 すると、動き出します。もしNoicon.pic がつながっている場合は、何かテキスチャーを設定してください。 (下図例ではサンプルと同じ Default_color.dds がつながっています) 出来たPPGの中でLamp 0 はライトの位置です。 LampColorはライトの色、AmbiColor はマテリアル;アンビエントの色です。 色々値を変化させて、ちゃんと動作するか遊んで見てください。 (コードタブにて、[コンパイル]というボタンを押すと、最初に記述されている項目を正しく表示してくれます) ![]() 基本的な操作はこのようになります。ここまでは前置きの話でした…。 では、いよいよ本題のスタートです!!! 追加情報 このCgfxのPPG右上のアイコンからこのシェーダーと値の設定された状態をプリセットとして保存できます。 名前を付けて保存しておくと、次回からはここからいきなり始めることが出来ます。 ![]() |
RT_Toon を作ろう
1, 基本色;デフューズ色の設定さーてはじまり,、はじまり・・・♪ まずは基本から単色設定までの記述になります。>>解説とコードはFMTさんの御協力です、感謝・感謝・・・ そして、最初から各種設定を織り込む済みからスタートしています。 単色としてデフューズカラーを設定してみましょう。
FxComposerで見てみると、右上にDiffuseColor欄が出来、色選択して変えるとオブジェクト色が変化します。 右上の項目に設定内容がズラーット表示されないのは < string UIWidget="None";>;と行末に書いたからです。 このFxComposerは使いやすく、真ん中のタブをEditorにすると、.cgfxをテキスト表示し、 構文にエラーが合った場合、その行が黄色になり、中央下段のTasksにてエラー行とその内容が表示されて便利です。 < 難点は日本語表示してくれない。 > ![]() さて、ここまでの.cgfxをSoftimage上で表示してみます。
RenderTreeで、ノード>リアルタイム>Cg>Cgfxノードを取り出し、ダブルクリックして表示したPPG内で上記.cgfxファイルを指定します。 CgfxノードをマテリアルノードのRealtimeという所と接続して、画面をOpneGLに設定します。 コードタブ内の [コンパイル]ボタン を押して、表示を更新させます。DiffuseColorの色を変えるとポリゴンオブジェクトの色が変化します。 |
RT_Toon を作ろう
2, 輪郭線;シェーダーの複製さーて、当初予想より速く進んでいますよ・・・♪(私;Ritaroより・・・、バトンタッチ!!) 影の内積にしようかとも思ったのですが、最初の流れどおり輪郭に行ってみました。 というのもシェーディングとかは色々工夫を加えて行きますけど、輪郭は一回作ったらそれでほぼシェーダは固定なので、 先に実装しておいた方が解り易いかなーっと思いまして・・・。 で、輪郭なのですが、実際のオブジェクトが持つ頂点を二つに複製しなければいけません。 既に世にありますツーン風の輪郭線を描画したゲーム(ジェット・・・・)があります通り、ジオメトリを複製すれば簡単なのですが、 折角プログラマブルシェーダなのでシェーダで複製したいと思います。<外野コメントすばらしい!! 頂点シェーダにデータを取るのはサーフェイスと共有できます。元のオブジェクトは同じですからね。 そこから先を二つに分けます。 FMT_VertexShaderの流れと、FMT_VertexShader_Outlineの流れです。 あ、流れという言葉が出来たのでシェーダの流れを簡単に説明しますと・・・。 シェーダの流れ
という感じのグループ分けの流れになります。 で、1.は大概一つにして共有できますが、 シェーダを頂点シェーダから切り替えたい場合は2.からいきなり二つの川に分かれます。川中島の合戦ですね。 頂点シェーダまで共通でいいんだよ~って言う場合は 4.から分かれます。 シェーダ表現を完全に分けたい場合は5.テクニックを分け、 一回の描画で複数種類のシェーダを一度に表示したい今回のような場合は、5.テクニックは一つでパスを複数持ちます。 ツーパスっていう感じですね。 ※それぞれ分けたいときは構造体名を分けないと途中からおかしなことになります。といってもSIがエラー行を表示してくますが・・・。 さて、今回のコードからは追加記述分、注目部分の抜粋になります、全コードは.cgfxを見てみてください。
今度はこれをFxComposerで見てみると、右上に輪郭線の太さ/輪郭線の色/デフューズの色欄が出来ています。 ここまでの.cgfxをSoftimage上で表示してみます。ご覧の通りです。<スンバらしい
![]() |
RT_Toon を作ろう
3, 影の色;シェード色の設定 (ハーフランバート) ![]() マテリアルの色の話に戻ります。 今度は影の色を付ける…ということで、ライトの設定、 そこから発せられた光から暗くなる部分を計算するのに内積の話が出来きます。
そこで、内積に必要な法線ベクトルとライトベクトルを用意しなければいけないので、そこの追加から手をつけまししょう。 ・ディレクショナルライトのセマンティックを追加する:dirlight_vec0 ・シェードカラーUIを追加する (シェーディングで明るい所と暗い所の色を設定) ・サーフェイスフラグメントシェーダに以下の計算を追加する ├頂点シェーダから出力した法線ベクトルをIN(nomalize関数で正規化)に設定する ├セマンティック定義したdirlight_vec0 を入力する ├ランバートの手法に基づいて内積を計算する ├内積をハーフランバートに変更する (1.0~-1.0範囲を1.0~0.0範囲に再設定) └lerp関数を使用して DiffuseColor と ShadeColor で色設定を可能にする となっております。 ライトは dirlight_vec0 が Softimageシーン内の Infinitライト の一個目を見てくれます。 増やしても一個だけです。複数見るのはまたおいおいやっていきましょう~ノシ ハーフランバートですが、ご存じない方おります?? 割と有名な手法で、ゲームを紹介するサイトにて " HalfLife2 " の表現手法のところで紹介していましたね。 テクスチャトゥーンをやる時もこの計算は必要です。 あとはlerp関数ですね。 これはCgリファレンスのドキュメントにも記載されていますが、 色Aと色Bを普通にアルファブレンディングするための関数です。 計算式にすると
となり、アルファの明暗で色Aと色Bをブレンドします。テクスチャブレンディングにも使われますね。^^ 追加記述分、注目部分の抜粋になります、全コードは.cgfxを見てみてください。
今度はこれをFxComposerで見てみると、右上にdirlight_vec0欄が出来ています。(45 -45 -45 0という値を仮入力しています) ShadeColor も設定するとこんな色合いになります。
では.cgfxをSoftimage上で表示してみます。
1つ目のライトをデータを自動的に取得して陰影を計算しています。 まだ仮段階ですが、キャラの肌に設定すると、こんな感じを得ることが出来ます。
|
RT_Toon を作ろう
4, 色のグラデーション幅とその位置設定
![]() その位置が表面のどの角度付近に表示されるか決められると表現力が増します。 そこで、それらを設定出来るように、 シェーディングの幅とバイアスを調整できるパラメータを追加していきます。 Floatパラメータの ShadingWidthと ShadingBias を追加しました。 ShadingWidth:シェーディングの幅 ShadingBias:シェーディングの位置 です。 ハーフランバートの値からShadingBias を 引いてやると ShadingBias値の0を基準にして-1が暗い方向へ、+1が明るい方向へとシフトします。 ![]() smoothstep関数は
0以下、1以上はClampされるのでhlambertを作ったときの再Clampは必要ないみたいです。 ※NVidiaDeveloperサイトでDL出来るCg_Users_Manual_JP.pdfを参照してみてください。 ShadingWidthを2で割っているのは、GUI上直感的に分かりやすいように、 ShadingWidthが0の時に通常のシェーディング ShadingWidthが1の時に2階調シェーディングとさせたかったからです。 ![]() ShadingWidthが0.5のときに早々に2階調になっちゃいますよね^^計算式にすると 追加記述分、注目部分の抜粋になります、全コードは.cgfxを見てみてください。
では.早々にcgfxをSoftimage上で表示してみます。
ShadingWidth とShading Biasのスライダーが追加されました。 項目の頭に緑色のアイコンが付いていますので、当然アニメーションを設定することが可能です。 まだ仮段階ですが、キャラの肌に設定すると、こんな感じを得ることが出来ます。 |
RT_Toon を作ろう
5, テキスチャー設定![]() 今回はコメント欄も詳細記述されているので、同じような説明になります。 追加されたものは、 //├texture宣言;テクスチャファイルを指定することが出来るようになる //└sampler型でテクスチャの型を決めてシェーダに渡します。今回は2Dテクスチャなのでsampler2Dです。 ちなみにsampler2D型の中で定義している
はMinFilter が縮小フィルタで、MagFilter が拡大フィルタになっています。 Nearest にすると ポイントサンプルの効果が得られて、拡大してもテクスチャのドットがぼけません。
そしてテクスチャを展開するにはUVが必要ですね? UVは struct appdataに TEXCOORD0を追加すること で取得できます。 TEXCOORD0~TEXCOORD7 の 8段 まで取得できます。 TEXCOORD を追加することで シェーダPPGのUIにも TextureProjectionを設定するためのUI が表示されるようになりますね。 ![]() FX Composerの場合
そして、vertexOutput の struct に float4 tVec1 : TEXCOORD1; を用意します。 頂点シェーダからフラグメントシェーダへは法線データもUVデータも同じ頂点のデータとしてしか認識させられないので、 TEXCOORD に入れて渡すことになります。 ※ここが今後いろいろ工夫する羽目になるので、覚えておくと良いでしょう。 次にフラグメントシェーダではtex2D関数を使用してsamplerで入力したテクスチャBaseMapをUVで展開します。 そのテクスチャとトゥーンの結果を乗算して出力します。
OutColorをRGBとAに分けて上記の乗算結果のRGBをOutColorのRGBに、 テクスチャのアルファだけをOutColorのAに渡すことで、 テクスチャのアルファでアルファブレンディングされた結果になります。 そこで、アルファブレンディングをするためには、サーフェイス用パスpass p0のBlendEnable = true;とすることで、 これ以下のアルファブレンディング設定に基づき、合成されます。(BlendFunc、FuncAdd) ※例えばint2(SrcAlpha, OneMinusSrcAlpha);をint2(One, One);とすると加算になりますね。 といったところでシェーディング、テクスチャ、輪郭と要素はそろったので、あとは応用でいろんなことが出来るようになります。 追加記述分、注目部分の抜粋になります、全コードは.cgfxを見てみてください。
では.テキスチャーのアルファーブレンドの表示を見てみましょう。
BlueA_00.ddsというテキスチャーは、アルファーが約50%入っているものです。 これをテキスチャーの色だけで、グラデーション無しで半透明にするには、 DiffuseColorを白、ShadingWidthを0、ShadinBiasを-1に設定します。 BaseTextureにBlueA_00.ddsテキスチャーが貼られていて、半透明になっています。(目の影)
|
さて、その1は一旦ここまでとしたいと思います。 ここまでのものでも、色々と遊べると思いますが、次は更に色々と面白い表現に挑戦していきたいと思います。 |
という訳で、次回はリアルタイムシェーダー その2です。 乞う、ご期待!!
![]() |