Векторы Position
и LookAt
вашей камеры не могут быть одинаковыми по двум осям, перпендикулярным вектору Up
. В результате получается NaN (не число).
Эту ситуацию также можно охарактеризовать как Gimbol Lock , поскольку повороты вокруг осей X(Roll)
и Y(Pitch)
выровнены, что делает невозможным определение Z(Yaw)
по предоставленной информации.
Проблема возникает при создании матрицы View
в следующей строке:
effect.View = Matrix.CreateLookAt(camera.Position, camera.LookingAt, Vector3.UnitZ);
Подставляя значения аргумента:
effect.View = Matrix.CreateLookAt(new Vector3(0,0,1), new Vector3(0,0,0), new Vector3(0,0,1));
Аннотированный частичный источник для CreateLookAt при реализации (см. здесь для получения сквозного вызова)
public static void CreateLookAt(ref Vector3 cameraPosition, ref Vector3 cameraTarget, ref Vector3 cameraUpVector, out Matrix result)
{
var vector = Vector3.Normalize(cameraPosition - cameraTarget);
Normalize((0,0,1) - (0,0,0))
-> (x,y,z)/Length
Length = (0 - 0)² + (0 - 0)² + (0 - 1)²
-> 1
(0/Length,0/Length,1/Length)
-> (0/1,0/1,1/1)
-> (0,0,1)
* OK
var vector2 = Vector3.Normalize(Vector3.Cross(cameraUpVector, vector));
Работа наизнанку:
Cross((0,0,1),(0,0,1))
-> (y1 * z2 - z1 * y2, z1 * x2 - x1 *z2, x1 * y2 - y1 *x2)
->
(0 * 1 - 1 * 0, 1 * 0 - 0 * 1, 0 * 0 - 0 * 0)
-> (0,0,0)
* Математически ОК, Геометрически не определено (не определяет плоскость, перпендикулярную входным точкам)
Normalize(Cross((0,0,1),(0,0,1)))
-> Normalize(0,0,0)
Length = (0 - 0)² + (0 - 0)² + (0 - 0)² -> 0
(0/Length,0/Length,0/Length)
-> (0/0,0/0,0/0)
-> (NaN,NaN,NaN)
* UH-OH
* * * * * * * * * * * * * * * * * * * * * * * * * * NaN
Результат деления на ноль с нулем без знака, как определено IEEE 754 .
Поскольку любая операция с NaN
приводит к NaN
. NaN
распространяется на матрицы World
и Projection
, что приводит к черному экрану.
Другими словами:
Если вы стоите, глядя (Camera.Position
= (0,0,6)
), игнорируя тот факт, что ваша голова должна наклониться, чтобы увидеть их, у ваших ног (Camera.LookAt
= (0,0,0)
), возможно ли определить направление компаса, где вектор Up
равен Vector3.UnitZ
, с которым вы столкнулись? Нет, это невозможно, вы можете быть лицом к плоскости в любом направлении.
Если я прошу координаты Мира на одну единицу перед вашими ногами (1,0,0)
, я могу сказать, в каком направлении вы находитесь.