GAMES101作业6,加速结构

作业要求
在这里插入图片描述

相比于作业5,将光线封装起来 修改Render()

for (uint32_t j = 0; j < scene.height; ++j) {
        for (uint32_t i = 0; i < scene.width; ++i) {
            // generate primary ray direction
            float x = (2 * (i + 0.5) / (float)scene.width - 1) *
                      imageAspectRatio * scale;
            float y = (1 - 2 * (j + 0.5) / (float)scene.height) * scale;
            // TODO: Find the x and y positions of the current pixel to get the
            // direction
            //  vector that passes through it.
            // Also, don't forget to multiply both of them with the variable
            // *scale*, and x (horizontal) variable with the *imageAspectRatio*
        Vector3f dir = Vector3f(x, y, -1); 
        dir = normalize(dir);
        //封装
        Ray ray(eye_pos,dir);
        framebuffer[m++]= scene.castRay(ray,0);            

        }
        UpdateProgress(j / (float)scene.height);
    }

判断光线射进包围盒情况
在这里插入图片描述
在这里插入图片描述

inline bool Bounds3::IntersectP(const Ray& ray, const Vector3f& invDir,
                                const std::array<int, 3>& dirIsNeg) const
{
    // invDir: ray direction(x,y,z), invDir=(1.0/x,1.0/y,1.0/z), use this because Multiply is faster that Division
    // dirIsNeg: ray direction(x,y,z), dirIsNeg=[int(x>0),int(y>0),int(z>0)], use this to simplify your logic
    // TODO test if ray bound intersects

    //光线与包围盒相交有三种情况:1.光从包围盒里面射出,则沿着光的射线有一个交点。2.光的反向延长线射向包围盒,此时t没有正数解。3.光与包围盒相交
   
    //这里使用乘以invDIr,乘法比除法快很多
    float t_Min_x = (pMin.x - ray.origin.x)*invDir[0];
    float t_Min_y = (pMin.y - ray.origin.y)*invDir[1];
    float t_Min_z = (pMin.z - ray.origin.z)*invDir[2];
    float t_Max_x = (pMax.x - ray.origin.x)*invDir[0];
    float t_Max_y = (pMax.y - ray.origin.y)*invDir[1];
    float t_Max_z = (pMax.z - ray.origin.z)*invDir[2];
     //dirIsNeg判断光线正方向
    //  dirIsNeg: ray direction(x,y,z), dirIsNeg=[int(x>0),int(y>0),int(z>0)],判断光线朝向
    if(!dirIsNeg[0])
    {
        auto t = t_Min_x;
        t_Min_x = t_Max_x;
        t_Max_x = t;
    }
    if(!dirIsNeg[1])
    {
        auto t = t_Min_y;
        t_Min_y = t_Max_y;
        t_Max_y = t;
    }
    if(!dirIsNeg[2])
    {
        auto t = t_Min_z;
        t_Min_z = t_Max_z;
        t_Max_z = t;
    }
 	// enter取max tmin exit取min tmax
    float t_enter = std::max(t_Min_x,std::max(t_Min_y,t_Min_z));
    float t_exit =  std::min(t_Max_x,std::min(t_Max_y,t_Max_z));
    if(t_enter<t_exit&&t_exit>=0)
        return true;
    else
        return false;
}

这里我们先要搞清楚BVH递归是如何实现的
在这里插入图片描述

Intersection BVHAccel::getIntersection(BVHBuildNode* node, const Ray& ray) const
{
    // TODO Traverse the BVH to find intersection
    // 用IntersectP中注释的思路
    Vector3f invDir=ray.direction_inv;

    std::array<int, 3> dirIsNeg;
    dirIsNeg[0] = (ray.direction[0]>0);
    dirIsNeg[1] = (ray.direction[1]>0);
    dirIsNeg[2] = (ray.direction[2]>0);
    Intersection inter;
    //判断是否在包围盒里
    if(!node->bounds.IntersectP(ray,invDir,dirIsNeg)){
        return inter;
    }
    //找到了
    if(node->left == nullptr && node->right == nullptr){
        return node->object->getIntersection(ray);
    }
    //寻找左子树 右子树
    Intersection l = getIntersection(node->left,ray);
    Intersection r = getIntersection(node->right,ray);
    //找到更近的子树
    return l.distance<r.distance?l:r;
    
}

运行结果
在这里插入图片描述
SAH
引用老师给的网站:当物体分布不是很均匀的时候,BVH的分割效果就会很差
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值