Неожиданный результат при отмене проецирования координат экрана в DirectX

Чтобы определить, нажал ли пользователь какой-либо из моих 3D-объектов, я пытаюсь превратить экранные координаты щелчка в вектор, который затем использую, чтобы проверить, не попал ли какой-либо из моих треугольников. Для этого я использую XMVector3Unproject метод, предоставляемый DirectX, и я реализую все в C ++ / CX.

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

Вектор в результате непроекции
Положение курсора в момент, когда происходит щелчок (выделено желтым цветом), видно в изометрическом виде слева. Как только я нажимаю, вектор, возникающий из-за непроектирования, появляется за моделью, указанной на изображениях, как белая линия, пронизывающая модель. Таким образом, вместо того, чтобы исходить из положения курсора и переходить на экран в изометрическом виде, он появляется в совершенно ином положении.

Когда я перемещаю мышь в изометрической проекции по горизонтали при щелчке, а после этого перемещаю мышь по вертикали и щелкаю по рисунку ниже. Все линии на двух изображениях представляют векторы, полученные в результате нажатия. Модель была удалена для лучшей видимости.

Вектор, полученный в результате непроекции, происходит из того же места
Как видно из приведенного выше изображения, все векторы, как представляется, происходят из одного и того же места. Если я изменю вид и повторю процесс, появится тот же шаблон, но с другим происхождением векторов.

Разные перспективы, разное происхождение векторов

Вот фрагменты кода, которые я использую, чтобы придумать это. Прежде всего, я получаю позицию курсора с помощью приведенного ниже кода и передаю его моему методу «SelectObject» вместе с шириной и высотой области рисования:

void Demo::OnPointerPressed(Object^ sender, PointerEventArgs^ e)
{
Point currentPosition = e->CurrentPoint->Position;

if(m_model->SelectObject(currentPosition.X, currentPosition.Y, m_renderTargetWidth, m_renderTargetHeight))
{
m_RefreshImage = true;
}
}

Метод «SelectObject» выглядит следующим образом:

bool Model::SelectObject(float screenX, float screenY, float screenWidth, float screenHeight)
{
XMMATRIX projectionMatrix = XMLoadFloat4x4(&m_modelViewProjectionConstantBufferData->projection);
XMMATRIX viewMatrix       = XMLoadFloat4x4(&m_modelViewProjectionConstantBufferData->view);
XMMATRIX modelMatrix      = XMLoadFloat4x4(&m_modelViewProjectionConstantBufferData->model);

XMVECTOR v = XMVector3Unproject(XMVectorSet(screenX, screenY, 5.0f, 0.0f),
0.0f,
0.0f,
screenWidth,
screenHeight,
0.0f,
1.0f,
projectionMatrix,
viewMatrix,
modelMatrix);

XMVECTOR rayOrigin = XMVector3Unproject(XMVectorSet(screenX, screenY, 0.0f, 0.0f),
0.0f,
0.0f,
screenWidth,
screenHeight,
0.0f,
1.0f,
projectionMatrix,
viewMatrix,
modelMatrix);

// Code to retrieve v0, v1 and v2 is omitted

if(Intersects(rayOrigin, XMVector3Normalize(v - rayOrigin), v0, v1, v2, depth))
{
return true;
}
}

В конце концов вычисленный вектор используется Intersects метод пространства имен DirectX :: TriangleTests для определения попадания треугольника. Я пропустил код в приведенном выше фрагменте, потому что он не имеет отношения к этой проблеме.

Для рендеринга этих изображений я использую матрицу ортографической проекции и камеру, которую можно вращать вокруг своей локальной оси x и y, которая генерирует матрицу вида. Матрица мира всегда остается одной и той же, то есть это просто матрица тождеств.

Матрица вида рассчитывается следующим образом (на примере из книги Фрэнка Луны «Программирование 3D-игр»):

void Camera::SetViewMatrix()
{
XMFLOAT3 cameraPosition;
XMFLOAT3 cameraXAxis;
XMFLOAT3 cameraYAxis;
XMFLOAT3 cameraZAxis;

XMFLOAT4X4 viewMatrix;

// Keep camera's axes orthogonal to each other and of unit length.
m_cameraZAxis = XMVector3Normalize(m_cameraZAxis);
m_cameraYAxis = XMVector3Normalize(XMVector3Cross(m_cameraZAxis, m_cameraXAxis));

// m_cameraYAxis and m_cameraZAxis are already normalized, so there is no need
// to normalize the below cross product of the two.
m_cameraXAxis = XMVector3Cross(m_cameraYAxis, m_cameraZAxis);

// Fill in the view matrix entries.
float x = -XMVectorGetX(XMVector3Dot(m_cameraPosition, m_cameraXAxis));
float y = -XMVectorGetX(XMVector3Dot(m_cameraPosition, m_cameraYAxis));
float z = -XMVectorGetX(XMVector3Dot(m_cameraPosition, m_cameraZAxis));

XMStoreFloat3(&cameraPosition, m_cameraPosition);
XMStoreFloat3(&cameraXAxis   , m_cameraXAxis);
XMStoreFloat3(&cameraYAxis   , m_cameraYAxis);
XMStoreFloat3(&cameraZAxis   , m_cameraZAxis);

viewMatrix(0, 0) = cameraXAxis.x;
viewMatrix(1, 0) = cameraXAxis.y;
viewMatrix(2, 0) = cameraXAxis.z;
viewMatrix(3, 0) = x;

viewMatrix(0, 1) = cameraYAxis.x;
viewMatrix(1, 1) = cameraYAxis.y;
viewMatrix(2, 1) = cameraYAxis.z;
viewMatrix(3, 1) = y;

viewMatrix(0, 2) = cameraZAxis.x;
viewMatrix(1, 2) = cameraZAxis.y;
viewMatrix(2, 2) = cameraZAxis.z;
viewMatrix(3, 2) = z;

viewMatrix(0, 3) = 0.0f;
viewMatrix(1, 3) = 0.0f;
viewMatrix(2, 3) = 0.0f;
viewMatrix(3, 3) = 1.0f;

m_modelViewProjectionConstantBufferData->view = viewMatrix;
}

На него влияют два метода, которые вращают камеру вокруг осей X и Y камеры:

void Camera::ChangeCameraPitch(float angle)
{
XMMATRIX rotationMatrix = XMMatrixRotationAxis(m_cameraXAxis, angle);

m_cameraYAxis = XMVector3TransformNormal(m_cameraYAxis, rotationMatrix);
m_cameraZAxis = XMVector3TransformNormal(m_cameraZAxis, rotationMatrix);
}

void Camera::ChangeCameraYaw(float angle)
{
XMMATRIX rotationMatrix = XMMatrixRotationAxis(m_cameraYAxis, angle);

m_cameraXAxis = XMVector3TransformNormal(m_cameraXAxis, rotationMatrix);
m_cameraZAxis = XMVector3TransformNormal(m_cameraZAxis, rotationMatrix);
}

Матрица мира / модели и матрица проекции рассчитываются следующим образом:

void Model::SetProjectionMatrix(float width, float height, float nearZ, float farZ)
{
XMMATRIX orthographicProjectionMatrix = XMMatrixOrthographicRH(width, height, nearZ, farZ);

XMFLOAT4X4 orientation = XMFLOAT4X4
(
1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f
);

XMMATRIX orientationMatrix = XMLoadFloat4x4(&orientation);

XMStoreFloat4x4(&m_modelViewProjectionConstantBufferData->projection, XMMatrixTranspose(orthographicProjectionMatrix * orientationMatrix));
}

void Model::SetModelMatrix()
{
XMFLOAT4X4 orientation = XMFLOAT4X4
(
1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f
);

XMMATRIX orientationMatrix = XMLoadFloat4x4(&orientation);

XMStoreFloat4x4(&m_modelViewProjectionConstantBufferData->model, XMMatrixTranspose(orientationMatrix));
}

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

Редактировать 1:

Я предполагаю, что это связано с тем фактом, что моя камера находится в точке (0, 0, 0) в мировых координатах. Камера вращается вокруг своей локальной оси X и Y. Из того, что я понимаю, матрица вида, созданная камерой, строит плоскость, на которую проецируется изображение. Если это так, то это объясняет, почему луч находится в «неожиданном» месте.

Я предполагаю, что мне нужно переместить камеру из центра, чтобы она находилась за пределами объекта. Однако, если просто изменить переменную-член m_cameraPosition камеры моя модель полностью искажается.

Кто-нибудь может и готов помочь?

11

Решение

Спасибо за подсказку, Капил. Я попробовал XMMatrixLookAtRH метод, но не смог изменить высоту / отклонение камеры с использованием этого подхода, поэтому я отказался от этого подхода и сам создал матрицу.

Что решило мою проблему, так это транспонирование матриц модели, вида и проекции с использованием XMMatrixTranspose прежде чем передать их XMVector3Unproject, Таким образом, вместо того, чтобы иметь следующий код

  XMMATRIX projectionMatrix = XMLoadFloat4x4(&m_modelViewProjectionConstantBufferData->projection);
XMMATRIX viewMatrix       = XMLoadFloat4x4(&m_modelViewProjectionConstantBufferData->view);
XMMATRIX modelMatrix      = XMLoadFloat4x4(&m_modelViewProjectionConstantBufferData->model);

XMVECTOR rayBegin = XMVector3Unproject(XMVectorSet(screenX, screenY, -m_boundingSphereRadius, 0.0f),
0.0f,
0.0f,
screenWidth,
screenHeight,
0.0f,
1.0f,
projectionMatrix,
viewMatrix,
modelMatrix);

это должно быть

  XMMATRIX projectionMatrix = XMMatrixTranspose(XMLoadFloat4x4(&m_modelViewProjectionConstantBufferData->projection));
XMMATRIX viewMatrix       = XMMatrixTranspose(XMLoadFloat4x4(&m_modelViewProjectionConstantBufferData->view));
XMMATRIX modelMatrix      = XMMatrixTranspose(XMLoadFloat4x4(&m_modelViewProjectionConstantBufferData->model));

XMVECTOR rayBegin = XMVector3Unproject(XMVectorSet(screenX, screenY, -m_boundingSphereRadius, 0.0f),
0.0f,
0.0f,
screenWidth,
screenHeight,
0.0f,
1.0f,
projectionMatrix,
viewMatrix,
modelMatrix);

Мне не совсем понятно, почему мне нужно транспонировать матрицы перед передачей их в непроектируемый метод. Однако я подозреваю, что это связано с проблемой, с которой я сталкиваюсь при перемещении камеры. Эта проблема уже была описана здесь в StackOverflow этот проводка.

Мне пока не удалось решить эту проблему. Простое перемещение матрицы представления не решает ее. Тем не менее, моя основная проблема решена, и моя модель, наконец, кликабельна.

Если кому-то есть что добавить и пролить свет на то, почему матрицы нужно транспонировать или почему перемещение камеры искажает модель, пожалуйста, продолжайте и оставляйте комментарии или ответы.

6

Другие решения

Я использовал XMMatrixLookAtRH API в Model::SetViewMatrix() функция для расчета матрицы вида и получил приличные значения v а также rayOrigin векторы.

Например:

XMStoreFloat4x4(
&m_modelViewProjectionConstantBufferData->view,
XMMatrixLookAtRH(m_cameraPosition, XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f),
XMVectorSet(1.0f, 0.0f, 0.0f, 0.0f))
);

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

НОТА: Вы должны дать фокус а также направление вверх параметры вектора для использования XMMatrixLookAtRH API вместо вашего текущего подхода.

4

Я могу получить равные значения v а также rayOrigin векторы, использующие XMMatrixLookAtRH метод, а также ваша пользовательская матрица представления с этим кодом без необходимости операций транспонирования матрицы:

#include <directxmath.h>

using namespace DirectX;

XMVECTOR m_cameraXAxis;
XMVECTOR m_cameraYAxis;
XMVECTOR m_cameraZAxis;
XMVECTOR m_cameraPosition;

XMMATRIX gView;
XMMATRIX gView2;
XMMATRIX gProj;
XMMATRIX gModel;

void SetViewMatrix()
{
XMVECTOR lTarget = XMVectorSet(2.0f, 2.0f, 2.0f, 1.0f);

m_cameraPosition = XMVectorSet(1.0f, 1.0f, 1.0f, 1.0f);
m_cameraZAxis = XMVector3Normalize(XMVectorSubtract(m_cameraPosition, lTarget));
m_cameraXAxis = XMVector3Normalize(XMVector3Cross(XMVectorSet(1.0f, -1.0f, -1.0f, 0.0f), m_cameraZAxis));

XMFLOAT3 cameraPosition;
XMFLOAT3 cameraXAxis;
XMFLOAT3 cameraYAxis;
XMFLOAT3 cameraZAxis;

XMFLOAT4X4 viewMatrix;

// Keep camera's axes orthogonal to each other and of unit length.
m_cameraZAxis = XMVector3Normalize(m_cameraZAxis);
m_cameraYAxis = XMVector3Normalize(XMVector3Cross(m_cameraZAxis, m_cameraXAxis));

// m_cameraYAxis and m_cameraZAxis are already normalized, so there is no need
// to normalize the below cross product of the two.
m_cameraXAxis = XMVector3Cross(m_cameraYAxis, m_cameraZAxis);

// Fill in the view matrix entries.
float x = -XMVectorGetX(XMVector3Dot(m_cameraPosition, m_cameraXAxis));
float y = -XMVectorGetX(XMVector3Dot(m_cameraPosition, m_cameraYAxis));
float z = -XMVectorGetX(XMVector3Dot(m_cameraPosition, m_cameraZAxis));

XMStoreFloat3(&cameraPosition, m_cameraPosition);
XMStoreFloat3(&cameraXAxis, m_cameraXAxis);
XMStoreFloat3(&cameraYAxis, m_cameraYAxis);
XMStoreFloat3(&cameraZAxis, m_cameraZAxis);

viewMatrix(0, 0) = cameraXAxis.x;
viewMatrix(1, 0) = cameraXAxis.y;
viewMatrix(2, 0) = cameraXAxis.z;
viewMatrix(3, 0) = x;

viewMatrix(0, 1) = cameraYAxis.x;
viewMatrix(1, 1) = cameraYAxis.y;
viewMatrix(2, 1) = cameraYAxis.z;
viewMatrix(3, 1) = y;

viewMatrix(0, 2) = cameraZAxis.x;
viewMatrix(1, 2) = cameraZAxis.y;
viewMatrix(2, 2) = cameraZAxis.z;
viewMatrix(3, 2) = z;

viewMatrix(0, 3) = 0.0f;
viewMatrix(1, 3) = 0.0f;
viewMatrix(2, 3) = 0.0f;
viewMatrix(3, 3) = 1.0f;

gView = XMLoadFloat4x4(&viewMatrix);

gView2 = XMMatrixLookAtRH(m_cameraPosition, XMVectorSet(2.0f, 2.0f, 2.0f, 1.0f),
XMVectorSet(1.0f, -1.0f, -1.0f, 0.0f));

//m_modelViewProjectionConstantBufferData->view = viewMatrix;
printf("yo");
}

void SetProjectionMatrix(float width, float height, float nearZ, float farZ)
{
XMMATRIX orthographicProjectionMatrix = XMMatrixOrthographicRH(width, height, nearZ, farZ);

XMFLOAT4X4 orientation = XMFLOAT4X4
(
1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f
);

XMMATRIX orientationMatrix = XMLoadFloat4x4(&orientation);

gProj = XMMatrixTranspose( XMMatrixMultiply(orthographicProjectionMatrix, orientationMatrix));
}

void SetModelMatrix()
{
XMFLOAT4X4 orientation = XMFLOAT4X4
(
1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f
);

XMMATRIX orientationMatrix = XMMatrixTranspose( XMLoadFloat4x4(&orientation));

gModel = orientationMatrix;
}

bool SelectObject(float screenX, float screenY, float screenWidth, float screenHeight)
{
XMMATRIX projectionMatrix = gProj;
XMMATRIX viewMatrix = gView;
XMMATRIX modelMatrix = gModel;
XMMATRIX viewMatrix2 = gView2;

XMVECTOR v = XMVector3Unproject(XMVectorSet(screenX, screenY, 5.0f, 0.0f),
0.0f,
0.0f,
screenWidth,
screenHeight,
0.0f,
1.0f,
projectionMatrix,
viewMatrix,
modelMatrix);

XMVECTOR rayOrigin = XMVector3Unproject(XMVectorSet(screenX, screenY, 0.0f, 0.0f),
0.0f,
0.0f,
screenWidth,
screenHeight,
0.0f,
1.0f,
projectionMatrix,
viewMatrix,
modelMatrix);

// Code to retrieve v0, v1 and v2 is omitted
auto diff = v - rayOrigin;
auto diffNorm = XMVector3Normalize(diff);

XMVECTOR v2 = XMVector3Unproject(XMVectorSet(screenX, screenY, 5.0f, 0.0f),
0.0f,
0.0f,
screenWidth,
screenHeight,
0.0f,
1.0f,
projectionMatrix,
viewMatrix2,
modelMatrix);

XMVECTOR rayOrigin2 = XMVector3Unproject(XMVectorSet(screenX, screenY, 0.0f, 0.0f),
0.0f,
0.0f,
screenWidth,
screenHeight,
0.0f,
1.0f,
projectionMatrix,
viewMatrix2,
modelMatrix);

auto diff2 = v2 - rayOrigin2;
auto diffNorm2 = XMVector3Normalize(diff2);

printf("hi");
return true;
}

int main()
{
SetViewMatrix();
SetProjectionMatrix(1000, 1000, 0.0f, 1.0f);
SetModelMatrix();

SelectObject(500, 500, 1000, 1000);

return 0;
}

Пожалуйста, проверьте вашу заявку с этим кодом и подтвердите. Вы увидите, что код такой же, как ваш предыдущий код. Единственное добавление — начальные значения параметров камеры, вычисление матрицы 2-го вида в SetViewMatrix() с помощью XMMatrixLookAtRH метод и вычисления векторов с использованием обеих матриц вида в SelectObject(),

Нет необходимости транспонировать

Мне не нужно было транспонировать какую-либо матрицу. Транспонирование не должно требоваться для проекция а также модель матрицы, потому что они обе являются диагональными матрицами, и их транспонирование даст одну и ту же матрицу. Я не думаю, что транспонирование Посмотреть матрица обязательна. Формула XMMatrixLookAtRH объяснил Вот обеспечивает матрицу просмотра точно так же, как у вас. Также приведен пример проекта Вот не транспонирует свои матрицы при проверке пересечения. Вы можете скачать и проверить пример проекта.

Возможные источники проблем

1) Инициализация: единственный код, который я не смог увидеть, это ваша инициализация m_cameraZAxis, m_cameraXAxis, nearZ, farZ параметры и т. д. Кроме того, я не использовал ваши функции вращения камеры. Как вы можете видеть, я инициализировал камеру, используя для расчета векторы положения, цели и направления. Проверьте, если ваш первоначальный расчет m_cameraZAxis согласуется с моим примером кода.

2) LH / RH внешний вид: убедитесь, что нет случайного смешения левая рука а также правая рука выглядит в любом месте вашего кода.

3) Проверьте, если ваш код вращения (ChangeCameraPitch или же ChangeCameraYaw) случайно создает оси камеры, которые не ортогональный. Вы используете камеру Ось ординат как вход в ChangeCameraYaw и как вывод в ChangeCameraPitch, Но Ось ординат сбрасывается в SetViewMatrix по перекрестному произведению или осям X и Z. Таким образом, более раннее значение оси Y может быть потеряно.

Удачи с вашим приложением! Скажите, если вы найдете правильное решение и причину вашей проблемы.

3

Как уже упоминалось, проблема не была полностью решена, хотя щелчок теперь работает. Проблема с искажением модели при перемещении камеры, которая, как я подозревал, связана, все еще существовала. То, что я имел в виду под «искаженной моделью», видно на следующем рисунке:

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

Левое изображение показывает, как выглядит модель, когда камера расположена в центре мира, то есть (0, 0, 0), а правое изображение показывает, что происходит, когда я перемещаю камеру в отрицательном направлении оси Y. Как можно видеть, модель расширяется внизу и уменьшается в верхней части, что аналогично описанному в ссылка на сайт Я уже предоставил выше.

В конечном итоге я решил обе проблемы:

  1. Транспонировать матрицы перед передачей их в XMVector3Unproject (уже описанный выше)
  2. Транспонировал матрицу моего взгляда, изменив код SetViewMatrix метод (см. код ниже)

SetViewMatrix Теперь метод выглядит следующим образом:

void Camera::SetViewMatrix()
{
XMFLOAT3 cameraPosition;
XMFLOAT3 cameraXAxis;
XMFLOAT3 cameraYAxis;
XMFLOAT3 cameraZAxis;

XMFLOAT4X4 viewMatrix;

// Keep camera's axes orthogonal to each other and of unit length.
m_cameraZAxis = XMVector3Normalize(m_cameraZAxis);
m_cameraYAxis = XMVector3Normalize(XMVector3Cross(m_cameraZAxis, m_cameraXAxis));

// m_cameraYAxis and m_cameraZAxis are already normalized, so there is no need
// to normalize the below cross product of the two.
m_cameraXAxis = XMVector3Cross(m_cameraYAxis, m_cameraZAxis);

// Fill in the view matrix entries.
float x = -XMVectorGetX(XMVector3Dot(m_cameraPosition, m_cameraXAxis));
float y = -XMVectorGetX(XMVector3Dot(m_cameraPosition, m_cameraYAxis));
float z = -XMVectorGetX(XMVector3Dot(m_cameraPosition, m_cameraZAxis));

//XMStoreFloat3(&cameraPosition, m_cameraPosition);
XMStoreFloat3(&cameraXAxis, m_cameraXAxis);
XMStoreFloat3(&cameraYAxis, m_cameraYAxis);
XMStoreFloat3(&cameraZAxis, m_cameraZAxis);

viewMatrix(0, 0) = cameraXAxis.x;
viewMatrix(0, 1) = cameraXAxis.y;
viewMatrix(0, 2) = cameraXAxis.z;
viewMatrix(0, 3) = x;

viewMatrix(1, 0) = cameraYAxis.x;
viewMatrix(1, 1) = cameraYAxis.y;
viewMatrix(1, 2) = cameraYAxis.z;
viewMatrix(1, 3) = y;

viewMatrix(2, 0) = cameraZAxis.x;
viewMatrix(2, 1) = cameraZAxis.y;
viewMatrix(2, 2) = cameraZAxis.z;
viewMatrix(2, 3) = z;

viewMatrix(3, 0) = 0.0f;
viewMatrix(3, 1) = 0.0f;
viewMatrix(3, 2) = 0.0f;
viewMatrix(3, 3) = 1.0f;

m_modelViewProjectionConstantBufferData->view = viewMatrix;
}

Поэтому я просто обменялся координатами строк и столбцов. Обратите внимание, что я должен был убедиться, что мой ChangeCameraYaw метод вызывается до моего ChangeCameraPitch метод. Это необходимо, потому что ориентация модели иначе не такая, как я хочу.

Существует также другой подход, который можно использовать. Вместо того, чтобы транспонировать матрицу вида путем замены координат строки и столбца и транспонирования перед передачей в XMVector3Unproject, я мог бы использовать row_major Ключевое слово в вершинном шейдере вместе с матрицей вида:

cbuffer ModelViewProjectionConstantBuffer : register(b0)
{
matrix model;
row_major matrix view;
matrix projection;
};

Я наткнулся на эту идею в этот Сообщение блога. Ключевое слово row_major влияет на то, как шейдерный компилятор интерпретирует матрицу в памяти. Этого также можно добиться, изменив порядок умножения матрицы векторов в вершинном шейдере, т. Е. Используя pos = mul(view, pos); вместо pos = mul(pos, view);

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

1
По вопросам рекламы [email protected]