OpenGL教程翻译 第十七课 环境光(Ambient Lighting)

OpenGL教程翻译 第十七课 环境光(Ambient Lighting)

原文地址:(源码请从原文主页下载)

Background

光照是3D图形学的最重要的研究领域之一。对光照得体的模拟会使渲染的场景增加很多视觉吸引力。之所以使用“模拟”这个词是因为你无法准确的模仿出光照在自然界中的样子。真正的光是由大量的称为“光子”的粒子组成的,并且同时表现出波和粒子的特性(光的“波粒二象性”)。如果你在程序中试图序计算每一个光子的作用,那么你将很快用光电脑的计算力。

因此,这些年来开发了一些光照模型,它们捕捉了光照射在物体上使它们可见而产生的核心效果。随着3D图形学领域的发展和计算机计算能力的提高,这些光照模型变得越来越复杂。在接下来的几章教程中我们将完成对基础光照模型的学习,,这些模型虽然实现起来较为简单,不过对场景的整体氛围有极大的贡献。

基本的光照模型叫做“环境光/漫反射光/镜面反射光”(’Ambient/Diffuse/Specular’)。环境光是当你在平常晴天时在室外看到的光的类型。虽然太阳越过整个天空,他的光线在一天的不同时刻以不同角度照射这个世界,但是大多数的东西都是可见的,即使它们在阴影中。因为光线能从任何物体上反弹,最终照射到所有物体,所以不在太阳路径上的物体也会被照亮。这个角度来说上,甚至是房间里的灯泡也像表现得如同太阳一样传播环境光,因为如果房间不是很大的话,每一件物体都会被均等的照亮。环境光被模拟为没有原点,没有方向,并且对场景中的所有物体都有相同效果的光。

漫反射光强调了光线照射到物体表面的角度会影响物体被照射的亮度的事实。物体有光照射的一面比另一面(不直接面向光源的一面)更亮。我们只看到太阳散播的环境光没有明确的方向,然而,在太阳光中也有漫反射光。当他照射到一个高的建筑物的时候你通常能看到建筑物的一侧比另一侧亮一些。漫反射光的最重要的特性是他的方向。

镜面反射光相对于光本身更强调是物体的属性。当光线以特定的角度照射物体时,反射光使物体的某一部分闪光,而观察者站在在特定的的点才能看到。金属材质的物体经常会有一些镜面反射特性。例如,晴天的时候一辆汽车的边缘会闪闪发光。计算镜面反射光照不仅需要考虑光照射的方向(并且反射),也要考虑观察者的位置。

在3D应用程序中,你通常不需直接创建环境、漫反射、或镜面反射光。相反的,我们要使用光源,例如太阳(在室外)、一个灯泡(在室内)或者一个手电筒(在洞穴)。不同的光源类型有不同的环境光、漫反射光、镜面反射光强度组合和一些其他的特性。例如,手电筒有一个锥形的光束,距离较远的物体根本不会被照亮。

在以下的教程中我们将会开发一些实用的光源类型,同时学习基础光照模型。

我们将从一种叫做“是没有具体的原点。这就意味着所有的光线彼此平行。光线的方向由一个向量确定,这个向量用来计算在场景中所有物体表面上的光,无论他们的位置在哪里。太阳光很好的符合了平行光的范畴。如果你尝试计算太阳光照射两个相邻的建筑的角度,你会得到两个几乎完全一样的值(即他们之间的不同仅仅是一个微小的分数)。这是因为太阳距离地球大概1.5亿千米远的地方,因此,我们简单地忽略它的位置而只需考虑它的方向。

平行光的另一个特性是无论与发光的物体距离多远,他的亮度都保持相同。这和我们在接下来的教程中学习的另一个光源点光源不同。点光源随着距离增大亮度变得越来越弱(例如灯泡)。

下面这张图片阐明了平行光:

我们已经看到在太阳中既有环境光也有漫反射光。我们在这一部分中讲述环境光,而在下一章中学习漫反射光。

在之前的教程中我们学习了如何从纹理中提取像素的颜色。颜色有三条通道(红、绿和蓝),每一个通道都是一个字节。这就意味着颜色取值范围是0到255.通道之间不同的组合可以产生不同的颜色。当所有的通道都为0时颜色为黑色。当他们都为255时颜色为白色。其他的颜色在两者之间。通过以相同的缩放因子同时缩放三个颜色通道的值,我们可以得到相同的颜色,只不过器明暗度不一样(取决于缩放因子)

当白光接触物体表面,反射的光仅仅是物体表面的颜色。反射光可能会亮或者暗一点,取决于光源的强度,不过还是相同的基色。如果光源是纯粹的红色(255,0,0),反射光只能是红色中的某一类型。这是因为纯红光没有绿色和蓝色通道可以从物体表面反射回来。如果物体表面是纯蓝色,则最终结果是纯黑色。基本原则是光线只能暴露出对象的实际颜色,而不能给它“上色”。

我们将光源的颜色指定为三个取值在【0-1】之间的浮点值。通过将光的颜色和对象的颜色相乘我们将得到反射的颜色。然而,我们也要考虑环境光的强度。因此,我们设定环境光的强度为一个范围在【0-1】之间的单独的浮点值,将它与我们刚刚计算得到所有通道的反射光相乘。下面的方程式总结了环境光的计算:

Pixel—像素 ambient intensity–环境光强度

在本次的教程代码实例中你可以通过按“A和“S”键来增加或者减小环境光的强度,观察在对在之前的教程中创建的纹理金字塔的影响。这只是。

很多人认为要尽量避免环境光,因为它看起来有些虚假,而且其简单的实现方式对于场景的真实性也没有太大的贡献。通过使用先进的方法例如全局照明,我们可以消除对环境光的需求,因为(使用全局照明)从物体反射出来而照射到其他对象的光一样可以被考虑。因为我们还没有那么深入,你通常需要一些少量的环境光,以避免物体的一面被照亮而另外一个面完全黑暗。天色渐晚的时候,为了使光看起来更好,我们需要进行大量的调整参数和协调工作。

Code Walkthru

中,包括编译和链接等操作。从现在开始我们将通过从Technique类派生的类实现视觉效果。

2.将GLUT初始化和callback管理移动到GLUTBacked组件中。这个组件注册自己来接收来自GLUT的callback调用并通过名为ICallbacks的C++接口把他们发送给应用。

3.将全局变量和main cpp文件中的变量移动到一个可被看做是“应用类”的类中。以后我们将把它扩展成一个为所有应用提供常用功能的基类。这种方法在许多的游戏引擎和框架中很受欢迎。

这个教程中的大多数的代码(除了光照中特定的代码)并不是新的,而仅仅是根据以上的设计原则的重新布局,因此只对新的头文件进行说明。

(glut_backend.h:24)

void GLUTBackendInit(int argc, char** argv);bool GLUTBackendCreateWindow(unsigned intWidth, unsigned int Height, unsigned int bpp, bool isFullScreen, const char*pTitle);

GLUT很多特定的代码都被移动到一个叫做"GLUT backend"的组件,这个组件使我们能更容易的进行GLUT的初始化和使用上面的GLUTBackendCreateWindow函数创建窗口。

(glut_backend.h:28)

人生难免遇风雨,天空晴朗有阴云,别因雨水湿透衣衫而难过,

OpenGL教程翻译 第十七课 环境光(Ambient Lighting)

相关文章:

你感兴趣的文章:

标签云: