在3D场景中,每个像素最终显示出来的颜色都是经过大量计算而得到的,其中一些计算是依赖于场景中的光照以及场景中物体对光线的反射和吸收情况.

例如,对于一个红色的物体, 在白色光(白光是红光,绿光和蓝光等量的光) 的照射下它是红色的, 而在绿色光的照射下它将显示为黑色.

如果场景不存在光源效果,那么就没有了3D效果。 下图左边是有光照的效果, 右图是没有光照的效果.

(一)OpenGL的光照模型

OpenGL的光, 可以分解为红,绿,蓝3种分量. 对于光源来说, 使用其发射的红,绿,蓝光的量来描述.
对于物体表面的材质则可以使用其在各个方向反射的红,绿,蓝光的比例来描述.

OpenGL的光照模型将光照分为4个独立的部分:
环境光(ambient light)
漫射光(diffuse light)
镜面反射光(specular light)
发射光(emitted light)
这4种光分别计算,然后被叠加起来.

下面来张示意图, 它比较好的解释了其中3种光照效果组成部分。

环境光(ambient light)

环境光是场景中的基本光源。如果你进入一个漆黑的屋子,环境光通常是零,但走到外面时,总是有光能让你看到。环境光没有方向(所以也将其称为“全局光照模型”).

在室内, 环境通常是经环境散射无法确定方向的光, 就好像来自四面八方的光.

漫射光(diffuse light)
实际看看周围的桌面,墙面,太阳照射到上面的时候,我们就能看到光,大多数情况下,我们看到的多数光源是漫射光传播到我们的眼睛。

就像下图这样子:

我们平时看到的桌面或者墙壁都是平滑的,那么也就是说n法线都应该是垂直向上才对,也就是说光的反射不一定能传播进我们的眼睛了?那为什么我们从不同角度看这个桌面,它的漫射光都是一样的呢?

解决这个问题的关键就是:在微观条件下表面都是粗糙的。

就是如果我们使用显微镜观察一个很平滑的桌面,也会发现是凹凸不平的。凹凸不平到什么程度呢?从所有不同方向和角度都能观察到其粗糙程度是一样的。这么思考之后,就可以想通了,微观法线并不是垂直向上的,而是在不同角度。

镜面反射光(specular light)

就是平时我们看到的一个光滑球面会发出的耀眼光点。如下图:

金属表面,塑料,玻璃,瓶子等容易观察到这种镜面反射光.

关于镜面反射光的几点说明:

1 球面容易看到镜面反射光,是因为球面的法线向外扩散,让看到高亮光的区域更大,那么就更加容易看到镜面反射光了。

2 镜面表面很平滑,那么镜面反射光就会很集中,虽然看到的区域小,但是因为高亮的强度很大,那么就可以很清晰的看到镜面反射光了。

3 其实镜面反射光可以发生在任何物体和任何表面上。

4 粗糙的表面镜面反射光效果很弱或者甚至看不到镜面反射光

发射光(emitted light)

这种光是一种材质发出来的光,用来模拟物体发出来的光, 在3dsmax中,被称为自发光材质.

比如一个场景中有个白炽灯泡, 那么这个为这个灯泡就可以赋上"自发光材质"

下图是3dsmax的光照渲染出来的效果, 按上面的理论, 它应该是由以上四种光源类型叠加出来的.

笔者来给大家分离单独的光源类型, 看看实际效果是什么样子.

首先, 环境光(ambient light) , 这个场景是开放的不是室内, 因此我们就不管环境光了.

然后, 发射光(emitted light), 在下面场景中是不存在的. 我们也不管.

我们只研究一下下面场景中的,  漫射光(diffuse light), 镜面反射光(specular light) 是个什么样子.

下面是被分离出来的 漫射光(diffuse light)

下面是被分离出来的 镜面反射光(specular light)

因此,这个场景中的光照,就是由上面两张图片所示的 漫射光(diffuse light), 镜面反射光(specular light) 构成的。

(二)法线向量

法线向量简称法线。是垂直于表面的向量。对于一个平面, 所有顶点的法线都是一样的。 对于曲面,各个顶点的法线方向可能不同。

笔者当初学习3dsmax的时候,总不知道法线是什么,后来学会了3dsmax的法线对齐功能的用法,突然就明白了法线是什么了。

这个法线对齐要求先在要被对齐的对象(下图是长方体) 的某个面点一下, 系统确定了这个面的法线, 在下图是长方体顶面上的蓝线。

然后再去要对齐到的对象的那个面上点一下,系统又确定了那个面的法线, 在下图是球面上那根亮绿色的线。

然后,两个面就按法线相向的姿式对到一齐去了。

不用搬出公式,也不用废话,你明白了吗?

法线在3dsmax里面还决定了某个面是否可见, 法线正方向的面你的眼睛可见, 法线反方向的面,你的眼睛就看不见这个面了。

如下面左图是球体法线正方向对着你的眼睛, 所以其面都可见。 而右图是球体的法线的正方向在在球的背面,对着你眼睛的是法线反方向,因此前面的面消失了,看到了球内部。

     

而在OpenGL中,OpenGL是使用法线向量来确定一个物体表面的某个顶点所接受的光照的。如果不想使用OpenGL的光照功能,就可以免去为顶点指定法线向量这个步骤的。

原创文章,出自"博客园, 猪悟能'S博客" : http://www.cnblogs.com/hackpig/

SharpGL学习笔记(九) OpenGL的光照模型, 术语解释的更多相关文章

  1. SharpGL学习笔记(七) OpenGL的变换总结

    笔者接触OpenGL最大的困难是: 经常调试一份代码时, 屏幕漆黑一片, 也不知道结果对不对,不知道如何是好! 这其实就是关于OpenGL"变换"的基础概念没有掌握好, 以至于对& ...

  2. SharpGL学习笔记(十一) 光源创建的综合例子:光源参数可调节的测试场景

    灯光的测试例子:光源参数可以调节的测试场景 先看一下测试场景和效果. 场景中可以切换视图, 以方便观察三维体和灯光的位置.环境光,漫射光,镜面反射光都可以在四种颜色间切换. 灯光位置和摄像机位置(Lo ...

  3. 多线程学习笔记九之ThreadLocal

    目录 多线程学习笔记九之ThreadLocal 简介 类结构 源码分析 ThreadLocalMap set(T value) get() remove() 为什么ThreadLocalMap的键是W ...

  4. MDX导航结构层次:《Microsoft SQL Server 2008 MDX Step by Step》学习笔记九

    <Microsoft SQL Server 2008 MDX Step by Step>学习笔记九:导航结构层次   SQL Server 2008中SQL应用系列及BI笔记系列--目录索 ...

  5. python3.4学习笔记(九) Python GUI桌面应用开发工具选择

    python3.4学习笔记(九) Python GUI桌面应用开发工具选择 Python GUI开发工具选择 - WEB开发者http://www.admin10000.com/document/96 ...

  6. Go语言学习笔记九: 指针

    Go语言学习笔记九: 指针 指针的概念是当时学C语言时了解的.Go语言的指针感觉与C语言的没啥不同. 指针定义与使用 指针变量是保存内存地址的变量.其他变量保存的是数值,而指针变量保存的是内存地址.这 ...

  7. go微服务框架kratos学习笔记九(kratos 全链路追踪 zipkin)

    目录 go微服务框架kratos学习笔记九(kratos 全链路追踪 zipkin) zipkin使用demo 数据持久化 go微服务框架kratos学习笔记九(kratos 全链路追踪 zipkin ...

  8. Python学习笔记九

    Python学习笔记之九 为什么要有操作系统 管理硬件,提供接口. 管理调度进程,并且将多个进程对硬件的竞争变得有序. 操作系统发展史 第一代计算机:真空管和穿孔卡片 没有操作系统,所有的程序设计直接 ...

  9. SharpGL学习笔记(十五) 纹理映射

    纹理映射非常实用,在游戏场景中已经无所不在了. 一个较少的多边形构成的模形,配合好的纹理贴图进行映射,可以得到逼真的效果.游戏中的天空,地面,墙面,和植物都是纹理贴图进行映射的. 例如最终幻想8的男女 ...

随机推荐

  1. [SQL Server] 复制数据库任务

    假设你要生产环境下的数据做相应的测试,比如修改及测试存储过程.更改和优化索引等.但是你用户在连接数据库的情况下,你又不能断开数据库的连接.如何取得数据库的副本呢? 一.  利用数据库任务中的复制数据库 ...

  2. c# winform 获取当前程序运行根目录,winform 打开程序运行的文件夹

    // 获取程序的基目录. System.AppDomain.CurrentDomain.BaseDirectory // 获取模块的完整路径. System.Diagnostics.Process.G ...

  3. Xcode :Missing file warnings

    http://stackoverflow.com/a/5379013

  4. IE10假死/未响应是为什么?

    不知道大家在使用IE10的时候会不会有像是假死一样的情况发生,在打开网页或者进行任何操作都会变得奇慢无比.随着最近在网上看视频的次数越来越多,这个问题越来越突出,越来越频发.于是分析进程的等待链,看看 ...

  5. 4 Flask 命令行模式

    preface 在Django中我们可以使用python manage.py shell进入 shell下面调试,在flask下面我们需要安装第三方模块来进入shell模式,安装的模块为Flask-S ...

  6. Lua 中 number 转换各种进制,以及string串转number

    原文地址:http://blog.csdn.net/david_dai_1108/article/details/71699449 --region : NumConvert.lua --Date : ...

  7. C#获取当前时区转换方法

    今天给Mongodb插入数据的时候发现,日期时间对不上,原来Mongodb(麻狗)默认是0时区,所以日期当然出错. 所以用下面进行转换就可以: log.AddTime = DateTime.Speci ...

  8. 在Linux上安装SVN服务

    1.安装SVNyum install subversion 2.查看版本svnserve --version3.创建目录mkdir -p /web/svndata3.创建repo测试库svnadmin ...

  9. 通过phoenix在hbase上创建二级索引,Secondary Indexing

    环境描述: 操作系统版本:CentOS release 6.5 (Final) 内核版本:2.6.32-431.el6.x86_64 phoenix版本:phoenix-4.10.0 hbase版本: ...

  10. 【转】WCF OpenTimeout, CloseTimeout, SendTimeout, ReceiveTimeout

    关于这四个属性,在MSDN中的解释有点敷衍了事.Open/Close/Receive/Send本是HTTP/TCP/SOCKET的概念,Read/Write Operation则是Web Servic ...