構造色のレンダリング手法ってどんなものがあるのかと探していたところ、下記の論文を見つけました。
とても勉強になりましたが、アカデミックな論文はなかなか理解に時間がかかってしまうので、要点をまとめてみます。
僕の理解が完全に正しいかはちょっと自信がないので、もし間違いなどございましたら申し訳ありません。
構造色とは
構造色とは、色素を持っていない物体がその微細な形状により示す色のことです。
物体の構造(微細な形状)から生まれる光の干渉により、一部の波長が強められて色が出てきます。
また、見る角度などによって色が変わる性質があります。
構造色は蝶の翅やタマムシ、貝殻、シャボン玉などに見られます。
ミドリシジミの構造色 pic.twitter.com/svFoiT4FLR
— ハルマ・K (@halya_11) 2018年4月15日
こんなものも。
光路差テクスチャ
前節で、構造色は物体の構造から生まれる光の干渉により発生すると説明しました。
この物体の構造には、薄膜や多層膜、回折格子といったものがあります。
出典: 汎用的な構造色レンダリング手法の開発 p. 4
これらの干渉の仕方はそれぞれ原理が違います。
また例えば回折格子1つを取ってもいろんな種類があるため、
それぞれの回折格子によって光の干渉の仕方が異なります。
しかしいずれの場合も、最終的に光路差が生まれることで色がもたらされるという意味では同じです。
そこで、上記の論文では汎用的な手法として光路差を表すテクスチャを作成しています。
出典: 汎用的な構造色レンダリング手法の開発 p. 19
上図の右が光路差を表すテクスチャです。
これはメッシュ上のある点における入射角および反射角と光路差の関係を表したものです。
Lをライト方向のベクトル、Eは視点方向のベクトル、Nを法線、Tを接線としたとき、
L・N、L・Tと光路差の関係、E・N、E・Tと光路差の関係を示しています。
これはそれぞれの干渉の原理を数式化することで求められます。
このテクスチャを用意すれば当該点における入射角による光路差と反射角による光路差を求められることになります。
また論文では、位置依存テクスチャを使うことで薄膜の厚みなどを反映しています(図3.3の左図)。
たとえばシャボン玉などの薄膜は位置によって厚みが微妙に変わり、結果光路差が変わるので、
光路差テクスチャから得られた光路差に位置依存テクスチャの値を乗算したものを光路差としています。
構造色テクスチャ
つぎに光路差と構造色の関係を表すテクスチャを作っています。
出典: 汎用的な構造色レンダリング手法の開発 p. 24
これは入射光による光路差と反射光による光路差を入力として、対応する色を出力します。
また、これは計算で求めた反射光のスペクトル分布を用いて、XYZ表色系の色として求めます。
それをRGB表色系に変換して作られたテクスチャが構造色テクスチャです。
こうして作ったテクスチャを先ほど求めた光路差を使ってサンプリングすれば当該地点における色が求められます。
所感
ここまで物理的な正しさを保ちつつリアルタイムに構造色がレンダリングできる手法があるのは素晴らしいことです。
ただいざ使おうとすると物体の構造が数式で表せないといけなかったり、近似が多いわりに色の細かい調整は効かなかったりで、ゲームの現場では頻繁に使われるイメージは沸きませんでした。
ただ基本的な考え方は十二分に使えるものなので、これをもとに有用な構造色のシェーダが作れそうです。