基于Qt的OpenGL可编程管线学习(8)- 探照灯
关于探照灯的效果如下图所示:
探照灯需要传入光源的位置,光源的方向以及夹角的大小(夹角为光源覆盖的夹角的一半)
计算思路:
用光源到点的距离与光源的方向的单位向量做点乘,得到夹角的cos,用计算的夹角cos与
传入的角度的cos做比较,确定光线照射的范围。边缘不部分计算的cos做基底,然后给定一个幂,
就可以做到渐变的效果;探照灯的计算时也要算上衰减
Shader中的相关代码如下:
vec3light=M_LightPos.xyz;floatdistanceLight=0.0;//距离光源的距离floatattenuation=1.0;//衰减系数//衰减因子floatconstantFactor=0.9;//常亮衰减常数floatlinerFactor=0.0;//线性衰减系数floatexpFactor=0.0;//平方衰减系数//点光源if(M_LightPos.w!=0.0){light=M_LightPos.xyz-M_WordPos;distanceLight=length(light);attenuation=1.0/(constantFactor+linerFactor*distanceLight+expFactor*distanceLight*distanceLight);}vec3LightNormal=normalize(light);//指向光源的单位向量vec3NormalNormal=normalize(M_normal);//法线的单位向量light=M_LightPos.xyz-M_WordPos;vec3spotLightPointDirection=normalize(-light);vec3spotLightDirection=normalize(M_SpotLightDirection.xyz);floatspotDegreeCos=dot(spotLightPointDirection,spotLightDirection);floatspotCutoffCos=cos(M_SpotLightCutoff*3.14/180.0);floatdiffuseIntensity=0.0;if(M_SpotLightDirection.w>0&&M_SpotLightCutoff>0){if(spotDegreeCos>spotCutoffCos){diffuseIntensity=pow(max(0.0,spotDegreeCos),M_SpotLightDirection.w)*2;}}else{diffuseIntensity=max(0.0,dot(NormalNormal,LightNormal));}vec4diffuseColor=M_DiffuseLightColor*M_DiffuseMaterial*diffuseIntensity*attenuation;
CPU中的设置
//光源位置floatnLightPos[4]={0.0f,0.0f,-2.0f,1.0f};OpenGLCore->glUniform4fv(m_LightPos,1,nLightPos);//探照灯方向及角度floatnSpotLightDirection[4]={0.0f,0.0f,-1.0f,128.0f};OpenGLCore->glUniform4fv(m_SpotLightDirection,1,nSpotLightDirection);floatnSpotLightDegree=30.0f;OpenGLCore->glUniform1f(m_SpotLightCutoff,nSpotLightDegree);
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。