藍と淡々

物作り冒険譚


【シェーダー】GLSLで書く!Unityシェーダー - ライティング編① -

こんにちは(๑◔‿◔๑)

最近シェーダーの勉強をしているので、忘れないうちに整理しておこうと思います。

シェーダーは数学の知識が絡んできて、解説しようとするととても大変なので、今回はメモ的な内容になってしまいます・・・

自分でも理解が深まったら誰でもわかるようなシェーダー入門向けの記事を書く、、予定です((((・ิ(・ิω(・ิω・ิ)ω・ิ)・ิ))))


ライティング

1. 標準的なライティング方程式

Clit = Cspec + Cdiff + Camb

Clit・・・全てのライティグの結果得られる色
Cspec・・・鏡面成分(specular)
Cdiff・・・拡散成分(diffuse)
Camb・・・環境成分(ambient)

・鏡面成分

Cspec = (v・r)^Mgls * Sspec * Mspec

v・・・カメラからの視線方向ベクトル
r・・・反射光ベクトル
Mgls・・・フォン係数(鏡面反射指数)
Sspec・・・光の色
Mspec・・・マテリアルの色
(全て単位ベクトル)

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
処理の軽い、視線方向ベクトル v と、入射光ベクトル l の中間ベクトル h を利用した、ブリンモデルもある。

Cspec = (n・h)^Mgls * Sspec * Mspec

n・・・表面の法線ベクトル
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

・拡散成分

ランバート拡散

Cdiff = (n・l) * Sdiff * Mdiff

n・・・表面の法線ベクトル
l・・・入射光ベクトル
Sdiff・・・光の色
Mdiff・・・マテリアルの色


これだと影の部分がかなり暗くなってしまうので、明るく補正をかけたものがこちら。
ハーフランバート拡散

Cdiff = ((n・l) * 0.5 + 0.5)^2 * Sdiff * Mdiff

・環境成分

Camb = Gamb * Mamb

Gamb = グローバルな環境光
Mamb = マテリアルの色


このライティング方程式をGLSLで記述してみる。


gist17ac611b5e3db993b8fc


鏡面成分の計算で↓のコードがある。

reflect(-L, surfaceNormal)

これは、R(反射光ベクトル)を求めるために、

R = 2(N・L)N - L

つまり

R = 2(面法線ベクトル・入射光ベクトル)面法線ベクトル ー 入射光ベクトル

という計算をする必要があるので、

GLSLの組み込み関数、reflect(I, N) == I - 2 * dot(N, I) * N を使っている。

L に負の符合を付けて逆ベクトルを与えているのは、reflectだと光源から表面へのベクトルを入射光ベクトルとしているため、符合を逆転させる必要がある。


これをそのままオブジェクトにアタッチしてみたのがこちら。

(鏡面+拡散+環境)

f:id:MegumiSoft:20151009221823p:plain:w400


ハーフランバートも試してみる。

uniform vec4 _LightColor0;
uniform vec4 _Color; // Propertiesから入力
varying vec4 color;

#ifdef VERTEX
void main() {	            
	vec3 surfaceNormal = normalize(vec3(_Object2World * vec4(gl_Normal, 0.0)));
	vec3 L = normalize(_WorldSpaceLightPos0.xyz);
	float halfLambert = max(0.0, dot(surfaceNormal, L)) * 0.5 + 0.5;
	vec3 diffuseReflection = vec3(_LightColor0) * vec3(_Color) * halfLambert * halfLambert;
	color = vec4(diffuseReflection, 1.0);
	
	gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}
#endif

#ifdef FRAGMENT
void main() {
	gl_FragColor = color;
}
#endif

結果がこちら。

(拡散(ハーフランバート)のみ)

f:id:MegumiSoft:20151009222726p:plain:w400


これはケッコーお気に入りです(✿´ ꒳ ` )


さてさて、まずはシェーダーで基本的なライティングを試してみました。

他にも色々なライティングがあるので、まだまだ勉強して紹介していこうと思います。

今回は、シェーダー入門向けにしては難しく、シェーダーわかるよ!って方向けにはライティングという基礎的なことだったので、あまり良い記事になりませんでしたが、もうちょっとシェーダーの理解が深まったら入門向けの記事を書いてみようかな、と思っています。

それではまた。

( :3) ×)〆 ~~~スイ〜


ゲームアプリの数学 Unityで学ぶ基礎からシェーダーまで

ゲームアプリの数学 Unityで学ぶ基礎からシェーダーまで