2012-01-16 3 views
1

Так что на днях я решил написать трассировщик лучей, но я застрял, потому что забыл всю свою векторную математику. У меня есть точка за экраном (глаз/камера, 400,300, -1000), а затем точка на экране (плоскость от 0,0,0 до 800,600,0), которую я получаю только используя значения x и y текущего пикселя, который я ищу (используя SFML для рендеринга, так что это что-то вроде 267,409,0)Рэй трассировочные векторы

Проблема в том, что я не знаю, как правильно наложить луч. Я использую это для тестирования сфера пересечения (C++):

bool SphereCheck(Ray& ray, Sphere& sphere, float& t) 
{ //operator * between 2 vec3s is a dot product 
    Vec3 dist = ray.start - sphere.pos; //both vec3s 
    float B = -1 * (ray.dir * dist); 
    float D = B*B - dist * dist + sphere.radius * sphere.radius; //radius is float 
    if(D < 0.0f) 
     return false; 
    float t0 = B - sqrtf(D); 
    float t1 = B + sqrtf(D); 
    bool ret = false; 
    if((t0 > 0.1f) && (t0 < t)) 
    { 
     t = t0; 
     ret = true; 
    } 
    if((t1 > 0.1f) && (t1 < t)) 
    { 
     t = t1; 
     ret = true; 
    } 
    return ret; 
} 

Так я понимаю, что начало луча будет положение глаз, но то, что это направление?

Или, если это не так, есть ли лучший способ сделать это? Я слышал о некоторых людях, использующих start луча как (x, y, -1000) и в качестве (0,0,1), но я не знаю, как это будет работать.

На стороне примечания, как бы вы сделали преобразования? Я предполагаю, что для изменения угла камеры вы просто настраиваете x и y камеры (или экран, если вам нужно резкое изменение)

+0

Я думаю, что так оно и должно быть, но я забыл все, что я знаю об векторной математике, поэтому я не совсем уверен. – Chris

+0

В основном, что я пытаюсь сказать, как мне отдать луч, потому что я думаю, что, возможно, я ошибаюсь. – Chris

+0

@ Крис: как сказал Ноктюрн, вы бросали луч из глаза через пиксель. Направление дается путем вычитания одной точки из другой. –

ответ

0

Одна вещь, которую я вижу, - это то, что когда вы создаете свои лучи, вы не используя центр каждого пикселя на экране в качестве точки для построения вектора направления. Вы не хотите использовать только координаты (x, y) в сетке для построения этих векторов.

Я ознакомился с вашим примером кода, и расчет действительно неверен. Это то, что вы хотите.

http://www.csee.umbc.edu/~olano/435f02/ray-sphere.html (я взял этот курс в колледже, этот парень знает свой материал)

По сути, это означает, что у вас есть этот луч, который имеет происхождение и направление. У вас есть сфера с точкой и радиусом. Вы используете уравнение луча и вставляете его в сферическое уравнение и решаете для t. Это t - расстояние между началом луча и точкой пересечения на сферах поверхность. Я не думаю, что ваш код делает это.

0

Итак, я понял, что начало луча будет положением глаз, но каково направление?

Вы имеете камеру, определенные векторы front, up и right (перпендикулярно друг к другу и нормализовали) и «положение» (положение глаз).

Вы также width и height окна просмотра (пикселей), вертикальное поле зрения (vfov) и горизонтальное поле зрения (hfov) в градусах или радианах.

Есть также 2D x и y координаты пикселя. Ось X (2D) указывает вправо, ось Y (2D) указывает вниз.

Для плоского экрана луча в можно рассчитать следующим образом:

startVector = eyePos; 
endVector = startVector 
    + front 
    + right * tan(hfov/2) * (((x + 0.5)/width)*2.0 - 1.0) 
    + up * tan(vfov/2) * (1.0 - ((y + 0.5f)/height)*2.0); 

rayStart = startVector; 
rayDir = normalize(endVector - startVector); 

Это предполагает, что плоский экран плоский. Для экстремальных полевых углов (fov> = 180 degreess) вы можете сделать сферическую плоскость экрана и использовать разные формулы.

как бы вы сделали преобразований

матриц.

1

Параметр «Луч» в функции,

bool SphereCheck(Ray& ray, Sphere& sphere, float& t) 
{ 
    ... 
} 

уже должна содержать информацию о направлении и с этим направлением вы должны проверить, если луч пересекает сферу или нет. (Параметр входящего «луча» - это вектор между точкой камеры и пикселем, который отправляется лучам.)

Поэтому локальная переменная «dist» кажется устаревшей.

 Смежные вопросы

  • Нет связанных вопросов^_^