在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. 关于WSDL的理解

    WSDL是由types, message, portType组成. 而binding, service则是具体的绑定. portType有哪些operation. 然后是portType的Endpoi ...

  2. LR URL编码和解码方法

    问题:URL=http://www.baidu.com/s?wd=%E6%B5%B7%E6%B7%80%E9%BB%84%E5%BA%84"中要对%E6%B5%B7%E6%B7%80%E9% ...

  3. springMVC中如何访问WebContent中的资源文件

    一.问题: 我的工程目录如下: WebContent |-css |-js |-imgs |-META-INF |-WEB-INF |-jsp |-login.jsp 如何在login.jsp中引用i ...

  4. RequestDispatcher 的 forward和include

    1.RequestDispatcher 的 forward和include: http://www.avajava.com/tutorials/lessons/what-is-a-request-di ...

  5. 安装MongoDB 到服务器

    用管理员身份运行CMD > cd C:\Program Files\mongodb\bin > C:\Program Files\mongodb\bin>mongod --dbpat ...

  6. 【java】 java SPI

    SPI(Service provider interface)是旨在由第三方实现或扩展的API.它可以用于启用框架扩展和可替换组件. 服务是一组众所周知的接口或(通常是抽象的)类.服务提供者是服务的特 ...

  7. Oauth2.0(一):为什么需要 Oauth2.0 协议?

    假设有两家互联网企业 A 和 B,其中 B 是一家提供相片云存储的公司.即 B 的用户可以把相片上传到 B 网站上长期保存,然后可以在不同的设备上查看.某一天,A 和 B 谈成了一项合作:希望 B 用 ...

  8. 随笔 -- IO -- Socket/ServerSocket -- 系统概述

    随笔 -- IO -- Socket/ServerSocket -- Echo(BIO)实例 Java 网络编程 网络编程是指编写运行在多个设备(计算机)的程序,这些设备都通过网络连接起来. java ...

  9. Python对象(下)

    前面一篇文章介绍了一些Python对象的基本概念,这篇接着来看看Python对象相关的一些内容. Python对象的比较 Python对象有三个要素:身份,类型和值,所以我们就分别从这三个角度出发看看 ...

  10. 接口请求json解析问题

    今天同事问请求公司内部接口返回的json无法用json_decode解析,然后我让他把请求结果写入文件,然后文件发给我试试. 在打开这个文件之后我发现第一句话是 这是很令人奇怪的,为什么会出现一个双引 ...