最終更新: mikk_ni3_92 2009年03月27日(金) 13:47:33履歴
現在地 >> メニュー >> サンプルコード::Cg >> Cg::基本編07 >> Cg::光源と反射の計算
シェーダプログラムではおおよそ以下のような記述となる。
光源に一切影響しない色。
式を見てわかるように、「0」以上なら、みずから発光している事になる。
(※まわりへの光の影響はない)
特別な計算はいらない。値を指定するだけである。
光源からの光ではなく、壁や天井など周りに様々反射して到達した光に対する照らされ方。
計算はあらかじめ環境光の値を設定しておき、
それに対し物体が持つ特有のambient値を掛け算する。
図はランバート反射についてである。
物体面の他、光源の色と位置も使って計算を行う。
以下の図のように、視点の位置が計算にかかわってくる。
計算式は以下の通り(phongのモデル、Blinのモデル)
※「n」が大きいほど、ハイライトがシャープになる(はず)
【プログラム例】
■phongのモデル
■Blinのモデル
シェーダプログラムではおおよそ以下のような記述となる。
float3 emissive = ... //放射輝度 float3 ambient = ... //環境光 float3 diffuse = ... //拡散反射 float3 specular = ... //鏡面光 OUT.color.xyz = emissive + ambient + diffuse + specular; //色の決定 OUT.color.w = 1; //α値は1
光源に一切影響しない色。
式を見てわかるように、「0」以上なら、みずから発光している事になる。
(※まわりへの光の影響はない)
特別な計算はいらない。値を指定するだけである。
//CPU側 CGparameter Ke; ... ... const float Emissive[3] = {0.0, 0.0, 0.0}; Ke = cgGetNamedParameter(... ..., "Ke"); cgSetParameter3fv(Ke, Emissive); ... ... //GPUシェーダ側 float 3 emissive = Ke; //この例では(0,0,0)なので、みずから発光はしない
光源からの光ではなく、壁や天井など周りに様々反射して到達した光に対する照らされ方。
計算はあらかじめ環境光の値を設定しておき、
それに対し物体が持つ特有のambient値を掛け算する。
//CPU側 float myGlobalAmb[3] = { 0.2, 0.2, 0.2 }; //環境光 float Ambient[3] = {0.24725, 0.1995, 0.0745};//物体のambient CGparameter globalAmb; CGparameter Ka; globalAmb = cgGetNamedParameter(Vert_Prog, "globalAmbient"); Ka = cgGetNamedParameter(Vert_Prog, "Ka"); cgSetParameter3fv(Ka, Ambient); ... ... //GPUシェーダ側 float3 ambient = Ka * globalAmbient;// 環境光反射の計算
図はランバート反射についてである。
物体面の他、光源の色と位置も使って計算を行う。
//CPU側 CGparameter Kd; Kd = cgGetNamedParameter(... ..., "Kd"); float Diffuse[3] = {0.75164, 0.60648 , 0.22648}; cgSetParameter3fv(Kd, Diffuse); ... ... //GPUシェーダ float3 L = normalize(lightPosition - P); //(光源 - 頂点位置)を正規化 → 点から見た光源への単位ベクトル float diffuseLight = max(dot(N, L), 0); //法線NとLの内積を計算。 0と比較し、大きい方を返す float3 diffuse = Kd * lightColor * diffuseLight; //拡散光 = (拡散光の係数) * (光源の色) * (diffuseLight)
以下の図のように、視点の位置が計算にかかわってくる。
計算式は以下の通り(phongのモデル、Blinのモデル)
※「n」が大きいほど、ハイライトがシャープになる(はず)
【プログラム例】
■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;