首页 > 代码库 > 基于Qt的OpenGL可编程管线学习(8)- 探照灯
基于Qt的OpenGL可编程管线学习(8)- 探照灯
关于探照灯的效果如下图所示:
探照灯需要传入光源的位置,光源的方向以及夹角的大小(夹角为光源覆盖的夹角的一半)
计算思路:
用光源到点的距离与光源的方向的单位向量做点乘,得到夹角的cos,用计算的夹角cos与
传入的角度的cos做比较,确定光线照射的范围。边缘不部分计算的cos做基底,然后给定一个幂,
就可以做到渐变的效果;探照灯的计算时也要算上衰减
Shader中的相关代码如下:
vec3 light = M_LightPos.xyz; float distanceLight = 0.0; // 距离光源的距离 float attenuation = 1.0; // 衰减系数 // 衰减因子 float constantFactor = 0.9; // 常亮衰减常数 float linerFactor = 0.0; // 线性衰减系数 float expFactor = 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); } vec3 LightNormal = normalize(light); // 指向光源的单位向量 vec3 NormalNormal = normalize(M_normal); // 法线的单位向量 light = M_LightPos.xyz - M_WordPos; vec3 spotLightPointDirection = normalize(-light); vec3 spotLightDirection = normalize(M_SpotLightDirection.xyz); float spotDegreeCos = dot(spotLightPointDirection, spotLightDirection); float spotCutoffCos = cos(M_SpotLightCutoff * 3.14 / 180.0); float diffuseIntensity = 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)); } vec4 diffuseColor = M_DiffuseLightColor * M_DiffuseMaterial * diffuseIntensity * attenuation;
CPU中的设置
// 光源位置 float nLightPos[4] = {0.0f, 0.0f, -2.0f, 1.0f}; OpenGLCore->glUniform4fv(m_LightPos, 1, nLightPos); // 探照灯方向及角度 float nSpotLightDirection[4] = {0.0f, 0.0f, -1.0f, 128.0f}; OpenGLCore->glUniform4fv(m_SpotLightDirection, 1, nSpotLightDirection); float nSpotLightDegree = 30.0f; OpenGLCore->glUniform1f(m_SpotLightCutoff, nSpotLightDegree);
本文出自 “不会飞的纸飞机” 博客,请务必保留此出处http://douzhq.blog.51cto.com/12552184/1931068
基于Qt的OpenGL可编程管线学习(8)- 探照灯
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。