OpenGL - Lighting

1 简单光照

OpenGL简单光照光源分为:

辐射光(Emitted Light)是最简单的一种光,它直接从物体发出并且不受任何光源影响。

环境光(Ambient Light)是由光源发出经环境多次散射而无法确定其方向的光,即似乎来自所有方向。

漫射光(Diffuse Light)来自一个方向,它垂直于物体时比倾斜时更明亮。

镜面光(Specular Light)来自特定方向并沿另一方向反射出去。

1.1 创建光源

光源有许多特性,如颜色、位置、方向等。

设置光源特性参数的函数:

void glLight{if}[v]( GLenum light , GLenum pname , TYPEparam )

参数light指定所创建的光源号,如 GL_LIGHT0 ,GL_LIGHT1 ,GL_LIGHT2
... ...

参数pname指定光源特性

参数param设置相应光源特性值


pname 参数名


缺省值


说明


GL_AMBIENT


( 0.0 , 0.0 , 0.0 , 1.0 )


环境光的颜色


GL_DIFFUSE


( 1.0 , 1.0 , 1.0 , 1.0 )


漫反射光的颜色


GL_SPECULAR


( 1.0 , 1.0 , 1.0 , 1.0 )


镜面光的颜色


GL_POSITION


( 0.0 , 0.0 , 1.0 , 0.0 )


光源位置坐标


GL_SPOT_DIRECTION


( 0.0 , 0.0 , -1.0 )


点光源聚光方向矢量


GL_SPOT_EXPONENT


0.0


点光源聚光指数


GL_SPOT_CUTOFF


180.0


点光源聚光截止角


GL_CONSTANT_ATTENUATION


1.0


常数衰减因子


GL_LINER_ATTENUATION


0.0


线性衰减因子


GL_QUADRATIC_ATTENUATION


0.0


平方衰减因子

注:只有 GL_LIGHT0 的 GL_DIFFUSE 和 GL_SPECULAR 的缺省值为 (
1.0 ,1.0 ,1.0,1.0 )

其他光源的 GL_DIFFUSE 和 GL_SPECULAR 缺省值均为 (
0.0 ,0.0 ,0.0,1.0 )

1.2 启动光照

glEnable( GL_LIGHTING ); // 启用光照

glEnable( GL_LIGHT0 ); // 启用指定光源

2 光照模型

OpenGL光照模型由以下三部分组成:

2.1 全局环境光

2.2 近视点和无穷远视点

2.3 双面光照

2.1 全局环境光

每个光源都能对场景提供环境光。

此外,还有一个环境光,它不来自任何特定的光源,称之为全局环境光。

这也就是为什么我们不加任何自定义光源,也能看见绘制的物体的原因。

设置全局环境光:

float Light_Model_Ambient[] = { 0.2 , 0.2 , 0.2 , 1.0 };// 缺省值

glLightModelfv( GL_LIGHT_MODEL_AMBIENT ,Light_Model_Ambient );

Light_Model_Ambient参数值指定了整个场景中的环境RGBA浓度。

最大值为1.0,最小值为-1.0。

2.2 局部视点和无穷远视点

视点位置能影响镜面反射中高光的计算。

即顶点的高光强度不仅取决于顶点法向量,而且取决于顶点到光源的方向以及顶点到视点的方向。

对于无穷远视点,视点到任何顶点的方向都是相同的。

而对于局部视点,视点到每个顶点的方向是不同的。

所以需要计算视点到每个顶点的方向,因而性能降低了,但效果质量提高了。

缺省时,使用的是无穷远视点。

glLightModeli( GL_LIGHT_MODEL_LOCAL_VIEWER , GL_TRUE );// 将视点设置为局部视点

glLightModeli( GL_LIGHT_MODEL_LOCAL_VIEWER , GL_FALSE );// 将视点设置为无穷远视点

2.3 双面光照

光照计算是对所有多边形(包括其正面和背面)进行的。

而一般情况下,只设置正面光照条件,而忽略背面。

但有时候需要看到物体内侧的光照效果,这就需要用到双面光照。

glLightModeli( LIGHT_MODEL_TWO_SIDE , GL_TRUE ); // 启用双面光照

glLightModeli( LIGHT_MODEL_TWO_SIDE , GL_FALSE ); // 禁用双面光照

2.3.1 双面光照 - 示例

绘制一个没有底面的圆锥,这样就可以看见圆锥内部。

程序截图

未启用双面光照,看不见圆锥内部,看到圆锥的底面为绿色,这是由环境光造成的。

启用双面光照后,就可以看见圆锥内部了。

3 光源衰减

真实的光,离光源越远则光强越小。

而方向光源是无穷远光源,因此距离对光强没有影响,所以方向光没有衰减,但位置光则有衰减。

OpenGL是通过光源光强乘以衰减系数来计算衰减光照的。

衰减系数 = 1 / ( Kc + Kl*d + Kq*d*d )

d = 光源位置到物体顶点的距离

Kc = GL_CONSTANT_ATTENUATION 常数衰减因子

Kl = GL_LINER_ATTENUATION 线性衰减因子

Kq = GL_QUADRATIC_ATTENUATION 二次衰减因子

缺省时,衰减因子为( 1 , 0 , 0 ) 即不进行衰减

glLightf( GL_LIGHT0 , GL_CONSTANT_ATTENUATION , 1.0 );

glLightf( GL_LIGHT0 , GL_LINEAR_ATTENUATION , 0.0 );

glLightf( GL_LIGHT0 , GL_QUADRATIC_ATTENUATION , 0.0 );

环境光、漫反射光和镜面光的强度都衰减,

辐射光和全局环境光的强度不衰减

4 聚光

位置光源可以定义成聚光形式,即将光的形状限制在一个圆锥内。

用来模拟现实世界中的聚光灯。聚光的具体使用步骤如下:

4.1 设置聚光源位置

GLfloat light_position[]={ 1.0 , 1.0 , 1.0 , 1.0 };

glLightfv( GL_LIGHT0 , LIGHT_POSITION , light_position );

4.2 设置聚光最大散布角

聚光最大散布角就是光锥的轴与中心线的夹角,也就是光锥顶角的一半。

聚光最大散布角可以选择在[ 0.0 , 90.0 ]之间的值,以及一个特定值:180.0

缺省时最大散布角为180.0,即顶角为360度,光源照向所有方向。

glLightf( GL_LIGHT0,GL_SPOT_CUTOFF , 45.0 );

4.3 设置聚光方向

聚光方向决定光锥的轴,缺省值为( 0.0 , 0.0 ,-1.0 ) , 即指向负Z轴。

GLfloat spot_direction[]={ -1.0 , -1.0 , 0.0 };

glLightfv( GL_LIGHT0 , GL_SPOT_DIRECTION , spot_direction);

4.4 设置聚光指数

聚光指数控制光的集中程度,光锥中心的光强最大,越靠边的光强越小。

缺省时为0,即均匀照射。

glLightf( GL_LIGHT0 , GL_SPOT_EXPONENT , 2.0 );

5 辐射光

通过GL_EMISSION定义一个RGBA值,使物体看起来象发出这种颜色的光一样。

而现实中,除光源外,其他物体都不发光;可以利用这一特性来模拟光源。

0GLfloat mat_emission[]={ 0.1 , 0.2 , 0.3, 1.0 };

glMaterialfv( GL_FRONT , GL_EMISSION , mat_emission );

6 控制光源位置

光源的位置也可以通过变换矩阵,调整光源函数和视点变换函数来获得三种不同的效果:

1.光源位置保持固定

2.光源绕物体移动

3.光源随视点移动

6.1 物体旋转光源平移 - 示例

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

时间: 2025-01-15 16:50:24

OpenGL - Lighting的相关文章

<OpenGL>Lighting

I. Hidden-Surface Removal Purpose: In order to increase performance, it is very important to draw objects that are closer to the viewing position and to eliminate objects obscured by others nearer to the eye. Depth buffer: a value associating a depth

Color, Material, Lighting

[Color, Material, Lighting] The material and lighting parameters are used to control the built-in vertex lighting. Vertex lighting is the standard Direct3D/OpenGL lighting model that is computed for each vertex. material & parameters 参数用于控制vertex lig

图形世界分裂的两派——理清Direct3D和OpenGL的脉络

计算机三维图形是指将用数据描述的三维空间通过计算转换成二维图像并显示或打印出来的技术,API(Application Programming Interface)即"应用程序接口"是连接应用程序与操作系统.实现对计算机硬件控制的纽带,Direct3D和OpenGL是目前的两大3D图形 API,要在你的3D显卡上进行3D特效的制作.实现都必须通过它们(Vooodoo迷们肯定对Glide接口记忆尤深,可惜已随着3dfx的倒闭而作古,其它还有Heidi等接口).关于D3D和OpenGL的理论

EBU5405: 3D Graphics Programming Tools - Coursework 2019

EBU5405: 3D Graphics Programming Tools - Coursework 2019In this coursework you will develop an articulated and interactive object in the shape of acrawling animal using C and OpenGL. The main objectives of this project are to practice anddemonstrate:

OpenGL教程翻译 第十八课 漫反射光(Diffuse Lighting)

OpenGL教程翻译 第十七课 环境光(Ambient Lighting) 原文地址:http://ogldev.atspace.co.uk/(源码请从原文主页下载) Background 环境光和漫反射光的主要不同是,漫反射光的计算需要依靠光线方向而环境光完全忽略了它!当只有环境光时整个场景被均等照亮.漫反射光会使物体面对光的部分比背对光的部分更加明亮. 此外漫反射光还增加了一点新的计算,光线的入射角决定了表面的亮度.通过下面的图片来演示这个概念: 让我们假设两条光线的强度是一样的,而唯一不一

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

OpenGL教程翻译 第十七课 环境光(Ambient Lighting) 原文地址:http://ogldev.atspace.co.uk/(源码请从原文主页下载) Background 光照是3D图形学的最重要的研究领域之一.对光照得体的模拟会使渲染的场景增加很多视觉吸引力.之所以使用"模拟"这个词是因为你无法准确的模仿出光照在自然界中的样子.真正的光是由大量的称为"光子"的粒子组成的,并且同时表现出波和粒子的特性(光的"波粒二象性").如果

Mali GPU OpenGL ES 应用性能优化--基本方法

1. 常用优化工具 2. 常用优化方案 OpenGL ES优化的主要工作是在图形管道中找到影响性能的bottleneck,其bottleneck一般表现在以下几方面: ? 在应用程序代码中,如冲突检测     ? GPU与主内存间的数据传输     ? 在VP(Vertex Processor)中的顶点处理     ? 在FP(Fragment Processor)中的片断处理 可通过DS-5 Streamline来定位性能瓶颈(Locate bottleneck).为了获取更好的性能,可从以下

iOS开发——图形编程OC篇&OpenGL ES2.0编程步骤

OpenGL ES2.0编程步骤 OpenGL ES (OpenGL for Embedded Systems) 是 OpenGL 三维图形 API 的子集,针对手机.PDA和游戏主机等嵌入式设备而设计.该API由Khronos集团定义推广,Khronos是一个图形软硬件行业协会,该协会主要关注图形和多媒体方面的开放标准. 1. 保存全局变量的数据结构 以下例子程序均基于Linux平台. 1 typedef struct _escontext 2 { 3 void* userData; // P

三维图像技术与OpenGL基础理论

英文原文:3D Graphics with OpenGL Basic Theory 中文译文:三维图像技术与OpenGL基础理论 1. 计算机图像硬件 1.1 GPU(图像处理单元) 如今,计算机拥有用来专门做图像处理显示的GPU模块,拥有独立的图像处理储存(显存). 1.2 像素和画面 任何图像显示都是基于栅格的格式.一个栅格既是一张二维的像素直角坐标网.像素具有两个属性:颜色和位置.颜色通常使用RGB(红绿蓝)来表示,典型的有用8位或者24位二进制位(真彩色)表示一种颜色.位置则用坐标(x,