C++ raytracer: камера и луч
Всем привет, пишу свой raytracer под линукс терминал, решил для начала описать сферу, соответственно вот её класс (использовал стандартный алгоритм для проверки пересечения вектора со сферой, в конце вопроса добавил скрин):
class Sphere
{
public:
float radius;
vector3 center;
bool is_intersect(vector3 camera, vector3 ray)
{
// вектор от камеры до центра сферы
vector3 v = center - camera;
// модуль вектора
float abs_v = v.length();
// ray уже нормализирован ранее
float pr_v_on_ray = ray.dot_product(v);
float l2 = abs_v * abs_v - pr_v_on_ray * pr_v_on_ray;
return l2 - radius * radius <= 0;
}
};
vector3 - самописный тип трёхмерного вектора со всеми стандартными операциями над векторами. (модуль, скалярное произведение, нормализация и остальные)
Создаю сферу с центром в (0,0,0) и вроде бы всё работает:
// от искажения, т.к. ячейки в терминале не квадратные
float distortion = (8.0 / 16) * (width / height);
Sphere sphere = {0.5, vector3(0,0,0)};
for (int i = 0; i < width; ++i)
{
for (int j = 0; j < height; ++j)
{
vector2 xy = (vector2((float)i, (float)j) / vector2(width, height))
* vector2(2,2) - vector2(1,1); // x,y Є [-1.0; 1.0]
xy.x *= distortion;
vector3 camera = vector3(0,0,1);
// луч, вылетающий из камеры
vector3 ray = vector3(xy.x, xy.y, -1).normalize();
if (sphere.is_intersect(camera, ray)) mvaddch(j,i, '@');
Однако, стоит изменить координаты центра сферы и происходит искажение:
Sphere sphere = {0.5, vector3(-0.5,-0.5,0)};
Правильно ли я понимаю механизм "пускания" лучей из точки (камеры): например нам нужно пустить луч из точки (1,2,3) в точку (5,2,1), значит координаты луча будут (5-1,2-2,1-3) = (4,0,-2)? Если понятно что ray.x и ray.y должны проходить по всем пикселям терминала, то каким должно быть значение ray.z?
Не совсем понятно как устроены координаты камеры, я предполагаю что (x,y,z) это смещение камеры относительно начала координат, соответственно например изменяя z должнен изменяться размер проекции шара, так и есть, однако при изменении x и y всё ломается. Не понимаю как рассмотреть шар со всех 6 сторон (потом матрицы поворота привязать смогу)
Что вызывает искажение выше?
Моя финальная цель: камера вращающаяся вокруг сферы (источник света добавлю позже)
Алгоритм is_intersect():


