《《光线跟踪算法》PPT课件.ppt》由会员分享,可在线阅读,更多相关《《光线跟踪算法》PPT课件.ppt(38页珍藏版)》请在三一办公上搜索。
1、光线跟踪算法,主要内容:一、实验设计二、静止多光源实现三、材料属性对光照效果的影响四、移动光源的实现,实验设计,问题一、影响光照效果的因素?问题二、OPENGL光线跟踪函数的函数?问题三、光线跟踪实现的基本步骤?,一、OPENGL中影响光照效果的因素?,1、光源光的种类:环境光:light_ambient 散射光:light_diffuse 镜面光:light_specular光源的分类:方向性光源:无限远,所有光线是平行的位置性光源:位置决定场景中的效果区别:GLfloat light_position 中的第四个参数,2、材料属性材料的环境颜色:GL_AMBIENT材料的散射颜色:GL_D
2、IFFUSE材料的镜面颜色:GL_SPECULAR 材料的镜面指数:GL_SHININESS材料的发射颜色:GL_EMISSION,问题二、OPENGL光线跟踪函数的函数?,光源:void glLightif(GLenum light,GLenum pname,TYPEparam);void glLightifv(GLenum light,GLenum pname,TYPE*param);Light:指定光源 pname:光源属性 param:属性值材料属性:void glMaterialif(GLenum face,GLenum pname,TYPEparam);void glMateria
3、lifv(GLenum face,GLenum pname,TYPE*param);Face:那个面受光照 pname:光源属性 param:属性值,问题三、光线跟踪实现的基本步骤?,一、创建光源二、选择光照模型三、定义材料属性有了这些知识,我们就可以进行第一个简单的多光源实验。,静止多光源实现,自己的工作:按照光线跟踪实现的步骤进行。设置光源参数,衰减因子,聚光灯参数,材料属性参数,调用glLightfv,glMaterialfv,glEnable等函数进行设置。已有的:实现静态光源显示void reshape(int w,int h)void display(void),创建光源1、设置光
4、源参数方向性光源,环境光颜色为蓝色GLfloat light_ambient=0.0,0.0,1.0,1.0;GLfloat light_diffuse=1.0,1.0,1.0,1.0;GLfloat light_specular=1.0,1.0,1.0,1.0;GLfloat light_position=1.0,1.0,1.0,0.0;位置性光源,环境光和散射光颜色为红色GLfloat light1_ambient=1.0,0.0,0.0,1.0;GLfloat light1_diffuse=1.0,0.0,0.0,1.0;GLfloat light1_specular=1.0,1.0,1
5、.0,1.0;GLfloat light1_position=0.0,2.0,2.0,1.0;,2、衰减因子定义衰减因子目的:增强真实效果glLightf(GL_LIGHT0,GL_CONSTANT_ATTENUATION,2.0);glLightf(GL_LIGHT0,GL_LINEAR_ATTENUATION,1.0);glLightf(GL_LIGHT0,GL_QUADRATIC_ATTENUATION,0.5);glLightf(GL_LIGHT1,GL_CONSTANT_ATTENUATION,1.5);glLightf(GL_LIGHT1,GL_LINEAR_ATTENUATION
6、,0.5);glLightf(GL_LIGHT1,GL_QUADRATIC_ATTENUATION,0.2);三个参数的默认值为1,0,0,3,聚光灯参数光源LIGHT1GLfloat spot_direction=1.0,-1.0,-1.0;glLightfv(GL_LIGHT1,GL_SPOT_DIRECTION,spot_direction);glLightf(GL_LIGHT1,GL_SPOT_CUTOFF,45.0);/默认值180glLightf(GL_LIGHT1,GL_SPOT_EXPONENT,5.0);/用于控制光的集中度,越高强度越集中,4,glLightfv的调用 gl
7、Lightfv(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);glLightfv(GL_LIGHT1,GL_AMBIENT,light1_ambient);glLightfv(GL_LIGHT1,GL_DIFFUSE,light1_diffuse);glLightfv(GL_LIGHT1,
8、GL_SPECULAR,light1_specular);glLightfv(GL_LIGHT1,GL_POSITION,light1_position);,5,glEnable的调用作用:启用光源 glEnable(GL_LIGHTING);glEnable(GL_LIGHT0);glEnable(GL_LIGHT1);,6,光源保持静止,void reshape(int w,int h)glViewport(0,0,(GLsizei)w,(GLsizei)h);glMatrixMode(GL_PROJECTION);glLoadIdentity();if(w=h)glOrtho(-1.5,
9、1.5,1.5*(GLfloat)h/(GLfloat)w,1.5*(GLfloat)h/(GLfloat)w,-10.0,10.0);else glOrtho(-1.5*(GLfloat)w/(GLfloat)h,1.5*(GLfloat)w/(GLfloat)h,-1.5,1.5,-10.0,10.0);glMatrixMode(GL_MODELVIEW);glLoadIdentity();首先确定视口和投影矩阵,接着在模型视图矩阵中加载单位矩阵,然后再设置光源。由于使用单位阵,乘模型视图矩阵之后原来制定的光源位置并没有发生变化。,选择光照模型,静态多光源实现过程中使用默认设置:即观察者位
10、于无穷远且只有一面接受光照 glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular);glMaterialfv(GL_FRONT,GL_SHININESS,mat_shininess);glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER,GL_FALSE);,定义材料属性,材料属性值设置GLfloat mat_specular=1.0,1.0,1.0,1.0;GLfloat mat_shininess=50.0;glMaterialfv的调用glMaterialfv(GL_FRONT,GL_SPECULAR,mat_spec
11、ular);glMaterialfv(GL_FRONT,GL_SHININESS,mat_shininess);,display()函数void display(void)glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);/清空缓冲区 glutSolidSphere(1.0,20,16);/画圆,半径为1.0 glFlush();/保证绘图命令被实际执行,效果展示,屏蔽位置性光源只有方向性光源,屏蔽方向性光源只有位置性光源,静止多光源,材料属性对光照效果的影响,遇到的问题:如何将不同的材料属性赋予不同的球体?,如何将不同的材料属性赋予不同的球体?
12、,猜测可以通过调用glTranslatef()来实现查阅发现:glPushMatrix();glTranslatef();glMaterialfv();glutSolidSphere();glPopMatrix();,创建光源/环境光,散射光和镜面光参数GLfloat light_ambient=0.0,0.0,1.0,1.0;GLfloat light_diffuse=1.0,1.0,1.0,1.0;GLfloat light_specular=1.0,1.0,1.0,1.0;GLfloat light_position=1.0,1.0,1.0,0.0;/glLightfv的调用glLigh
13、tfv(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的调用glEnable(GL_DEPTH_TEST);glEnable(GL_LIGHTING);glEnable(GL_LIGHT0);,材料属性值设置 GLfloat no_mat=0.0,0.0,0.0,1.0;
14、GLfloat mat_ambient=0.7,0.7,0.7,1.0;GLfloat mat_diffuse=0.1,0.5,0.8,1.0;GLfloat mat_specular=1.0,1.0,1.0,1.0;GLfloat no_shininess=0.0;GLfloat low_shininess=5.0;GLfloat high_shininess=100.0;GLfloat mat_emission=0.3,0.2,0.2,0.0;,glMaterialfv的调用,第一个球:只有散射颜色和发射颜色 glPushMatrix();glTranslatef(-1.0,-0.5,-2
15、.0);glMaterialfv(GL_FRONT,GL_AMBIENT,no_mat);glMaterialfv(GL_FRONT,GL_DIFFUSE,mat_diffuse);glMaterialfv(GL_FRONT,GL_SPECULAR,no_mat);glMaterialfv(GL_FRONT,GL_SHININESS,no_shininess);glMaterialfv(GL_FRONT,GL_EMISSION,mat_emission);glutSolidSphere(1.0,16,16);/绘制小球 glPopMatrix();,第二个球:只有散射颜色和镜面颜色,且镜面指数
16、低 glPushMatrix();glTranslatef(0.0,-0.5,-3.0);glMaterialfv(GL_FRONT,GL_AMBIENT,no_mat);glMaterialfv(GL_FRONT,GL_DIFFUSE,mat_diffuse);glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular);glMaterialfv(GL_FRONT,GL_SHININESS,low_shininess);glMaterialfv(GL_FRONT,GL_EMISSION,no_mat);glutSolidSphere(1.0,16,16);g
17、lPopMatrix();,第三个球:只有散射颜色和镜面颜色,且镜面指数为高 glPushMatrix();glTranslatef(1.0,-0.5,-4.0);glMaterialfv(GL_FRONT,GL_AMBIENT,no_mat);glMaterialfv(GL_FRONT,GL_DIFFUSE,mat_diffuse);glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular);glMaterialfv(GL_FRONT,GL_SHININESS,high_shininess);glMaterialfv(GL_FRONT,GL_EMISSIO
18、N,no_mat);glutSolidSphere(1.0,16,16);glPopMatrix();,静态光源控制void reshape(int w,int h)glViewport(0,0,(GLsizei)w,(GLsizei)h);glMatrixMode(GL_PROJECTION);glLoadIdentity();if(w=h)glOrtho(-1.5,1.5,-1.5*(GLfloat)h/(GLfloat)w,1.5*(GLfloat)h/(GLfloat)w,-10.0,10.0);else glOrtho(-1.5*(GLfloat)w/(GLfloat)h,1.5*(
19、GLfloat)w/(GLfloat)h,-1.5,1.5,-10.0,10.0);glMatrixMode(GL_MODELVIEW);glLoadIdentity();,效果展示,第一个小球只有散射颜色和发射颜色第二个小球只有散射颜色和镜面颜色,且镜面指数低 第三个小球只有散射颜色和镜面颜色,且镜面指数为高,动态光源实现,采用什么方式实现动态光源?通过点击鼠标产生鼠标事件,进而移动光源,鼠标事件函数,目的通过点击鼠标控制旋转void mouse(int button,int state,int x,int y)switch(button)case GLUT_LEFT_BUTTON:if(s
20、tate=GLUT_DOWN)spin=(spin+30)%360;/全局变量spin的控制 glutPostRedisplay();break;default:break;,void display3(void)/模型和视图变换 GLfloat position=0.0,0.0,1.5,1.0;glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);glPushMatrix();glTranslatef(0.0,0.0,-5.0);glPushMatrix();glRotated(GLdouble)spin,1.0,0.0,0.0);/全局变量spi
21、n初值为0,通过鼠标事件改变它的值,进而进行旋转 glLightfv(GL_LIGHT0,GL_POSITION,position);glTranslated(0.0,0.0,1.5);glDisable(GL_LIGHTING);glColor3f(0.0,1.0,1.0);glutWireCube(0.1);/绘制立方体函数,目的是为了更好的显示效果 glEnable(GL_LIGHTING);glPopMatrix();glutSolidSphere(1.0,20,16);/绘制圆 glPopMatrix();glFlush();,void reshape3(int w,int h)/投
22、影和视口变换 glViewport(0,0,(GLsizei)w,(GLsizei)h);/作用调整绘图像素矩阵,使它占据整个窗口 glMatrixMode(GL_PROJECTION);/表示吧当前矩阵指定用于投影变换,后续的变换调用影响的是投影矩阵 glLoadIdentity();/对当前矩阵进行初始化 gluPerspective(40.0,(GLfloat)w/(GLfloat)h,1.0,20.0);/*void gluPerspective(GLdouble fovy,GLdouble aspect,GLdouble near,GLdouble far);创建一个表示对称透视视图
23、凭借头体的矩阵,并把它与当前矩阵相乘 fovy yz平面上视野的角度,它的值必须在0.0,180.0.aspect是这个平截头体的纵横比,即宽度除高度 near and far 观察点与近侧剪裁平面及远侧裁剪平面的距离,值为正数*/glMatrixMode(GL_MODELVIEW);/以后变换影响的是模型视图矩阵 glLoadIdentity();/对当前矩阵进行初始化,效果展示,光源在上面时,光源在下侧时,main()的实现,int main(int argc,char*argv)/初始化 glutInit(,glutInitWindowPosition(100,100);glutCreateWindow(argv0);init2();glutDisplayFunc(display2);glutReshapeFunc(reshape);glutInit(,体会:,OpenGL提供了一个很好图形应用程序接口,通过调用其中的函数库,我们可以达到事半功倍的效果!只有通过实习才能够更深刻的了解到每个函数的具体作用,才能够更好的运用。图形学实验做好了可以给你以美感,是一种享受。,Thank you!,