OpenGL中创建聚光灯的效果

现在,我们使用如下的数组来指定一个光源的位置:

// 指定光源位置的数组

GLfloat lightPos[] = {0.0f, 0.0f, 75.0f, 1.0f};

// 设置光源0的位置

glLightfv(GL_LIGHT0,GL_POSITION,lightPos);

lightPos数组的最后一个值在此为1.0,它表示光源的实际位置就在(X,Y,Z)所表示的位置。在默认情况下,光线从这个位置均匀地向四周发射。如果我们把lightPos数组的最后一个值设为0.0,可以使光源看上去像是来自无限远处,并沿着向量(X,Y,Z)所指定的方向射入。这种看似来自无限远处的光源称为方向性光源,它会均匀地照射在物体的表面,它的所有光线都是平行的,是一种平行光。反之,对于位置性光源,光线会从光源处向不同方向发散开来。

接下来,我们通过设置一些参数,来实现聚光灯的效果,代码如下所示:

// 指定光源的位置和光照值

GLfloat lightPos[] = {0.0f, 0.0f, 75.0f, 1.0f};

GLfloat ambientLight[] = {0.5f, 0.5f, 0.5f, 1.0f};

GLfloat specular[] = {1.0f, 1.0f, 1.0f, 1.0f};

GLfloat specref[] = {1.0f, 1.0f, 1.0f, 1.0f};

GLfloat spotDir[] = {0.0f, 0.0f, -1.0f};

// 执行场景的初始化设置

void SetupRC()

{

...

// 启用光照计算

glEnable(GL_LIGHTING);

// 设置微弱的环境光,使物体可见

glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientLight);

// 设置光源0的散射光和镜面光成分

glLightfv(GL_LIGHT0,GL_DIFFUSE,ambientLight);

glLightfv(GL_LIGHT0,GL_SPECULAR,specular);

// 设置光源0的位置

glLightfv(GL_LIGHT0,GL_POSITION,lightPos);

// 设置光源0的聚光灯效果,切角50度

glLightf(GL_LIGHT0,GL_SPOT_CUTOFF,50.0f);

// 启用光源0

glEnable(GL_LIGHT0);

// 启用颜色追踪

glEnable(GL_COLOR_MATERIAL);

// 设置材料属性

glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);

// 设置镜面光反射属性及强镜面指数

glMaterialfv(GL_FRONT, GL_SPECULAR,specref);

glMateriali(GL_FRONT, GL_SHININESS,128);

...

}

上述代码中的GL_SPOT_CUTOFF值指定了从聚光灯发射出来的光锥的发散角度。其中,光线是沿光锥边缘的中线发散出来的。对于一种常规的位置光源,这个角度为180度;而对于聚光灯,只有0度到90度的值是有效的。聚光灯发射一个光锥,这个锥体外面的物体并不会被照射到,如图所示:

注意,OpenGL中的光源本身无法被直接看到。聚光灯并没有创建可见的光锥,平行光也没有创建平行的光束。为了在OpenGL中创建这些效果,我们必须绘制相关的几何图形。

单调着色,低表面模拟度

平滑着色,高表面模拟度

在我们的这个示例中,增加球体的表面模拟度有助于改善光照效果,但是仍然可以看到极为不自然的人为效果,这便是顶点光照的一个缺点。通过对顶点施加光照并对它们进行匀和,我们便得到了一个粗糙的光照近似值。这种顶点光照的方法在许多情况下已经够用,但是它在有些情况下仍会显得不够充分。为了实现最佳的光照效果,必须借助着色器。这一部分的示例程序完整代码已经放到了GitHub上,有需要的朋友可以参考一下(https://github.com/dxm3dp/OpenGL-05-Spot点击打开链接),期待更加绚丽自然的效果。

    本文出自杜晓萌的博客,请勿用于任何商业用途,转载请保持完整性并标明出处:                   http://blog.csdn.net/haohan_meng

时间: 2024-12-25 20:23:12

OpenGL中创建聚光灯的效果的相关文章

Android OpenGL ES(六)----进入三维在代码中创建投影矩阵和旋转矩阵

我们现在准备好在代码中添加透视投影了.Android的Matrix类为它准备了两个方法------frustumM()和perspectiveM().不幸的是,frustumM()的个缺陷,它会影响某些类型的投影,而perspectiveM()只是从Android的ICS版本开始才被引入,在早期的Android版本里并没有这个方法.我们可以简单地支持ICS及其以上的版本,但是这样会丢掉很大一部分市场,一些用户依然运行早期的Android版本. 作为替代,我们可以创建我们自己的方法来实现投影矩阵.

openGL中的混合

    之前在项目中就使用过混合,但是研究的不深入,近期美术的一个需求让我下决心重新深入的研究了一下混合以及它在cocos2d-x中的使用,在这里分享给大家. 混合(blend,有些翻译书上把它称作混融,以下简称混合),在openGL中,当一个输入的片元通过了所有相关的片元测试,就可以在与颜色缓存中当前的内容通过某种方式进行合并了.最简单的,也是默认的方式,就是直接覆盖已有的值,实际上不能称作是合并.除此之外,我们也可以将帧缓存中已有的颜色与输入的片元颜色进行混合.这是在openGL流程上的定义

Assignment 4 OpenGL中正十二面体追踪球实现(平移、旋转、多面体线框体切换)

一.使用平台    windows  8.1     visual  studio  2012    二.使用方法     鼠标左键控制旋转,鼠标右键控制平移,点击鼠标中键出现菜单可选多面体 或线框体绘制.     键盘↑↓←→控制平移,F1 和 F2 键分别为多面体和线框体绘制的切换.  三.实现简述     主函数  在 main 函数中与这次实验相关的主要有以下几个函数:  glutReshapeFunc(myReshape);  //窗口改变时重新设

OpenGL中glPushMatrix和glPopMatrix的原理

glPushMatrix.glPopMatrix操作事实上就相当于栈里的入栈和出栈. 很多人不明确的可能是入的是什么,出的又是什么. 比如你当前的坐标系原点在你电脑屏幕的左上方.如今你调用glPushMatrix,然后再调用一堆平移.旋转代码等等,然后再绘图.那些平移和旋转都是基于左上角为原点进行变化的.并且都会改变坐标的位置,经过了这些变化后,你的坐标肯定不再左上角了. 那假设想恢复怎么办呢?这时就调用glPopMatrix从栈里取出一个"状态"了,这个状态就是你调用glPushMa

OpenGL中的投影使用

OpenGL中的投影使用 在OpenGL中,投影矩阵指定了可视区域的大小和形状.对于正投影与透视投影这两种不同的投影类型,它们分别有各自的用途. 正投影 它适用于2D图形,如文本.建筑绘图等.在它的应用场合,我们希望在屏幕上展示准确的物体大小和度量. 透视投影 它使用透视除法,对距离观察者较远的物体进行缩短和收缩.因为可视区域前端和后端的宽度度量方法并不相同,导致两个逻辑大小相同的物体,当它们分别位于可视区域的前面和后面时,前者看上去要比后者大一些. 下图展示了平截头体(frustum)所定义的

在iOS中创建静态库

如果你作为iOS开发者已经有一段时间,可能会有一套属于自己的类和工具函数,它们在你的大多数项目中被重用. 重用代码的最简单方法是简单的 拷贝/粘贴 源文件.然而,这种方法很快就会成为维护时的噩梦.因为每个app都有自己的一份代码副本,你很难在修复bug或者升级时保证所有副本的同步. 这就是静态库要拯救你的.一个静态库是若干个类,函数,定义和资源的包装,你可以将其打包并很容易的在项目之间共享. 在本教程中,你将用两种方法亲手创建你自己的通用静态库. 为了获得最佳效果,你应该熟悉Objective-

什么是OpenGL中的深度、深度缓存、深度测试?

原文来自http://blog.csdn.net/xiaoquanhuang/article/details/6613705 1)直观理解 深度其实就是该象素点在3d世界中距离摄象机的距离,深度缓存中存储着每个象素点(绘制在屏幕上的)的深度值!深度测试决定了是否绘制较远的象素点(或较近的象素点),通常选用较近的,而较远优先能实现透视的效果!!! 2)Z值(深度值).Z buffer(深度缓存) 下面先讲讲Z坐标.Z坐标和X.Y坐标一样.在变换.裁减和透视除法后,Z的范围为-1.0~1.0.Dep

OpenGL中glVertex、显示列表(glCallList)、顶点数组(Vertex array)、VBO及VAO区别

OpenGL中glVertex.显示列表(glCallList).顶点数组(Vertex array).VBO及VAO区别 1.glVertex 最原始的设置顶点方法,在glBegin和glEnd之间使用.OpenGL3.0已经废弃此方法.每个glVertex与GPU进行一次通信,十分低效. glBegin(GL_TRIANGLES); glVertex(0, 0); glVertex(1, 1); glVertex(2, 2); glEnd(); 2.显示列表(glCallList) 每个gl

OpenGL中的颜色混合功能(一)

我们知道,材料属性和光照参数可以极大地增加图形的逼真度,但除此之外,我们在对现实世界进行建模时,有许多效果是通过混合颜色的方式实现的.透明的物体,像是玻璃水杯,在它后面发射过来的光会与透明物体的颜色混合在一起.这种透明在OpenGL中的实现方式,是通过首先绘制背景物体,然后把前景物体(比如水杯)与颜色缓冲区中已经存在的颜色进行混合而实现的.在这一过程中,颜色的alpha值成分发挥了重要作用. 颜色的混合功能 在一般情况下,OpenGL在渲染时把颜色值存放在颜色缓冲区中,把每个片段(像素)的深度值