实验 2.5BVH 光线加速求交:Model 平移存在严重偏移问题

实验 2.5 中用 bvh 加速光线求交。发现对 Model 进行 translation 平移变化时渲染物体会偏移严重,scale 放大缩小时正常。


如图 1,translation(0,0,0) 渲染正常;图 2,translation(0, -0.5, 0) 不正常,偏移到只剩一个角。

# bvh.cpp
optional<Intersection> BVH::intersect(const Ray& ray, [[maybe_unused]] const GL::Mesh& mesh,const Eigen::Matrix4f obj_model){
  // ....
  trans_ray.direction =
          (model_inv * Vector4f(ray.direction.x(), ray.direction.y(), ray.direction.z(), 1.0f))
              .head<3>();
  trans_ray.origin =
          (model_inv * Vector4f(ray.origin.x(), ray.origin.y(), ray.origin.z(), 1.0f)).head<3>();
  isect = ray_node_intersect(root, trans_ray);
  if (isect.has_value()) {
  // 对 isect 返回值的一些变化操作
  // .....
  }
}

应该是 ray_node_intersect() 有问题但不知道哪里有问题:confounded:

同学,注意到你的光线的方向向量和起点坐标在变为齐次坐标时,都是添加的 1。而事实上,坐标值确实应当添加 1,而向量则应当添加 0。

太奇怪了,我也是这样,不知道是哪里出问题了

在模型坐标系中求解得到结果后,返回的时候需要再乘以 model 得到返回值,这个结果像是有关模型坐标系的变换出现了一些问题

上次的问题还没有解决:sob:。当设置 Model 偏移量很小的时候translation(0,0.1,0) 渲染出来存在黑色块。

// 使用 BVH 求交
optional<Intersection> BVH::intersect(const Ray& ray, [[maybe_unused]] const GL::Mesh& mesh,
                                      const Eigen::Matrix4f obj_model)
{
    model = obj_model;
    optional<Intersection> isect;
    if (!root) {
        isect = std::nullopt;
        return isect;
    }
    Ray trans_ray;
    Eigen::Matrix4f model_inv = this->model.inverse();
    trans_ray.direction =
        (model_inv * Vector4f(ray.direction.x(), ray.direction.y(), ray.direction.z(), 1.0f))
            .head<3>().normalized();
    trans_ray.origin =
        (model_inv * Vector4f(ray.origin.x(), ray.origin.y(), ray.origin.z(), 1.0f)).head<3>();
    isect = ray_node_intersect(root, trans_ray);
    if (isect.has_value()) {
        Vector3f world_intersection =
            (model * (isect->t * trans_ray.direction + trans_ray.origin).homogeneous()).head<3>();
        float dis     = (world_intersection - ray.origin).norm();
        isect->t      = dis;
        isect->normal = (model_inv.transpose() *
                         Vector4f(isect->normal.x(), isect->normal.y(), isect->normal.z(), 1.0f))
                            .head<3>();
    }
    return isect;
}

if (isect.has_value()) 中对返回值的坐标变换存在问题吗,还是在 ray_node_intersect() 函数进行一些特殊处理?