Поверните сферу так, чтобы ее полюс направился к камере

У меня есть сфера, северный полюс которой находится в точке (0, 0, 1), а центр - в точке (0, 0, 0). У меня также есть камера, произвольно расположенная в сцене и смотрящая на (0, 0, 0). Я хочу повернуть сферу так, чтобы ее северный полюс лежал на линии от (0, 0, 0) до положения камеры. Я выполняю эту задачу в вершинном шейдере и хотел бы, чтобы она была максимально простой, чтобы избежать падения FPS. Кто-нибудь знает какой-нибудь простой метод, как вычислить матрицу вращения или даже более простой способ, как выполнить вращение вершин сферы?

2 ответа

Решение

Матрица вращения довольно проста в исполнении.

Если вы считаете матрицу состоящей из 4 строк.

Сторона вектора вверх вектор вперед вектор позиции

Вы вычисляете вектор от 0, 0, 0 до камеры. Это просто (camX, camY, camZ) (рассчитывается как положение камеры - происхождение объекта).

Оттуда у вас теперь есть ваш прямой вектор. Сначала нормализуй это.

Итак, давайте предположим, что вектор роста равен 0, 1, 0.

Вы можете просто скрестить этот вектор вверх и нормализованный вектор вперед. Это дает вам побочный вектор. Наконец, скрестите произведение боковых и прямых векторов, чтобы получить ИСТИНА вверх. и у вас есть 3 верхних ряда вашей матрицы. Финальная строка будет 0,0,0,1 в любом случае в вашем примере.

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

 D3DXVECTOR3 toCam = camPos - spherePos;
 D3DXVECTOR3 fwdVector;
 D3DXVec3Normalize( &fwdVector, &toCam );

 D3DXVECTOR3 upVector( 0.0f, 1.0f, 0.0f );
 D3DXVECTOR3 sideVector;
 D3DXVec3CrossProduct( &sideVector, &upVector, &fwdVector );
 D3DXVec3CrossProduct( &upVector, &sideVector, &fwdVector );

 D3DXVec3Normalize( &upVector, &toCam );
 D3DXVec3Normalize( &sideVector, &toCam );

 D3DXMATRIX orientation( sideVector.x, sideVector.y, sideVector.z, 0.0f,
                         upVector.x,   upVector.y,   upVector.z,   0.0f,
                         fwdVector.x,  fwdVector.y,  fwdVector.z,  0.0f,
                         spherePos.x,  spherePos.y,  spherePos.z,  1.0f );

Если вам нужна простейшая матрица вращения, это самое лучшее, что вы можете сделать:

ρ = sqrt (x 2 + y 2)
r = sqrt (x 2 + y 2 + z 2)


M =  x/ρ        -y/ρ     x/r
     y z/(r ρ)   x/ρ     y/r
    -ρ/r         0     z/r
Самое простое вращение будет включать более сложную матрицу.

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