W jaki sposób moduł cieniujący HLSL wpływa na wynik renderowania?

11

Rozumiem składnię HLSL, na przykład udajmy, że mam to jako mój 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;
}

i kompiluję to w ten sposób:

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);

Jak to jest ... wiedzieć, że się zmienia ... Nie jestem pewien, co dokładnie potok między HLSL a rzeczywistymi pikselami / wierzchołkami na ekranie.

Czy to właśnie ich „stosuje”?

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);

Pamiętaj, że jestem jak dosłowny początkujący w tych sprawach. Czy ktoś może wyjaśnić, co robi? Zakładam, że funkcja HLSL wierzchołka przechodzi przez każdy wierzchołek, a następnie zmienia je na cokolwiek mam w funkcji, a wyjście jest tym, co zostało zmienione ... i podobnie w przypadku modułu cieniującego piksele?

Kolejne zamieszanie, wiem, co to jest piksel i rozumiem, co to jest wierzchołek ... ale co dokładnie robi moduł cieniujący piksele?


źródło
W porządku, nikt tego nie robi
Bobobobo

Odpowiedzi:

10

Jak to jest ... wiedzieć, że się zmienia ... Jestem zmieszany dokładnie na potoku między HLSL a rzeczywistymi pikselami / wierzchołkami na ekranie.

Działa to mniej więcej tak: po wydaniu wywołania remisowego (DrawPrimitives, DrawIndexedPrimitives w D3D, Draw w 10+ itp.) Przetwarzane są dane geometrii związane z rurociągiem (bufory wierzchołków). Dla każdego wierzchołka moduł cieniujący wierzchołek jest wykonywany w celu utworzenia wierzchołka wyjściowego w przestrzeni klipu.

Następnie GPU wykonuje pewne stałe funkcje na wierzchołku przestrzeni wycinania, takie jak przycinanie / wygładzanie i przenoszenie wierzchołka na przestrzeń ekranu, gdzie zaczyna rasteryzować trójkąty. Podczas rasteryzacji każdego trójkąta GPU interpoluje atrybuty wierzchołków na powierzchni tego trójkąta, dostarczając każdy interpolowany atrybut do modułu cieniującego piksele w celu uzyskania półfinałowego koloru dla tego piksela (mieszanie jest stosowane po wykonaniu modułu cieniującego pikseli, a zatem „pół- finał").

czy to właśnie ich „stosuje”:

Kod, który opublikowałeś, najpierw kompiluje shadery, a następnie wiąże je z potokiem, gdzie pozostają aktywne dla kolejnych wywołań losowania, dopóki nie zostaną zmienione. W rzeczywistości nie powoduje ich wykonania.

Czy ktoś może wyjaśnić, co robi, zakładając, że funkcja HLSL wierzchołka przechodzi przez każdy wierzchołek (jako pozycja wejściowa: POZYCJA i kolor: KOLOR), a następnie zmienia je na cokolwiek mam w funkcji, a wynik jest tym, co zostało zmienione. ... (to samo dotyczy Pixel Shader).

Kolejne zamieszanie, wiem, co to jest piksel i rozumiem, co to jest wierzchołek ..... ale czym dokładnie jest moduł cieniujący Pixel ......

Moduł cieniujący wierzchołki jest odpowiedzialny za przekształcanie wierzchołków z obszaru modelu do obszaru przycinania.

Moduł cieniujący pikseli odpowiada za obliczenie przedostatniego koloru / głębokości dla piksela na podstawie interpolowanych atrybutów wierzchołków.


źródło
9

Spróbuję wyjaśnić, jak to działa, nie używając dużo żargonu.

Jeśli zależy Ci na prostocie niż na prędkości interaktywnej, powierzchnia 3D w komputerze byłaby po prostu ogromną chmurą punktów w przestrzeni, wystarczająco gęstą, abyśmy mogli renderować każdy punkt indywidualnie, bez przerw między nimi.

Chcesz zapisać model tylko raz w pamięci, ale musisz go wyświetlić w różnych rozmiarach i pod różnymi kątami, więc podczas renderowania modelu 3D musisz „przekształcić” wszystkie punkty podczas odczytywania ich z pamięci. Na przykład, aby renderować model o 50% jako duży, musisz przeskalować pozycje punktów o połowę:

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

Jest to prawie najprostszy „moduł cieniujący wierzchołek”, jaki można sobie wyobrazić: weźmie pozycję pamięci z pamięci, a wyjdzie nowa pozycja wierzchołka, w połowie tak duża. Pół-duży wierzchołek nie jest zapisywany z powrotem w pamięci - jest natychmiast wykorzystywany do renderowania, a następnie wyrzucany.

Chociaż rażące uproszczenie, które nie ma kluczowych pojęć , w duchu opisuje aspekty, w jaki filmy robią grafikę.

Interaktywna grafika (gry) nie może sobie pozwolić na takie proste, ponieważ muszą renderować grafikę o kilka rzędów wielkości szybciej niż film.

W grach nie możemy sobie pozwolić na wyrenderowanie jednego punktu na każdy piksel na ekranie, a także dodatków na pokrycie braków. Tak więc, jako kompromis, przerwa między każdym z trzech pobliskich punktów jest renderowana jako trójkąt, który z różnych przyczyn technicznych woli mieć co najmniej 10 pikseli dużych na ekranie.

Trójkąt 3D można wyświetlić na ekranie 2D, a następnie podzielić na stos linii 1D, z których każdy można podzielić na stos pikseli 0D. W ten sposób możemy podzielić i pokonać problem renderowania trójkąta 3D w prostszy problem renderowania wielu pikseli 0D w izolacji. Komputer może rozwiązać prostsze problemy w krótszym czasie.

Moduł cieniujący piksele to mały program uruchamiany na każdym pikselu, który jest generowany z dezasemblacji trójkąta.

out.color = in.color;

Jest to prawie najprostszy „moduł cieniujący pikseli”, jaki można sobie wyobrazić: wchodzi mieszanka kolorów trzech trójkątów i wychodzi ten sam kolor. Wejścia pochodzą z wyjść „shadera wierzchołków”, a wyjścia są zapisywane na ekranie w pamięci.

Tak więc - „shader wierzchołków” to program działający w układzie GPU. Jego wejściem jest „bufor wierzchołków” w pamięci GPU, a jego wyjście jest podawane bezpośrednio do „shadera pikseli”. „Moduł cieniujący piksele” to także program działający w układzie GPU. Jego dane wejściowe są połączeniem trzech wierzchołków z modułu cieniującego wierzchołki, a jego wynik to piksel na ekranie.

bmcnett
źródło
-2

Nie martw się teraz o moduł cieniujący pikseli. Jeśli jesteś całkowicie początkującym, powinieneś być cześć światem GLSL / HLSL z tylko shaderem wierzchołków i fragmentów. Kiedy już się zaznasz i zaczniesz rozumieć ruch zmienny itp., Poszerz swoje horyzonty.

Zdecydowanie polecam podręcznik, aby dowiedzieć się, jak działa API. Książki OpenGL również wykonują dobrą robotę ilustrując, jak zmieniły się rzeczy na przestrzeni lat od stałego potoku do dynamicznego programowalnego potoku.

Idź mistrzu!

Bryan C.
źródło
1
Moduł cieniujący fragmenty pełni tę samą funkcję co moduł cieniujący pikseli.
1
Nie sądzę, abyśmy mogli odpowiedzieć na pytanie, czy OP jest początkujący we wszystkich programach do gier - stwierdził tylko, że jest początkujący w pisaniu kodu modułu cieniującego. Nauka pisania shaderów jest bardzo ważnym narzędziem, które należy mieć w szopie twórców gier, nie będę ich po prostu przeglądać, chyba że jesteś na bardzo wczesnym etapie nauki tworzenia gier.
Olhovsky