优化Ray Tracer

时间:2014-12-07 21:05:00

标签: c++ optimization graphics rendering raytracing

我的任务是优化以下光线跟踪器:

void Scene::RayTrace() 
{

    for (int v = 0; v < fb->h; v++)  // all vertical pixels in framebuffer
    {
        calculateFPS(); // calculates the current fps and prints it

        for (int u = 0; u < fb->w; u++) // all horizontal pixels in framebuffer
        {

            fb->Set(u, v, 0xFFAAAAAA); // background color
            fb->SetZ(u, v, FLT_MAX);  // sets the Z values to all be maximum at beginning
            V3 ray = (ppc->c + ppc->a*((float)u + .5f) + ppc->b*((float)v + .5f)).UnitVector(); // gets the camera ray

            for (int tmi = 0; tmi < tmeshesN; tmi++)  // iterates over all triangle meshes
            {
                if (!tmeshes[tmi]->enabled) // doesn't render a tmesh if it's not set to be enabled
                    continue;
                for (int tri = 0; tri < tmeshes[tmi]->trisN; tri++) // iterates over all triangles in the mesh
                {
                    V3 Vs[3]; // triangle vertices
                    Vs[0] = tmeshes[tmi]->verts[tmeshes[tmi]->tris[3 * tri + 0]];
                    Vs[1] = tmeshes[tmi]->verts[tmeshes[tmi]->tris[3 * tri + 1]];
                    Vs[2] = tmeshes[tmi]->verts[tmeshes[tmi]->tris[3 * tri + 2]];
                    V3 bgt = ppc->C.IntersectRayWithTriangleWithThisOrigin(ray, Vs); // I don't entirely understand what this does

                    if (bgt[2] < 0.0f || bgt[0] < 0.0f || bgt[1] < 0.0f || bgt[0] + bgt[1] > 1.0f) 
                        continue;
                    if (fb->zb[(fb->h - 1 - v)*fb->w + u] < bgt[2])
                        continue;

                    fb->SetZ(u, v, bgt[2]);
                    float alpha = 1.0f - bgt[0] - bgt[1];
                    float beta = bgt[0];
                    float gamma = bgt[1];
                    V3 Cs[3]; // triangle vertex colors
                    Cs[0] = tmeshes[tmi]->cols[tmeshes[tmi]->tris[3 * tri + 0]];
                    Cs[1] = tmeshes[tmi]->cols[tmeshes[tmi]->tris[3 * tri + 1]];
                    Cs[2] = tmeshes[tmi]->cols[tmeshes[tmi]->tris[3 * tri + 2]];
                    V3 color = Cs[0] * alpha + Cs[1] * beta + Cs[2] * gamma;
                    fb->Set(u, v, color.GetColor()); // sets this pixel accordingly

                }

            }


        }
        fb->redraw();
        Fl::check();
    }

}

两件事:

  1. 我不完全理解ppc->C.IntersectRayWithTriangleWithThisOrigin(ray, Vs);的作用。任何人都可以用光线追踪来解释这个问题吗?这是我的“平面针孔相机”类中的功能(这个功能是给我的):

    V3 V3::IntersectRayWithTriangleWithThisOrigin(V3 r, V3 Vs[3]) 
    {
    
        M33 m; // 3X3 matrix class
        m.SetColumn(0, Vs[1] - Vs[0]);
        m.SetColumn(1, Vs[2] - Vs[0]);
        m.SetColumn(2, r*-1.0f);
        V3 ret; // Vector3 class
        V3 &C = *this;
        ret = m.Inverse() * (C - Vs[0]);
        return ret;
    
    }
    
  2. 这方面的基本步骤很明显,我只是看不出它实际上在做什么。

    1. 我如何从这里优化此光线追踪器?我在网上发现了一些关于“kd树”的东西,但我不确定它们有多复杂。有没有人在简单的优化解决方案上有一些很好的资源?我在解读那些内容时遇到了一些困难。
    2. 谢谢!

2 个答案:

答案 0 :(得分:0)

到目前为止,最大的优化可能是使用某种bounding volume hierarchy。现在,代码将所有光线与所有对象的所有三角形相交。对于BVH,我们反而问:“给定这条光线,哪些三角形相交?”这意味着对于每条光线,您通常只需要测试与少数基元和三角形的交集,而不是测试场景中的每个三角形。

答案 1 :(得分:0)

  1. IntersectRayWithTriangleWithThisOrigin

    • 从外观上看
    • 它从三角形边创建逆变换矩阵(三角形基矢量是X,Y)
    • 没有得到Z轴我希望那里的光线方向而不是像素的位置(光线原点)
    • 但可能会误解某些内容
    • 无论如何,逆矩阵计算是最大的问题
    • 你为每个像素的每个三角形计算它很多
    • 更快的是在光线追踪(一次)之前计算每个三角形的逆变换矩阵
    • 其中X,Y是基础,Z垂直于它们面向与相机始终相同方向的展位
    • 然后只需将光线转换为光线并检查交叉点的限制
    • 只是matrix*vector而很少if而不是逆矩阵计算
    • 另一种方式是代数求解光线与平面交点
    • 应该导致更简单的方程然后矩阵求逆
    • 之后只是基础向量绑定检查的主要内容