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

原创 2016年06月14日 11:28:01

       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,它们的具体算法会在下一篇中计算,将不同的光照影响加在一起,就得到物体最终显示的颜色。

       下一篇将分析不同的发光体。

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




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

相关文章推荐

cocos2d-x颜色混合模式完成光照效果

使用Cocosd-x3.2的颜色混合功能和裁剪功能完成光照效果,简单易用,效果图如下: 代码://底图,光照图(一般是有透明度的白色图) 光移动的时间,循环次数 Node * HelloWorl...

cocos2d-x实现透视朦胧光照效果

cocos2d-x实现透视朦胧光照效果 (2011-08-11 15:43:35) 转载▼ 标签: 杂谈 分类: cocos2d-x学习 ...

让System.out.println回家种田

<script type="text/javascript"

cocos2D-X源码分析之从cocos2D-X学习OpenGL(8)----纹理

纹理(Texture)就是图片,它用来给物体增加细节,cocos2d-x中使用Texture2D类处理2D纹理贴图,本篇就从cocos2d-x中的Texture2D类介绍openGL纹理。      ...

cocos2D-X源码分析之从cocos2D-X学习OpenGL(20)----模型,网格和材质

openGL在cocos2d-x中的应用点,调用的api基本已经介绍的差不多了,这一篇介绍一些3d游戏中的概念,它们也和底层有一些关系,也是游戏中常用的一些封装。       当我们要在屏幕上绘制简单...

cocos2d-x 源码分析 总目录

这篇博客用来整理与cocos2d-x相关的工作,只要有新的分析、扩展或者修改,都会更改此文章。 祝大家愉快~ 1.源码分析 1.CCScrollView源码分析          http:/...

cocos2D-X源码分析之从cocos2D-X学习OpenGL(13)----模板测试

像素着色器调用完成后。模板测试就开始了,它可以丢弃片元,模板缓冲在渲染时获得有意思的效果。     模板缓冲中一个模板值有8位大小,每个窗口都会创建一个默认的模板缓冲,它可以通过数据控制屏幕显示,从而...

cocos2d-x 源码分析 : control 源码分析 ( 控制类组件 controlButton)

control的设计整体感觉挺美的,在父类control定义了整个控制事件的基础以及管理,虽然其继承了Layer,但其本身和UI组件的实现并没有关联。在子类(controlButton,control...

cocos2D-X源码分析之从cocos2D-X学习OpenGL(7)----GLSL

上一篇博客介绍了cocos2d-x中的着色器类相关的结构,以及着色器的一些原理,这一篇将介绍着色器语言。

Cocos 3D功能初探学习笔记(1)---摄像机

本篇首先介绍摄像机,其实2D时cocos引擎就有摄像机这个概念,每个节点都拥有一个摄像机类,当时的摄像机类的使用实例就是实现节点对象的缩放旋转,因为节点本身就自带这些功能,所以摄像机使用的场合并不多,...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

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