Як насправді шейдер 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 вершини проходить через кожну вершину, а потім змінює їх на все, що у мене є у функції, а вихід - те, що було змінено ... і аналогічно для піксельного шейдера?

Ще одна плутанина, я знаю, що таке піксель, і я розумію, що таке вершина ... але що саме робить шейдер пікселів?


Це нормально, ніхто не робить
bobobobo

Відповіді:


10

Як це ...... знаю, що змінити .... Я точно заплутався в трубопроводі між HLSL та власними пікселями / вершинами на екрані.

Це працює приблизно так: при видачі виклику малювання (DrawPrimitive, DrawIndexedPrimitive у D3D, Draw у 10+ тощо) обробляються дані геометрії, які ви прив'язали до конвеєра (ваші вершинні буфери). Для кожної вершини шейдер вершин виконується для отримання вихідної вершини у просторі кліпу.

Потім GPU виконує деякі фіксовані функції у цій вершині простору кліпів, такі як відсікання / відсікання та виведення вершини в екранний простір, де вона починає розсіювати трикутники. Під час растеризації кожного трикутника GPU інтерполює атрибути вершин по всій поверхні цього трикутника, подаючи кожен інтерпольований атрибут піксельній шейдері для отримання напівфінального кольору для цього пікселя (змішування застосовується після виконання піксельного шейдера, таким чином "напів- остаточний »).

це те, що насправді "застосовує" їх:

Код, який ви опублікували, спочатку компілює шейдери, а потім прив'язує їх до конвеєра, де вони залишаються активними для будь-яких наступних дзвінків на розтягнення до зміни. Це насправді не призводить до їх виконання.

Може хтось може пояснити, що це робить, припускаючи, що функція HLSL вершини проходить через кожну вершину (як вхідне положення: ПОЗИЦІЯ та колір: КОЛІР), а потім змінює їх на все, що у мене є у функції, а вихід - те, що було змінено. ... (те саме стосується і Pixel Shader).

Ще одна плутанина, я знаю, що таке піксель, і я розумію, що таке вершина ..... але що саме робить шейдер Pixel ......

Вершина шейдера відповідає за перетворення вершин з простору моделі в простір кліпу.

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


9

Я спробую пояснити, як все працює, не використовуючи багато жаргону.

Якщо простота, а не інтерактивна швидкість, викликає занепокоєння, 3D-поверхня в комп'ютері буде просто величезною хмарою точок у просторі, досить щільною, щоб ми могли просто виводити кожну точку окремо, без прогалин між ними.

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

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

Це чи не найпростіший "вершиновий шейдер", який можна уявити: він переходить у вершинну позицію з пам'яті, а назовні виходить нова вершина, наполовину більша. Напівширша вершина не зберігається в пам'яті - вона використовується негайно для візуалізації, а потім викидається.

Хоча груба спрощеність, яка не має ключових понять , це в дусі описує аспекти того, як фільми роблять графіку.

Інтерактивна графіка (ігри) не може дозволити собі бути такою простою, тому що їм потрібно візуалізувати графіку на кілька порядків швидше, ніж фільм.

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

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

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

out.color = in.color;

Це чи не найпростіший "піксельний шейдер", який можна уявити: він поєднує кольори трьох вершин вершин, а з одного виходить один і той же колір. Входи надходять з виходів "вершинного шейдера", а виходи записуються на екран в пам'ять.

Отже - "вершина шейдера" - це програма, яка працює всередині чіпа GPU. Його вхід є "вершинним буфером" в пам'яті GPU, а його вихід подається безпосередньо в "піксельний шейдер". "Піксельний шейдер" - це також програма, яка працює всередині чіпа GPU. Його входи - це суміш трьох вершин із вершинного шейдера, а його вихід - піксель на екрані.



-2

Не хвилюйтесь про піксельний шейдер прямо зараз. Якщо ви є початківець, вам слід привітатись світу GLSL / HLSL лише з вершинами та фрагментами. Як тільки ви знайомі, і ви почнете розуміти змінний рух і таке інше, тоді розширіть свій кругозір.

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

Іди чемпіон!


1
Фрагментний шейдер виконує ту ж функцію, що і піксельний шейдер.

1
Я не думаю, що ми можемо сказати з питання, чи є ОП початківцем у всіх ігрових програмуваннях - він лише заявив, що він є початківцем у написанні шейдерного коду. Навчитися писати шейдери - це дуже важливий інструмент, який можна мати в сараї для розробників ігор, я б не просто обмацував їх, якщо ви не знаходитесь лише на самих початкових етапах навчання ігор.
Ольховський
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.