您的位置:首页 > 移动开发 > Cocos引擎

cocos2D-X源码分析之从cocos2D-X学习OpenGL(16)----基本光照

2016-06-14 11:28 573 查看
       cocos引擎目前已经支持3d功能,之前在3d教程中介绍了cocos2d-x的3d功能中的光照,但是只是粗略的介绍了四种光源,因为光照的重要性和复杂性,这个系列文章会分两篇介绍光照,本篇介绍光照的基础-ADS模型,下一篇详细介绍几种光源。
       ADS模型是光照的基本模型,包括Ambient(环境光),Diffuse(漫反射)和Specular(点光源)三种光照在物体上的效果是这样的:



       三种光照共同影响物体,模拟出一般的光照效果,被称作ADS模型,也叫Phong模型。
       环境光是一个来自远处的光源,它会让物体显示一些颜色,全局照明的原理非常简单,它用光的颜色乘以一个很小的常量ambient因子,然后乘以物体颜色,最后得到环境光照射物体之后的颜色。
       在cocos2d-x中,在Mesh类(网格,3d模型渲染的最小单元)中以uniform的方式向着色器传递光照的参数,处理环境光的时候,是直接传递环境光颜色,但是在创建环境光的时候要设置一个强度值,在传递前,会用光强乘以颜色再传,在应用程序中处理好计算可以减少着色器的计算量,是个提高效率的好方法。
auto ambLight = static_cast<AmbientLight *>(light);
const Color3B &col = ambLight->getDisplayedColor();
ambientColor.add(col.r / 255.0f * intensity, col.g / 255.0f * intensity, col.b / 255.0f * intensity);       漫反射就没那么简单了,它模拟一个发光物对物体方向性的影响,它是ADS模型中最重要的组成部分,面向光源的一面比其他面更亮,它涉及到一些数学和物理概念,如图所示:


       我们在初中物理中学习过光的发射,它是光照和平面的垂直方向(法线方向)形成入射角,反射是入射角等于发射角,光线会从另一个方向反射出去,在模拟计算光照的时候,我们仍然需要法线这个概念,因为当入射光线和法线夹角为0时,光照的效果是最大化的,当为90度时,光照的效果几乎为0,我们要模拟出这个效果。
       法线向量是垂直于顶点表面的向量,由于顶点没有表面的概念,我们利用顶点周围的顶点计算出这个顶点的表面,因为向量叉乘可以得到垂直于两个向量的向量,我们可以用这种方法得到法向量,有时为了模拟凹凸不平的平面效果,我们还会使用法线贴图去定义每个点的法线向量。
       下一步我们就获得光的方向,光源类提供了获得光照的方法:Vec3 SpotLight::getDirection() const
{
Mat4 mat = getNodeToParentTransform();
return Vec3(-mat.m[8], -mat.m[9], -mat.m[10]);
}

Vec3 SpotLight::getDirectionInWorld() const
{
Mat4 mat = getNodeToWorldTransform();
return Vec3(-mat.m[8], -mat.m[9], -mat.m[10]);
}      两个向量准备好了,我们就可以计算漫反射光照了: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;
}       最后一个参数attenuation是为计算另外两种光源准备的,这里就会传1,而漫反射光就是法向量乘以光源方向,注意,因为法向量由平面指向外方向,所以对应的“光方向”就是由物体平面的点指向光源,所以传的时候,是真正光源方向的相反数:for (int i = 0; i < MAX_DIRECTIONAL_LIGHT_NUM; ++i)
{
vec3 lightDirection = normalize(u_DirLightSourceDirection[i] * 2.0);
combinedColor.xyz += computeLighting(normal, -lightDirection, u_DirLightSourceColor[i], 1.0);
}       ADS模型就剩下Specular高光了,它也是依照光的方向向量和法向量,另外还会参考视角方向,基本算法就是将光线方向(注意,这次是真正的光线方向了)通过GLSL内置的reflect函数计算出反射光线,然后用反射光线乘以视线方向,从而获得光照参数,这个光照参数还要进行一次幂操作,之一要多少次幂和光线强度有关,被称作发光值,发光值越高,反射光的能力越强,散射的越少,高光点越小,下图就是不同高光值得影响


       cocos2d-x并没有进行这部分的光照计算,基本采用的都是反射光的计算方法,在聚光灯和点光源的处理上就是乘以不同的attenuation,它们的具体算法会在下一篇中计算,将不同的光照影响加在一起,就得到物体最终显示的颜色。
       下一篇将分析不同的发光体。
       能力不足,水平有限,如有错误,欢迎指出。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: