1 / 38

光线跟踪算法

光线跟踪算法. 主要内容: 一、实验设计 二、静止多光源实现 三、材料属性对光照效果的影响 四、移动光源的实现. 实验设计. 问题一、影响光照效果的因素? 问题二、 OPENGL 光线跟踪函数的函数? 问题三、光线跟踪实现的基本步骤?. 一、 OPENGL 中影响光照效果的因素?. 1 、光源 光的种类: 环境光: light_ambient 散射光: light_diffuse 镜面光: light_specular 光源的分类: 方向性光源:无限远,所有光线是平行的 位置性光源:位置决定场景中的效果 区别:

nira
Download Presentation

光线跟踪算法

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 光线跟踪算法 • 主要内容: • 一、实验设计 • 二、静止多光源实现 • 三、材料属性对光照效果的影响 • 四、移动光源的实现

  2. 实验设计 • 问题一、影响光照效果的因素? • 问题二、OPENGL光线跟踪函数的函数? • 问题三、光线跟踪实现的基本步骤?

  3. 一、OPENGL中影响光照效果的因素? • 1、光源 • 光的种类: • 环境光:light_ambient • 散射光:light_diffuse • 镜面光:light_specular • 光源的分类: • 方向性光源:无限远,所有光线是平行的 • 位置性光源:位置决定场景中的效果 • 区别: • GLfloat light_position[] 中的第四个参数

  4. 2、材料属性 • 材料的环境颜色:GL_AMBIENT • 材料的散射颜色:GL_DIFFUSE • 材料的镜面颜色:GL_SPECULAR • 材料的镜面指数:GL_SHININESS • 材料的发射颜色:GL_EMISSION

  5. 问题二、OPENGL光线跟踪函数的函数? • 光源: • void glLight{if}(GLenum light, GLenum pname, TYPEparam); • void glLight{if}v(GLenum light, GLenum pname, TYPE *param); • Light:指定光源 pname:光源属性 param:属性值 • 材料属性: • void glMaterial{if}(GLenum face, GLenum pname, TYPEparam); • void glMaterial{if}v(GLenum face, GLenum pname, TYPE *param); • Face:那个面受光照pname:光源属性 param:属性值

  6. 问题三、光线跟踪实现的基本步骤? • 一、创建光源 • 二、选择光照模型 • 三、定义材料属性 • 有了这些知识,我们就可以进行第一个简单的多光源实验。

  7. 静止多光源实现 • 自己的工作: • 按照光线跟踪实现的步骤进行。 • 设置光源参数,衰减因子,聚光灯参数,材料属性参数,调用glLightfv,glMaterialfv, glEnable等函数进行设置。 • 已有的: • 实现静态光源显示 • void reshape (int w, int h) • void display(void)

  8. 创建光源 • 1、设置光源参数 • 方向性光源,环境光颜色为蓝色 • 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.0, 1.0 }; • GLfloat light1_position[] = { 0.0, 2.0, 2.0, 1.0 };

  9. 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, 0.5); • glLightf(GL_LIGHT1, GL_QUADRATIC_ATTENUATION, 0.2); • 三个参数的默认值为1,0,0

  10. 3,聚光灯参数 • 光源LIGHT1 • GLfloat spot_direction[] = { 1.0, -1.0, -1.0 }; • glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION, spot_direction); • glLightf(GL_LIGHT1, GL_SPOT_CUTOFF, 45.0); • //默认值180 • glLightf(GL_LIGHT1, GL_SPOT_EXPONENT, 5.0); • //用于控制光的集中度,越高强度越集中

  11. 4,glLightfv的调用 • 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); • 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);

  12. 5,glEnable的调用 • 作用:启用光源 • glEnable(GL_LIGHTING); • glEnable(GL_LIGHT0); • glEnable(GL_LIGHT1);

  13. 6,光源保持静止 • 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*(GLfloat)w/(GLfloat)h, -1.5, 1.5, -10.0, 10.0); • glMatrixMode(GL_MODELVIEW); • glLoadIdentity(); • } • 首先确定视口和投影矩阵,接着在模型视图矩阵中加载单位矩阵,然后再设置光源。由于使用单位阵,乘模型视图矩阵之后原来制定的光源位置并没有发生变化。

  14. 选择光照模型 • 静态多光源实现过程中使用默认设置: • 即观察者位于无穷远且只有一面接受光照 • glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); • glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess); • glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_FALSE);

  15. 定义材料属性 • 材料属性值设置 • GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 }; • GLfloat mat_shininess[] = { 50.0 }; • glMaterialfv的调用 • glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); • glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);

  16. display()函数 • void display(void) • { • glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);//清空缓冲区 • glutSolidSphere (1.0, 20, 16);//画圆,半径为1.0 • glFlush ();//保证绘图命令被实际执行 • }

  17. 效果展示 • 屏蔽位置性光源 • 只有方向性光源

  18. 屏蔽方向性光源 • 只有位置性光源

  19. 静止多光源

  20. 材料属性对光照效果的影响 遇到的问题: 如何将不同的材料属性赋予不同的球体?

  21. 如何将不同的材料属性赋予不同的球体? • 猜测可以通过调用glTranslatef()来实现 • 查阅发现: • glPushMatrix(); • glTranslatef (); • glMaterialfv(); • glutSolidSphere(); • glPopMatrix();

  22. 创建光源 • //环境光,散射光和镜面光参数 • 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的调用 • 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的调用 • glEnable(GL_DEPTH_TEST); • glEnable(GL_LIGHTING); • glEnable(GL_LIGHT0);

  23. 材料属性值设置 • GLfloat no_mat[] = { 0.0, 0.0, 0.0, 1.0 }; • 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};

  24. glMaterialfv的调用 第一个球:只有散射颜色和发射颜色 glPushMatrix(); • glTranslatef (-1.0, -0.5, -2.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();

  25. 第二个球: • 只有散射颜色和镜面颜色,且镜面指数低 • 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); • glPopMatrix();

  26. 第三个球: • 只有散射颜色和镜面颜色,且镜面指数为高 • 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_EMISSION, no_mat); • glutSolidSphere(1.0, 16, 16); • glPopMatrix();

  27. 静态光源控制 • 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*(GLfloat)w/(GLfloat)h, -1.5, 1.5, -10.0, 10.0); • glMatrixMode(GL_MODELVIEW); • glLoadIdentity(); • }

  28. 效果展示 • 第一个小球 • 只有散射颜色和发射颜色 • 第二个小球 • 只有散射颜色和镜面颜色,且镜面指数低 • 第三个小球 • 只有散射颜色和镜面颜色,且镜面指数为高

  29. 动态光源实现 • 采用什么方式实现动态光源? • 通过点击鼠标产生鼠标事件,进而移动光源

  30. 鼠标事件函数,目的通过点击鼠标控制旋转 • void mouse(int button, int state, int x, int y) • { • switch (button) • { • case GLUT_LEFT_BUTTON: • if (state == GLUT_DOWN) • { • spin = (spin + 30) % 360; • //全局变量spin的控制 • glutPostRedisplay(); • } • break; • default: break; • } • }

  31. 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); • //全局变量spin初值为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 (); • }

  32. void reshape3 (int w, int h)//投影和视口变换 • { • 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); • 创建一个表示对称透视视图凭借头体的矩阵,并把它与当前矩阵相乘 • fovy yz平面上视野的角度,它的值必须在[0.0,180.0]. • aspect是这个平截头体的纵横比,即宽度除高度 • near and far 观察点与近侧剪裁平面及远侧裁剪平面的距离,值为正数*/ • glMatrixMode(GL_MODELVIEW); • //以后变换影响的是模型视图矩阵 • glLoadIdentity();//对当前矩阵进行初始化 • }

  33. 效果展示 • 光源在上面时

  34. 光源在下侧时

  35. main()的实现 • int main(int argc, char** argv) • { • //初始化 • glutInit(&argc, argv); • glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH); • glutInitWindowSize (500, 500);//窗口大小 • glutInitWindowPosition (100, 100);//窗口位置 • glutCreateWindow (argv[0]);//创建窗口 • init (); • glutDisplayFunc(display); • glutReshapeFunc(reshape); • glutInit(&argc, argv); • glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH); • glutInitWindowSize (500, 500);

  36. glutInitWindowPosition (100, 100); • glutCreateWindow (argv[0]); • init2 (); • glutDisplayFunc(display2); • glutReshapeFunc(reshape); • glutInit(&argc, argv); • glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH); • glutInitWindowSize (500, 500); • glutInitWindowPosition (100, 100); • glutCreateWindow (argv[0]); • init3 (); • glutDisplayFunc(display3); • glutReshapeFunc(reshape3); • glutMouseFunc(mouse); • glutMainLoop(); • return 0; • }

  37. 体会: • OpenGL提供了一个很好图形应用程序接口,通过调用其中的函数库,我们可以达到事半功倍的效果! • 只有通过实习才能够更深刻的了解到每个函数的具体作用,才能够更好的运用。 • 图形学实验做好了可以给你以美感,是一种享受。

  38. Thank you!

More Related