cocos2D-X源码分析之从cocos2D-X学习OpenGL(17)----发光体

原创 2016年06月14日 18:57:46

      cocos引擎支持四种发光体:环境光,方向光,点光源和聚光灯,上一篇已经介绍了基本光照模型,其中也介绍了环境光的算法,下面就介绍另外三种光源。


       当一个光源很远的时候,来自光源的每条光线接近于平行,这看起来像是来自于同一个方向,比如太阳由于离我们无限远,所以太阳光被定义为平行光,因为所有的光线都是平行的,对场景中每个物体的光都保持一致,光照计算会和场景中的其他物体相似。

       点光是一个有位置的光源,它向所有方向发光,光线随着距离增加逐渐变暗。灯泡和火炬就是这样的点光。


     点光源的计算方式和之前的方向光使用同一个函数,只是加入了一个调整的参数,代码如下:

vec3 computeLighting(vec3 normalVector, vec3 lightDirection, vec3 lightColor, float attenuation)
{
    float diffuse = max(dot(normalVector, lightDirection), 0.0);
    vec3 diffuseColor = lightColor  * diffuse * attenuation;
    
    return diffuseColor;
}
for (int i = 0; i < MAX_POINT_LIGHT_NUM; ++i)

{
    vec3 ldir = v_vertexToPointLightDirection[i] * u_PointLightSourceRangeInverse[i];
    float attenuation = clamp(1.0 - dot(ldir, ldir), 0.0, 1.0);
    combinedColor.xyz += computeLighting(normal, normalize(v_vertexToPointLightDirection[i]), u_PointLightSourceColor[i], attenuation);
}
       添加的这个attenuation参数使用的是点光的位置乘以点光源范围的倒数,然后用1减去这个值得平方,最后获得0到1之间的attenuation参数,最后在computeLighting函数中传入这个attenuation参数,这个值其实是点光源在它的范围内的衰减值。

auto pointLight = static_cast<PointLight *>(light);
Mat4 mat= pointLight->getNodeToWorldTransform();
const Color3B &col = pointLight->getDisplayedColor();
//光的颜色
_pointLightUniformColorValues[enabledPointLightNum].set(col.r / 255.0f * intensity, col.g / 255.0f * intensity, col.b / 255.0f * intensity);
//光的位置
_pointLightUniformPositionValues[enabledPointLightNum].set(mat.m[12], mat.m[13], mat.m[14]);
//光范围的倒数
_pointLightUniformRangeInverseValues[enabledPointLightNum] = 1.0f / pointLight->getRange();
++enabledPointLightNum;
       聚光灯是一种位于环境某处的光源,不是向所有方向,只有某个方向会被照亮,如图所示,聚光灯通过切光角表示:



       由于如果我们在聚光灯的边界“一刀切”的话,这种转变过于强烈,所以聚光灯一般用两个角度表示,一个是内角一个外角,在这两个角度之间是线性逐步减小,cocos2d也采用这种方式处理聚光灯

//计算范围精度值
vec3 ldir = v_vertexToSpotLightDirection[i] * u_SpotLightSourceRangeInverse[i];
float attenuation = clamp(1.0 - dot(ldir, ldir), 0.0, 1.0);
vec3 vertexToSpotLightDirection = normalize(v_vertexToSpotLightDirection[i]);

vec3 spotLightDirection = normalize(u_SpotLightSourceDirection[i] * 2.0);

//计算光线方向和点方向之间的夹角
float spotCurrentAngleCos = dot(spotLightDirection, -vertexToSpotLightDirection);

//在内角外角之间
attenuation *= smoothstep(u_SpotLightSourceOuterAngleCos[i], u_SpotLightSourceInnerAngleCos[i], spotCurrentAngleCos);
attenuation = clamp(attenuation, 0.0, 1.0);
combinedColor.xyz += computeLighting(normal, vertexToSpotLightDirection, u_SpotLightSourceColor[i], attenuation);
       聚光灯的attenuation精度值包括点光源的范围精度值以及在内外角之间的衰减值,两个值相乘,在固定在0到1的范围之间就得到聚光灯的精度值,最后在传入到计算光照的函数里得到聚光灯对于光照的影响值


        能力不足,水平有限,如有错误,欢迎指出。


版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

cocos2D-X源码分析之从cocos2D-X学习OpenGL(10)----MVP矩阵

上一篇介绍了openGL的变换和坐标系,本篇就介绍游戏引擎中一个重要的概念-MVP矩阵,首先涉及到透视投影和正交投影的概念,关于这个概念请参考之前的文章(文章地址:http://blog.csdn.n...

Cocos2d-x 3.2编写常用UI组件(四)发光的标题BlinkTitile

如果看了上一节我推荐的文章,并且掌握了遮罩层的运用,那么本节介绍的发光标题就非常的简单了。 没有看也没关系,现在我来具体讲一下ClippingNode 正文: 关于遮罩Clippin...

阶段性总结和如何定义我的“第二版”

非常高兴的通知大家,我的cocos2d-x权威指南第2版已经

关于cocos2d-x权威指南,关于我

非常高兴的告诉大家,我本人编写cocos2d-x书籍----cocos2d-x权威指南已经出版了,感谢大家一直以来的支持,可以说,正是有了大家对于我原创cocos2d-x文章的支持,才有了这本书。  ...

cocos2d-x 3.x的底层渲染机制

3.0之前是visit后就draw,而draw是真正的OpenGL操作。也就是说,每访问一个对象,先计算节点的渲染数据,然后马上渲染。因为节点是按树形结构组织的,如果两个父节点p1和p2的深度分别是1...

我的2012年终总结

转眼这一年过去了,在这个博客里发文章到现在也有一年了,以往的这个时候我都在其他地方写一篇博客来总结自己的一年,现在想既然都在这个博客里面写文章,那么今年我的年终总结也放到这里吧。        这一年...

Android 3D 游戏学习笔记(5)-法向量及材质

小满(bill man)个人原创,欢迎转载,转载请注明地址,小满(bill man)的专栏地址http://blog.csdn.net/bill_man 1.法向量 在光学中,有一个概念非常重要,...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)