BRDF Explorerでシェーダーを書いてみよう
2013/3/11
Tag: download,free,shader,画像処理
はじめに
はじめまして。自称DF随一のゆるふわ系社員、松岡です。
春になってきて、ぽかぽか陽気の日も多くなってきました。
眠くて眠くて・・・ほんと・・・zzz・・・いやいや、ちゃんと仕事しますよ!
今回は、シェーダーを自分で書いてみようという記事を書いてみます。
CGにおいて、見た目のキモになる部分といえば、シェーダーですよね!(ホントですか?
シェーダーしだいで無味乾燥なポリゴンも実写と見違えるような絵に大変身するなんてこともあるわけです!
BRDF Explorer
今回はDinsneyがフリーで公開しているツール「BRDF Explorer」を使ってシェーダーを書いて、表示してみたいと思います。
以下のURLが公式ページになります。
http://www.disneyanimation.com/technology/brdf.html
まずは公式ページからバイナリをダウンロードしてサクっと使ってみちゃいましょう。
まずGet Startedの”win32 binary”をクリックして以下のページからダウンロードします。
現在、brdf-1.0.0-win32.zipが最新みたいですね。
こいつは単なるzipファイルなので適当なフォルダ展開しちゃえばOKです。
使ってみる
さあ、早速使ってみましょう。展開したフォルダのbrdf.exeが本体ですね。起動してみましょう。
以上のような、画面が出たと思います。この状態はなんのこっちゃわからないので、BRDF Explorerのシェーダーファイルである.brdfファイルを読み込んでみます。
メニューから[File]-[Open BRDF]で、ファイル選択ダイアログが出てくると思いますので、ファイルを選択します。
.brdfファイルは、brdfsフォルダにあります。brdfsフォルダの下にはblinnやphongなどの一般的なシェーダーモデルで記述されたファイルが配置してあります。
手始めに、今回はblinn.brdfでも選択してみましょうか。
すると以下の様な画面が表示されたはずです。
さて、下のほうのタブLit Sphereを選択した状態にしておいてください。
これで、このblinnモデルは古典的なシェーダーモデルの一つで、プラスティックなどを表現したりしますね。
左にあるのが、blinnモデルのパラメーターです。
“n”や”ior”を変更して、どう絵が変わるか試してみましょう。例えば、”n”を大きくすると、スペキュラーの値が変わるのがわかると思います。
他にも、cook-torranceモデルや、oren-nayerモデルなどがあるので試してみましょう。
自分でシェーダーを書いてみる
ここからはbrdfsフォルダにはない、自分オリジナルの俺々なシェーダーを記述したいと思います。
まずは、適当な.brdfファイルをコピーして別の名前をつけてください。
ここでは、phong.brdfをコピーして、oreore.brdfとしてみます。
では、まずはこのoreore.brdfを読み込んで見ましょう。すると、何も変更していないので当たり前ですが、blinnシェーダーと同じようなシェーダーになると思います。
それでは、oreore.brdfを変更して名実ともに俺々なシェーダーにしていきましょう。
oreore.brdfをテキストエディターで開いて見ましょう。
.brdfファイルは大きく2つの部分に分けられます。
○パラメータ定義部
::begin parameters //略 ::end parameters
ここにGUIからのパラメータを定義します。
○シェーダー定義部
::begin shader //略 ::end shader
ここに、以下の関数を定義することでシェーダーを記述します。
つまり、この関数がシェーダー本体だと考えていいでしょう。
vec3 BRDF( vec3 L, vec3 V, vec3 N, vec3 X, vec3 Y )
この関数の引数の意味は以下の表のようになっています。
変数 | 意味 | 説明 |
vec3 L | ライトの方向 | シェーディングする点へ照射される光の方向 |
vec3 V | 視点の方向 | シェーディングする点から見たカメラのある方向 |
vec3 N | 法線方向 | シェーディングする点の法線方向 |
vec3 X | 接線方向 | シェーディングする点の接線方向。tangent。異方向性シェーディングを実現するときに用いる。 |
vec3 Y | 従法線方向 | シェーディングする点の従法線方向。binormal。異方向性シェーディングを実現するときに用いる。 |
返り値のvec3はシェーディング結果の色を返します。
変更してみる
まず、oreore.brdfは全体的に暗いですね。
元のphong.brdfはphongのシェーディングモデルを記述してあるのですが、これだけではスペキュラーだけでディフューズがありません。それでは寂しいのでディフューズを足してみましょう。lambertがいいかなと思います。
以下のように書き換えてください。
//lambertのディフューズモデル float lambert( vec3 L, vec3 N) { return max(0, dot(L,N)); } //phongのスペキュラーモデル float phong( vec3 L, vec3 V, vec3 N) { vec3 R = reflect(L,N); return pow(max(0, dot(R,V)),n); } vec3 BRDF( vec3 L, vec3 V, vec3 N, vec3 X, vec3 Y ) { //diffuse float diffuse = lambert(N,L); // specular float specular = phong(L,V,N); float val = diffuse + specular; return vec3(val); }
書き換えた.brdfファイルの反映は以下のようにreloadすればOKです。
見慣れた絵が出てきたと思います。
それでは次はシェーディングに色を付けてみましょう。
::begin parameters float n 1 1000 100 float r 0 1 1 float g 0 1 1 float b 0 1 1 ::end parameters //略 vec3 BRDF( vec3 L, vec3 V, vec3 N, vec3 X, vec3 Y ) { //diffuse float diffuse = lambert(N,L); // specular float specular = phong(L,V,N); return vec3(r,g,b)*diffuse + vec3(specular); }
これで、パラメータr,g,bを変更することでディフューズの色が変更できるようになりました。
スペキュラーの反射モデルの変更
ここまでだったら、普通のphongモデルのシェーダーなのでつまらないですね。仕上げに異方向性反射に挑戦してみます。
今回はkajiya-kayの異方向性反射を実装してみたいと思います。
kajiya-kayモデルはよく髪の毛などのシェーディングに用いられます。
それではoreore.brdfを以下のように変更してみてください。
::begin parameters float n 1 1000 100 float d_weight 0 1 1 float s_weight 0 1 1 float r 0 1 1 float g 0 1 1 float b 0 1 1 ::end parameters ::begin shader vec3 reflect(vec3 I, vec3 N) { return 2*dot(I,N)*N - I; } float KajiyaDiffuse( vec3 hairTangent, vec3 lightVector) { float df = dot( hairTangent,normalize( lightVector ) ); df = 1.0 - (df * df); if ( df < 0 ) df = 0; if ( df > 0 ) df = sqrt( df ); return df; } float KajiyaSpecular( vec3 hairTangent, vec3 lightVector, vec3 viewVector ) { float kspec; float sintl; float sinte; float vt; sintl = KajiyaDiffuse( hairTangent, lightVector ); vt = dot(viewVector,hairTangent); sinte = 1.0 - (vt * vt); if ( sinte < 0 ) sinte = 0; if ( sinte > 0 ) sinte = sqrt( sinte ); // equl on paper : (t.l)(t.e) + sin(t,l)sin(t.e) kspec = sintl * sinte - dot( normalize(lightVector), hairTangent ) * vt; if ( kspec < 0 ) kspec = 0; kspec = pow(kspec,n); return kspec; } // vec3 BRDF( vec3 L, vec3 V, vec3 N, vec3 X, vec3 Y ) { vec3 T = Y;// //diffuse float diffuse = KajiyaDiffuse(T,L); // specular float specular = KajiyaSpecular(T,L,V); return vec3(r,g,b)*diffuse*d_weight + vec3(specular)*s_weight; } ::end shader
すると、以下のように異方向性反射が実現できるはずです。
なんとなく髪の毛っぽくなったでしょうか?
おわりに
今回は、BRDF Explorerを用いてシェーダーを記述してみました。
もちろんBRDF Explorerで作ったシェーダー(.brdf)はそのままでは各種ゲームエンジンやレンダラにはもっていけません。
しかしシェーダー記述における基本は、ベクトルをかけたり足したりして色を求めるだけですので、その他のツールに移植するのも難しくないでしょう。
BRDF Explorerの場合、シェーダーを変更したら、すぐにそのシェーディング結果を確認できるのがいいですね。
みなさんもぜひBRDF Explorerで遊んでみてください。
それではまた!
コメント
コメントフォーム