Я просматриваю все учебные пособия по MS по DirectX и заметил, что они всегда передают в метод матрицы World, View и Projection, а затем умножают их в вершинном шейдере.
Есть ли причина сделать это вместо того, чтобы умножать матрицы перед рисованием и затем передавать одну матрицу WVP шейдеру? Таким образом, матрицы будут умножаться один раз на кадр, а не один раз на вершину, верно?
Заранее спасибо.
Изменить: обновлено с примером кода
Уроки MS:
matrix World;
matrix View;
matrix Projection;
struct VS_INPUT
{
float4 Pos : POSITION;
float4 Color : COLOR;
};
struct VS_OUTPUT
{
float4 Pos : SV_POSITION;
float4 Color : COLOR;
};
PS_INPUT VS( VS_INPUT input )
{
VS_OUTPUT output;
output.Pos = mul( input.Pos, World );
output.Pos = mul( output.Pos, View );
output.Pos = mul( output.Pos, Projection );
output.Color = input.Color;
return output;
}
Почему бы не так
matrix WVP;
struct VS_INPUT
{
float4 Pos : POSITION;
float4 Color : COLOR;
};
struct VS_OUTPUT
{
float4 Pos : SV_POSITION;
float4 Color : COLOR;
};
PS_INPUT VS( VS_INPUT input )
{
VS_OUTPUT output;
output.Pos = mul( input.Pos, WVP );
output.Color = input.Color;
return output;
}
В этом примере ваше предложение о предварительном умножении матриц мира, ракурса и проекции имеет смысл и будет более эффективным. Я не уверен, почему учебники держат их отдельно для этого простого примера.
Иногда имеет смысл держать их отдельно (или держать матрицу мира отдельно и иметь комбинированную матрицу проекции вида). Иногда вы можете захотеть сделать освещение в мировом пространстве, а не в объектном пространстве, например, чтобы получить доступ к позиции вершины мирового пространства в вершинном шейдере. Если вы выполняете какое-то создание экземпляров, вы можете разделить матрицу космического мира, на что указывает DeadMG. Во многих случаях, хотя вы захотите объединить их, как вы предлагаете.
Потому что матрица Мира меняется для каждого объекта. Если вы передадите матрицу WVP шейдеру, вам придется менять эту матрицу каждый раз, когда вы перерисовываете — очень неэффективно, и вы будете умножать ее на ЦП, что также будет очень медленным. С другой стороны, вы можете отправить все мировые матрицы в графический процессор одновременно в аппаратном буфере экземпляров, а затем умножить их все на графическом процессоре, который на самом деле ничем не соответствует масштабу современного графического процессора, и затем выполнить один вывод. вызов.
Короче говоря, когда вы добавляете аппаратное копирование, то это делается в шейдере. значительно более эффективным.
Я думаю, что каждая матрица может меняться в каждом кадре. Если вы не смотрите таким же образом для некоторых, вид может измениться, если вы расположите вид с камеры под другим углом или координатами, чтобы наблюдать за миром / объектами.
Таким образом, матрицы будут умножаться один раз за кадр вместо
один раз на вершину, верно?
Термин «на кадр» здесь не имеет смысла. Почему мы называем его вершинным шейдером? потому что это процесс для каждой вершины, поэтому независимо от того, где вы умножаете матрицу 3 в одну (вне или внутри шейдера), каждая вершина должна применяться к этой единственной матрице перед рисованием. и GPU — лучший выбор для такой задачи, как вычисление вектора / матрицы и другая графическая обработка.