opengl光照

看一张图片:



图中绘制了两个大小相同的白色球体。其中右边的一个是没有使用任何光照效果的,它看起来就像是一个二维的圆盘,没有立体的感觉。左边的一个是使用了简单的光照效果的,我们通过光照的层次,很容易的认为它是一个三维的物体

眼睛之所以看见各种物体,是因为光线直接或间接的从它们那里到达了眼睛。人类对于光线强弱的变化的反应,比对于颜色变化的反应来得灵敏。因此对于人类而言,光线很大程度上表现了物体的立体感。


建立光照模型

OpenGL在处理光照时采用这样一种近似:把光照系统分为三部分,分别是光源、材质和光照环境。

光源就是光的来源,可以是前面所说的太阳或者电灯等。

材质是指接受光照的各种物体的表面,由于物体如何反射光线只由物体表面决定(OpenGL中没有考虑光的折射),材质特点就决定了物体反射光线的特点。

光照环境是指一些额外的参数,它们将影响最终的光照画面,比如一些光线经过多次反射后,已经无法分清它究竟是由哪个光源发出,这时,指定一个“环境亮度”参数,可以使最后形成的画面更接近于真实情况。


在物理学中,光线如果射入理想的光滑平面,则反射后的光线是很规则的(这样的反射称为镜面反射)。

光线如果射入粗糙的、不光滑的平面,则反射后的光线是杂乱的(这样的反射称为漫反射)。

现实生活中的物体在反射光线时,并不是绝对的镜面反射或漫反射,但可以看成是这两种反射的叠加。

对于光源发出的光线,可以分别设置其经过镜面反射和漫反射后的光线强度。对于被光线照射的材质,也可以分别设置光线经过镜面反射和漫反射后的光线强度。这些因素综合起来,就形成了最终的光照效果。


法线向量
根据光的反射定律,由光的入射方向和入射点的法线就可以得到光的出射方向。

因此,对于指定的物体,在指定了光源后,即可计算出光的反射方向,进而计算出光照效果的画面。

在OpenGL中,法线的方向是用一个向量来表示。
不幸的是,OpenGL并不会根据你所指定的多边形各个顶点来计算出这些多边形所构成的物体的表面的每个点的法线(这话听着有些迷糊),通常,为了实现光照效果,需要在代码中为每一个顶点指定其法线向量。
指定法线向量的方式与指定颜色的方式有雷同之处。在指定颜色时,只需要指定每一个顶点的颜色,OpenGL就可以自行计算顶点之间的其它点的颜色。

并且,颜色一旦被指定,除非再指定新的颜色,否则以后指定的所有顶点都将以这一向量作为自己的颜色。

在指定法线向量时只需要指定每一个顶点的法线向量,OpenGL会自行计算顶点之间的其它点的法线向量。

并且,法线向量一旦被指定,除非再指定新的法线向量,否则以后指定的所有顶点都将以这一向量作为自己的法线向量。

使用glColor*函数可以指定颜色,而使用glNormal*函数则可以指定法线向量。


注意:使用glTranslate*函数或者glRotate*函数可以改变物体的外观,但法线向量并不会随之改变。

然而,使用glScale*函数,对每一坐标轴进行不同程度的缩放,很有可能导致法线向量的不正确,虽然OpenGL提供了一些措施来修正这一问题,但由此也带来了各种开销。

因此,在使用了法线向量的场合,应尽量避免使用glScale*函数。即使使用,也最好保证各坐标轴进行等比例缩放。



控制光源
在OpenGL中,仅仅支持有限数量的光源。

使用GL_LIGHT0表示第0号光源,GL_LIGHT1表示第1号光源,依次类推.

OpenGL至少会支持8个光源,即GL_LIGHT0到GL_LIGHT7。

使用glEnable函数可以开启它们。例如,glEnable(GL_LIGHT0);可以开启第0号光源。

使用glDisable函数则可以关闭光源。

一些OpenGL实现可能支持更多数量的光源,但总的来说,开启过多的光源将会导致程序运行速度的严重下降,玩过3D Mark的朋友可能多少也有些体会。一些场景中可能有成百上千的电灯,这时可能需要采取一些近似的手段来进行编程,否则以目前的计算机而言,是无法运行这样的程序的。


每一个光源都可以设置其属性,这一动作是通过glLight*函数完成的。

glLight*函数具有三个参数,第一个参数指明是设置哪一个光源的属性,第二个参数指明是设置该光源的哪一个属性,第三个参数则是指明把该属性值设置成多少。光源的属性众多,下面将分别介绍。


(1)GL_AMBIENT、GL_DIFFUSE、GL_SPECULAR属性。

这三个属性表示了光源所发出的光的反射特性(以及颜色)。

每个属性由四个值表示,分别代表了颜色的R, G, B, A值。

GL_AMBIENT表示该光源所发出的光,经过非常多次的反射后,最终遗留在整个光照环境中的强度(颜色)。

GL_DIFFUSE表示该光源所发出的光,照射到粗糙表面时经过漫反射,所得到的光的强度(颜色)

GL_SPECULAR表示该光源所发出的光,照射到光滑表面时经过镜面反射,所得到的光的强度(颜色)。


(2)GL_POSITION属性。

表示光源所在的位置。

由四个值(X, Y, Z, W)表示。

如果第四个值W为零,则表示该光源位于无限远处,前三个值表示了它所在的方向。

这种光源称为方向性光源,通常,太阳可以近似的被认为是方向性光源。

如果第四个值W不为零,则X/W, Y/W, Z/W表示了光源的位置。

这种光源称为位置性光源。对于位置性光源,设置其位置与设置多边形顶点的方式相似,各种矩阵变换函数例如:glTranslate*、glRotate*等在这里也同样有效。

方向性光源在计算时比位置性光源快了不少,因此,在视觉效果允许的情况下,应该尽可能的使用方向性光源


(3)GL_SPOT_DIRECTION、GL_SPOT_EXPONENT、GL_SPOT_CUTOFF属性。

表示将光源作为聚光灯使用(这些属性只对位置性光源有效)。很多光源都是向四面八方发射光线,但有时候一些光源则是只向某个方向发射,比如手电筒,只向一个较小的角度发射光线。

GL_SPOT_DIRECTION属性有三个值,表示一个向量,即光源发射的方向。

GL_SPOT_EXPONENT属性只有一个值,表示聚光的程度,为零时表示光照范围内向各方向发射的光线强度相同,为正数时表示光照向中央集中,正对发射方向的位置受到更多光照,其它位置受到较少光照。数值越大,聚光效果就越明显。

GL_SPOT_CUTOFF属性也只有一个值,表示一个角度,它是光源发射光线所覆盖角度的一半(见下图),其取值范围在0到90之间,也可以取180这个特殊值。取值为180时表示光源发射光线覆盖360度,即不使用聚光灯,向全周围发射。


(4)GL_CONSTANT_ATTENUATION、GL_LINEAR_ATTENUATION、GL_QUADRATIC_ATTENUATION属性。

这三个属性表示了光源所发出的光线的直线传播特性(这些属性只对位置性光源有效)。

现实生活中,光线的强度随着距离的增加而减弱,OpenGL把这个减弱的趋势抽象成函数:


衰减因子 = 1 / (k1 + k2 * d + k3 * k3 * d)


其中d表示距离,光线的初始强度乘以衰减因子,就得到对应距离的光线强度。

k1, k2, k3分别就是GL_CONSTANT_ATTENUATION, GL_LINEAR_ATTENUATION, GL_QUADRATIC_ATTENUATION。

通过设置这三个常数,就可以控制光线在传播过程中的减弱趋势。

属性还真是不少。当然了,如果是使用方向性光源,(3)(4)这两类属性就不会用到了,问题就变得简单明了。



  控制材质


材质与光源相似,也需要设置众多的属性。不同的是,光源是通过glLight*函数来设置的,而材质则是通过glMaterial*函数来设置的。


glMaterial*函数有三个参数。第一个参数表示指定哪一面的属性。可以是GL_FRONT、GL_BACK或者GL_FRONT_AND_BACK。分别表示设置“正面”“背面”的材质,或者两面同时设置。

第二、第三个参数与glLight*函数的第二、三个参数作用类似。

下面分别说明glMaterial*函数可以指定的材质属性。


(1)GL_AMBIENT、GL_DIFFUSE、GL_SPECULAR属性。

这三个属性与光源的三个对应属性类似,每一属性都由四个值组成。

GL_AMBIENT表示各种光线照射到该材质上,经过很多次反射后最终遗留在环境中的光线强度(颜色)。

GL_DIFFUSE表示光线照射到该材质上,经过漫反射后形成的光线强度(颜色)。

GL_SPECULAR表示光线照射到该材质上,经过镜面反射后形成的光线强度(颜色)。

通常,GL_AMBIENT和GL_DIFFUSE都取相同的值,可以达到比较真实的效果。

使用GL_AMBIENT_AND_DIFFUSE可以同时设置GL_AMBIENT和GL_DIFFUSE属性。


(2)GL_SHININESS属性。

该属性只有一个值,称为“镜面指数”,取值范围是0到128。

该值越小,表示材质越粗糙,点光源发射的光线照射到上面,也可以产生较大的亮点。该值越大,表示材质越类似于镜面,光源照射到上面后,产生较小的亮点。


(3)GL_EMISSION属性。该属性由四个值组成,表示一种颜色。OpenGL认为该材质本身就微微的向外发射光线,以至于眼睛感觉到它有这样的颜色,但这光线又比较微弱,以至于不会影响到其它物体的颜色。


(4)GL_COLOR_INDEXES属性。

该属性仅在颜色索引模式下使用,由于颜色索引模式下的光照比RGBA模式要复杂,并且使用范围较小,这里不做讨论。




选择光照模型


这里所说的“光照模型”是OpenGL的术语,它相当于我们在前面提到的“光照环境”。

在OpenGL中,光照模型包括四个部分的内容:

全局环境光线(即那些充分散射,无法分清究竟来自哪个光源的光线)的强度、

观察点位置是在较近位置还是在无限远处、物体正面与背面是否分别计算光照、

镜面颜色(即GL_SPECULAR属性所指定的颜色)的计算是否从其它光照计算中分离出来,并在纹理操作以后在进行应用。


以上四方面的内容都通过同一个函数glLightModel*来进行设置。

该函数有两个参数,第一个表示要设置的项目,第二个参数表示要设置成的值。


GL_LIGHT_MODEL_AMBIENT表示全局环境光线强度,由四个值组成。

GL_LIGHT_MODEL_LOCAL_VIEWER表示是否在近处观看,若是则设置为GL_TRUE,否则(即在无限远处观看)设置为GL_FALSE。
GL_LIGHT_MODEL_TWO_SIDE表示是否执行双面光照计算。如果设置为GL_TRUE,则OpenGL不仅将根据法线向量计算正面的光照,也会将法线向量反转并计算背面的光照。


GL_LIGHT_MODEL_COLOR_CONTROL表示颜色计算方式

如果设置为GL_SINGLE_COLOR,表示按通常顺序操作,先计算光照,再计算纹理。

如果设置为GL_SEPARATE_SPECULAR_COLOR,表示将GL_SPECULAR属性分离出来,先计算光照的其它部分,待纹理操作完成后再计算GL_SPECULAR。

后者通常可以使画面效果更为逼真(当然,如果本身就没有执行任何纹理操作,这样的分离就没有任何意义)。



OpenGL默认是关闭光照处理的。要打开光照处理功能,使用下面的语句:
glEnable(GL_LIGHTING);
要关闭光照处理功能,使用glDisable(GL_LIGHTING);即可。




本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/509868.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Nifi 之 kafka消费存入hbase

添加kafka processor,配置如下 kakfa数据格式为JSON: {"events_tag":"103913","query_word":"华大癌变 虎嗅","time":"2018-08-09 13:01:11"} 添加putHbaseJSON,json格式添加数…

web通讯录之搜索功能

手机号搜索: 姓名搜索: 拼音搜索: 城市搜索: 性别搜索: 点击姓名或者电话显示完整信息 相信大家期待自己所写的搜索功能类似于百度、谷歌这种搜索引擎,有兴趣的读者可以去学学SEO,在这里我…

Hbase 删表过程

Hbase 执行删表命令后(drop),表的数据会移动到 /hbase/archive 目录下,并不会直接从hdfs删除,后台会有进程定期去检查(默认五分钟),如果这张表没有快照则会删除,有快照会保留数据。 刚drop时&a…

opengl纹理单元

可以这样简单的理解为:显卡中有N个纹理单元(具体数目依赖你的显卡能力),每个纹理单元(GL_TEXTURE0、GL_TEXTURE1等)都有GL_TEXTURE_1D、GL_TEXTURE_2D等,如下代码: [cpp] view plain…

Spark 创建 hive表报错 ROW FORMAT DELIMITED is only compatible with 'textfile', not 'parquet'

场景: 在spark分析数据时,创建hive表失败。 提示异常 : 19/10/09 10:59:18 INFO execution.SparkSqlParser: Parsing command: CREATE EXTERNAL TABLE IF NOT EXISTS dm_xxx.user_area(biFollowersCount String,city String,created_at Str…

多重纹理和纹理组合器

多重纹理和纹理组合器 本文主要介绍OpenGL中两种技术的使用方法:多重纹理技术和纹理组合器技术,最终根据参考【2】中的代码,实现了两个简单的演示DEMO,其中使用到了《八叉树颜色量化、BMP、TGA文件解析》篇章中提供的图像解析类。…

ClouderaManager agent 报错,无法连接到结群 Error, CM server guid updated, expected xxx , received xxx

场景 集群版本:CDH 6.0.1 服务器版本:Centos 7.3 JAVA版本:1.8 异常出现原因 搭建集群中遇到异常,删除agent节点,重新部署CM后发现异常,CDH处于无法使用状态 异常 查看agent日志会出现,说无法连接到…

CDH Kerberos 认证下Kafka 消费方式

集群Kerberos认证安装参考:https://datamining.blog.csdn.net/article/details/98480008 目录 环境: 配置 Java Producer 代码 文件内容: kafka_client_jaas.conf krb5.conf ( kerberos 配置文件复制过来即可) kafka.keytab Java Co…

IntelliJ IDEA Maven jar包冲突解决,快速发现jar包冲突

IntelliJ IDEA 自带的Diagrams 去查看jar包冲突相当费劲 ~ ,安装个插件即可快速解决该问题 打开Settings,搜索maven helper,并安装 安装完成后,直接打开pom文件,点击Dependency Analyzer 删除冲突jar包,在…

osg基本图元

OSG绘制几何体学习总结(超全)在osg中,场景图形采用一种自顶向下的,分层的树状数据结构来组织空间数据集,以提高渲染的效率 场景图形树结构的顶部是一个根节点,从根节点向下延伸,各个组节点中均包…

如何用css设计出商品购物图片

代码: 常见问题:背景填充时候图片大小不一致、重复等等问题,建议在插入图片的时候最好不用img标签直接在div中添加背景图片,有利于对背景图片的更改。 插入图片:background-image: url(../img/product-auto/benz-amg-s…

OLTP、OLAP与HTAP 区别

OLTP On-Line Transaction Processing联机事务处理过程(OLTP) 也称为面向交易的处理过程,其基本特征是前台接收的用户数据可以立即传送到计算中心进行处理,并在很短的时间内给出处理结果,是对用户操作快速响应的方式之一。 这样做的最大优点…

osg布告板技术(Billboard)

公告牌技术,即billboard技术,在3D游戏中有着广泛的应用.它的本质就是用预先做好的几幅 位图来代替3D物体,极大地节省资源和提高速度.仔细观察<<魔法门>>系列游戏,它的精灵,树木,物 品都是二维图象,但由于它始终朝向观察者,你根本看不到它"扁"的一面,所以…

osg坐标系转换

osg中将局部坐标系下的点坐标换算成全局坐标系下点的坐标 标签&#xff1a; matrixlist2012-05-17 16:27 2940人阅读 评论(1) 收藏 举报分类&#xff1a;osg&#xff08;7&#xff09; 坐标变换版权声明&#xff1a;本文为博主原创文章&#xff0c;未经博主允许不得转载。 今天…

C#/WPF 播放音频文件

C#播放音频文件的方式&#xff1a; 播放系统事件声音使用System.Media.SoundPlayer播放wav使用MCI Command String多媒体设备程序接口播放mp3&#xff0c;wav&#xff0c;avi等使用WindowsMediaPlayer的COM组件来播放(可视化)使用DirectX播放音频文件使用Speech播放(朗读器&am…

Hbase 二级索引 Solr int字段排序问题 can not sort on multivalued field

Hbase Solr 同步二级索引后&#xff0c;进行int字段排序时报错 报错如下 {"responseHeader":{"zkConnected":true,"status":400,"QTime":75,"params":{"q":"*:*","sort":"hbase_index…

OpenGL渲染管线,着色器,光栅化等概念理解

卧槽&#xff0c;前些日子看这几个概念就十分想吐槽&#xff0c;这么难理解的概念窃以为纯属翻译的不够接地气。————首先&#xff0c;光栅化&#xff08;Rasterize/rasteriztion&#xff09;。这个词儿Adobe官方翻译成栅格化或者像素化。没错&#xff0c;就是把矢量图形转化…

Hbase Solr 二级索引 同步int数据报错com.ngdata.hbaseindexer.parse.ByteArrayValueMappers: Error mapping byte

二级索引实现方式&#xff1a;Hbase Key-Value Store Indexer Solr 同步int数据时提示异常 异常如下 2019-12-16 17:39:18,346 WARN com.ngdata.hbaseindexer.parse.ByteArrayValueMappers: Error mapping byte value 101 to int java.lang.IllegalArgumentException: off…

CDH 6 安装 Hbase 二级索引 Solr + Key-Value Store Indexer

目录 一、集群安装Solr Key-Value Store Indexer 二、创建Hbase二级索引 1.更改表结构&#xff0c;允许复制 2.创建相应的SolrCloud集合 3.创建 collection实例并将配置文件上传到 zookeeper 4.创建 Lily HBase Indexer 配置 5.配置Morphline文件 6.注册 Lily HBase I…

glClipPlane剪裁平面

glClipPlane裁剪平面 (2012-02-21 12:49:18) 转载▼标签&#xff1a; 半平面 裁剪 线框 球体 表示 杂谈 分类&#xff1a; OPENGL void glClipPlane(GLenum plane, const GLdouble *equation); 定义一个裁剪平面。equation参数指向平面方程Ax By Cz D …