聚光灯原理:(可想象成探照灯)
运行效果图
片元shader
uniform vec4 U_LightPos;//光源位置
uniform vec3 U_EyePos;//眼睛的位置
uniform vec4 U_LightDirection;// 聚光灯轴线也就是中心线的方向
uniform float U_Cutoff;//中心线和照射方向的最大夹角
uniform vec4 U_AmbientLightColor;//环境光颜色
uniform vec4 U_AmbientMaterial;//环境光材质
uniform vec4 U_DiffuseLightColor;//漫反射光颜色
uniform vec4 U_DiffuseMaterial;//漫反射光材质
uniform vec4 U_SpecularLightColor;//镜面光颜色
uniform vec4 U_SpecularMaterial;//镜面光材质
varying vec3 V_Normal; //转换到世界空间的法线坐标
varying vec3 V_WorldPos;//转换到世界空间的顶点坐标
void main()
{
//将角度转弧度
float radianCutoff=U_Cutoff*3.14/180.0;
//计算夹角的余弦值
float cosThta=cos(radianCutoff);
//将聚光灯的轴线向量归一化
vec3 spotLightDirection=normalize(U_LightDirection.xyz);
//--计算环境光
vec4 ambientColor=U_AmbientLightColor*U_AmbientMaterial;
//--计算漫反射光
vec3 L=vec3(0.0);
float distance=0.0;
float attenuation=1.0;
float constantFactor=0.5;
float linearFactor=0.3;
float expFactor=0.1;
if(U_LightPos.w==0.0)//如果是方向光
{
L=U_LightPos.xyz;
}
else
{
//计算点光源的入射方向,也就是光线的照射方向
//因为点光源光线是发散的,所以必须计算入射光线,这点有别于平行光
L=U_LightPos.xyz-V_WorldPos;
//计算被照射点到光源的距离,点光源会随着距离的增加发生衰减,所以距离的计算也是必须的
distance=length(L);
//根据公式计算点光源的衰减因子
attenuation=1.0/(constantFactor+linearFactor*distance+expFactor*distance*distance);
}
//入射光线归一化
L=normalize(-L);
//法向量归一化
vec3