所有光线追踪器所具有的一件事就是ray类射线进行像素颜色的采集。 让我们将射线看作函数p(t)= A + t * B。这里p是一个3D位置,沿着3D线。 A是射线源,B是射线方向,射线参数是t。 [ ray.h:
#ifndef RAYH
#define RAYH
#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;
};
#endif
假定观测者位于原点处,他将观测上图所示的截面。为了获得每个像素的颜色,观测者将向该像素所在的位置发射出一条射线(ray)进行采样。 作者使用右手坐标系,观察点在(0,0,0),y轴向上,x轴向右,屏幕里面是z的负轴,u,v偏移量表示距离左下角的距离。 [ 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. 射线追踪器的核心是发送射线,计算在这些射线的方向上看到的是什么颜色。 这是计算哪一条射线从观察点到一个像素的计算方法,可以计算出射线方向上的颜色。 cpp:
#include
#include
#include “ray.h”
using namespace std;
vec3 Color(const ray& r)
{
vec3 unit_direction = unit_vector(r.direction());
//t从0到1
float t = 0.5f \* (unit\_direction.y() + 1.0f);
//线性混合,t=1时蓝色,t=0时白色,t介于中间时是混合颜色
//blended\_value = (1-t)\*start\_value + t\*end\_value
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(“IMG.ppm”);
int nx = 800;
int ny = 400;
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++)
{
//u从0开始越来越接近1;v从无限接近1开始,越来越接近0
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;
}
运行效果: 参考书籍:《Ray Tracing in One Weekend》 RTIOW系列项目地址:GitHub RTIOW系列笔记: RTIOW-ch1:Output an image RTIOW-ch2:The vec3 class RTIOW-ch3:Rays, a simple camera, and background RTIOW-ch4:Adding a sphere RTIOW-ch5:Surface normals and multiple objects RTIOW-ch6:Antialiasing RTIOW-ch7:Diffuse Materials RTIOW-ch8:Metal RTIOW-ch9:Dielectrics RTIOW-ch10:Positionable camera RTIOW-ch11:Defocus Blur RTIOW-ch12:Where next