Пример #1
0
// `計算點光源, 它和頂點位置, 頂點面向, 光源位置有關.`
void CalculatePointLight(Vertex_VCN *pVertices, int num_vertices)
{
	for ( int i=0; i<num_vertices; i++ )
	{
		// `求出轉換後在世界座標系的頂點位置`
		Vector4 vPosition = pVertices[i].m_Position * g_world_matrix;
		// `求出轉換後在世界座標系的頂點面向, RotateVector函式只做旋轉, 忽略位移.`
		Vector4 vNormal = g_world_matrix.RotateVector(pVertices[i].m_Normal);
		// `計算出頂點位置到光源的方向跟長度`
		Vector4 vVertex_to_Light = g_vLightPosition - vPosition; 
		float light_distance = vVertex_to_Light.NormalizeAndGetLength();
		// `vDistance用來計算光線隨距離衰減公式中1/(a*1 + b*d + c*d^2)分母的(1, d, d^2)`
		Vector4 vDistance(1.0f, light_distance, light_distance * light_distance);
		// `g_vLightAttenuation里記錄了計算衰減公式1/(a + b*d + c*d^2)里的(a,b,c)`
		// `Vector3Dot(vDistance, g_vLightAttenuation) = (a,b,c) dot (1,d,d^2) = (a + b*d + c*d^2)`
		Vector4 vAttenuation = Vector3Dot(vDistance, g_vLightAttenuation);
		// `頂點面向跟光線方向的交角, 決定反射光的強度.`
		Vector4 vIntensity = Vector3Dot(vNormal, vVertex_to_Light);
		// `把intensity局限在永遠大於0的范圍`
		vIntensity.Clamp_to_0();
		// `累加上隨距離衰減的光線強度`
		pVertices[i].m_Color += vIntensity * g_vLightColor / vAttenuation;
		pVertices[i].m_Color.Clamp_to_1();
	}
}
Пример #2
0
// `計算點光源, 它和頂點位置, 頂點面向, 光源位置, 光源方向, 光柱交角有關.`
void CalculateSpotLight(Vertex_VCN *pVertices, int num_vertices)
{
	float fSpotLightCutoffCos = FastMath::Cos( FastMath::DegreeToRadian(g_fSpotLightCutoff) );

	for ( int i=0; i<num_vertices; i++ )
	{
		// `求出轉換後在世界座標系的頂點位置`
		Vector4 vPosition = pVertices[i].m_Position * g_world_matrix;
		// `求出轉換後在世界座標系的頂點面向, RotateVector函式只做旋轉, 忽略位移.`
		Vector4 vNormal = g_world_matrix.RotateVector(pVertices[i].m_Normal);
		// `計算出頂點位置到光源的方向跟長度`
		Vector4 vVertex_to_Light = g_vLightPosition - vPosition; 
		float light_distance = vVertex_to_Light.NormalizeAndGetLength();
		// `頂點面向跟光線方向的交角, 可以決定反射光的強度.`
		Vector4 vCosine = Vector3Dot(g_vLightDirection, vVertex_to_Light);
		// `把vCosine局限在永遠大於0的范圍`
		vCosine.Clamp_to_0();
		float fCosine = vCosine.GetX();
		if ( fCosine >= fSpotLightCutoffCos )
		{
			// `頂點跟光線的交角小於fSpotightCutoffCos時, 才落在光柱范圍內.`
			Vector4 vDistance(1.0f, light_distance, light_distance * light_distance);
			// `g_vLightAttenuation里記錄了計算衰減公式1/(a + b*d + c*d^2)里的(a,b,c)`
			// `Vector3Dot(vDistance, g_vLightAttenuation) = (a,b,c) dot (1,d,d^2) = (a + b*d + c*d^2)`
			Vector4 vAttenuation = Vector3Dot(vDistance, g_vLightAttenuation);
			// `比較靠近光柱外圍部分的頂點, 光線會衰減.`
			float fFalloff = pow(fCosine, g_fSpotLightExponent);
			Vector4 vIntensity = Vector3Dot(vNormal, vVertex_to_Light);
			pVertices[i].m_Color += fFalloff * vIntensity * g_vLightColor / vAttenuation;
			pVertices[i].m_Color.Clamp_to_1();
		}
	}
}
Пример #3
0
// `計算方向光, 它只跟頂點面向和光源方向有關.`
void CalculateDirectionalLight(Vertex_VCN *pVertices, int num_vertices)
{
	for ( int i=0; i<num_vertices; i++ )
	{
		// `求出轉換後在世界座標系的頂點面向, RotateVector函式只做旋轉, 忽略位移.`
		Vector4 normal = g_world_matrix.RotateVector(pVertices[i].m_Normal);
		// `頂點面向跟光線方向的交角, 決定反射光的強度.`
		Vector4 intensity = Vector3Dot(normal, g_vLightDirection);
		// `把intensity局限在永遠大於0的范圍`
		intensity.Clamp_to_0();
		// `累加上計算出來方向光的強度`
		pVertices[i].m_Color += intensity * g_vLightColor;
		pVertices[i].m_Color.Clamp_to_1();
	}
}