現在地メニュー >> Cg >> Cg編05 >> Cg編05::ライティング1
関連:GLSL編04

オブジェクト座標系でのライティング


オブジェクト座標系ということは、物体の中心に原点がある座標系である。

ここでは、簡潔にするために
「オブジェクト座標系」と「ワールド座標系」が一致している
状態でライティングを考えてみる。

つまり、描画物に対し、平行移動や回転移動などを行わず
ワールド座標系でも原点に物体が置いてある状態で考える。

基本的には以下の図



「halfVec」は
  • 頂点から視点へのベクトル「EyeVec」(図の青いベクトル)
  • 頂点から光源へのベクトル「LightVec」(図の赤いベクトル)
の和の平均値。
つまり、halfVec = (EyeVec + LightVec) / 2ということ。

陰影付けにおいて計算上必要なのは、
「法線とLightVecの内積」、「法線とhalfVecの内積」
である。

◆拡散反射と鏡面反射


【拡散反射】
拡散反射光(diffuse)にはランバート反射のモデル等がある。

【プログラム例】
float3 L = normalize(lightPosition - P); //(光源 - 頂点位置)を正規化 → 点から見た光源への単位ベクトル
float diffuseLight = max(dot(N, L), 0); //法線NとLの内積を計算。 0と比較し、大きい方を返す
float3 diffuse = Kd * lightColor * diffuseLight; //拡散光 = (拡散光の係数) * (光源の色) * (diffuseLight)

【鏡面反射】
鏡面反射光には「phongのモデルやBlinのモデル」がある


■phongのモデル
float3 V = normalize(eyePos - P);
float3 R = normalize(2*dot(L,N)*N - L);
float specularLight = pow(max(dot(R,V), 0), shininess);
if (diffuseLight <= 0) specularLight = 0;
float3 specular = Ks * lightColor * specularLight;

■Blinのモデル
float3 V = normalize(eyePos - P);//Blinのモデルで計算
float3 H = normalize(L + V);
float specularLight = pow(max(dot(N, H), 0), shininess);
if (diffuseLight <= 0) specularLight = 0;
float3 specular = Ks * lightColor * specularLight;

頂点シェーダの記述


上で説明したような原理をそのまま記述してもよい。
しかし、ここでは簡潔にするために「lit関数」を使用する。


float4 lit(ndotl, ndoth, m)
「Blinのモデル」をつかってライティング係数を計算する。
【ndotl】:「法線ベクトルと光源ベクトルの内積」を指定。
【ndoth】:「法線ベクトルとhalfVecの内積」を指定。
【m】:鏡面指数


この計算で返ってきたライティング係数はそれぞれ
x:1
y:diffuseに演算する係数
z:speclarに演算する係数
w:1
である。

【例】:光源の色は(1,1,1)
float3 calcVertexLighting(VertexIn input, 
						uniform float3 objEye,
						uniform float4 objLight)
{
	float3 eyeVec = normalize(objEye - input.position.xyz);//視点へのベクトル
	float3 lightVec = normalize(objLight.xyz - input.position.xyz);//光源へのベクトル
	float3 halfVec = normalize(eyeVec + lightVec);
	float3 normalVec = normalize(input.normal.xyz);
	
	float NL = dot(normalVec,lightVec);
	float NH = dot(normalVec,halfVec);

	float3 lightColor = float3(1,1,1);//光の色は(1,1,1)
	float4 lightingCoff = lit(NL,NH,52); 

	float3 ambMaterial = float3( 0.24725, 0.1995, 0.0745);
	float3 diffMaterial = float3(0.75164, 0.60648 , 0.22648);
	float3 specMaterial = float3(0.628281, 0.555802,0.366065);

	float3 color = lightColor * lightingCoff.x * ambMaterial
					+ lightColor * lightingCoff.y * diffMaterial
					+ lightColor * lightingCoff.z * specMaterial;

	return color;
}

このように、それぞれの光の要素の色は
 (光源の色)*(材質の反射係数)*(ライティング係数)
で計算できる。
そして、全ての光の要素を足したものが、ライティングした色となる。

サンプルコード

目次

― その他 ―

Wiki内検索

計測中...(07.10.8〜)

Save The World






▲よろしければ広告のクリックもお願いします


▲ランキングに参加しました

管理人/副管理人のみ編集できます