101作业5

任务

  1. 根据图片生成光线

任务1

补全Render函数,根据图片像素产生相机坐标下的光线,其中相机坐标中的原点 o o o 已知,所以目标是求得相机坐标下的方向 d d d。一开始采用如下的策略,直接计算每一个像素的宽度dx(长度与宽度相等),但是的坏处是不够标准。

void Renderer::Render(const Scene& scene)
{
    std::vector<Vector3f> framebuffer(scene.width * scene.height);

    float scale = std::tan(deg2rad(scene.fov * 0.5f));
    float imageAspectRatio = scene.width / (float)scene.height;
    // Use this variable as the eye position to start your rays.
    Vector3f eye_pos(0);
    int m = 0;
    for (int j = 0; j < scene.height; ++j)
    {
        for (int i = 0; i < scene.width; ++i)
        {
            // generate primary ray direction
            float x;
            float y;           
            float dx = scale * 1 / (scene.height/2.0);
            x = (i + 0.5 - scene.width /2.0) * dx;
            y = -(j + 0.5 - scene.height /2.0) * dx;
            Vector3f dir = Vector3f(x, y, -1); // Don't forget to normalize this direction!
            dir = normalize(dir);
            framebuffer[m++] = castRay(eye_pos, dir, scene, 0);
        }
        UpdateProgress(j / (float)scene.height);
    }

之后看了一篇博客https://blog.csdn.net/Q_pril/article/details/123825665推荐的这个链接
链接
才发觉应该用更标准的流程来做,即从像素空间—>NDC空间—>Canonical Cube—>相机空间(即View 变换后、投影变换前的空间)。
在这里插入图片描述
上图为从像素空间—>NDC空间—>Canonical Cube的变换的思路,最后的Screen Space即为Canonical Cube的近平面。
最后,要将近平面中的点从Canonical Cube恢复到相机空间中,从而得到相机空间中光线的方向,我们只需要课件中提到的需要t(top)和r(right)即可,这里题目显式地给出了fov(field of view)和aspectRatio。

   x = (2 * (i+0.5)/scene.width - 1) * scale * imageAspectRatio;
   y = (1 - 2 * (j+0.5)/scene.height) * scale;

任务2

所谓muller-Trumbore算法,直接照抄公式即可。

bool rayTriangleIntersect(const Vector3f& v0, const Vector3f& v1, const Vector3f& v2, const Vector3f& orig,
                          const Vector3f& dir, float& tnear, float& u, float& v)
{
    // TODO: Implement this function that tests whether the triangle
    // that's specified bt v0, v1 and v2 intersects with the ray (whose
    // origin is *orig* and direction is *dir*)
    // Also don't forget to update tnear, u and v.
    Vector3f E1 = v1 - v0;
    Vector3f E2 = v2 - v0;
    Vector3f S = orig - v0;
    Vector3f S1 = crossProduct(dir,E2);
    Vector3f S2 = crossProduct(S,E1);
    float scale = 1.0 / dotProduct(S1,E1);
    tnear = dotProduct(S2,E2) * scale;
    u = dotProduct(S1,S) * scale;
    v = dotProduct(S2,dir) * scale;
    if(u>=0&&v>=0&&1-u-v>=0&&tnear>=0)return true;
    else return false;
}

最后,结果如下图:
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值