かぴぱらの「のんびり開発日記」

空いている時間に、のんびり開発やるっす! モデリングも!シェーダーも!

全体表示

[ リスト ]

イメージ 1

最近のゲームでは、一般的になってきたライティングで
SHライティング、球面調和ライティング、PRTと言われている手法を紹介したいと思います。

かなり情報が出てるので知っている人や、実装済みの人には、つまらない記事になると思います。
また、間違った解釈をしていた場合はすみません。誤っておきます。
それらを踏まえて読んでください。


▼参考リンク
■An Efficient Representation for Irradiance Environment Maps
http://graphics.stanford.edu/papers/envmap/

※上記のリンク先には、ソースコードがあるので一度、目を通しておいてください。
http://graphics.stanford.edu/papers/envmap/prefilter.c
http://graphics.stanford.edu/papers/envmap/envmaprender.in

ここの、サイトはカプコンの「バイオハザード5」で採用された技法です。


■3Dグラフィックス・マニアックス
http://journal.mycom.co.jp/column/graphics/068/index.html
ここでは、球面調和ライティングについて詳しく書かれています。


さて、
・「球面調和関数ってなんだよ?使うと良いことがあるの?」
・「どうやってライティングとして使っていくの?」
・「意味が分からないよ。」
って人のために説明していきたいと思います。
※あまり詳しくは説明せず、使い方や調べる時のきっかけを書いていきたいと思います。




▼「球面調和関数ってなんだよ?使うと良いことがあるの?」
まず、
シェーダーで、平行光源を使用する場合は、以下のパラメータを使いますよね?
・光源の色
・光源の向き

では、1000個の平行光源を実装する場合、パラメーターはどうなりますか?
・光源の色x1000個分
・光源の向きx1000個分
を用意する。
ってことになりますよね。

でも、球面調和関数を使えば、float 9個の係数xRGB要素3つ = 27個の係数が
あれば実装できます。

なんで?と思いますが、出来るんですよ。


そもそも、球面調和関数をつかって何をするかというと

まず、キューブマップテクスチャをライト情報として使います。
キューブ環境マップを求めることで、各方向のライト(環境光)が分かると思います。
そのキューブマップテクスチャをデータとして全て持つ場合は、大きなデータになります。
ですので、キューブマップテクスチャを圧縮し、データを軽くして使おうって事です。
(1000個分の平行光源だけでなく、全方向のライトの色が作れます)

圧縮するとどういったデータになるかというと
各RGB値ごとにfoat9個の係数で表すことが出来ます。
・float 9x3=27個
この情報さえ、メモリにあればキューブマップテクスチャが復元できます。
※復元といっても元通りではなく、ある程度の色情報が再現できます。(元のキューブマップがぼやけた感じになる)
 また、係数9個というのは、ウニみたいなものを作るためのもので、係数が増えることでより復元できますが
 9個(ウニを作る3段階)で事足りるので9個となっています。


▼「どうやってライティングとして使っていくの?」
では、処理の流れを書いていきます。

1.平行光源の情報をRGB値ごとの9個の係数に変換。
  平行光源の情報は係数に足されていきます。係数は最初は0です。
  
・変換関数
void updatecoeffs(float hdr[3], float domega, float x, float y, float z)

hdr[0] // 光源 R値(0.0f~1.0f)
hdr[1] // 光源 G値(0.0f~1.0f)
hdr[2] // 光源 B値(0.0f~1.0f)
x,y,z // 光源の向き

を使うことで
float coeffs[9][3] // 9個の係数xRGBの3つ
に係数が溜め込まれていきます。


2.係数をマトリクスに変換

・変換関数
void tomatrix(void)を使い

coeffs[9][3]の係数をマトリクスに変換する
・R値の係数9個を、4x4マトリクスに変換(R係数マトリクス)
・G値の係数9個を、4x4マトリクスに変換(G係数マトリクス)
・B値の係数9個を、4x4マトリクスに変換(B係数マトリクス)
を行います。


3.環境ライト色の復元(ピクセルシェーダーなどで)

・復元関数
float1 irradmat (matrix4 M, float3 v)
M // 係数マトリクス
V // 法線ベクトル
return 係数マトリクスで復元された値

・R係数マトリクスで、R値復元
・G係数マトリクスで、G値復元
・B係数マトリクスで、B値復元

処理的には、
法線ベクトルと法線ベクトルx係数マトリクス の内積で求まります。

不思議だと思いますが、そういう方法で作れるのです。
式は決まっていますが、詳しい情報は自分で調べてみてください。

シェーダーで、どの部分を担当すれば良いかは、色々試してみると良いと思います。


▼「意味が分からないよ。」
・無限の平行光源が作れる。また全方向のライト情報が作れる。(半球ライティングも真っ青)
・パラメーターは、RGB係数マトリクスと、法線ベクトルでキューブマップが出来る。
・復元計算も内積だけで軽い。
・ライトを作る部分は重いと思うなら、事前に計算しておけば処理が食わない。
・係数は、別の係数との線形補完を行うことで、復元された値も線形補完される。


どうでしたか?
すばらしい処理だと思いませんか?

ゲーム会社を目指している学生のみなさんは是非実装してみてくださいね。

※ちなみに、SHライティングは平行光源だけです。
点光源、スポットライトなどは別に作る必要があります。

この記事に

閉じる コメント(2)

アバター

ご訪問ありがとうございました。
あけましておめでとうございます。
ゲームは苦手なので、よく判りませんが・・・。えへへへ。

2010/1/3(日) 午前 9:57 gra*df*n*1956 返信する

顔アイコン

あけましておめでとうございます。
(^−^)
こちらこそ、来ていただいてありがとうございます。
また、遊びにきてくださいね〜(^0^ノシ

2010/1/3(日) 午後 3:45 かぴぱら 返信する

コメント投稿

顔アイコン

顔アイコン・表示画像の選択

名前パスワードブログ
絵文字
×
  • オリジナル
  • SoftBank1
  • SoftBank2
  • SoftBank3
  • SoftBank4
  • docomo1
  • docomo2
  • au1
  • au2
  • au3
  • au4
投稿

.


みんなの更新記事