1.Shade4PointLights函数解析:
调用方法:
// Add approximated illumination from non-important point lights
#ifdef VERTEXLIGHT_ON
o.sh += Shade4PointLights (
unity_4LightPosX0, unity_4LightPosY0, unity_4LightPosZ0,
unity_LightColor[0].rgb, unity_LightColor[1].rgb, unity_LightColor[2].rgb, unity_LightColor[3].rgb,
unity_4LightAtten0, worldPos, worldNormal);
#endif
unity_4LightPosX0, unity_4LightPosY0, unity_4LightPosZ0中存储了4个点光源在世界空间中的位置
文档中是这样说的:
unity_4LightPosX0, unity_4LightPosY0, unity_4LightPosZ0 | float4 | (ForwardBase pass only) world space positions of first four non-important point lights. |
unity_4LightAtten0 | float4 | (ForwardBase pass only) attenuation factors of first four non-important point lights. |
unity_LightColor | half4[4] | (ForwardBase pass only) colors of of first four non-important point lights. |
(unity_4LightPosX0[0],unity_4LightPosY0[0],unity_4LightPosZ0[0]),
(unity_4LightPosX0[1],unity_4LightPosY0[1],unity_4LightPosZ0[1]),
(unity_4LightPosX0[2],unity_4LightPosY0[2],unity_4LightPosZ0[2]),
(unity_4LightPosX0[3],unity_4LightPosY0[3],unity_4LightPosZ0[3])。
函数原型:
// Used in ForwardBase pass: Calculates diffuse lighting from 4 point lights, with data packed in a special way.
float3 Shade4PointLights (
float4 lightPosX, float4 lightPosY, float4 lightPosZ,
float3 lightColor0, float3 lightColor1, float3 lightColor2, float3 lightColor3,
float4 lightAttenSq,
float3 pos, float3 normal)
{
// to light vectors
float4 toLightX = lightPosX - pos.x;//四个分量分别是四个点光源的x坐标减去物体位置的x坐标。
float4 toLightY = lightPosY - pos.y;//四个分量分别是四个点光源的y坐标减去物体位置的y坐标。
float4 toLightZ = lightPosZ - pos.z;//四个分量分别是四个点光源的z坐标减去物体位置的z坐标。
// squared lengths
float4 lengthSq = 0;
lengthSq += toLightX * toLightX;
lengthSq += toLightY * toLightY;
lengthSq += toLightZ * toLightZ;//lengthSq的每一个分量是点光源到物体位置距离(点光源-顶点向量的模)的平方。简而言之,是光源方向向量的模的平方。
// NdotL
float4 ndotl = 0;
ndotl += toLightX * normal.x;
ndotl += toLightY * normal.y;
ndotl += toLightZ * normal.z;//ndotl的每一个分量为点光源-顶点向量与顶点法线的点积。
// correct NdotL
float4 corr = rsqrt(lengthSq);//coor的每一个分量为点光源到顶点距离(点光源-顶点向量的模)的倒数。简而言之,是光源方向向量的模的倒数。
ndotl = max (float4(0,0,0,0), ndotl * corr);//ndotl * corr的每一个分量为点光源-顶点向量(单位化后)与顶点法线的点积。简而言之,是光源方向向量与法线的夹角余弦值。
// attenuation
float4 atten = 1.0 / (1.0 + lengthSq * lightAttenSq);//计算衰减,基础是平方反比定律
float4 diff = ndotl * atten;
// final color
float3 col = 0;
col += lightColor0 * diff.x;
col += lightColor1 * diff.y;
col += lightColor2 * diff.z;
col += lightColor3 * diff.w;
return col;
}
光源的衰减公式:
http://forum.unity3d.com/threads/light-attentuation-equation.16006/
Spot lights attenuate linearly over their range. At the point of light, intensity is at max, at the end of light's range, it is zero. Linear dropoff in between.
Point lights attenuate with something that pretty much matches quadratic attenuation in fixed function D3D/OpenGL: if rgoes from 0 at light's position to 1 at it's range, then intensity is
-
1.0 / ( 1.0 + 25.0 *r *r )