OpenGL光照和颜色
OpenGL场景中模型颜色的产生,大致为如下的流程图所描述:++
++++++ ++++++ ++++++ ++++++
(1)当不开启光照时,使用顶点颜色来产生整个表面的颜色。
用glShadeModel可以设置表面内部像素颜色产生的方式。GL_FLAT/GL_SMOOTH.
++
(2)一般而言,开启光照后,在场景中至少需要有一个光源(GL_LIGHT0...GL_LIGHT7)
通过glEnable(GL_LIGHT0) glDisable(GL_LIGHT0) 来开启和关闭指定的光源。
--- 全局环境光 ---
1 2 | GLfloat gAmbient[] = {0.6, 0,6, 0,6, 1.0}; glLightModelfv(GL_LIGHT_MODEL_AMBIENT, gAmbient); |
++
(3)设置光源的光分量 -- 环境光/漫色光/镜面光
默认情况下,GL_LIGHT0...GL_LIGHT7 的GL_AMBIENT值为(0.0, 0.0, 0.0, 1.0);
GL_LIGHT0的GL_DIFFUSE和GL_SPECULAR值为(1.0, 1.0, 1.0, 1.0),
GL_LIGHT1...GL_LIGHT7 的GL_DIFFUSE和GL_SPECULAR值为(0.0, 0.0, 0.0, 0.0)。
1 2 3 4 5 6 | GLfloat lightAmbient[] = {1.0, 1.0, 1.0, 1.0}; GLfloat lightDiffuse[] = {1.0, 1.0, 1.0, 1.0}; GLfloat lightSpecular[] = {0.5, 0.5, 0.5, 1.0}; glLightfv(GL_LIGHT0, GL_AMBIENT, lightAmbient); glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDiffuse); glLightfv(GL_LIGHT0, GL_SPECULAR, lightSpecular); |
++
(4)设置光源的位置和方向
-- 平行光 -- 没有位置只有方向
1 2 | GLfloat lightPosition[] = {8.5, 5.0, -2.0, 0.0}; // w=0.0 glLightfv(GL_LIGHT0, GL_POSITION, lightPosition); |
-- 点光源 -- 有位置没有方向
1 2 | GLfloat lightPosition[] = {8.5, 5.0, -2.0, 1.0}; // w不为0 glLightfv(GL_LIGHT0, GL_POSITION, lightPosition); |
-- 聚光灯 -- 有位置有方向
1 2 3 4 5 | GLfloat lightPosition[] = {-6.0, 1.0, 3.0, 1.0}; // w不为0 glLightfv(GL_LIGHT0, GL_POSITION, lightPosition); GLfloat lightDirection[] = {1.0, 1.0, 0.0}; glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, lightDirection); // 聚光灯主轴方向 spot direction glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 45.0); // cutoff角度 spot cutoff |
** 平行光不会随着距离d增加而衰减,但点光源和聚光灯会发生衰减。
attenuation为衰变系数,系数值越大,衰变越快。
默认情况下,c=1.0, l=0.0, q=0.0
1 2 3 | glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 2.0); // c 系数 glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 1.0); // l 系数 glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, 0.5); // q 系数 |
++
(5)设置材质属性
环境光、散射光不受视点位置的影响。物体看起来是什么颜色,很大程度上地受到散射光的影响,环境光反射也对物体的颜色有一定的影响。
因为当光直射物体时,散射光最强;非直射时,环境光效果明显。对于真实的世界中的物体,其散射光与环境光通常是同一个颜色。
物体的镜面反射会在物体表面产生一个高亮区。观察者所看到的镜面反射依赖于视点位置 -- 沿着反射光的方向亮度最高。
默认情况下,材质的GL_AMBIENT值为(0.2, 0.2, 0.2, 1.0);GL_DIFFUSE值为(0.8, 0.8, 0.8, 1.0);
GL_SPECULAR值为(0.0, 0.0, 0.0, 1.0);GL_SHININESS值为0.0【取值范围为[0.0, 128.0],数值越大,高亮区越小,亮度越高】;
GL_GL_EMISSION值为(0.0, 0.0, 0.0, 1.0)
1 2 3 4 5 6 7 8 9 10 11 12 | GLfloat matAmbient[] = {0.6, 0.6, 0.6, 1.0}; GLfloat matDiffuse[] = {0.35, 0.35, 0.35, 1.0}; GLfloat matAmbDif[] = {0.5, 0.5, 0.5, 1.0}; GLfloat matSpecular[] = {0.2, 0.2, 0.2, 1.0}; GLfloat shine[] = {5.0}; GLfloat matEmission[] = {0.3, 0.1, 0.1, 1.0}; glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, matAmbient); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, matDiffuse); glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, matAmbDif); // 将背景颜色和散射颜色设置成同一颜色 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, matSpecular); glMaterialfv(GL_FRONT, GL_SHININESS, shine); glMaterialfv(GL_FRONT, GL_EMISSION, matEmission); // 用来模拟物体发光的效果,但这不是光源 |
++
(6)颜色材质模式
使用颜色材质可以用较小的代价,快速改变场景中模型的颜色。其具体用法如下:
1 2 3 4 5 6 7 8 | glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT, GL_DIFFUSE); glColor3f(0.2, 0.5, 0.8); /*** 绘制一些物体 ***/ glColorMaterial(GL_FRONT, GL_SPECULAR); glColor3f(0.9, 0.1, 0.3); /*** 绘制另外一些物体 ***/ glDisable(GL_COLOR_MATERIAL); |
++
(7)参考
http://fly.cc.fer.hr/~unreal/theredbook/
http://www.john-chapman.net/content.php?id=3
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)