OpenGL光照设置
光照模型
OpenGL光照模型分为三种光:Ambient Light 环境光, Diffuse Light漫反射光, Specular Light镜面反射光.
一、创建光源
void glLightfv (GLenum light, GLenum pname, const GLfloat *params)
light: OpenGL提供8个光源 GL_LIGHT0 ~ GL_LIGHT7
pname: 光源属性
GL_AMBIENT 环境光 默认 (0.0, 0.0, 0.0, 1.0)
GL_DIFFUSE 漫反射光 默认 (1.0, 1.0, 1.0, 1.0)
GL_SEPCULAR 镜面反射光 默认 (1.0, 1.0, 1.0, 1.0)
GL_POSITION 光源位置齐次坐标(x,y,z,w) 默认 (0.0, 0.0, 1.0, 0.0)
GL_SPOT_DIRECTION 点光源聚光方向矢量(x,y,z) 默认 (0.0, 0.0, -1.0)
GL_SPOT_EXPONENT 点光源聚光指数 默认 (0.0)
GL_SPOT_CUTOFF 点光源聚光截止角 默认 (180)
GL_CONSTANT_ATTENUATION 常量衰减因子 默认 (1.0)
GL_LINER_ATTENUATION 线性衰减因子 默认 (0.0)
GL_QUADRATIC_ATTENUATION 平方衰减因子 默认 (0.0)
params: 光源属性值
GLfloat light_position[] = { 0.0, 0.0, 0.0, 0.0 };
GLfloat light_ambient [] = { 0.0, 0.0, 0.0, 1.0 };
GLfloat light_diffuse [] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 };
glLightfv(GL_LIGHT0, GL_POSITION, light_position); // 指定位置
glLightfv(GL_LIGHT0, GL_AMBIENT , light_ambient ); // 设置环境光
glLightfv(GL_LIGHT0, GL_DIFFUSE , light_diffuse ); // 设置漫反射光
glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular); // 设置镜面反射光
光源的衰减
离光源越远则光强越弱。由于定向光源是模拟的无穷远得光源,所以不会根据距离改变而衰减,所以在定向光源中是禁用衰减的; 对于定位光源有衰减。OpenGL的光衰减是通过光源的发光量乘以衰减因子来实现衰减的。
衰减系数 = 1/(K0+K1*D+K2*D2)
其中: D = 光源位置与顶点之间的距离
K0 = GL_CONSTANT_ATTENUATION //常数衰减因子
K1 = GL_LINER_ATTENUATION // 线性衰减因子
K2 = GL_QUADRATIC_ATTENUATION // 二次衰减因子
OpenGL中默认的衰减因子为(1,0,0),即不进行衰减。
二、启用光源
glEnable(GL_LIGHTING);
glEnable(GL_LIGHTn);
三、材质
OpenGL用材质对光的红、绿、蓝三原色的反射率来近似定义材料的颜色。
物体的材质跟光源一样,也分为环境、漫反射和镜面反射成分,它们决定了材料对环境光、漫反射光和镜面反射光的反射程度。其中对环境光和漫反射光的反射程度决定了物体的颜色。
比如对于一朵红色的花,它对绿色和蓝色的反射能力比较弱,对红色分量的反射能力比较强,所以呈现出来是红色。材质的镜面反射率在RGB三个分量上通常是一致的,即反射的光跟光源的颜色基本是一致的,只不过强度会减弱。镜面反射光的强度还取决于观察点的位置,当观察点正好处于入射光的反射光线上,亮斑的亮度达到最大值。
这3个材质的属性都是反应的物体对外界光线的反射情况,有些物体本身可以发射弱光,OpenGL中是通过设置材料的辐射光来实现的,可以使物体看起来像是发射出设定的辐射光一样,以达到特殊的效果。物体的辐射光使用glMaterialfv(GL_FRONT, GL_EMISSION, earth_mat_emission)来设置。
总体来说材质定义了物体对环境光、漫反射光、镜面光的反射(吸收)能力。我们看到的物体的颜色(或亮度)是光源的颜色(或亮度)经过物体的材质反射(吸收)之后发散出来的颜色(或亮度)。
定义材质的函数使用glMaterialfv
void glMaterialfv (GLenum face, GLenum pname, const GLfloat *params);
face: 表示当前材质应用于哪个表面上 GL_FRONT、GL_BACK、GL_FRONT_AND_BACK
pname: 指定正在设置的材质属性
GL_AMBIENT 材质的环境光颜色 默认(0.2, 0.2, 0.2, 1.0)
GL_DIFFUSE 材质的漫反射光颜色 默认(0.8, 0.8, 0.8, 1.0)
GL_AMBIENT_AND_DIFFUSE 环境光和漫反射光颜色 默认(0.8, 0.8, 0.8, 1.0)
GL_SEPCULAR 材质镜面反射光颜色 默认(0.0, 0.0, 0.0, 1.0)
GL_SHININESS 镜面指数(光亮度) 默认(0.0)
GL_EMISSION 材质辐射光颜色 默认(0.0, 0.0, 0.0, 1.0)
GL_COLOR_INDEXS 材质环境、漫反射和镜面反射颜色 默认(0, 0, 1)
params: 属性值
GLfloat mat_ambient[] = { 0.3f, 0.3f, 0.3f, 1.0f };
GLfloat mat_diffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f };
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
使用颜色材质:
除了glMaterialfv设置材质,还可以用glColorMaterial设置材质。glColorMaterial在绘图过程中根据glColor实时设置材质。
要使用glColorMaterial,需要启动颜色跟踪功能 glEnable(GL_COLOR_MATERIAL)
四、光照使用总结
1. 设置光源参数: 需要多次调用带有不同参数的glLightfv函数,设置环境光(Ambient Light)、漫射光(Diffuse Light)、镜面光(Specular Light)和光照位置(Position)等。
2. 开启光照,使用glEnable(GL_LIGHTING)和glEnable(GL_LIGHTXX)来开启光照和XX号光源,前者相当于光源的总开关,后者是对应的开启相应号数的光源。
3. glMaterialfv或glColorMaterial设置材质
4. 法线的设置
下图是对光照应用的例子,红色球代表太阳,材质的辐射光为红光,绿色球代表地球,绕太阳公转,材质的辐射光为蓝光,镜面反射光为红色(蓝色地球上的红色区域):
void CWinGLView::OnDraw(CDC* /*pDC*/)
{// 创建透视效果视图 CRect rectSize;GetClientRect(&rectSize);double dbViewWidth = 800;int cx = rectSize.Width();int cy = rectSize.Height();glViewport(0, 0, cx, cy);glMatrixMode(GL_PROJECTION);glLoadIdentity();gluPerspective(80.0f, 1.0f, 1.0f, 20.0f);glClearColor(0.3, 0.7, 0.5, 0);glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //清理颜色和深度缓存 glMatrixMode(GL_MODELVIEW);glLoadIdentity();gluLookAt(0.0, 12.0, 10.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);// 定义太阳光源,它是一种白色的光源 {GLfloat sun_light_position[] = { 0.0f, 0.0f, 0.0f, 1.0f }; //光源的位置在世界坐标系圆心,齐次坐标形式GLfloat sun_light_ambient[] = { 0.0f, 0.0f, 0.0f, 1.0f }; //RGBA模式的环境光,为0GLfloat sun_light_diffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f }; //RGBA模式的漫反射光,全白光GLfloat sun_light_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f }; //RGBA模式下的镜面光 ,全白光glLightfv(GL_LIGHT0, GL_POSITION, sun_light_position);glLightfv(GL_LIGHT0, GL_AMBIENT, sun_light_ambient);glLightfv(GL_LIGHT0, GL_DIFFUSE, sun_light_diffuse);glLightfv(GL_LIGHT0, GL_SPECULAR, sun_light_specular);//开启灯光glEnable(GL_LIGHT0);glEnable(GL_LIGHTING);glEnable(GL_DEPTH_TEST);}// 定义太阳的材质并绘制太阳 {GLfloat sun_mat_ambient[] = { 0.0f, 0.0f, 0.0f, 1.0f }; //定义材质的环境光颜色,为0GLfloat sun_mat_diffuse[] = { 0.0f, 0.0f, 0.0f, 1.0f }; //定义材质的漫反射光颜色,为0GLfloat sun_mat_specular[] = { 0.0f, 0.0f, 0.0f, 1.0f }; //定义材质的镜面反射光颜色,为0GLfloat sun_mat_emission[] = { 0.8f, 0.0f, 0.0f, 1.0f }; //定义材质的辐射广颜色,为偏红色GLfloat sun_mat_shininess = 0.0f;glMaterialfv(GL_FRONT, GL_AMBIENT, sun_mat_ambient);glMaterialfv(GL_FRONT, GL_DIFFUSE, sun_mat_diffuse);glMaterialfv(GL_FRONT, GL_SPECULAR, sun_mat_specular);glMaterialfv(GL_FRONT, GL_EMISSION, sun_mat_emission);glMaterialf(GL_FRONT, GL_SHININESS, sun_mat_shininess);glutSolidSphere(3.0, 40, 32);}// 定义地球的材质并绘制地球 {GLfloat earth_mat_ambient[] = { 0.0f, 0.0f, 1.0f, 1.0f }; //定义材质的环境光颜色,骗蓝色GLfloat earth_mat_diffuse[] = { 0.0f, 0.0f, 0.5f, 1.0f }; //定义材质的漫反射光颜色,偏蓝色GLfloat earth_mat_specular[] = { 1.0f, 0.0f, 0.0f, 1.0f }; //定义材质的镜面反射光颜色,红色GLfloat earth_mat_emission[] = { 0.0f, 0.0f, 0.0f, 1.0f }; //定义材质的辐射光颜色,为0GLfloat earth_mat_shininess = 30.0f;glMaterialfv(GL_FRONT, GL_AMBIENT, earth_mat_ambient);glMaterialfv(GL_FRONT, GL_DIFFUSE, earth_mat_diffuse);glMaterialfv(GL_FRONT, GL_SPECULAR, earth_mat_specular);glMaterialfv(GL_FRONT, GL_EMISSION, earth_mat_emission);glMaterialf(GL_FRONT, GL_SHININESS, earth_mat_shininess);glRotatef(m_angle, 0.0f, -1.0f, 0.0f);glTranslatef(7.0f, 0.0f, 0.0f);glutSolidSphere(3.0, 40, 32);}glFlush();SwapBuffers(m_hDC);
}
OpenGL光照设置相关推荐
- 【OpenGL】二十二、OpenGL 光照效果 ( 模型准备 | 光照设置 | 启用光照 | 启用光源 | 设置光源位置 | 设置光照参数 | 设置环境光 | 设置反射材质 | 设置法线 )
文章目录 一.模型准备 二.光照设置 1.启用光照设置 2.启用光源 3.设置光照参数 4.设置环境光 5.设置反射材质 三.光照法线设置 1.设置光源位置 2.设置法线 3.代码示例及运行效果 四. ...
- OpenGL 光照贴图Lighting maps
OpenGL光照贴图Lighting maps 光照贴图Lighting maps简介 漫反射贴图 镜面光贴图 采样镜面光贴图 光照贴图Lighting maps简介 在上一节中,我们讨论了让每个物体 ...
- freeglut_光照设置_材质设置_笔记与心得
详细记录下最近被老师和师兄掐着脖子撵着做的OPENGL显示和鼠标键盘交互,突然意识到软件著作权不会查重,并且最终的是MFC+OPENGL的模式,和单独opengl代码是不同的~那我就放心开源了~ (1 ...
- 【OpenGL】十、OpenGL 绘制点 ( 初始化 OpenGL 矩阵 | 设置投影矩阵 | 设置模型视图矩阵 | 绘制点 | 清除缓冲区 | 设置当前颜色值 | 设置点大小 | 绘制点 )
文章目录 一.初始化 OpenGL 矩阵 1.设置投影矩阵 2.设置模型视图矩阵 二.绘制点 1.清除缓冲区 2.设置当前颜色值 3.设置绘制点的大小 4.绘制点 5.将缓冲区绘制到前台 三.部分代码 ...
- Lighting Window 光照设置界面 光照系列2
Lighting Window 光照设置界面 本文档主要是对Unity官方手册的个人理解与总结(其实以翻译记录为主:>) 仅作为个人学习使用,不得作为商业用途,欢迎转载,并请注明出处. 文章中涉 ...
- OpenGL编程设置
OpenGL编程设置 13小时前 一.环境配置 由于微软公司为了推销自己的产品DirectX,击败OpenGL,因此现在的windows操作系统只支持OpenGL1.1版本,而现在的OpengGL版本 ...
- OpenGL glBlendFunc() 设置颜色混合 透明度叠加计算
glBlendFunc();–混合 OpenGL 会把源颜色和目标颜色各自取出,并乘以一个系数(源颜色乘以的系数称为"源因子",目标颜色乘以的系数称为"目标因子" ...
- IOS – OpenGL ES 设置图像滤镜 GPUImageAmatorkaFilter
目录 一.简介 二.效果演示 三.源码下载 四.猜你喜欢 零基础 OpenGL (ES) 学习路线推荐 : OpenGL (ES) 学习目录 >> OpenGL ES 基础 零基础 Ope ...
- Unity中的部分环境光照设置以及简单雾的效果
Unity中的部分环境光照设置以及简单雾的效果 环境光照 为什么要使用环境光照 效果实现 灯光渲染窗口 第一部分 第二部分: 环境光照 雾 结尾 先发一张最近测试出的demo图片,这个项目是开启了UR ...
最新文章
- 数据中心节能大法 —— 尽在上海11月中国数据中心展
- oracle查询表占用空,查询dba_tables 为啥有的表的表空间为空
- Elasticsearch 7.9.0 发布
- 锁用不好,可能把自己锁住哦!(解决多线程的死锁问题)
- 《JVM系列》深入浅出类加载机制中<init>和<Clinit>的区别【一篇即可搞懂初始化机制】
- 【BZOJ 2721】 2721: [Violet 5]樱花 (筛)
- Bigtable:一个分布式的结构化数据存储系统(转)
- mysql必_MySQL必知必会(一)
- java captivate_flashremoting-java-win-en.exe
- 易点易动助力叮咚买菜数字化管理固定资产和易耗品
- 如何清空c盘只剩系统_如何深度清理c盘空间(怎么清理c盘只留下系统)
- 一年Java的阿里电话面试全纪录
- 微信小程序开发者工具构建npm
- html修改网站图标,分享内容,分享图标等
- win7 计算机无法搜索文件夹,win7文件搜索功能不能使用了
- 华为WEB前端全栈成长计划招募
- 高通WLAN框架学习(17)-- NIO和PNO
- UML总结—包图(Package Diagram)
- Zookeeper安装与可视化客户端详细使用教程
- 【转】以太坊上的分片
热门文章
- 安装win7和win10或win7和linux双系统
- uni-app textarea解决点击软键盘上自带收起按钮输入框没有取消焦点的问题(监听软键盘自带收起按钮)
- 十年磨一剑,腾讯云数据库品牌重磅升级, “企业级分布式数据库TDSQL”来了!
- 小白的笨笨知识【用原生js实现一个倒计时项目】
- 周鸿祎VS马化腾 你选哪个做老板?
- 欧洲冠军杯决赛要开打了 排兵布阵 排出你最喜爱的阵容! Champions League Final
- 推箱子游戏C++实现原理
- Linux 周期性计划任务 crontab
- Hive学习:数据仓库的建立
- 什么是AECQ认证?