读书人

光线追踪(RayTracing)算法理论与实践(

发布时间: 2012-11-23 22:54:33 作者: rapoo

光线追踪(RayTracing)算法理论与实践(二)平面、材质、联合
提要

经过上次的学习,我们已经可以建立一个简单的光线追踪的场景,接下来,我们继续我们的征程。

今天要得到的最终效果如下:

光线追踪(RayTracing)算法理论与实践(2)平面、材质、联合


平面

平面在空间几何中可以用一个向量(法向量)和平面中的一点P0来表示。

平面就是满足下式的点集:n.(P-P0)=0

得到:n.P=d;d=n.P0;

则平面类我们就可以用代码这样来描述:



材质

在真实世界中,白色物体在绿光照射下看起来是绿色而不是白色,红色物体在绿光照射下看起来是黑色,而有的同样颜色的物体在同样的光照下亮度却不同,这都是由物体的材质不同造成的。
首先在项目中添加一个颜色类,然后定义一些方法。

color.h



光线追踪(RayTracing)算法理论与实践(2)平面、材质、联合


材质这一块有很多东西可以来探讨,而且它和光照联系的很紧密,这里先不探讨。

联合

之前的渲染测试我们都只渲染了单个的物体,现在我们需要在场景中显示多个物体,就上开篇的那副图一样。

首先回到光线追踪的原理,从摄像机发射一条射线之后,当场景中只有单个物体,只需计算一个,就可以得到一个result,当场景中又多个物体的时候,我们需要做的就是计算多次,取距离最近的那个result。

创建一个union类,在渲染的时候将要渲染的东西都进去。

union.h



最后我们来加一点反射的效果,在main.cpp中添加一个函数。

void renderRecursive(){    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);    glLoadIdentity();                                   // Reset The View    glTranslatef(-0.5f,-0.5f,-1.0f);    glPointSize(2.0);    PerspectiveCamera camera( GVector3(0, 10, 10),GVector3(0, -0.5, -1),GVector3(0, 1, 0), 90);    Plane* plane1=new Plane(GVector3(0, 1, 0),1.0);    CSphere* sphere1=new CSphere(GVector3(-2, 5, -2), 4.0);    CSphere* sphere2=new CSphere(GVector3(5, 5, -7), 3.0);    plane1->material=new CheckerMaterial(0.1f,0.5f);    sphere1->material=new PhongMaterial(Color::red(), Color::white(), 16,0.25);    sphere2->material=new PhongMaterial(Color::green(), Color::white(), 16,0.25);    Union scene;    scene.push(plane1);    scene.push(sphere1);    scene.push(sphere2);    long maxDepth=20;    long maxReflect=5;    float dx=1.0f/WINDOW_WIDTH;    float dy=1.0f/WINDOW_HEIGHT;    float dD=255.0f/maxDepth;    glBegin(GL_POINTS);    for (long y = 0; y < WINDOW_HEIGHT; ++y)    {        float sy = 1 - dy*y;        for (long x = 0; x < WINDOW_WIDTH; ++x)        {            float sx =dx*x;            CRay ray(camera.generateRay(sx, sy));            IntersectResult result = scene.isIntersected(ray);            //IntersectResult result = plane1.isIntersected(ray);            if (result.isHit)            {                Color color = rayTraceRecursive(&scene, ray, maxReflect);                //Color color = result.object->material->sample(ray, result.position, result.normal);                //Color color =plane1.material->sample(ray, result.position, result.normal);                color.saturate();                //color.show();                glColor3ub(color.r*255,color.g*255,color.b*255);                glVertex2f(sx,sy);            }        }    }    glEnd();    // 交换缓冲区    glfwSwapBuffers();}

结果就是最上面的那幅图了。


结语

以前自己只玩过一些opengl的东西,不过那些都有现成的接口让你掉,原理上也不用理解得很深,往往一两句语句就可以实现一个简单的效果。

而现在,从原理到实现,每一句代码都需要先在真实世界中想清楚,然后抽象成代码,不管对编程技巧还是数学功底都会有很高的要求,所以在编写这些代码的时候我又回头去看C++ primer,学线性代数。。当然收获也很大。

源码可以点这里下载。

参考用JavaScript玩转计算机图形学(一)光线追踪入门-http://www.cnblogs.com/miloyip/archive/2010/03/29/1698953.html
光线追踪技术的理论和实践(面向对象)-http://blog.csdn.net/zhangci226/article/details/5664313Wikipedia, Ray Tracing
计算机图形学(第三版)(美)赫恩 著,(美)巴克 著。


读书人网 >其他相关

热点推荐