【Ray Tracing in One Weekend】(ch3)射线类

本文介绍了一个简单的光线追踪程序实现过程,包括如何定义光线类、创建简易相机并计算背景颜色。通过该程序,读者可以理解光线追踪的基本原理及其核心组件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Chapter 3: Rays, a simple camera, and background

所有的 Ray Tracer 都有的一个类便是 Ray 类了。

一条射线上一点的公式如下:

p(t)=A+tB.

p(t)便是射线(由三维空间中一点及一条由此点出发的直线构成)上任意一点。A是射线起点的向量,B是射线方向的向量。

这里写图片描述

其代码 Ray.h 如下

//#ifdef RAYH
//#define RAYH
//#endif
#include "Vec3.h"

class Ray
{
public:
    Ray(){}
    Ray(const Vec3& a, const Vec3& b) { A = a; B = b; }
    Vec3 origin() const { return A; }
    Vec3 direction() const { return B; }
    Vec3 point_at_parameter(float t) const { return A + t*B; }

    Vec3 A;
    Vec3 B;
};

Ray Tracer 的核心便是发射射线,然后计算这些射线方向上分别应显示什么颜色。

At the core of a ray tracer is to send rays through pixels and compute what color is seen in the direction of those rays.This is of the form calculate which ray goes from the eye to a pixel, compute what that ray intersects, and compute a color for that intersection point.

作者建议,应code一个简易的camera,同时编写一个color方法来return背景的颜色。

作者把eye也就是camera放在(0,0,0)这个点,然后使用右手坐标系,y轴正方向向上,x轴正方向向右,z轴正方向向外,同时用u、v两个偏移向量表示点距左下角的距离。

这里写图片描述

注意此时并没有给出射线的方向向量B的单位长度值,是为了方便起见。

此时 Main.cpp 中的 code 如下:

#include <iostream>
#include <fstream>
#include "Ray.h"
using namespace std;


Vec3 Color(const Ray& r)
{
    Vec3 unit_direction = unit_vector(r.direction());
    float t = 0.5f*(unit_direction.y() + 1.0f);

    //(1-t)*白色+t*蓝色,结果是一个蓝白的渐变
    return (1.0f - t)*Vec3(1.0, 1.0, 1.0) + t*Vec3(0.5, 0.7, 1.0);
}

int main()
{

    ofstream outfile;
    outfile.open("firstImage.ppm");

    int nx = 200;
    int ny = 100;
    outfile << "P3\n" << nx << " " << ny << "\n255\n";

    Vec3 lower_left_corner(-2.0f, -1.0f, -1.0f);
    Vec3 horizontal(4.0f, 0.0f, 0.0f);
    Vec3 vertical(0.0f, 2.0f, 0.0f);
    Vec3 origin(0.0f, 0.0f, 0.0f);


    for (int j = ny - 1; j >= 0; j--)
    {
        for (int i = 0; i < nx; i++)
        {
            float u = float(i) / float(nx);
            float v = float(j) / float(ny);
            Ray r(origin, lower_left_corner + u*horizontal + v*vertical);
            Vec3 col = Color(r);
            int ir = int(255.99*col[0]);
            int ig = int(255.99*col[1]);
            int ib = int(255.99*col[2]);
            outfile << ir << " " << ig << " " << ib << "\n";
        }
    }
    outfile.close();
    return 0;
}

此时就很像:从像素块中央拿着一个个小的望远镜(一条条射线)看向场景,观察到颜色,然后填在像素块里。

最后所得效果:

这里写图片描述

这里还需要解释一个概念叫做 linear blend 也叫 linear interpolation 或 lerp。即 线性插值。

blended_value = (1-t)*start_value + t*end_value

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值