您当前的位置: 首页 >  flashinggg

GAMES101作业7-多线程提速实现步骤详解

flashinggg 发布时间:2022-06-19 18:52:35 ,浏览量:1

目录

用循环VS不用循环

用循环:spp=2,t=5min

不用循环:spp=2,t=1min

多线程优化

原Render.cpp思路

(1)发出主射线primary ray,并调用castRay()函数实现对每个像素着色;

(2)UpdateProgres()

(3)保存

实现多线程的步骤

(1)首先要划分出不同的线程

(2)创建出每个线程执行的函数

(3)分行进行步骤(2)函数的调用

(4)别忘记thread需要执行的join

(5)渲染进程结束

多线程完整代码

多线程前后结果对比

提到优化,本次作业体现在渲染时长上面:spp取相同值的情况下,渲染时长越短当然效果是越好的!对于优化,这里有两个方面可以实现优化:

(1)较少循环的使用;

(2)使用多线程;

用循环VS不用循环

首先那不得不从代码本身结构去做优化,我们把目光聚焦在Bounds.hpp的IntersectP()函数上。

用循环:spp=2,t=5min

先看看最开始利用循环实现的代码:

inline bool Bounds3::IntersectP(const Ray& ray, const Vector3f& invDir,
                                const std::array& dirIsNeg) const
{
    // TODO test if ray bound intersects
    //判断包围盒Bounding Box与光线是否相交
    //tenter = max{tmin} texit = min{tmax}
    //先给个无穷初值
    double tenter = -std::numeric_limits::infinity();
    double texit = std::numeric_limits::infinity();
    for (int i = 0; i < 3; i++) {
        //求三个轴的tmin,tmax
        // invDir: ray direction(x,y,z), invDir=(1.0/x,1.0/y,1.0/z),
        double tmin = (pMin[i] - ray.origin[i]) * invDir[i];
        double tmax = (pMax[i] - ray.origin[i]) * invDir[i];
        //用dirIsNeg判断光线方向
        if (!dirIsNeg[i])//如果i= 0;
}

其他内容不变,spp=2时,渲染时长为5min。

不用循环:spp=2,t=1min

代码为: 

inline bool Bounds3::IntersectP(const Ray& ray, const Vector3f& invDir,
                                const std::array& dirIsNeg) const
{
    Vector3f tmin = (pMin - ray.origin) * invDir;
    Vector3f tmax = (pMax - ray.origin) * invDir;
    if (dirIsNeg[0])
        std::swap(tmin.x, tmax.x);
    if (dirIsNeg[1])
        std::swap(tmin.y, tmax.y);
    if (dirIsNeg[2])
        std::swap(tmin.z, tmax.z);
    float texit = std::min(tmax.x, std::min(tmax.y, tmax.z));
    float tenter = std::max(tmin.x, std::max(tmin.y, tmin.z));
    return tenter = 0;
}

spp=2,渲染时长为1min。

很直观的可以看到,两个结果没有任何差别,但时间就是缩短了整整4min!循环的使用大幅度延长了渲染时间,这点我在作业6最后也做了一些讨论:

 GAMES101作业6-BVH完成全过程_flashinggg的博客-CSDN博客

多线程优化

多线程是在Render.cpp中实现的,可以先看看Render.cpp代码的思路是什么:

原Render.cpp思路 (1)发出主射线primary ray,并调用castRay()函数实现对每个像素着色;

这部分我在作业5里已经很详细地讲了如何计算方向,指路:

GAMES101作业5-从头到尾理解代码&Whitted光线追踪_flashinggg的博客-CSDN博客

//发射主射线primary ray
void Renderer::Render(const Scene& scene)
{
    //Image
    std::vector framebuffer(scene.width * scene.height);
    //deg2rad() 度数->弧度
    float scale = std::tan(deg2rad(scene.fov * 0.5f));
    //aspect_radio=width/height
    float imageAspectRatio = scene.width / (float)scene.height;
 
    //eye(相机中心)定为(278,273,-800)
    Vector3f eye_pos(278, 273, -800);

    //遍历每个像素
    int m = 0;
    int spp = 16;
    sitd::cout             
关注
打赏
1688896170
查看更多评论
0.3106s