版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第11章
真实感图形的绘制1本章目标掌握真实感图形绘制的主要内容光照、纹理、阴影等重点掌握光照方程、基本纹理映射及多边形绘制学会使用OpenGL的相关函数2第11章真实感图形的绘制简单光照模型多边形绘制方法纹理映射阴影311.1简单光照模型11.1.1环境光(Ambientlight)在物体和周围环境之间多次反射后,最终达到平衡时的一种光,又称为背景光光强(度):空间上分布均匀,即任何位置和方向光强度一样,亮度值记为Ia反射系数:与物体表面性质有关,决定物体表面呈现的亮度,记为Ka光照模型方程
Ie=
KaIa
Ie为物体表面呈现的亮度
Ka
=0.4Ka
=0.8511.1简单光照模型11.1.2漫反射(DiffuseReflection)点光源:向周围所有方向发射等强度的光漫反射光是由物体表面的粗糙不平引起的,它均匀地向各个方向传播,与视点无关漫反射光在空间均匀分布,反射光强I与入射光的入射角θ的余弦成正比,即:
其中,Kd是漫反射系数(0~1之间的常数),与物体表面性质有关;Ip是入射光(光源)的光强;θ是入射光的入射角,即入射光与物体表面法向量之间的夹角611.1简单光照模型向量表示的计算设物体表面在照射点P处的单位法向量为N,P到点光源的单位向量为L,则上式可表达为如下的向量形式:如果有多个光源,则可以把各个光源的漫反射光照效果进行叠加:711.1简单光照模型11.1.3镜面反射光和冯(Phong)反射模型高光(highlight):光滑物体表面在点光源的照射下形成一块特别亮的区域镜面反射(SpecularReflection)物体表面对入射光的反射遵循反射定律(1)反射光与入射光位于表面法向两侧(2)理想反射面而言:入射角=反射角观察者在反射方向上看到反射光最强911.1简单光照模型Phong模型(非理想反射面)计算公式:Ks是物体表面镜面反射系数,它与入射角和波长有关;α是视线与反射方向的夹角;
n为镜面高光系数,用来模拟镜面反射光在空间中的汇聚程度,它是一个反映物体表面光泽度的常数;近似地描述了镜面反射光的空间分布。1011.1简单光照模型简化Phong模型SSHβL,N,R都是单位向量1111.1简单光照模型局部光照方程结合环境光、漫反射光及镜面反射光当光源与视点无穷远时,对表面上任意一点而言,L和V固定不变,H只需计算一次Hβ1311.1简单光照模型11.1.4光的衰减光在传播过程中,能量会衰减传播过程光源到物体表面的传播,使入射光强度变弱物体表面到人眼的传播,使人接受到物体表面的反射光强度减弱光到物体表面的衰减考虑衰减的方程1411.1简单光照模型物体表面到人眼过程中的衰减深度暗示技术(DepthCueing)使据视点远的点比近的点暗一些亮度计算前参考面n=Nf;后参考面n=Nb(规范化视见体内)分别赋比例因子Sf和Sb(Sf>Sb)给点物体上的一点的深度N0,比例因子S01511.1简单光照模型13.1.5产生颜色前面的光照模型仅用于白光,只能产生灰度彩色模型计算选择合适模型(如RGB、HSV等)为颜色的三个分量分别建立光照方程RGB模型光源的颜色[IpR,IpG,IpB],环境光的颜色[IaR,IaG,IaB]表面反射系数(1)环境反射:[KaR,KaG,KaB](2)漫反射:[KdR,KdG,KdB](3)镜面反射:[KsR,KsG,KsB]1711.1简单光照模型彩色光照方程(模型)1811.1简单光照模型11.1.6多个光源如果场景中有m个光源,那么物体上任一点的亮度应该为m个光源的贡献之和在RGB彩色模型中,λ分别为R、G和B。
注意:Iλ可能会超出系统允许的最大亮度值,处理方法(1)截去超出部分,设置为最大值(2)首先计算出所有亮度值,再进行变换(如缩放变换)使其落在系统规定范围之内1911.1简单光照模型 函数glLight*()参数pname及param说明
2111.1简单光照模型(3)启动光照在OpenGL中,必须明确指出光照是否有效或无效。如果光照无效,则只是简单地将当前颜色映射到当前顶点上去,不进行法向、光源等复杂计算,那么显示的图形就没有真实感要使光照有效,首先得启动光照,即:
glEnable(GL_LIGHTING);若使光照无效,则调用gDisable(GL_LIGHTING)可关闭当前光照。然后,必须使所定义的每个光源有效。glEnable(GL_LIGHT0);其它光源类似,只是光源号不同而已2211.1简单光照模型(4)例:简单光照#include<gl/glut.h>#include<GL/glaux.h>#pragmacomment(lib,"glaux.lib")
voidmyinit(void){GLfloatlight_position[]={1.0,1.0,1.0,0.1};GLfloatlight_color[]={1.0,0.0,0.0,1.0};glLightfv(GL_LIGHT0,GL_POSITION,light_position);glLightfv(GL_LIGHT0,GL_AMBIENT,light_color);glLightfv(GL_LIGHT0,GL_DIFFUSE,light_color);glLightfv(GL_LIGHT0,GL_SPECULAR,light_color);glEnable(GL_LIGHTING);glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);}
voiddisplay(void){glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT);auxSolidSphere(1.0);//绘制球体glFlush();}2311.1简单光照模型voidmain(void){ glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB); glutInitWindowSize(250,250); glutInitWindowPosition(300,300); glutCreateWindow("SimpleLighting"); myinit(); glutReshapeFunc(myReshape); glutDisplayFunc(display); glutMainLoop();}2511.1简单光照模型(5)聚光定位光源可以定义成聚光灯形式,即将光的形状限制在一个圆锥内。一、定义聚光源位置。因为聚光源也是定向光源,所以他的位置同一般定向光一样。如:
GLfloatlight_position[]={1.0,1.0,1.0,1.0};glLightfv(GL_LIGHT0,LIGHT_POSITION,light_position);2611.1简单光照模型(6)例:多光源#include<GL/glut.h>#include<GL/glaux.h>#pragmacomment(lib,"glaux.lib")/*初始化光源、材质等*/voidmyinit(void){GLfloatmat_ambient[]={0.2,0.2,0.2,1.0};GLfloatmat_diffuse[]={0.8,0.8,0.8,1.0};GLfloatmat_specular[]={1.0,1.0,1.0,1.0};GLfloatmat_shininess[]={50.0};GLfloatlight0_diffuse[]={0.0,0.0,1.0,1.0};GLfloatlight0_position[]={1.0,1.0,1.0,0.0};GLfloatlight1_ambient[]={0.2,0.2,0.2,1.0};GLfloatlight1_diffuse[]={1.0,0.0,0.0,1.0};GLfloatlight1_specular[]={1.0,0.6,0.6,1.0};GLfloatlight1_position[]={-3.0,-3.0,3.0,1.0};GLfloatspot_direction[]={1.0,1.0,-1.0};glMaterialfv(GL_FRONT,GL_AMBIENT,mat_ambient);glMaterialfv(GL_FRONT,GL_DIFFUSE,mat_diffuse);glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular);glMaterialfv(GL_FRONT,GL_SHININESS,mat_shininess);//转下页2911.1简单光照模型
//接上页glLightfv(GL_LIGHT0,GL_DIFFUSE,light0_diffuse);glLightfv(GL_LIGHT0,GL_POSITION,light0_position);glLightfv(GL_LIGHT1,GL_AMBIENT,light1_ambient);glLightfv(GL_LIGHT1,GL_DIFFUSE,light1_diffuse);glLightfv(GL_LIGHT1,GL_SPECULAR,light1_specular);glLightfv(GL_LIGHT1,GL_POSITION,light1_position);glLightf(GL_LIGHT1,GL_SPOT_CUTOFF,30.0);glLightfv(GL_LIGHT1,GL_SPOT_DIRECTION,spot_direction);glEnable(GL_LIGHTING);glEnable(GL_LIGHT0);glEnable(GL_LIGHT1);glDepthFunc(GL_LESS);glEnable(GL_DEPTH_TEST);}3011.1简单光照模型voiddisplay(void){glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glPushMatrix();glTranslated(-3.0,-3.0,3.0);//光源1位置
glDisable(GL_LIGHTING);glColor3f(1.0,0.0,0.0);auxWireCube(0.1);//绘制光源1glEnable(GL_LIGHTING); glPopMatrix();auxSolidSphere(2.0); glFlush();}3111.1简单光照模型voidmyReshape(GLsizeiw,GLsizeih){glViewport(0,0,w,h);glMatrixMode(GL_PROJECTION);glLoadIdentity();if(w<=h) glOrtho(-5.5,5.5,-5.5*(GLfloat)h/(GLfloat)w, 5.5*(GLfloat)h/(GLfloat)w,-10.0,10.0);else glOrtho(-5.5*(GLfloat)w/(GLfloat)h,5.5*(GLfloat)w/(GLfloat)h,-5.5,5.5,-10.0,10.0);glMatrixMode(GL_MODELVIEW);glLoadIdentity();}voidmain(void){glutInitDisplayMode(GLUT_SINGLE GLUT_RGBA);glutInitWindowSize(250,250);glutInitWindowPosition(300,300);glutCreateWindow("Multi_lights");myinit();glutReshapeFunc(myReshape);glutDisplayFunc(display);glutMainLoop();}32第11章真实感图形的绘制简单光照模型多边形绘制方法纹理映射阴影3311.2多边形绘制方法11.2.1均匀着色(FlatShading)方法任取多边形上一点,利用光照明方程计算出它的颜色用这个颜色填充整个多边形适合于如下情况光源在无穷远处,L·N相等视点在无穷远处,H·N相等多边形是物体表面的精确表示特点优点:每个多边形只需计算一次光照明方程,速度快缺点:相邻多边形颜色过渡不光滑3411.2多边形绘制方法11.2.2光滑着色(SmoothShading)采用插值方法Gouraud(高洛德)方法用多边形顶点的颜色进行插值生成中间点的颜色Phone(冯)方法对顶点的法向量进行插值计算出中间点的法向量3511.2多边形绘制方法11.2.3Gouraud着色方法(颜色插值方法)主要步骤1、计算多边形的单位法向量2、计算多边形顶点的单位法向量(共享顶点的多边形法向量的平均值)3、利用光照明方程计算顶点颜色4、对多边形顶点颜色进行双线性插值,获得多边形内部各点的颜色3611.2多边形绘制方法(1)计算多边形顶点的单位法向量
近似取顶点v的法向量为共享该顶点的多边形单位法向量的平均值3711.2多边形绘制方法(2)内部点颜色计算:双线性插值
已知P1(x1,y1)、P2(x2,y2)、P3(x3,y3),颜色分别为I1、I2和I3。A(xA,yA)和B(xB,yB)为交点,P(x,y)为AB上一点,计算P点的颜色3811.2多边形绘制方法增量法优化计算IA,IB,IP(1)扫描线y递增为y+1,IA和IB的增量分别为ΔIA和ΔIB(2)当x递增一个单位(P点沿扫描线右移一个单位)时,IP的增量为ΔIP3911.2多边形绘制方法11.2.3Phong着色方法(法向插值着色方法)方法:通过对多边形顶点法向量进行插值,获得多边形内 部各点的法向量,再利用光照方程计算各点的亮度主要步骤:1、计算多边形单位法向量2、计算多边形顶点单位法向量(以上两步同Gouraud着色方法)3、对多边形顶点法向量进行双线性插值,获得内部各点的法向量4、利用光照明方程计算多边形内部各点颜色4011.2多边形绘制方法法向量双线性插值4111.2多边形绘制方法法向量双线性插值计算优化(1)扫描线y递增为y+1,NA和NB的增量分别为ΔNA和ΔNB(2)当x递增一个单位(P点沿扫描线右移一个单位)时,NP的增量为ΔNP42第11章真实感图形的绘制简单光照模型多边形绘制方法纹理映射阴影4311.3纹理映射背景光照模型只能生成光滑的物体表面自然界中的物体表面具有丰富的细节,如木纹、桔子凹凸表面、沙砾路面丰富的表面细节难以用计算机图形方法生成采用将图片贴到物体表面上的方法绘制樱桃木桔子凹凸面沙砾路面4411.3纹理映射纹理(Texture)纹理是物体表面的细小结构,它可以是光滑表面的花纹、图案,即颜色纹理(2D)纹理也可以是物体表面的三维结构纹理还可以是粗糙的表面(如桔子表面的皱纹),称为几何纹理,是基于物体表面的微观几何形状的表面纹理4511.3纹理映射纹理(续)纹理空间:纹理图案所在空间,记为st坐标系(一般是平面)纹素(texel):纹理最小单元,位置由纹理坐标(s,t)标识两种来源数字图像,用二维数组表示数学公式定义得纹理函数4611.3纹理映射纹理映射(TextureMapping)将一块纹理图案映射到物体表面上,产生物体表面的细节颜色计算方法用表面上点对应的纹素值代替该点的漫反射系数纹理与物体表面的对应关系纹理坐标:s,t变化范围[0,1]PT4711.3纹理映射实例:圆柱面映射圆柱面上的点对应的纹理坐标styxzrh4811.3纹理映射实例:球面映射
θ和ψ变化范围分别[0,360]和[-90,90](1)(2)球面垂直向外映射到柱面上,再将柱面展开到矩形上4911.3纹理映射实例:圆环面映射R是环的主半径,r是次半径;θ和ψ变化范围[0,360]Rr对应的纹理坐标5011.3纹理映射OpenGL函数纹理映射是一个相当复杂的过程,最基本的执行纹理映射所需的步骤。基本步骤如下:一、定义纹理;二、控制滤波;三、说明映射方式;四、激活纹理;五、绘制图形,即给出顶点的纹理坐标和几何坐标。
注意:纹理映射只能在RGBA方式下执行,不能运用于颜色表方式。
5111.3纹理映射一、定义纹理二维纹理定义的函数:voidglTexImage2D(GLenumtarget,GLintlevel,Glintcomponents,GLsizeiwidth,glsizeiheight,GLintborder,GLenumformat,GLenumtype,constGLvoid*pixels);target是常数GL_TEXTURE_2D; level表示多级分辨率的纹理图像的级数,若只有一种分辨率,则level设为0;components是一个从1到4的整数,指出选择了R、G、B、A中的哪些分量用于调整和混合,1表示选择了R分量,2表示选择了R和A两个分量,3表示选择了R、G、B三个分量,4表示选择了R、G、B、A四个分量;
5211.3纹理映射width和height给出了纹理图像的长度和宽度;border为纹理边界宽度,它通常为0,width和height必须是2m+2b,这里m是整数,长和宽可以有不同的值,b是border的值。纹理映射的最大尺寸依赖于OpenGL,但它至少必须是使用64x64(若带边界为66x66),若width和height设置为0,则纹理映射有效地关闭;参数format和type描述了纹理映射的格式和数据类型,参数format可以是GL_RGB、GL_RGBA、GL_RED、GL_GREEN、GL_BLUE、GL_ALPHA、GL_LUMINANCE或GL_LUMINANCE_ALPHA;参数type是GL_BYPE、GL_UNSIGNED_BYTE、GL_SHORT、GL_UNSIGNED_SHORT、GL_INT、GL_UNSIGNED_INT、GL_FLOAT或GL_BITMAP;参数pixels包含了纹理图像数据,这个数据描述了纹理图像本身和它的边界。5311.3纹理映射二、控制滤波;voidglTexParameter{if}[v](GLenumtarget,GLenumpname, TYPEparam);参数target可以是GL_TEXTURE_1D或GL_TEXTURE_2DPname和paramPnameparamGL_TEXTURE_WRAP_SGL_CLAM或GL_REPEATGL_TEXTURE_WRAP_TGL_CLAM或GL_REPEATGL_TEXTURE_MAG_FILTERGL_NEAREST或GL_LINEARGL_TEXTURE_MIN_FILTERGL_NEAREST或GL_LINEAR…..5411.3纹理映射三、设置纹理映射方式可以用纹理中的值来取代多边形(曲面)原来的颜色,或用纹理图像中的颜色与多边形(曲面)原来的颜色进行混合。voidglTexEnv{if}[v](GLenumtarget,GLenumpname, TYPEparam);参数target必须是GL_TEXTURE_ENV;若参数pname是GL_TEXTURE_ENV_MODE,则参数param可以是GL_DECAL、GL_MODULATE或GL_BLEND,以说明纹理值怎样与原来表面颜色的处理方式;若参数pname是GL_TEXTURE_ENV_COLOR,则参数param是包含四个浮点数(分别是R、G、B、a分量)的数组,这些值只在采用GL_BLEND纹理函数时才有用。5511.3纹理映射四、激活纹理;
glEnable(GL_TEXTURE_2D);五、定义纹理坐标在绘制纹理映射图形时,不仅要给每个顶点定义几何坐标,而且也要定义纹理坐标。voidglTexCoord{1234}{sifd}[v](TYPEcoords);设置当前纹理坐标,此后调用glVertex*()所产生的顶点都赋予当前的纹理坐标。5611.3纹理映射例:简单纹理映射#include<GL/glut.h>#include<math.h>#definenRows128#definenCols128GLubyteImage[3*nRows*nCols];//生成黑白棋盘格图像数据voidmakeCheckerboard(void){longcount=0;for(inti=0;i<nRows;i++)for(intj=0;j<nCols;j++){GLubytec=(((i/8)+(j/8))%2)*255; Image[count++]=c;Image[count++]=c; Image[count++]=c;}}5711.3纹理映射//纹理初始化voidmyinit(void){glClearColor(0.0,0.0,0.0,0.0);makeCheckerboard();glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_DECAL);glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);//GL_REPEATglTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);//GL_CLAMPglTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,nRows,nCols,0,GL_RGB,GL_UNSIGNED_BYTE,Image);glEnable(GL_DEPTH_TEST);glDepthFunc(GL_LESS);glEnable(GL_TEXTURE_2D);}5811.3纹理映射//绘制图形voiddrawRect()//正方形{ glBegin(GL_POLYGON); glTexCoord2f(1,0); glVertex3f(-2,2,0); glTexCoord2f(1,1); glVertex3f(2,2,0); glTexCoord2f(0,1); glVertex3f(2,-2,0); glTexCoord2f(0,0); glVertex3f(-2,-2,0); glEnd();}5911.3纹理映射#definenH30#definenC30voiddrawClinder(floatr,floath)//绘制圆柱面{floatdh=(float)h/nH;floatdc=2*3.14/nC;floatx[nC+1],z[nC+1],y1,y2;floats[nC+1],t1,t2;for(intj=0;j<=nC;j++){x[j]=r*sin(j*dc);z[j]=r*cos(j*dc);s[j]=j*dc/3.14/2;}for(inti=0;i<=nH;i++){if(i!=0){y1=y2;t1=t2;}y2=i*dh-0.5*h; t2=(y1+0.5*h)/h;if(i==0)continue;for(j=0;j<nC;j++){glBegin(GL_POLYGON); glTexCoord2f(s[j],t1);glVertex3f(x[j],y1,z[j]); glTexCoord2f(s[j+1],t1);glVertex3f(x[j+1],y1,z[j+1]); glTexCoord2f(s[j+1],t2);glVertex3f(x[j+1],y2,z[j+1]); glTexCoord2f(s[j],t2);glVertex3f(x[j],y2,z[j]);glEnd();}}}6011.3纹理映射voiddrawTorus(floatr,floatR)//绘制圆环{floatdh=6.28/nH;floatdc=6.28/nC;floats;for(inti=0;i<nC;i++){for(intj=0;j<nH;j++){glBegin(GL_POLYGON); s=i*dc/6.28;floatsx=r*cos(j*dh); floatsx1=r*cos(j*dh+dh); glTexCoord2f(s,j*dh/6.28);glVertex3f((R+sx)*sin(i*dc),r*sin(j*dh),(R+sx)*cos(i*dc)); glTexCoord2f(s,(j+1)*dh/6.28);glVertex3f((R+sx1)*sin(i*dc),r*sin(j*dh+dh),(R+sx1)*cos(i*dc)); s=(i+1)*dh/3.14/2;glTexCoord2f(s,(j*dh+dh)/6.28); glVertex3f((R+sx1)*sin((i+1)*dc),r*sin(j*dh+dh),(R+sx1)*cos((i+1)*dc)); glTexCoord2f(s,(j*dh)/6.28); glVertex3f((R+sx)*sin((i+1)*dc),r*sin(j*dh),(R+sx)*cos((i+1)*dc)); glEnd();} }}6111.3纹理映射voiddisplay(void){glClear(GL_COLOR_BUFFER_BIT|GL_DEP
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 二零二五年度医疗设备研发与应用合同3篇
- 二零二五版私募股权投资基金股权收购合同2篇
- 二零二五版企业股权激励项目执行与改进合同2篇
- 二零二五年度房产投资分期付款合同模板3篇
- 二零二五年蔬菜种子进口合同2篇
- 二零二五年度酒楼市场拓展与股权激励方案合同2篇
- 二零二五年模具生产项目质量保证合同3篇
- 二零二五版智能家居货款担保合同范本3篇
- 二零二五年船舶抵押借款合同范本修订版3篇
- 二零二五年户外活动用安全护栏租赁合同3篇
- 2024至2030年中国柔性电路板(FPC)行业市场深度分析及发展趋势预测报告
- IGCSE考试练习册附答案
- 小学三年级下一字多义(答案)
- Unit 6 同步练习人教版2024七年级英语上册
- 农耕研学活动方案种小麦
- 九三学社申请入社人员简历表
- 非诺贝特酸胆碱缓释胶囊-临床用药解读
- 设备管理:设备管理的维护与保养
- 2024年佛山市劳动合同条例
- 土特产行业现状分析
- 苏教版五年级上册数学简便计算大全500题及答案
评论
0/150
提交评论