OpenGL中的光照[光照计算]
2016-12-06 18:38
211 查看
光照设置
在OpenGL中当我们需要使用光照时,我们需要做如下的设置:开启场景中的光照计算
设置场景中光源的参数
开启设置好的光源
下面我们就依次进行:
开启和关闭光照计算
在OpenGL中使用glEnable和glDisable来开启和关闭光照计算:[cpp]
view plain
copy
print?
// 开启光照计算
glEnable(GL_LIGHTING);
//关闭光照计算
glDisable(GL_LIGHTING)
// 开启光照计算 glEnable(GL_LIGHTING); //关闭光照计算 glDisable(GL_LIGHTING)
设置光源参数
OpenGL的实现默认最少支持8个光源,这些光源的编号从0-7,依次是GL_LIGHT0、GL_LIGHT1 .... GL_LIGHT7,当我们使用是可以调用glLight来设置它们的参数,具体参数包括:GL_AMBIENT
设置光源中的环境光成分,调用如下:
[cpp]
view plain
copy
print?
//设置0号光源的环境光为
float ambient[] = {0.4, 0.4, 0.4, 1.0}
glLightfv(GL_LIGHT0, GL_AMBIENT, ambient)
//设置0号光源的环境光为 float ambient[] = {0.4, 0.4, 0.4, 1.0} glLightfv(GL_LIGHT0, GL_AMBIENT, ambient)散射光默认的取值是(0, 0, 0, 1)
GL_DIFFUSE
设置光源中的散射光成分,默认的取值 GL_LIGHT0是(1,1,1,1), 其他光源的取值是(0,0,0,1),调用方式:
[cpp]
view plain
copy
print?
//设置0号光源的环境光为
float diffuse[] = {0.4, 0.4, 0.4, 1.0}
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse)
//设置0号光源的环境光为 float diffuse[] = {0.4, 0.4, 0.4, 1.0} glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse)
GL_SPECULAR
设置光源中的平行光成分,默认的取值与GL_DIFFUSE中一样,GL_LIGHT0默认是(1,1,1,1),其他光源是(0,0,0,1)
GL_POSITION
设置光源的位置,GL_POSITON中指定的位置在调用glLight之后会通过当前的模型视图矩阵转换到相机坐标系中,GL_POSITION中的位置是一个齐次坐标,最后一个参数w如果为0,代表该光源是一个平行光,平行光中衰减参数是无效的。初始OpenGL中的光源位置在(0,0,1,0),也就是该光源是一个平行光,并且方向指向Z轴负方向。
GL_SPOT_DIRECTION
这个参数和以下两个参数都是用来设置聚光灯效果的光源的,GL_SPOT_DIRECTION简单来说就是设置聚光灯的方向,当聚光灯的开口角度是0~90度的时候,设置GL_SPOT_DIRECTION是有效的(也就是当GL_SPOT_CUTOFF是180度的时候设置GL_SPOT_DIRECTION并没有任何作用),默认的GL_SPOT_DIRECTION的取值是z轴负方向,也就是(0, 0, -1),在指定GL_SPORT_DIRECTION之后它会经过模型视图矩阵的变化变化到相机坐标系中。
GL_SPOT_EXPONENT
这个参数主要用来设置聚光灯的光线集中度,聚光灯的光的强度在光锥中心最高,越靠近边缘光的强度就越弱,这个参数设置的越大,聚光灯的聚光效果越强,这个参数的初始取值是0,它的取值范围限定在【0,128】
GL_SPOT_CUTOFF
这个参数主要用来设置聚光灯的辐射范围,默认值是180(类似与点光源),可以选择的取值范围是【0,90】以及180这个特殊值,可以参考下图:
GL_CONSTANT_ATTENUATION GL_LINEAR_ATTENUATION GL_QUADRATIC_ATTENUATION
这三个参数主要用来设置光的衰减参数,分别是常量衰减部分+线性部分+二次部分,具体衰减公式可以继续阅读下文。默认的取值是(1,0,0),也就是没有衰减。需要注意的是:这三个参数只对有位置的光源有用,对平行光源来说没有意义。
光照的应用示例
下文中主要列举了光源通过不同的参数设置所显现的不同效果:1. 仅使用环境光,默认的材质,开启光照计算后的效果:
[cpp]
view plain
copy
print?
glClearColor(0, 0, 0, 1)
glEnable(GL_DEPTH_TEST)
glEnable(GL_LIGHTING)
ambient = [0.8, 0.8, 0.8]
glLightfv(GL_LIGHT1, GL_AMBIENT, ambient)
glEnable(GL_LIGHT1)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glLoadIdentity()
glTranslatef(0, 0, -10)
glRotatef(xRot, 1, 0, 0)
glRotatef(yRot, 0, 1, 0)
glutSolidSphere(2, 32, 18)
glutSwapBuffers()
glClearColor(0, 0, 0, 1) glEnable(GL_DEPTH_TEST) glEnable(GL_LIGHTING) ambient = [0.8, 0.8, 0.8] glLightfv(GL_LIGHT1, GL_AMBIENT, ambient) glEnable(GL_LIGHT1) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) glLoadIdentity() glTranslatef(0, 0, -10) glRotatef(xRot, 1, 0, 0) glRotatef(yRot, 0, 1, 0) glutSolidSphere(2, 32, 18) glutSwapBuffers()运行效果:
2. 仅使用散射光,默认材质的效果
[cpp]
view plain
copy
print?
glClearColor(0, 0, 0, 1)
glEnable(GL_DEPTH_TEST)
glEnable(GL_LIGHTING)
diffuse = [0.8, 0.8, 0.8]
glLightfv(GL_LIGHT0, GL_AMBIENT, diffuse)
glEnable(GL_LIGHT0)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glLoadIdentity()
glTranslatef(0, 0, -10)
glRotatef(xRot, 1, 0, 0)
glRotatef(yRot, 0, 1, 0)
glutSolidSphere(2, 32, 18)
glutSwapBuffers()
glClearColor(0, 0, 0, 1) glEnable(GL_DEPTH_TEST) glEnable(GL_LIGHTING) diffuse = [0.8, 0.8, 0.8] glLightfv(GL_LIGHT0, GL_AMBIENT, diffuse) glEnable(GL_LIGHT0) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) glLoadIdentity() glTranslatef(0, 0, -10) glRotatef(xRot, 1, 0, 0) glRotatef(yRot, 0, 1, 0) glutSolidSphere(2, 32, 18) glutSwapBuffers()运行效果:
3. 仅包含平行光,代码如下:
[cpp]
view plain
copy
print?
glClearColor(0, 0, 0, 1)
glEnable(GL_DEPTH_TEST)
glEnable(GL_LIGHTING)
specular = [0.8, 0.8, 0.8]
glLightfv(GL_LIGHT1, GL_SPECULAR, specular)
glEnable(GL_LIGHT1)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glLoadIdentity()
glTranslatef(0, 0, -10)
glRotatef(xRot, 1, 0, 0)
glRotatef(yRot, 0, 1, 0)
glutSolidSphere(2, 32, 18)
glutSwapBuffers()
glClearColor(0, 0, 0, 1) glEnable(GL_DEPTH_TEST) glEnable(GL_LIGHTING) specular = [0.8, 0.8, 0.8] glLightfv(GL_LIGHT1, GL_SPECULAR, specular) glEnable(GL_LIGHT1) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) glLoadIdentity() glTranslatef(0, 0, -10) glRotatef(xRot, 1, 0, 0) glRotatef(yRot, 0, 1, 0) glutSolidSphere(2, 32, 18) glutSwapBuffers()运行效果:什么场景都看不见,主要是因为平行光依赖于视点与光线之间的角度关系
4. 修改光源的位置,当我们修改光源的位置时,以2中的示例为例,修改光源的位置:
[cpp]
view plain
copy
print?
glClearColor(0, 0, 0, 1)
glEnable(GL_DEPTH_TEST)
glEnable(GL_LIGHTING)
diffuse = [0.8, 0.8, 0.8]
position = [-1, 0, 0, 0]
glLightfv(GL_LIGHT0, GL_POSITION, position)
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse)
glEnable(GL_LIGHT0)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glLoadIdentity()
glTranslatef(0, 0, -10)
glRotatef(xRot, 1, 0, 0)
glRotatef(yRot, 0, 1, 0)
glutSolidSphere(2, 32, 18)
glutSwapBuffers()
glClearColor(0, 0, 0, 1) glEnable(GL_DEPTH_TEST) glEnable(GL_LIGHTING) diffuse = [0.8, 0.8, 0.8] position = [-1, 0, 0, 0] glLightfv(GL_LIGHT0, GL_POSITION, position) glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse) glEnable(GL_LIGHT0) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) glLoadIdentity() glTranslatef(0, 0, -10) glRotatef(xRot, 1, 0, 0) glRotatef(yRot, 0, 1, 0) glutSolidSphere(2, 32, 18) glutSwapBuffers()运行效果:
可以看到光源的位置确实由正前方转到左方了
5. 修改平行光源为点光源
将4中的平行光修改为点光源
[cpp]
view plain
copy
print?
glClearColor(0, 0, 0, 1)
glEnable(GL_DEPTH_TEST)
glEnable(GL_LIGHTING)
diffuse = [0.8, 0.8, 0.8]
position = [-1, 0, 0, 1]
glLightfv(GL_LIGHT0, GL_POSITION, position)
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse)
glEnable(GL_LIGHT0)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glLoadIdentity()
glTranslatef(0, 0, -10)
glRotatef(xRot, 1, 0, 0)
glRotatef(yRot, 0, 1, 0)
glutSolidSphere(2, 32, 18)
glutSwapBuffers()
glClearColor(0, 0, 0, 1) glEnable(GL_DEPTH_TEST) glEnable(GL_LIGHTING) diffuse = [0.8, 0.8, 0.8] position = [-1, 0, 0, 1] glLightfv(GL_LIGHT0, GL_POSITION, position) glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse) glEnable(GL_LIGHT0) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) glLoadIdentity() glTranslatef(0, 0, -10) glRotatef(xRot, 1, 0, 0) glRotatef(yRot, 0, 1, 0) glutSolidSphere(2, 32, 18) glutSwapBuffers()
6. 使用聚光源
我们将5中的点光源设置为聚光灯的模式,让它限定在一定范围内,代码如下:
[cpp]
view plain
copy
print?
glClearColor(0, 0, 0, 1)
glEnable(GL_DEPTH_TEST)
glEnable(GL_LIGHTING)
diffuse = [0.8, 0.8, 0.8]
position = [0, 0, -1, 1]
glLightfv(GL_LIGHT0, GL_POSITION, position)
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse)
glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 20.0)
glEnable(GL_LIGHT0)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glLoadIdentity()
glTranslatef(0, 0, -10)
glRotatef(xRot, 1, 0, 0)
glRotatef(yRot, 0, 1, 0)
glutSolidSphere(2, 32, 18)
glutSwapBuffers()
glClearColor(0, 0, 0, 1) glEnable(GL_DEPTH_TEST) glEnable(GL_LIGHTING) diffuse = [0.8, 0.8, 0.8] position = [0, 0, -1, 1] glLightfv(GL_LIGHT0, GL_POSITION, position) glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse) glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 20.0) glEnable(GL_LIGHT0) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) glLoadIdentity() glTranslatef(0, 0, -10) glRotatef(xRot, 1, 0, 0) glRotatef(yRot, 0, 1, 0) glutSolidSphere(2, 32, 18) glutSwapBuffers()
以上就是光源的使用,下文接着讲述材质部分的内容
相关文章推荐
- opengl光照方程的计算验证
- 现代OpenGL+Qt学习笔记之十一:使用halfway向量提高光照计算效率
- OpenGL中的光照系列之二[光照计算]
- OpenGL光照的计算模型
- OpenGL 光照方程的计算
- opengl使用Blin-phone模型计算镜面光照强度
- OpenGL的基础光照和计算
- OpenGL光照的计算模型
- 三种光照模型的计算
- OpenGL学习笔记(12)基本光照
- OpenGL-光照模型
- OpenGL编程指南12:光照_渲染真实球体
- glsl,opengl关于镜面光的计算,包括镜面高光
- 转一篇opengl 光照的文章
- OpenGL中GLSL渲染茶壶光照完整程序
- OpenGL学习笔记 (7) —— 三种不同的纹理滤波方式,光照和键盘控制
- 对于OpenGL中光照和颜色混合的理解
- OpenGL学习十四:光照1
- openGL图片占用内存计算
- OpenGL--光照