Sfârșitul conductelor de randare cu funcții fixe (și cum se deplasează)

Conducte cu funcții fixe nu mai au afaceri pe cardurile noastre video. Iată ce trebuie să știți despre ei - și cum să faceți trecerea de la ei, dacă încă nu ați făcut-o încă.

Început: Creșterea hardware-ului grafic

Odată, când dezvoltarea jocului (sau codarea a tot ceea ce are de a face cu grafica în timp real, într-adevăr) a fost limitată la scrierea pe o matrice relativ mică de intensități de culoare ( cadru tampon) și trimiteți-o la hardware, ați putea face orice doriți cu el. Ați putea desena imaginea una, zece sau o sută de ori. Ați putea trece din nou tamponul de cadre pentru a face unele FX îngrijite. Pe scurt, indiferent de procesorul dvs. a fost capabil să facă, ați putea face-o la imaginea care este trimis la monitor. Acest lucru v-a permis să faceți niște lucruri foarte bune și creative, însă niciodată (sau rareori) oamenii nu au folosit-o în această măsură. Dar de ce?

Răspunsul: pentru că a fost lent. O imagine de 640 × 480 pixeli (o rezoluție comună în acel moment) conține 307,200 pixeli. CPU-urile erau atât de mult mai lent, încât nu puteai să faci prea mult în timpul scurt care ți-a fost dat să desenezi acel cadru. La urma urmei, dacă doriți să continuați desenul la 30FPS, aveți doar aproximativ 30 de milimetri pentru a vă actualiza logica jocului și pentru a reda pe ecran, iar acest lucru trebuie să includă cheltuielile aferente intercomunicării cu hardware-ul. Nu a fost prea mult.

Apoi a venit de-a lungul cu GPU-urile cool conducând conducte. Tu, dezvoltatorul, ai avea grijă să actualizezi logica jocului și să trimiți texturile și triunghiurile la GPU, și ar face ca greutatea și numărul să fie ronțăit pe ele. Acelea erau conducte de randare cu funcții fixe (FFP): ceea ce înseamnă că nu ați putut configura configurarea funcții au efectuat. Le-ai putea spune "fa grija de ceață" sau "nu fa lumina pentru mine!" și ați putea configura o mulțime de celelalte parametrii, cu exceptia funcții ei înșiși au rămas. 

Hardware-ul a fost cablat și strict specializat, astfel încât a efectuat anumite operații standard ale datelor. Și pentru că a fost conectat în felul acesta, a fost atât de mult mai rapid decât să le faci pe procesor. Dar un dezavantaj a fost că ați plătit foarte mult pentru această viteză: ați plătit în flexibilitate. Dar dacă v-ați dorit vreodată să trasați ceva complex, procesorul pur și simplu nu a fost suficient de rapid și trimiterea nodurilor către GPU a fost singura opțiune.

Acesta este modul în care funcționa conducta fixă. Imaginea nu este concepută ca o reprezentare exactă, ci pentru a vă oferi o idee despre modul în care toate acestea au avut loc.

Cerințele pentru un realism mai bun

Lumea grafică se schimbă rapid. La fel ca toți oamenii creativi și talentați, dezvoltatorii de jocuri iubesc provocările și unul provocările pentru ei au fost (și vor rămâne!), pentru o lungă perioadă de timp, pentru a face imagini tot mai bune, realiste. 

Conducta cu funcții fixe a oferit câteva caracteristici frumoase, cum ar fi modurile multiple de amestecare, umbrirea perforex Gouraud, efectele de ceață, tampoanele de stencil (pentru volume umbră) și altele asemenea, astfel încât dezvoltatorii au folosit ceea ce puteau. În curând, s-au petrecut câteva efecte impresionante, toate în virtutea fenomenelor din viața reală simulate folosind câteva trucuri ieftine (bine, ieftine conform standardelor de astăzi). 

Totul mergea foarte bine, dar era încă limitat de numărul de funcții pe care le putea face conducta fixă. La urma urmei, lumea reală are atât de multe materiale diferite, iar pentru a le simula, singura variantă pe care au fost permise să le facă a fost schimbarea unor moduri de amestecare, adăugarea unor texturi sau adăugarea de texturi,.

Apoi sa întâmplat: au apărut primele GPU-uri programabile. Nu au venit peste noapte, bineînțeles, și au fost nevoiți să sosească într-o zi, dar acest lucru a creat încă emoție. Aceste GPU-uri aveau ceea ce era numit a canal de redare programabil: ați putea scrie acum programe, numite shader, într-o limbă de asamblare limitată și să le execute pentru fiecare vârf sau fragment, pe placa video. Acesta a fost un salt mare înainte, și a fost doar mai bine. 

În curând, limbile de asamblare au crescut în complexitate și expresivitate, iar limbajele de nivel înalt pentru programarea GPU au apărut, cum ar fi HLSL, GLSL și, ulterior, Cg. Astăzi avem shadere de geometrie care pot transmite chiar și noi noduri sau shadere care controlează dinamic tessellation și triunghiuri tessellated, iar în interiorul lor putem preleva o grămadă de texturi, se pot ramifica în mod dinamic și fac tot felul de matematici nebun la valorile de intrare.

Când îi dai dezvoltatorilor aceste avantaje, ei devin sălbatici; în curând scriau shadere pentru tot felul de lucruri: cartografierea paralaxelor, modelele de iluminare personalizată, refracția, numele dvs. Mai târziu, au apărut chiar și sisteme complete de iluminare personalizate, cum ar fi umbrirea amânată și pre-trecerea ușoară, și ați putut vedea efecte complexe post-procesare, cum ar fi ocluzia ambientală a spațiului ecranului și ocluzia ambientală bazată pe orizont. Unii au fost chiar "abuzează" shaders pentru a face repetitive, matematice-sarcini grele, cum ar fi prelucrarea statistică sau spargerea hash șir. (Acest lucru a fost înainte de calcularea scopurilor generale pe GPU-uri care au suport de bază.) 

Pe scurt, grafica pe calculator a explodat cu introducerea shaderelor și cu un motiv bun: capacitatea de a programa exact ceea ce sa întâmplat cu vârfuri, fragmente, texturi și așa mai departe și pentru a face acest lucru rapid, cu posibilități aproape nesfârșite.

O reprezentare simplificată a conductei programabile. Rețineți cum s-au înlocuit etapele de transformare specifice, de umbrire sau de textură cu shadere specializate. (Tessellation omis pentru claritate.)

Comutatorul complet

În curând, conductele cu funcții fixe au fost depășite, cel puțin pentru dezvoltatorii de jocuri. La urma urmei, de ce deranjeaza cu astfel de gradini cu pereti atunci cand poti programa exact ce se intampla cu datele tale? Au rămas în uz mai mult timp în unele aplicații în care realismul nu era o problemă, cum ar fi pentru CAD. Dar, în general, au fost ignorați. 

OpenGL ES 2.0, lansat în 2007, a depreciat sau a eliminat conducta sa cu funcții fixe în favoarea unui programator. OpenGL 3.2, înapoi în 2009, a eliminat în final toate noțiunile de procesare a vârfurilor cu funcții fixe și de procesare a fragmentelor (cu toate acestea, acestea rămân disponibile pentru uzul tradițional printr-o compatibilitate). Este clar că astăzi este foarte puțin sens să lucrați cu conducta limitată atunci când aveți GPU-uri puternice capabile să facă lucruri minunate la dispoziția dumneavoastră.

Deoarece aceste API vă obligă să utilizați shadere (și acest lucru include DirectX, care, deși nu elimină în mod explicit funcționalitatea, include instrumente care să ajute la migrarea de la abordarea veche și nu are practic nicio documentație nouă privind FFP), este dificil de obținut pentru un începător. Dacă începeți doar ca un începător de programare 3D, este mult mai ușor doar să îi spuneți API matricele, parametrii de iluminare și ce nu, și să o faci totul pentru tine. 

Dar, pe termen lung, veți beneficia mult mai mult dacă veți învăța să scrieți programe care descriu cu precizie procesul. Veți înțelege cu desăvârșire ce se întâmplă sub capotă, înțelegeți câteva concepte foarte importante pe care FFP nu le solicită și puteți să vă ajustați foarte ușor materialele pentru a face ceva complex, funcția fixă ​​nu poate face niciodată pentru dvs. (și este utilă pentru depanare, de asemenea!).

Am menționat OpenGL ES și m-am lăsat să mă construiesc în detaliu. Pe măsură ce jocurile pe mobil devin din ce în ce mai populare, este logic să se creeze lumi virtuale mereu în creștere în complexitate. Cele mai multe apeluri cu funcții fixe au fost eliminate în ES 2.0 (ceea ce, firește, înseamnă că nu mai există și versiuni ulterioare). Acest lucru înseamnă în mod esențial că, pentru a utiliza oricare dintre caracteristicile după ES 1.1, trebuie să utilizați shadere. 

ES 2.0 este susținută de dispozitive iPhone de la 3GS, iPads de la prima lansare și dispozitive iPod Touch de generație 3 și mai mare. Qualcomm Snapdragon, un chip utilizat pe scară largă în producția de telefonie Android, suportă, de asemenea, OpenGL ES 2.0. Acesta este foarte larg deoarece ES 2.0 nu este exact "nou": acum are peste 7 ani. Pentru a profita la maximum de aceste arhitecturi, trebuie să renunțați la conducta cu funcții fixe

Presupun că cei mai mulți dintre voi ați făcut asta cu mult timp în urmă, dar nu este atât de greu să vă imaginez câteva motoare grafice 2D sau jocuri vechi care încă utilizează funcția fixă ​​(pentru că nu mai este nevoie de mai multe). Acest lucru este bine, dar folosindu-l pentru proiecte noi sau programe de instruire în ele, pare a fi o pierdere de timp. Acest lucru este amplificat de faptul că o mulțime de tutoriale pe care le puteți găsi pe Internet sunt extrem de depășite și vă vor învăța cum să utilizați FFP de la început - și înainte de a vă dați seama ce se întâmplă, veți fi profund acolo.

Prima mea perie cu grafică 3D a fost un tutorial antic DirectX 7 scris în Visual Basic. În acel moment, folosirea conductei cu funcții fixe avea sens, în general, deoarece hardware-ul nu era suficient de avansat pentru a obține aceeași funcționalitate cu shaderele la aceeași rată. Dar astăzi vedem că API-urile grafice încep să scadă sau să-și piardă sever sprijinul pentru el și devine doar un artefact al trecutului. Este un artefact bun și util care ne face nostalgici, dar ar trebui să rămânem departe de el. Este vechi și nu mai este folosit.

Aceste reflexii și refracții drăguțe de fresnel, generate de un demo de la OGRE (Open-Source Graphics Rendering Engine), nu ar fi putut fi făcute niciodată dacă ați fi lipit de modalitățile pe care le sfătuiesc vechile tutoriale DirectX 8 sau OpenGL 1.1.

Concluzie

Dacă te afli într-o dezvoltare serioasă a jocului, lipirea la conducta cu funcții fixe este o relicvă a zilelor trecute. Dacă te gândești să intri în grafică 3D, sfatul meu (și sfatul multora, mulți dezvoltatori acolo) este să eviți pur și simplu. 

Dacă vedeți trecerea pozițiilor de iluminare în graficul API (nu ca parametru shader) sau apelurile funcției API, cum ar fi glFogv, alerga ca vântul și nu te uita înapoi. Există o lume curajoasă a unor GPU-uri programabile acolo și s-au petrecut mult timp. Orice altceva probabil că vă pierde timpul.

Chiar dacă sunteți doar în grafica 2D, este încă o idee înțeleaptă să nu mai bazați pe FFP. (Bineînțeles, asta e atâta timp cât ești bine dacă nu susții hardware antic.) Shaders-ul îți poate oferi niște efecte extraordinare, de fulger. Blurtarea imaginilor, ascuțirea, grila de urzeală, redarea vectorilor și simularea pe scară largă a particulelor sau fizicii pot fi făcute pe GPU și toate pot beneficia atât de jocuri 2D cât și de jocuri 3D. 

Deci, din nou, sfatul meu, chiar dacă nu intenționați să aflați în mod explicit despre dezvoltarea jocurilor 3D, este să învățați să scrieți shadere. Sunt plăcut să lucrați și vă garantez că veți petrece multe ore amuzante, permițând un efect de shader răcoros: o fereastră de zăpadă dinamic, vopsea auto sau cartografierea umbrite paralele sau orice doriți din inimă. Cel puțin mi sa întâmplat: odată ce sunteți obișnuit să lucrați cu conducta fixă ​​din cauza unor limitări (așa cum am fost forțat să revin în acea zi pentru a obține performanțe acceptabile la 5200FX), programarea GPU este o explozie, și grămezi de distracție.

Sper că le-am explicat acelora pentru care nu era clar cum a lucrat mult timp grafica 3D și cum funcționează acum și sper că am convins pe puțini dintre voi care au fost pe cale să urmeze tutorialele NeHe sau Swiftless altfel și du-te uite la ceva mai modern. Ca întotdeauna, s-ar fi putut face unele greșeli, deci nu ezitați să le indicați în comentarii. Pana data viitoare!