图形学光照与明暗处理_第1页
图形学光照与明暗处理_第2页
图形学光照与明暗处理_第3页
图形学光照与明暗处理_第4页
图形学光照与明暗处理_第5页
已阅读5页,还剩69页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1第八章明暗处理

为了使用几何模型创造逼真的图形场景,我们根据物体的材质属性、光源位置和视点计算物体表面的光照亮度。2内容Phong照明模型点光源线光源反射漫反射镜面反射环境反射Gouraud明暗处理Phong明暗处理阴影3点光源n为表面法向.

n在平面上各点处是相等的s

为光源的方向.

s

根据位置的不同不断改变,例如,

s1

s2.

光源靠近物体表面时,s的改变量变得更大

sns1s2nn4线光源当光源离得较远时,s的变化将变得不明显.当距离变得非常远时,s在一个表面上保持不变

例如太阳.被称为线光源(或平行光源,或分散光源.)ssnn5令Ii

为入射光的强度

,为

s和n

的夹角大小,0o90o.Ii

cos为单位表面区域接收到的光的数量当

=0,入射光垂直于表面。表面接收到的入射光的数量最多例如:

正午的太阳光当=90o时,它接收不到光照。当>90o时,光在表面的另一边,它也接收不到光照。cossncos6漫反射一个完美的粗糙表面几乎可以向所有方向反射光Lambert余弦定律

反射的光的数量为

Id=

RdIi

cosRd,漫反射系数为:

0Rd

1Id

与视点无关

cos为s在n上的投影.

如果s

n

是单位向量, cos=sn

(点乘)snsncosMicroscopicview7衰减

当光远离表面时,光的强度变弱对于一个点光源,衰减系数为,

d

为到点光源的距离.

a,b,

c

为以经验选择的启发式参数

、对于一个定向光源,Af=1(intheory)(inpractice)8漫反射

从一个点光源从一个线光源 Id=

RdIi

cos=

RdIi

(sn)9Purediffusereflectionfromdirectionalsourcepointing(1,1,1)10镜面反射平滑的亮的表面对光的反射.纯镜面反射的例子11镜面反射一个亮的表面以一个标准的方向反射光r

在跨越

n

s的表面上.

它和n的夹角大小与n和s的夹角大小相等

.0o90o.

当从

v方向观察表面上的一个点时,光的反射量为:

Ii,入射光强度

Rs,镜面反射系数,

0Rs

1snrsnrv12

为标准反射线

(r)

和视线

(v)

的夹角在一个亮表面上,当

v

偏离

r

时很少能发现反射光.

当在一个阴暗的表面上,在v处能发现更多的光。

这种现象可用cosk

来建模.k为物体的反光度。k越大,亮度越高。cos=rv光的衰减的建模与漫反射相同。snrv1314镜面反射从点光源从线光源

15找到反射射线

r,根据

n

sr,n和s为归一化向量.red_arrow=(n

•s)nr+s=2red_arrow

r=2(n

•s)ns

rsrsrsn16模拟材质属性为了提高效率,在公式中使用

h

n来近似r

v。h

被称为half-way向量.h=(s+v

)/2snrvh17使用模拟材质属性进行漫反射从一个点光源从一个线光源

h=(s+v

)/218kshalllessthan12819纯镜面反射20环境光的反射(background),Ia由于表面之间的多次反射,环境光(IAm)为均匀亮度. Ia=RaIAmRa,环境光反射系数,

0Ra

1Ia和表面法向及视点无关,和光源的位置(或方向)无关21PureAmbientfloatglobalAmbient[]={0.9,0.9,0.9,1.};glLightModelfv(GL_LIGHT_MODEL_AMBIENT,globalAmbient);22OverallPureDiffusePureAmbientPureSpecular23整体Phong照明模型对点光源的反射对线光源的反射

24ShinyTeapot

为生成彩色图片,分别对红色、绿色和蓝色进行明暗处理运算。GLfloatspecular[]={1.,1.,1.,1.};GLfloatambient[]={.41,.135,.067,1.};GLfloatdiffuse[]={.41,.135,.067,1.};glMaterialf(GL_FRONT,GL_SHININESS,125.);25快速明暗处理(FlatShading),基于多边形

表面的明暗是从表面反射的环境光、漫射光和镜面光的数量。在快速渲染中,只对多边形上的一个点进行一次反射计算。计算的结果将被赋给多边形上的所有像素.表面法向被用于计算整个多边形有同样的明暗值方法是有效率的,但过于粗糙。n26一个Machband

是在两个具有不同明暗值的多边形的邻接边上发现的条纹.Machbands经常发现于阴影上我们的眼睛对离散变化的明暗特别敏感

2728Gouraud明暗处理,基于顶点的

对多边形上的每个顶点进行一次明暗计算。

每个顶点有一个法向,可能是多边形的法向或者周围相邻几个法向的平均。使用这个顶点的法向计算这个顶点处像素的明暗值。n4n3n2n1n0nbncnandn29被这个多边形覆盖的其他像素的明暗值通过插值得到,如同计算颜色的情况。中间点的颜色C,由下式得到:

ABC30确定被多边形覆盖的一个像素点的颜色D的颜色由A和B确定E的颜色由

A和C确定F点的颜色由D和E确定BACDEF一行像素31ConstantShadingGouraudShading323334Phong明暗处理,基于像素不同于Gouraud明暗处理技术的对每个像素处明暗值进行插值计算,Phong提出对多边形上的每个像素的法向进行插值计算。然后计算每个像素处的明暗值。使用Gouraud明暗处理技术,我们常常需要将一个表面分割成小块来得到满意的结果。Phong明暗处理技术减少了过多的分割,但是需要更多的计算。它能产生更高质量的图片但也更慢。BACDEFArowofpixels35插值计算边缘和每一行像素的法向36Phong明暗处理技术示例37OpenGL

中的照明技术Enable/Disablelighting glEnable(GL_LIGHTING); //settingcolorsareignored glDisable(GL_LIGHTING);指定一个阴影模型 Eitherflatshadingorsmooth(Gouraud)shading glShadeModel(GL_FLAT); glShadeModel(GL_SMOOTH);指定每个顶点的法向量.例如,在原点绘制球体时

glNormal3f(x,y,z);glVertex3f(r*x,r*y,r*z);38在另一个法向被指定前,一个法向一直保持有效。//DrawacylinderglBegin(GL_QUAD_STRIP);t=0.;dt=(360./nslice)*3.1416/180.;for(j=0;j<=nslice;++j){

glNormal3f(cos(t),0.,sin(t)); glVertex3f(cos(t),0.,sin(t));

glVertex3f(cos(t),2.,sin(t));t=t+dt;}glEnd();zyx39voidtriangle(floatv[][3],inta,intb,intc){glBegin(GL_TRIANGLES); glVertex3fv(v[a]); glVertex3fv(v[b]); glVertex3fv(v[c]);glEnd();}

voidtetrahedron(){floatv[][3]={{-1.,-1.,-1.},{1.,-1.,1.},{-1.,1.,1.},{1.,1.,-1.}};

glNormal3f(-1.,-1.,1.);triangle(v,0,1,2);glNormal3f(1.,1.,1.);triangle(v,1,3,2);

glNormal3f(-1.,1.,-1.);triangle(v,0,2,3);

glNormal3f(1.,-1.,-1.);triangle(v,0,3,1);}(1,-1,1)

(-1,1,1)

(1,1,-1)xzy1320(-1,-1,-1)

40为了避免需要提供单位法向的困扰,你可以通过在

init()

中增加以下语句来让系统为你归一化所有向量

glEnable(GL_NORMALIZE);为一个光源指定颜色元素(r,g,b,a) GLfloatambient0[]={0.1,0.1,0.1,1.}; //GreyGLfloatdiffuse0[]={1.,1.,1.,1.}; //WhiteGLfloatspecular0[]={1.,1.,1.,1.}; //White

glLightfv(GL_LIGHT0,GL_AMBIENT,ambient0);glLightfv(GL_LIGHT0,GL_DIFFUSE,diffuse0);glLightfv(GL_LIGHT0,GL_SPECULAR,specular0);41实际生活中,一个光源的漫反射和镜面反射经常是相同的。

环境光依赖于环境。如果环境中有很多红色物体,环境光则微微倾向于红色。 GLfloata[]={0.1,0.,0.,1.}; //VerypaleredGLfloatd[]={1.,1.,0.,1.}; //YellowGLfloats[]={1.,1.,0.,1.}; //Yellow

glLightfv(GL_LIGHT0,GL_AMBIENT,a);glLightfv(GL_LIGHT0,GL_DIFFUSE,d);glLightfv(GL_LIGHT0,GL_SPECULAR,s);42OpenGL

已经可以调用下面语句将它转化为(r,g,b),作为全局环境光. floatglobalAmbient[]={r,g,b,1.};glLightModelfv(GL_LIGHT_MODEL_AMBIENT,globalAmbient);指定一个点光源的位置 GLfloatlight_position[]={2.,4.,6.,1.}; glLightfv(GL_LIGHT0,GL_POSITION,light_position);指定线光源的方向。

GLfloatlight_position[]={1.,1.,1.,0.}; glLightfv(GL_LIGHT1,GL_POSITION,light_position);s

为从物体指向光源的方向。它和光线方向相反。sn(x,y,z)43可以定义8个光源 GL_LIGHT0,GL_LIGHT1,…,GL_LIGHT7打开或关闭一个特定的光源

(在绘制之前或之后) glEnable(GL_LIGHT0); glDisable(GL_LIGHT0);默认模式下,OpenGL

假设观察者在无穷远处,这样视角为一个常数。

当观察者实际离得很近时,这种近似会导致严重的错误。 ToaskOpenGLtousethetrueviewingangleinthecalculationofspecularreflection. glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER,GL_TRUE);44网格大小的影响(Important)

下面,一个发光的白墙被分成不同的大小并用一个白色的线光源来渲染

GLfloatambient0[]={0.,0.,0.,1.}; GLfloatdiffuse0[]={.7,.7,.7,1.};GLfloatspecular0[]={1.,1.,1.,1.}; position[]={0.,0.,1.,0.};//光源方向

//视点位置(0,0,8)20×2010×104×42×21×1FastSlow45线光源和点光源在一个白色发光物体上的比较.视点位置在(0,0,8)Pointsourceat(0,0,8)Dir.sourceat(0,0,1)46对于一个点光源,我们可以指定一个常数为衰减系数 glLightf(GL_LIGHT1,GL_CONSTANT_ATTENUATION,.0);glLightf(GL_LIGHT1,GL_LINEAR_ATTENUATION,.5);glLightf(GL_LIGHT1,GL_QUADRATIC_ATTENUATION,0.);默认值为

a=1,b=0,c=0(没有衰减)对于更高的衰减,则为b和

c设定一个更高的系数,e.g.,1,1.5,2or3.47定义一个聚光灯(一个特殊的点光源)

的颜色值,位置,衰减常数的指定方式和普通点光源相同。另外,我们可以指定聚光灯的方向和遮光角度4850403020 GLfloatlight_direction[]={0,0,-1};//Fromthelight glLightfv(GL_LIGHT2,GL_SPOT_DIRECTION,light_direction);

glLightf(GL_LIGHT2,GL_SPOT_CUTOFF,20.);截止角在白墙上的影响。49e=0e=10e=100也可以设置GL_SPOT_EXPONENT默认值为0表示光强度从中心到边缘均匀分布一个更高的衰减范围导致中心强度更强。

glLightf(GL_LIGHT2,GL_SPOT_EXPONENT,10.);50指定一个亮红色物体的反射比GLfloatdiffuse[]={.41,.135,.067,1.};GLfloatspecular[]={1.,1.,1.,1.};glMaterialfv(GL_FRONT,GL_AMBIENT,diffuse);glMaterialfv(GL_FRONT,GL_DIFFUSE,diffuse);glMaterialfv(GL_FRONT,GL_SPECULAR,specular);glMaterialf(GL_FRONT,GL_SHININESS,125.);白色光源的方向为(1,1,1)51材质的反射镜面反射的红色、绿色和蓝色分量一般是相同的,因此光源的原始颜色将被反射。(在上一副关于茶壶的图片中最亮的部分为白色,和光源的颜色一样。)对于高度反光的材质,镜面反射率接近于1并且亮度可高达100甚至更高.暗表面的镜面反射率和亮度接近于0。一个材质属性,例如,反射比,在下一个值被指定之前保持有效。52材质的颜色主要取决于漫反射率。漫反射提供很多曲率和物体深度的信息。镜面反射产生的亮点为光源的模糊图像。53OverallPureDiffusePureAmbientPureSpecular54

GLfloatambient[]={.6,.59,.42,1.};GLfloatdiffuse[]={.5,.5,.35,1.};GLfloatspecular[]={.1,.1,.07,1.};glMaterialfv(GL_FRONT,GL_AMBIENT,ambient);glMaterialfv(GL_FRONT,GL_DIFFUSE,diffuse);glMaterialfv(GL_FRONT,GL_SPECULAR,specular);glMaterialf(GL_FRONT,GL_SHININESS,1.);光源为位于(1,1,1)处的白色线光源5556发光为让一个材料看起来发光,例如,下一页中的月亮. GLfloatemission[]={r,g,b,a};glMaterialfv(GL_FRONT,GL_EMISSION,emission);关闭emission:将r-,g-,b-部件设定为0值.注意一个发光物体不是一个光源.发光只是材质的一个属性GLfloatemission[]={1.,1.,.75,1.};glMaterialfv(GL_FRONT,GL_EMISSION,emission);draw_moon();GLfloatno_em[]={0.,0.,0.,1.};glMaterialfv(GL_FRONT,GL_EMISSION,no_em);57使用5种材质渲染的一副图片,两个纹理,16个点光源.月亮是一个发光物体。5859Transparent透明物体60透明物体1.定义混合函数,并打开混合glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);glEnable(GL_BLEND);2.定义材质的不透明度小于1.3.在绘制透明物体之前先绘制背景物体.正面和背面都使用填充多边形绘制。voidtransMaterial1(){GLfloata[]={.7,1.,.85,.3};GLfloats[]={1.,1.,1.,1.};glMaterialfv(GL_FRONT,GL_AMBIENT,a);glMaterialfv(GL_FRONT,GL_DIFFUSE,a);glMaterialfv(GL_FRONT,GL_SPECULAR,s);glMaterialf(GL_FRONT,GL_SHININESS,100.);}***616263所有的

OpenGL

参数,包括光照,都有默认值.在指定一个新的参数值之前,这个参数值一直保持有效。默认GL_LIGHT0

发出白光并且位于视点处。确切的光照明效果是很难预测的。

在调节光照参数时实验和经验都很重要。在一个PC机上

OpenGL

提供的照明效果是有限的。

64ShadowsShadow65ShadowBShadowsfromadirectionallightsource使用

i,j,k,l,pand;来移动茶壶.使用

arrowsandPgUp

PgDnkeys来移动光源.66光的方向为(dx,dy,dz).(x,y,z)在平面上的阴影位于(x’,y’,z’).我们有

x’=x+dx,y’=y+dy,

z’=z+dz.另外,a(x+dx)

+b

(y+dy)+c

(z+dz)+d=0.=(ax+by+cz+d)/(adx+bdy+cdz)(x,y,z)(x’,y’,z’)ax+by+cz+d=0(dx,dy,dz)67=(ax+by+cz+d)/(adx+bdy+cdz)68//设定矩阵M使得它将一个顶点投影到平面上//ax+by+cz+d=0.//光线的方向为(dx,dy,dz).voiddirectionalLightShadow(doubledx,doubledy,doubledz,doublea,doubleb,doublec,doubled,GLfloatM[16]){M[0]=b*dy+c*dz;M[4]=-b*dx;M[8]=-c*dx;M[12]=-d*dx;M[1]=-a*dy;M[5]=a*dx+c*dz;M[9]=-c*dy;M[13]=-d*dy;M[2]=-a*dz;M[6]=-b*dz;M[10]=a*dx+b*dy;M[14]=-d*dz;M[3]=0;M[7]=0;M[11]=0;M[15]=a*dx+b*dy+c*dz;}69GLfloatM[16];doubledx=…,dy=…,dz=…;glDisable(GL_LIGHTING);glColor4f(0.,0.,0.,1.);glPushMatrix();

directionalLightShadow(dx,dy,dz,0,0,1,5,M); glMultMatrixf(M);drawTeapot();glPopMatrix();在平面

z+5=0上绘制茶壶的阴影光线的方向为(dx,dy,dz)ShadowB70ShadowA从一个点光源得到的阴影71假设点光源位于原点.顶点(x,y,z)的在平面上的阴影为(x’,y’,z’).因此我们有x’=x,y’=y,

z’=z.另外,a(x)+b

(y)+c

(z)+d=0.=d/(ax+by+cz)x’=dx/(ax+by+cz)(x,y,z)(x’,y’,z’)(0,0,0)ax+by+cz+d=072如果光源位于(lx,ly,lz)而不是在原点,首先将光源移到原点(x,y,z)(x’,y’,z’)ax+by+cz+d=0(lx,ly,lz)(x,y,z)(x’,y’,z’)ax+by+cz+new_d=0(0,0,0)x=x–lxy=y–

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论