Как HLSL обрабатывает произвольно малые числа?

Прежде всего, я отрисовываю единичный квадрат, применяя преобразование мира, чтобы перевести его в середину экрана. До этого момента все работало нормально. Вот изображение результата.

введите описание изображения здесь

Однако, когда я применяю преобразование представления, я начинаю сталкиваться с некоторыми проблемами. Это код, где я создаю матрицу вида.

XMFLOAT4X4 viewMatrix;
XMVECTOR eye = XMLoadFloat3(&m_Eye);
XMVECTOR focus = XMLoadFloat3(&m_LookAt);
XMVECTOR up = XMLoadFloat3(&m_Up);
XMStoreFloat4x4(&viewMatrix, XMMatrixLookAtLH(eye, eye + focus, up));

И поэтому я отследил проблему до создания вектора lookAt в следующем коде.

float x = cos(XMConvertToRadians(m_Yaw)) * cos(XMConvertToRadians(m_Pitch));
float y = sin(XMConvertToRadians(m_Pitch));
float z = sin(XMConvertToRadians(m_Yaw)) * cos(XMConvertToRadians(m_Pitch));
XMVECTOR m_LookAt = -XMVector3Normalize(XMVectorSet(x, y, z, 0.0f));

Применяя следующие параметры...

  • m_Yaw = -90.0f
  • m_Pitch = 0.0f
  • m_Eye = (0.0f, 0.0f, -5.0f)

... результат в (-4.37113883e-008, 0.0, -1.0) посмотрите на вектор, в

{             1.0, 0.0, 4.37113883e-008, 0.0}
{             0.0, 1.0,             0.0, 0.0}
{-4.37113883e-008, 0.0,             1.0, 0.0}
{-2.18556949e-007, 0.0,             5.0, 1.0}

посмотреть матрицу и следующее изображение.

введите описание изображения здесь

Итак, я попытался создать жестко закодированный вектор lookAt с теми же параметрами m_Yaw и m_Pitch.

x = cos(-90) * cos(0) = 0 * 1 = 0
y = sin(0) = 0
z = sin(-90) * cos(0) = -1 * 1 = -1

Разница лишь в том, что значение х привело к 0 вместо -4.37113883e-008 Я считаю, что это связано с преобразованием в радианы. Одно это "решает" проблему, и результирующее изображение идентично первому.

Однако, так как я не могу сохранить эти значения фиксированными. Я создал небольшую константу const float kEpsilon = 0.0001f; и обнуляет любые компоненты из вектора lookAt, которые меньше, чем kEpsilon и больше чем -kEpsilon,

XMVECTOR lookAt = XMVectorSet(
    x < kEpsilon && x > -kEpsilon ? 0.0f : x,
    y < kEpsilon && y > -kEpsilon ? 0.0f : y,
    z < kEpsilon && z > -kEpsilon ? 0.0f : z,
    0.0f
);

Но это похоже на дешевое решение, и я до сих пор не понимаю, почему эта ошибка возникла. Это связано с какой-то особенностью DirectX, о которой я мог не знать? Или ошибка в моем коде?

Дополнительная информация:

0 ответов

Другие вопросы по тегам