При работе с 3D-графикой, образцы шейдеров ОБЫЧНО используют следующую операцию для преобразования векторного положения:
result = mul(matrix, vector);
Это, очевидно, означает то же, что и:
result = mul(vector, matrix_transposed);
Кроме того, просто чтобы упомянуть, большинство библиотек линейной алгебры предпочитают оставлять операцию умножения vector * matrix
только для простоты.
Теперь: скажем, я хочу преобразовать некоторую vector
(например, позицию) , используя некоторую конкретную матрицу (чтобы бетон, давайте использовать D3DX
матричные операции) . Итак, я создаю простую матрицу проекции мировоззрения и затем передаю ее моему шейдеру.
D3DXMatrixRotationX(&world, 0.05f);
D3DXMatrixLookAtLH(&view, &D3DXVECTOR3(400.0f, 80.0f, 0.0f),
&D3DXVECTOR3(0.1f, 0.1f, 0.0f),
&D3DXVECTOR3(0.0f, 1.0f, 0.0f));
D3DXMatrixPerspectiveFovLH(&projection, 0.5f, 800.0f / 600.0f, 1.0f, 1500.0f);
D3DXMATRIX wvp = world * view * projection;
Set Shader Parameter (wvp); // Pseudocode here
Вопрос:
И вот часть, которую я не могу понять - если все сделано таким образом, код шейдера должен быть
result = mul(vector, wvp)
, чтобы это преобразование работало (вектор умножается с левой стороны матрицы).
Почему это происходит? Как большинство образцов шейдеров имеют внутри себя преобразование result = mul(wvp, vector)
(и они не транспонируют матрицу перед установкой ее в качестве параметра)?
Где я не прав?
Спасибо.
Немного больше информации - матрица D3DX
имеет выравнивание по маске строки , и я использую соответствующую функцию, которая принимает матрицу маску строки в качестве параметра (cgSetMatrixParameterfr
в моем конкретном случае).
Конечно, я мог бы "транспонировать" эту матрицу, вызывая функцию cgSetMatrixParameterfc
, которая обрабатывает входные данные как матрицу основных столбцов (и "автоматически" транспонирует это), но это было бы смешно.