Как это работает при вычислении карты глубины?
-
19-09-2019 - |
Вопрос
С этого сайта: http://www.catalinzima.com/?page_id=14
Меня всегда смущало, как рассчитывается карта глубины.
Функция вершинного шейдера вычисляет положение следующим образом:
VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
{
VertexShaderOutput output;
float4 worldPosition = mul(input.Position, World);
float4 viewPosition = mul(worldPosition, View);
output.Position = mul(viewPosition, Projection);
output.TexCoord = input.TexCoord; //pass the texture coordinates further
output.Normal =mul(input.Normal,World); //get normal into world space
output.Depth.x = output.Position.z;
output.Depth.y = output.Position.w;
return output;
}
Что такое output.Position.z и output.Position.w?Я не уверен в математике, стоящей за этим.
А в пиксельном шейдере есть такая строка:вывод.Глубина = ввод.Глубина.x / ввод.Глубина.y;
Итак, вывод.Глубина - это вывод.Position.z / outputPOsition.w?Почему мы это делаем?
Наконец, в точечном световом шейдере (http://www.catalinzima.com/?page_id=55) чтобы преобразовать этот вывод в позицию, код:
//read depth
float depthVal = tex2D(depthSampler,texCoord).r;
//compute screen-space position
float4 position;
position.xy = input.ScreenPosition.xy;
position.z = depthVal;
position.w = 1.0f;
//transform to world space
position = mul(position, InvertViewProjection);
position /= position.w;
опять же, я этого не понимаю.Я вроде понимаю, почему мы используем InvertViewProjection, поскольку ранее мы умножали на проекцию вида, но то, что все z и теперь w делятся на 1, после чего вся позиция делится на w, меня немного смущает.
Решение
Чтобы полностью понять это, вам нужно понять, как работает алгебра, лежащая в основе 3D-преобразований.SO на самом деле не помогает (или я не знаю, как его использовать) выполнять матричную математику, поэтому это должно быть без причудливых формул.Однако вот некоторое высокоуровневое объяснение:
Если вы присмотритесь повнимательнее, то заметите, что все преобразования, которые происходят с положением вершины (от модели к миру, от вида к координатам клипа), выполняются с использованием 4D векторов.Это верно.4D.Зачем, когда мы живем в трехмерном мире ?Потому что в этом 4D-представлении все преобразования, которые мы обычно хотим выполнить с вершинами, можно выразить как матричное умножение.Это не тот случай, если мы останемся в 3D-представлении.А матричное умножение - это то, в чем хорош графический процессор.
Чему соответствует вершина в 3D в 4D ?Вот тут-то все и становится интересным.В (x, y, z)
точка соответствует прямой (a.x, a.y, a.z, a)
.Мы можем захватить любую точку на этой прямой, чтобы выполнить нужные нам вычисления, и обычно выбираем самую простую, a=1
(таким образом, нам не нужно выполнять никакого умножения, просто установите w=1
).
Так что это отвечает практически на все вопросы по математике, которые вы рассматриваете.Чтобы спроецировать 3D-точку в 4D, мы устанавливаем w = 1, чтобы получить обратно компонент из 4D-вектора, который мы хотим сравнить с нашими стандартными размерами в 3D, мы должны разделить этот компонент на w .
Эта система координат, если вы хотите погрузиться глубже, называется homogeneous coordinates
.