Bagaimana cara shader HLSL benar-benar akhirnya mempengaruhi output render?

11

Saya memahami sintaks HLSL, misalnya mari kita berpura-pura memiliki ini sebagai HLSL saya:

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

dan saya kompilasi seperti ini:

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

Bagaimana rasanya ... tahu untuk mengubah ... Saya bingung tentang apa sebenarnya saluran pipa antara HLSL dan piksel / simpul aktual pada layar.

Apakah ini yang sebenarnya "menerapkan" mereka?

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

Ingatlah bahwa saya seperti pemula dalam hal ini. Bisakah seseorang menjelaskan apa yang dilakukannya? Saya mengasumsikan fungsi HLSL verteks melewati setiap titik dan kemudian mengubahnya menjadi apa pun yang saya miliki dalam fungsi, dan outputnya adalah apa yang diubah ... dan juga untuk pixel shader?

Kebingungan lain, saya tahu apa itu pixel, dan saya mengerti apa itu vertex ... tapi apa sebenarnya yang dilakukan pixel shader?


sumber
Tidak apa-apa, tidak ada yang melakukannya
bobobobo

Jawaban:

10

Bagaimana rasanya ...... tahu untuk mengubah .... Saya bingung persis di jalur pipa antara HLSL dan Pixels / Vertex yang sebenarnya pada layar.

Ini bekerja kira-kira seperti ini: ketika Anda mengeluarkan panggilan draw (DrawPrimitive, DrawIndexedPrimitive di D3D, Draw in 10+, dan sebagainya), data geometri yang Anda ikat ke pipa (buffer vertex Anda) diproses. Untuk setiap simpul, simpul verteks dijalankan untuk menghasilkan simpul keluaran dalam ruang klip.

GPU kemudian melakukan beberapa fungsi tetap pada vertex ruang klip itu seperti kliping / culling dan membawa vertex ke ruang layar, di mana ia mulai meraster segitiga. Selama rasterisasi setiap segitiga, GPU menginterpolasi atribut verteks di seluruh permukaan segitiga itu, memberi makan setiap atribut yang diinterpolasi ke pixel shader untuk menghasilkan warna semi-final untuk pixel tersebut (pencampuran diterapkan setelah pixel shader dijalankan, dengan demikian "semi-" terakhir").

apakah ini yang sebenarnya "menerapkan" mereka:

Kode yang Anda poskan pertama-tama mengkompilasi shader, kemudian mengikatnya ke saluran pipa tempat mereka tetap aktif untuk setiap panggilan undian berikutnya sampai diubah. Itu sebenarnya tidak menyebabkan mereka dieksekusi.

Dapatkah seseorang mungkin menjelaskan APA yang dilakukannya, dengan asumsi fungsi Vertex HLSL melewati setiap simpul (sebagai input Posisi: POSISI dan warna: WARNA) dan kemudian mengubahnya menjadi apa pun yang saya miliki dalam fungsi, dan hasilnya adalah apa yang diubah. ... (berlaku juga untuk Pixel Shader).

Kebingungan lain, saya tahu apa itu pixel, dan saya mengerti apa itu vertex ..... tapi apa sebenarnya yang dilakukan shader Pixel ......

Vertex shader bertanggung jawab untuk mengubah simpul dari ruang model ke ruang klip.

Pixer shader bertanggung jawab untuk menghitung warna / kedalaman kedua dari belakang untuk pixel berdasarkan atribut vertex interpolasi.


sumber
9

Saya akan mencoba menjelaskan cara kerja tanpa menggunakan banyak jargon.

Jika kesederhanaan alih-alih kecepatan interaktif menjadi perhatian Anda, permukaan 3D di komputer hanya akan menjadi awan besar titik di ruang angkasa, cukup padat sehingga kami bisa membuat setiap titik satu per satu, tanpa celah di antara keduanya.

Anda ingin menyimpan model hanya sekali dalam memori, tetapi Anda harus menampilkannya dalam berbagai ukuran dan dari berbagai sudut, jadi ketika Anda membuat model 3D, Anda perlu "mengubah" semua poin saat Anda membacanya dari memori. Misalnya, untuk membuat model 50% lebih besar, Anda perlu mengatur skala posisi poin menjadi setengahnya:

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

Ini hampir merupakan "vertex shader" yang paling sederhana yang dapat dikandung seseorang: in pergi posisi vertex dari memori, dan keluarlah posisi vertex baru, setengah-besar. Vertex setengah-besar tidak disimpan kembali ke memori - itu digunakan segera untuk rendering dan kemudian dibuang.

Meskipun penyederhanaan berlebihan yang tidak memiliki konsep utama , ini dalam semangat menggambarkan aspek bagaimana film melakukan grafik.

Grafis interaktif (gim) tidak dapat sesederhana ini, karena mereka perlu membuat grafik beberapa urutan besar lebih cepat daripada film.

Dalam permainan, kami tidak mampu membuat satu titik untuk setiap piksel di layar, ditambah tambahan untuk menutupi celahnya. Jadi sebagai kompromi, celah antara masing-masing tiga titik terdekat diberikan sebagai segitiga, yang karena berbagai alasan teknis lebih suka setidaknya 10 piksel besar di layar.

Segitiga 3D dapat diproyeksikan ke layar 2D, kemudian dibagi menjadi tumpukan garis 1D, yang masing-masing dapat dibagi menjadi tumpukan piksel 0D. Dengan demikian kita dapat membagi dan menaklukkan masalah render segitiga 3D menjadi masalah sederhana render banyak 0D piksel secara terpisah. Komputer dapat memecahkan masalah yang lebih sederhana dalam waktu yang lebih singkat.

Pixel shader adalah program kecil yang kami jalankan pada setiap pixel sehingga dihasilkan dari pembongkaran segitiga.

out.color = in.color;

Ini hampir merupakan "pixel shader" yang paling sederhana yang dapat dikandung seseorang: in memadukan warna-warna dari tiga simpul segitiga, dan keluar menghasilkan warna yang sama. Input berasal dari output "vertex shader" dan output ditulis ke layar dalam memori.

Jadi - "vertex shader" adalah program yang berjalan di dalam chip GPU. Inputnya adalah "vertex buffer" dalam memori GPU, dan outputnya dimasukkan langsung ke dalam "pixel shader." "Pixer shader" juga merupakan program yang berjalan di dalam chip GPU. Inputnya merupakan perpaduan tiga simpul dari vertex shader, dan outputnya adalah piksel pada layar.

bmcnett
sumber
-2

Jangan khawatir tentang pixel shader sekarang. Jika Anda seorang pemula, Anda harus menjadi hello world dari GLSL / HLSL dengan vertex dan fragmen shader saja. Setelah Anda terbiasa dan Anda mulai memahami pergerakan variabel dan semacamnya, maka perluas wawasan Anda.

Saya sangat merekomendasikan buku teks untuk mendapatkan seluk beluk bagaimana API bekerja. Buku-buku OpenGL juga melakukan pekerjaan yang baik menggambarkan bagaimana hal-hal telah berubah selama bertahun-tahun dari pipa tetap ke pipa dinamis yang dapat diprogram.

Pergi juara!

Bryan C
sumber
1
Shader fragmen memenuhi fungsi yang sama dengan pixel shader.
1
Saya tidak berpikir kita dapat mengatakan dari pertanyaan apakah OP adalah pemula di semua pemrograman game - dia hanya menyatakan bahwa dia adalah pemula dalam menulis kode shader. Belajar menulis shader adalah alat yang sangat penting untuk memiliki di gudang permainan pengembang, saya tidak akan hanya mengabaikan mereka kecuali Anda hanya di sangat tahap awal belajar pengembangan game.
Olhovsky