Чтобы определить, нажал ли пользователь какой-либо из моих 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
камеры моя модель полностью искажается.
Кто-нибудь может и готов помочь?
Спасибо за подсказку, Капил. Я попробовал 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 этот проводка.
Мне пока не удалось решить эту проблему. Простое перемещение матрицы представления не решает ее. Тем не менее, моя основная проблема решена, и моя модель, наконец, кликабельна.
Если кому-то есть что добавить и пролить свет на то, почему матрицы нужно транспонировать или почему перемещение камеры искажает модель, пожалуйста, продолжайте и оставляйте комментарии или ответы.
Я использовал 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 вместо вашего текущего подхода.
Я могу получить равные значения 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 может быть потеряно.
Удачи с вашим приложением! Скажите, если вы найдете правильное решение и причину вашей проблемы.
Как уже упоминалось, проблема не была полностью решена, хотя щелчок теперь работает. Проблема с искажением модели при перемещении камеры, которая, как я подозревал, связана, все еще существовала. То, что я имел в виду под «искаженной моделью», видно на следующем рисунке:
Левое изображение показывает, как выглядит модель, когда камера расположена в центре мира, то есть (0, 0, 0), а правое изображение показывает, что происходит, когда я перемещаю камеру в отрицательном направлении оси Y. Как можно видеть, модель расширяется внизу и уменьшается в верхней части, что аналогично описанному в ссылка на сайт Я уже предоставил выше.
В конечном итоге я решил обе проблемы:
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);
Вот и все. Эти две проблемы действительно взаимосвязаны, но, используя то, что я разместил в этом вопросе, я смог решить обе проблемы, поэтому я принимаю свой ответ как ответ на этот вопрос. Надеюсь, это поможет кому-то в будущем.