全球彩票平台_全球彩票注册平台|官网下载地址

热门关键词: 全球彩票平台,全球彩票注册平台,全球彩官网下载地址

shader光照和阴影,OpenGL光源光照基础

SharpGL学习笔记(九) OpenGL的光照模型, 术语解释,sharpgl学习笔记

在3D场景中,每个像素最终显示出来的颜色都是经过大量计算而得到的,其中一些计算是依赖于场景中的光照以及场景中物体对光线的反射和吸收情况.

例如,对于一个红色的物体, 在白色光(白光是红光,绿光和蓝光等量的光) 的照射下它是红色的, 而在绿色光的照射下它将显示为黑色.

 

OpenGL的光照模型

OpenGL的光, 可以分解为红,绿,蓝3种分量. 对于光源来说, 使用其发射的红,绿,蓝光的量来描述.
对于物体表面的材质则可以使用其在各个方向反射的红,绿,蓝光的比例来描述.

OpenGL的光照模型将光照分为4个独立的部分:
环境光(ambient light)
漫射光(diffuse light)
镜面反射光(specular light)
发射光(emitted light)
这4种光分别计算,然后被叠加起来.

 

环境光(ambient light)

环境光是场景中的基本光源。如果你进入一个漆黑的屋子,环境光通常是零,但走到外面时,总是有光能让你看到。环境光没有方向(所以也将其称为“全局光照模型”).

在室内, 环境通常是经环境散射无法确定方向的光, 就好像来自四面八方的光.

 

漫射光(diffuse light)
实际看看周围的桌面,墙面,太阳照射到上面的时候,我们就能看到光,大多数情况下,我们看到的多数光源是漫射光传播到我们的眼睛。

就像下图这样子:

全球彩票注册平台 1

我们平时看到的桌面或者墙壁都是平滑的,那么也就是说n法线都应该是垂直向上才对,也就是说光的反射不一定能传播进我们的眼睛了?那为什么我们从不同角度看这个桌面,它的漫射光都是一样的呢?

解决这个问题的关键就是:在微观条件下表面都是粗糙的。

就是如果我们使用显微镜观察一个很平滑的桌面,也会发现是凹凸不平的。凹凸不平到什么程度呢?从所有不同方向和角度都能观察到其粗糙程度是一样的。这么思考之后,就可以想通了,微观法线并不是垂直向上的,而是在不同角度。

 

镜面反射光(specular light)

就是平时我们看到的一个光滑球面会发出的耀眼光点。如下图:

金属表面,塑料,玻璃,瓶子等容易观察到这种镜面反射光.

全球彩票注册平台 2

关于镜面反射光的几点说明:

1 球面容易看到镜面反射光,是因为球面的法线向外扩散,让看到高亮光的区域更大,那么就更加容易看到镜面反射光了。

2 镜面表面很平滑,那么镜面反射光就会很集中,虽然看到的区域小,但是因为高亮的强度很大,那么就可以很清晰的看到镜面反射光了。

3 其实镜面反射光可以发生在任何物体和任何表面上。

4 粗糙的表面镜面反射光效果很弱或者甚至看不到镜面反射光

 

 发射光(emitted light)

这种光是一种材质发出来的光,用来模拟物体发出来的光, 在3dsmax中,被称为自发光材质. 

比如一个场景中有个白炽灯泡, 那么这个为这个灯泡就可以赋上"自发光材质"

 

 下图是3dsmax的光照渲染出来的效果, 按上面的理论, 它应该是由以上四种光源类型叠加出来的.

笔者来给大家分离单独的光源类型, 看看实际效果是什么样子.

首先, 环境光(ambient light) , 这个场景中不存在环境光, 我们就不管了.

然后, 发射光(emitted light), 在下面场景中是不存在的. 我们也不管.

我们只研究一下下面场景中的,  漫射光(diffuse light), 镜面反射光(specular light) 是个什么样子.

全球彩票注册平台 3

 

 下面是被分离出来的 漫射光(diffuse light)

 全球彩票注册平台 4

 

 下面是被分离出来的 镜面反射光(specular light) 

全球彩票注册平台 5

 

) OpenGL的光照模型, 术语解释,sharpgl学习笔记 在3D场景中,每个像素最终显示出来的颜色都是经过大量计算而得到的,其中一...

在3D场景中,每个像素最终显示出来的颜色都是经过大量计算而得到的,其中一些计算是依赖于场景中的光照以及场景中物体对光线的反射和吸收情况.

在3D场景中,每个像素最终显示出来的颜色都是经过大量计算而得到的,其中一些计算是依赖于场景中的光照以及场景中物体对光线的反射和吸收情况.

一.标准光照模型
OpenGL与Direct3D提供了几乎相同的固定功能光照模型。什么是固定功能光照模型?在过去只有固定绘制流水线的时候,该流水线被限制只能使用一个光照模型,也即是固定功能光照模型。该模型基于phong光照模型。在下面的这个例子里,我们使用一个“基本”模型对固定功能光照模型提供了简化版本。这个基本模型的数学描述为高级公式为:
   surfaceColor = emissive ambient diffuse specular
从式子可以看出:物体表面的颜色是自发光(放射 emissive)、环境反射(ambient)、漫反射(diffuse)和镜面反射(specular)等光照作用的总和。每种光照作用取决于表面材质性质(例如亮度和材质颜色)和光源的性质(例如光的位置和颜色)。
下面对这个基本模型的各个部分进行讲解,最后我们使用CG语言写出该基本模型。

光照模型

在OpenGL光照模型中,除非一个物体自己会发光,否则它将受到3种不同类型的光的照射:环境光(ambient)、散射光(diffuse)和镜面光(specular)。

  • 全局环境光
    在我们没有用到光照之前,我们也能够看到场景中绘制的物体,原因是每个场景都有这个全局环境光,它不来自任何特定的光源。
  • 环境光(ambient)
    环境光并不来自任何特定的方向。它来自某个光源,但光线却是在房间或场景中四处反射,没有方向可言。由环境光所照射的物体在所有方向的表面都是均匀照亮的。
  • 散射光(diffuse)
    散射光具有方向性,来自于一个特定的方向,它根据入射光线的角度在表面上均匀地反射开来。
  • 镜面光(specular)
    镜面光具有很强的方向性,但它的反射角度很锐利,只沿一个特定的方向反射。

例如,对于一个红色的物体, 在白色光(白光是红光,绿光和蓝光等量的光) 的照射下它是红色的, 而在绿色光的照射下它将显示为黑色.

例如,对于一个红色的物体, 在白色光(白光是红光,绿光和蓝光等量的光) 的照射下它是红色的, 而在绿色光的照射下它将显示为黑色.

全球彩票注册平台 6

光源与材料

如果场景不存在光源效果,那么就没有了3D效果。 下图左边是有光照的效果, 右图是没有光照的效果.

如果场景不存在光源效果,那么就没有了3D效果。 下图左边是有光照的效果, 右图是没有光照的效果.

图片1.png

光源

OpenGL可以同时为我们提供8个有效的光源。也就是说,我们最多可以同时启用8个光源。它们分别是GL_LIGHT0,GL_LIGHT1,GL_LIGHT2 ……
其中,GL_LIGHT0是最特殊的一个光源,我们可以为GL_LIGHT0指定环境光成分。在默认情况下,GL_LIGHT0光源的颜色为白光,其他7个光源在默认情况下是没有颜色的,也即为黑色。

全球彩票注册平台 7

全球彩票注册平台 8

    
1.)自发光(emissive)
自发光光照作用独立于所有的光源。物体的自发光并不能照亮场景中的其他物体。换句话说,物体自发光不能照亮其他物体或者投下阴影。因此,一个放射性物体本身并不是一个光源。
另一个解释放射项的方法:它是一种在计算完其他所有光照项后添加的颜色。
自发光的数学公式:emissive = Ke
其中Ke代表材质的放射光颜色

全球彩票注册平台,光源种类

  • 环境光
    环境光是一种无处不在的光。环境光源放出的光线被认为来自任何方向。因此,当你仅为场景指定环境光时,所有的物体无论法向量如何,都将表现为同样的明暗程度。
  • 点光源
    由这种光源放出的光线来自同一点,且方向辐射自四面八方。
  • 平行光
    平行光又称镜面光,这种光线是互相平行的。从手电筒、太阳等物体射出的光线都属于平行光。
  • 聚光灯
    这种光源的光线从一个锥体中射出,在被照射的物体上产生聚光的效果。使用这种光源需要指定光的射出方向以及锥体的顶角α。

 

 

2.)环境光(ambient)
环境光来自于四面八方,故环境放射光照项并不依赖于光源的位置。
1.环境放射项依赖:1.材质的反射能力 2.照射到材质上的环境光的颜色。
2.用于环境放射项的数学公式:
ambient = Ka * globalAmbient
其中ka是材质的环境反射系数,globalAmbient是入射环境光的颜色。
ka= tex2D(_MainTex, i.uv.xy).rgb
globalAmbient=UNITY_LIGHTMODEL_AMBIENT.xyz

设置光源

 

 

全球彩票注册平台 9

1.设置环境光成分

对于GL_LIGHT0,我们可以为其指定环境光成分。调用

glLightfv(GL_LIGHT0,GL_AMBIENT,@AmbientLight);

在上述函数调用中,第一个参数表示我们要对GL_LIGHT0进行设置;
第二个参数表示我们要设置的是环境光成分;
第三个参数则是一个数组,它有4个值,分别表示光源中含有红、绿、蓝三种光线的成分,一般情况下都为1;
第四个参数为透明度值,一般也为1。
完整的代码是这样的:

void SetLight
{
    int AmbientLight[4]={1,1,1,1};
    glLightfv(GL_LIGHT0,GL_AMBIENT,@AmbientLight);
    glEnable(GL_LIGHT0);       //开启GL_LIGHT0光源
    glEnable(GL_LIGHTING);     //开启光照系统
}  

(一)OpenGL的光照模型

(一)OpenGL的光照模型

环境光.png

2.设置漫射光成分

通过对漫射光成分的设置,我们可以产生一个点光源。方法和设置环境光成分相似,只需调用

 glLightfv(GL_LIGHT0,GL_DIFFUSE,@DiffuseLight);

其中DiffuseLight是漫射光的颜色成分。可以根据不同需要指定不同的颜色,一般情况下也为(1,1,1,1)。

OpenGL的光, 可以分解为红,绿,蓝3种分量. 对于光源来说, 使用其发射的红,绿,蓝光的量来描述.
对于物体表面的材质则可以使用其在各个方向反射的红,绿,蓝光的比例来描述.

OpenGL的光, 可以分解为红,绿,蓝3种分量. 对于光源来说, 使用其发射的红,绿,蓝光的量来描述.
对于物体表面的材质则可以使用其在各个方向反射的红,绿,蓝光的比例来描述.

3.)漫反射项(diffuse)

3.设置镜面光成分

通过对镜面光成分的设置,我们可以产生一个平行光源。方法和设置漫射光成分相似,只需调用

glLightfv(GL_LIGHT0,GL_SPECULAR,@SpecularLight);

其中SpecularLight是镜面反射光的颜色成分。可以根据不同需要指定不同的颜色。

OpenGL的光照模型将光照分为4个独立的部分:
环境光(ambient light)
漫射光(diffuse light)
镜面反射光(specular light)
发射光(emitted light)
这4种光分别计算,然后被叠加起来.

OpenGL的光照模型将光照分为4个独立的部分:
环境光(ambient light)
漫射光(diffuse light)
镜面反射光(specular light)
发射光(emitted light)
这4种光分别计算,然后被叠加起来.

全球彩票注册平台 10

4.设置光源的位置

对于点光源和平行光源,我们常常需要指定光源的位置来产生需要的效果。方法仍然是调用glLightfv函数,仅仅是换换参数而已:

glLightfv(GL_LIGHT0,GL_POSITION,@LightPosition);

其中,LightPosition也是一个四维数组,四维数组的前3项依次为光源位置的X,Y,Z分量。
第四个值很特殊,一般为1或0。当LightPosition[4]=0的时候,表示光源位于距离场景无限远的地方,相当于平行光;而当LightPosition[4]=1时,光源的位置就是前三项所指定的位置,也就是成为了点光源。

 

 

图片2.png

材料

材料是针对场景中的物体而言的,但并不是指现实生活中构成物体的那种有质感材料,这里的材料只与物体的颜色有关(你可能会想到怎样表现类似金属、玻璃等物质质感,除了要使用光照系统并为它们指定合适的材质外,还要使用纹理贴图来表现)。OpenGL用材料对光的红、绿、蓝三原色的反射率来近似定义材料的颜色。当一束光照到物体上时,光本身有颜色(可以自己指定。通常情况下的白光是RGB三色光的混合),光照到物体上时,物体的材料会根据自身对光中的各种成分的反射参数决定反射哪种光,也就是物体所呈现出的颜色啦。所以并不是什么颜色的光照过来,物体就会呈现出什么颜色的光。

下面来张示意图, 它比较好的解释了其中3种光照效果组成部分。

下面来张示意图, 它比较好的解释了其中3种光照效果组成部分。

兰伯特(Lambert )光照模型是目前最简单通用的模拟漫反射的光照模型,定义如下:模型表面的明亮度直接取决于光线向量(light vector)和表面法线(normal)两个向量夹角的余弦值。光线向量是指这个点到光从哪个方向射入,表面法线则定义了这个表面的朝向。

设置材料

材质的设置与光源的设置类似。其函数为:

void glMaterial{if}[v](GLenum face,GLenum pname,TYPE param);

face可以是GL_FRONT、GL_BACK、GL_FRONT_AND_BACK,它表明当前材质应该应用到物体的哪一个面上;
pname说明一个特定的材质;
param是材质的具体数值,若函数为向量形式,则param是一组值的指针,反之为参数值本身。非向量形式仅用于设置GL_SHINESS。pname参数值具体内容见下表。另外,参数GL_AMBIENT_AND_DIFFUSE表示可以用相同的RGB值设置环境光颜色和漫反射光颜色。

![](http://image-for-blog.qiniudn.com/屏幕快照 2015-03-13 下午12.15.49.png)
完整代码如下:

void SetMaterialAndLight
{
   GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
   GLfloat mat_shininess[] = { 50.0 };

   GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };  //最后一个参数为0表示该光源是directional的
 //GLfloat light_position[] = { 1.0, 1.0, 1.0, 1.0 };  //最后一个参数非0表示该光源是positional的

   GLfloat light_ambient[] = { 0.0, 1.0, 0.0, 1.0 };
   GLfloat light_diffuse[] = { 0.0, 1.0, 0.0, 1.0 };
   GLfloat light_specular[] = { 0.0, 1.0, 0.0, 1.0 };

   glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
   glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);

   glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
   glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
   glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
   glLightfv(GL_LIGHT0, GL_POSITION, light_position);

   glEnable(GL_LIGHT0);       //开启GL_LIGHT0光源
   glEnable(GL_LIGHTING);     //开启光照系统
}  

全球彩票注册平台 11

全球彩票注册平台 12

diffuse = kd * lightColor * max ( NL(点积) , 0 )
max ( N
L(点积) , 0 )
规范化的向量N和L的点积是两个向量之间夹角的一个度量,夹角越小,P点受到更多的入射光照。而背向光源的表面将产生负数点积值,因此,公式*max ( NL(点积) , 0 )使得背向光源的表面的漫反射光为0,确保这些表面不会显示漫反射光照。

颜色追踪

在没有学习光照之前,我们是通过glColor()函数来指定物体颜色的,前面已经说过,这时候我们能看到我们所设置的物体颜色是因为有全局环境光的原因。当开启光照功能后,如果用上述的设置材料属性的方法进行设置,则原来设置的颜色与被光照到后物体呈现的颜色毫无关系,即原来的 glColor*()命令失去原有的作用。
但还有一种方法设置材料属性的方法,称为颜色追踪,即用颜色指定代替材料属性指定。使用颜色追踪,可以告诉OpenGL仅仅通过调用glColor来设置材料属性。为了启用颜色追踪,需要以GL_COLOR_MATERIAL为参数调用glEnable。接着,glColorMaterial函数根据glColor所设置的值来指定材料参数。

glEnable(GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT,GL_AMBIENT_AND_DIFFUSE);

如果调用了 glEnable(GL_COLOR_MATERIAL),那么就会使光照模型中的几种光根据glColor*()中的指定确定颜色;
void glColorMaterial(GLenum face, GLenum mode);
– face的取值GL_FRONT, GL_BACK与GL_FRONT_AND_BACK(默认值)
– mode的取值为GL_EMISSION, GL_AMBIENT, GL_DIFFUSE, GL_SPECULAR与 GL_AMBIENT_AND_DIFFUSE(默认值)
例如:

glEnable(GL_COLOR_MATERIAL); 
glColorMaterial(GL_FRONT, GL_DIFFUSE); /* now glColor* changes diffuse reflection */ 
glColor3f(0.2, 0.5, 0.8);

/* draw some objects here */ 

glColorMaterial(GL_FRONT, GL_SPECULAR); /* now glColor* changes specular reflection */
glColor3f(0.9, 0.0, 0.2);

/* draw other objects here */ 
glDisable(GL_COLOR_MATERIAL); 

另外,不需要使用glColorMaterial()时,确保禁用。

 

 

_WorldSpaceLightPos0这是一个表示世界做表中的光源的位置矢量或者方向矢量;
如果_WorldSpaceLightPos0.w为0,则表示该光源为平行光,_WorldSpaceLightPos0.xyz为此平行光的方向向量;
反之_WorldSpaceLightPos0.w不为0,则表示光源为点光源,_WorldSpaceLightPos0.xyz为此点光源.

材质RGB值和光源RGB值的关系

材质的颜色与光源的颜色有些不同。对于光源,R、G、B值等于R、G、B对其最大强度的百分比。若光源颜色的R、G、B值都是1.0,则是最强的白光;若值变为0.5,颜色仍为白色,但强度为原来的一半,于是表现为灰色;若R=G=1.0,B=0.0,则光源为黄色。对于材质,R、G、B值为材质对光的R、G、B成分的反射率。比如,一种材质的R=1.0,G=0.5,B=0.0,则材质反射全部的红色成分,一半的绿色成分,不反射蓝色成分。也就是说,若OpenGL的光源颜色为(LR,LG,LB),材质颜色为(MR,MG,MB),那么,在忽略所有其他反射效果的情况下,最终到达眼睛的光的颜色为(LR*MR,LG*MG,LB*MB)。同样,如果有两束光,相应的值分别为(R1,G1,B1)和(R2,G2,B2),则OpenGL将各个颜色成分相加,得到(R1 R2,G1 G2,B1 B2),若任一成分的和值大于1(超出了设备所能显示的亮度)则约简到1.0。

 

 

半兰伯特光照模型
半兰伯特光照模型,解了决光照无法到达的区域, 背光面更亮一些
diffuse = kd * lightColor * (N * L *0.5 0.5)
cos的值是-1到1之间,乘上0.5再加0.5后,值域是(0,1)

OpenGL 光照模效果的原理

OpenGL的光照模型是用来模拟现实生活中的光照的。它根据顶点的法线向量光源的位置决定顶点的明暗程度,根据顶点的材质光源中三原色的成分来决定物体将表现出怎样的颜色

环境光(ambient light)

环境光(ambient light)

4.)镜面反射项(specular)

使用OpenGL的光照模型的步骤:

  • 设置光源的种类、位置和方向(对于平行光源)
  1. 为每个图元的每个顶点指定它的法线向量
  2. 为各个图元指定它的材料

步骤1和步骤3上面已经说过了,下面解释一下步骤2。
众所周知,光线是根据物体表面法向来确定其反射方向的,所以想要对开启光照效果就要对物体表面的每个图元指定法向。如果场景中的物体是多边形网格模型,则需要自己计算每个网格的法向量然后再调用glNormal*()为每个网格指定法线向量。当然,如果你用的是类似glutSolidTorus()或者glutSolidSphere()这种GLUT工具包中的函数则不用自己指定图元的法向量。

本文由全球彩票平台发布于全球彩票注册平台编程,转载请注明出处:shader光照和阴影,OpenGL光源光照基础

TAG标签: 全球彩票平台
Ctrl+D 将本页面保存为书签,全面了解最新资讯,方便快捷。