Поэтому я решил переписать мой старый трассировщик лучей, написанный на C ++, и сделать это на C #, используя среду XNA.
У меня все еще есть моя старая книга, и я могу следить за примечаниями, однако я смущен некоторыми идеями, и мне было интересно, сможет ли кто-нибудь сформулировать это красиво.
for each x pixel do
for each y pixel do
//Generate Ray
//1 - Calculate world coordinates of current pixel
//1.1 Calculate Normalized Device coordinates for current pixel 1- to -1 (u, v)
u = (2*x/ WIDTH) - 1 ;
v = (2*y/HEIGHT) - 1 ;
Vector3 rayDirection = -1*focalLength + u'*u + v'*v
В приведенном выше коде u 'и v' - это нормальное основание, рассчитанное для данной камеры (я знаю, что одни и те же имена приводят в замешательство)
Если я следую книге и делаю так, как она выражается, это работает. Однако я пытаюсь использовать XNA и путаюсь в том, как выполнять те же действия, но с использованием матриц.
Итак, я попытался заменить следующие шаги кодом XNA
class Camera
{
public Camera(float width, float height)
{
AspectRatio = width/height;
FOV = Math.PI / 2.0f;
NearPlane = 1.0f;
FarPlane = 100.0f;
ViewMatrix = Matrix.CreateLookAt(Position, Direction,this.Up);
ProjectionMatrix=Matrix.CreatePerspectiveFieldOfView(FOV,
AspectRatio,NearPlane,FarPlane);
}
}
Именно в этот момент я запутался в порядке операций, которые я должен применить, чтобы получить вектор направления для любого пикселя (x, y)?
В моей голове я думаю:
(u, v) = ProjectionMatrix * ViewMatrix * ModelToWorld * Вершина (в пространстве модели)
Поэтому имело бы смысл, что
Вершина (в мировом пространстве) = Инверсия (ViewMatrix) * Инверсия (ProjectionMatrix) * [u, v, 0]
Я также вспомнил кое-что о том, как матрицу представления можно транспонировать и инвертировать, поскольку она ортонормирована.