現在地メニュー >> GLSL >> GLSL編04
INDEX:GLSL編03 << GLSL編04 >> GLSL編05

はじめに

ライティングでは座標系をしっかり理解する必要がある。

【関連】

ライティング


Cg編05では「オブジェクト座標系」をつかってライティングを行ったので、
ここでは「視点座標系」でライティングを行ってみる。

視点座標系

視点座標系は、モデルビュー行列を演算したあとの座標系。





視点座標系ではカメラ位置に原点があり、-Z方向を向いている座標系である。
つまり、物体の座標のz要素は負の値となっている。



ライティングの計算式


ライティングによって決まる色は、一般には次の式を使っている。
Color = ambient + diffuse + specular + (emission)
(出力色) = 環境光 + 拡散光 + 鏡面光 + (放射光)
そして各光の要素は
ある光の要素 = 計算した光の強さ * 光の色 * 材質の値
で計算する。

つまりライティングをする時には、これらの3つ(4つ)をシェーダ内で計算し、
出力色とすればよい。

※光源の色はデフォルト値の設定でライティングをしてみます。

光源に関する組み込み変数

CPUで与えられた光源データを受け取る組み込み変数は次のような構造体。
【GLSL1.5仕様書より】
struct gl_LightSourceParameters {
	vec4 ambient; // Acli
	vec4 diffuse; // Dcli
	vec4 specular; // Scli
	vec4 position; // Ppli
	vec4 halfVector; // Derived: Hi
	vec3 spotDirection; // Sdli
	float spotExponent; // Srli
	float spotCutoff; // Crli
				// (range: [0.0,90.0], 180.0)
	float spotCosCutoff; // Derived: cos(Crli)
				// (range: [1.0,0.0],-1.0)
	float constantAttenuation; // K0
	float linearAttenuation; // K1
	float quadraticAttenuation;// K2
};
uniform gl_LightSourceParameters gl_LightSource[gl_MaxLights];
▲「vec4 position」は視点座標系でのデータが格納されている。
また情報をCPUへ渡すにはglLight関数で設定する。(無ければデフォルト値)

頂点シェーダでの例


この例では、材質として「金」を設定。シェーダ内にそのデータを埋め込んでいる。
【glsl.vert】
//今回は材質係数をシェーダソースに埋め込んでいる
const float4 ambMaterial = float4( 0.24725, 0.1995, 0.0745,1);
const float4 diffMaterial = float4(0.75164, 0.60648 , 0.22648,1);
const float4 specMaterial = float4(0.628281, 0.555802,0.366065,1);
const float shinMaterial =  51.2 ;


//頂点シェーダ
void main(void)
{
	//投影変換 (モデルビュー * プロジェクション) * 頂点座標
	gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;

	//ambient計算
	float4 ambient = gl_LightSource[0].ambient * ambMaterial;//ambientの計算

	//各種基本的なベクトルを計算
	vec3 N = normalize(gl_NormalMatrix * gl_Normal);//視点座標の法線+正規化
	vec4 V = gl_ModelViewMatrix * gl_Vertex;//視点座標系の頂点位置
	vec3 L = normalize(gl_LightSource[0].position.xyz - V.xyz);//頂点→光源へのベクトル

	//diffuse計算
	float NdotL = dot(N,L);
	vec4 diffuse = vec4( max(0.0,NdotL) ) * gl_LightSource[0].diffuse * diffMaterial;


	//specular計算(Bilnのモデルを使用)
	vec3 H = normalize(gl_LightSource[0].halfVector.xyz);
	float NdotH = dot(N,H);
	vec4 specular = pow(max(0.0,NdotH),shinMaterial);
	if(NdotL <=0)//条件によってはspecular無し
	{
		specular = 0;
	}
	specular = specular* gl_LightSource[0].specular * specMaterial;
	
	
	//出力色
	gl_FrontColor = ambient + diffuse + specular;

}

詳細はCg編05::ライティング1を参照。

材質の組み込み変数

材質の組み込み変数は次の通り
【GLSL1.5仕様書より】
//
// compatibility profile only
//
struct gl_MaterialParameters {
	vec4 emission; // Ecm
	vec4 ambient; // Acm
	vec4 diffuse; // Dcm
	vec4 specular; // Scm
	float shininess; // Srm
};
uniform gl_MaterialParameters gl_FrontMaterial;
uniform gl_MaterialParameters gl_BackMaterial;

サンプルコード


GL_EXT_Cg_shader拡張

GLSLにはないが、Cgに存在する便利な型や関数などがある。
それを使用することができるようになる拡張。

例えばライティング係数の計算をしてくれる「lit関数」をGLSLで使用できるようになる。
【例】:GLSLでlit関数を使う(glsl.vert)
//今回は材質係数をシェーダソースに埋め込んでいる
const float4 ambMaterial = float4( 0.24725, 0.1995, 0.0745,1);
const float4 diffMaterial = float4(0.75164, 0.60648 , 0.22648,1);
const float4 specMaterial = float4(0.628281, 0.555802,0.366065,1);
const float shinMaterial =  51.2 ;


//頂点シェーダ
void main(void)
{
	//投影変換 (モデルビュー * プロジェクション) * 頂点座標
	gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;

	//ambient計算
	float4 ambient = gl_LightSource[0].ambient * ambMaterial;//ambientの計算

	//各種基本的なベクトルを計算
	vec3 N = normalize(gl_NormalMatrix * gl_Normal);//視点座標の法線+正規化
	vec4 V = gl_ModelViewMatrix * gl_Vertex;//視点座標系の頂点位置
	vec3 L = normalize(gl_LightSource[0].position.xyz - V.xyz);//頂点→光源へのベクトル
	vec3 H = normalize(gl_LightSource[0].halfVector.xyz);


	vec4 diffuse;//diffuse
	vec4 specular;//specular

	float4 lightingCoff = lit(dot(N,L),dot(N,H),shinMaterial);//拡張機能の使用

	diffuse = lightingCoff.y * gl_LightSource[0].diffuse * diffMaterial;
	specular = lightingCoff.z *  gl_LightSource[0].specular * specMaterial;

	//出力色
	gl_FrontColor = ambient + diffuse + specular;

}

目次

― その他 ―

Wiki内検索

計測中...(07.10.8〜)

Save The World






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


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

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