Как шейдер HLSL на самом деле влияет на вывод рендера?

11

Я понимаю синтаксис HLSL, например, давайте представим, что у меня это HLSL:

struct VOut
{
    float4 position : SV_POSITION;
    float4 color : COLOR;
};

VOut VShader(float4 position : POSITION, float4 color : COLOR)
{
    VOut output;

    output.position = position;
    output.position.xy *= 0.7f;    // "shrink" the vertex on the x and y axes
    output.color = color;

    return output;
}


float4 PShader(float4 position : SV_POSITION, float4 color : COLOR) : SV_TARGET
{
    return color;
}

и я собираю это так:

D3DX11CompileFromFile(L"shaders.hlsl", 0, 0, "VShader", "vs_5_0", 0, 0, 0, &VS, 0, 0);
D3DX11CompileFromFile(L"shaders.hlsl", 0, 0, "PShader", "ps_5_0", 0, 0, 0, &PS, 0, 0);

Как это нравится ... знать, чтобы изменить ... Я не совсем понимаю, каков конвейер между HLSL и фактическими пикселями / вершинами на экране.

Является ли это то, что на самом деле «относится» их?

dev->CreateVertexShader(VS->GetBufferPointer(), VS->GetBufferSize(), NULL, &pVS);
dev->CreatePixelShader(PS->GetBufferPointer(), PS->GetBufferSize(), NULL, &pPS);

// set the shader objects
devcon->VSSetShader(pVS, 0, 0);
devcon->PSSetShader(pPS, 0, 0);

Имейте в виду, я как буквальный новичок в этом деле. Может кто-то может объяснить, что он делает? Я предполагаю, что функция вершины HLSL проходит через каждую вершину, а затем меняет их на то, что у меня есть в функции, и вывод - что изменилось ... и аналогично для пиксельного шейдера?

Еще одна путаница, я знаю, что такое пиксель, и я понимаю, что такое вершина ... но что именно делает пиксельный шейдер?


источник
Это нормально, никто не делает
бобобо

Ответы:

10

Как это нравится ... знаю, чтобы изменить .... Я запутался точно в конвейере между HLSL и фактическими пикселями / вершинами на экране.

Это работает примерно так: при вызове отрисовки (DrawPrimitives, DrawIndexedPrimitives в D3D, Draw в 10+ и т. Д.) Обрабатываются данные геометрии, которые вы привязали к конвейеру (ваши буферы вершин). Для каждой вершины выполняется вершинный шейдер для создания выходной вершины в пространстве клипа.

Затем графический процессор выполняет некоторые фиксированные функции для этой вершины пространства клипа, такие как отсечение / отбраковка и перенос вершины в пространство экрана, где он начинает растеризацию треугольников. Во время растеризации каждого треугольника графический процессор интерполирует атрибуты вершин по всей поверхности этого треугольника, подавая каждый интерполированный атрибут в пиксельный шейдер, чтобы получить полуфинальный цвет для этого пикселя (смешивание применяется после выполнения пиксельного шейдера, таким образом, «полу окончательный ").

это то, что на самом деле «применяет» их:

Код, который вы опубликовали, сначала компилирует шейдеры, затем связывает их с конвейером, где они остаются активными для любых последующих вызовов отрисовки, пока не будут изменены. На самом деле это не заставляет их казняться.

Может кто-то, возможно, объяснить, что он делает, им предполагая, что функция Vertex HLSL проходит через каждую вершину (как входная позиция: положение и цвет: COLOR), а затем меняет их на то, что у меня есть в функции, а на выходе, что было изменено. ... (то же самое касается Pixel Shader).

Еще одно заблуждение, я знаю, что пиксель, и я понимаю, что такое вершина ..... но что именно делает пиксельный шейдер делать ......

Вершинный шейдер отвечает за преобразование вершин из пространства модели в пространство клипа.

Пиксельный шейдер отвечает за вычисление предпоследнюю цвета / глубин для пикселя на основе интерполированных атрибутов вершин.


источник
9

Я попытаюсь объяснить, как все работает, без использования большого жаргона.

Если вас интересует простота, а не интерактивная скорость, трехмерная поверхность в компьютере будет просто огромным облаком точек в пространстве, достаточно плотным, чтобы мы могли просто визуализировать каждую точку отдельно, без промежутков между ними.

Вы хотите сохранить модель только один раз в памяти, но вам нужно отобразить ее в различных размерах и под разными углами, поэтому при рендеринге 3D-модели вам необходимо «преобразовать» все точки, когда вы читаете их из памяти. Например, чтобы визуализировать модель на 50% больше, вам нужно масштабировать позиции точек вдвое:

out.position = in.position * 0.5;
out.color = in.color;

Это почти простейший «вершинный шейдер», который только можно себе представить: вход в позицию вершины из памяти и выход новой позиции вершины, наполовину меньше. Половина большой вершины не сохраняется в памяти - она ​​сразу используется для рендеринга, а затем выбрасывается.

Несмотря на грубое упрощение, в котором отсутствуют ключевые понятия , это в духе описывает аспекты, как фильмы делают графику.

Интерактивная графика (игры) не может позволить себе быть такой простой, потому что им нужно визуализировать графику на несколько порядков быстрее, чем фильм.

В играх, мы не можем позволить себе, чтобы сделать одну точку для каждого пикселя на экране, а также дополнительные услуги, чтобы покрыть пробелы. Таким образом, в качестве компромисса, промежуток между каждыми тремя близлежащими точками отображается в виде треугольника, который по различным техническим причинам предпочитает иметь размер экрана не менее 10 пикселей.

Трехмерный треугольник может быть спроецирован на 2D-экран, а затем разделен на стопку 1D линий, каждая из которых может быть разделена на стопку 0D пикселей. Таким образом, мы можем разделить и победить проблему рендеринга трехмерного треугольника в более простую задачу рендеринга большого количества 0D пикселей по отдельности. Компьютер может решить более простые задачи за меньшее время.

Пиксель затенение небольшой программа, которая бежит на каждом пикселе так генерируемый от разборки треугольника.

out.color = in.color;

Это почти самый простой «пиксельный шейдер», какой только можно представить: в нем смешиваются цвета трех треугольных вершин, а в другом - тот же цвет. Входные данные поступают с выходов «вершинного шейдера», а выходные данные записываются на экран в памяти.

Итак, «вершинный шейдер» - это программа, которая работает внутри чипа GPU. Его вход представляет собой «вершинный буфер» в памяти графического процессора, а его выход подается непосредственно в «пиксельный шейдер». «Пиксельный шейдер» - это также программа, которая работает внутри чипа GPU. Его входные данные представляют собой смесь трех вершин из вершинного шейдера, а его выходные данные представляют собой пиксель на экране.

bmcnett
источник
-2

Не беспокойтесь о пиксельном шейдере прямо сейчас. Если вы начинающий, вы должны быть привет мир из GLSL / HLSL только с вершин и фрагментов шейдеров. Как только вы познакомитесь и начнете понимать переменные движения и тому подобное, расширьте свой кругозор.

Я очень рекомендую учебник, чтобы понять, как работает API. Книги OpenGL также хорошо иллюстрируют, как за прошедшие годы произошли изменения от фиксированного конвейера к динамически программируемому конвейеру.

Иди чемпион!

Брайан С
источник
1
Фрагментный шейдер выполняет ту же функцию, что и пиксельный шейдер.
1
Я не думаю, что мы можем судить по вопросу, является ли OP новичком во всех игровых программах - он только заявил, что он новичок в написании шейдерного кода. Обучение написанию шейдеров - очень важный инструмент, который должен быть в сарае разработчика игр, я бы не стал просто замазывать их, если только вы не находитесь на самых ранних этапах изучения разработки игр.
Ольховский