Așa cum am promis - am publicat al doilea articol despre unele aspecte ale dezvoltării jocurilor în trei dimensiuni. Astăzi voi vorbi despre o tehnică care este folosită aproape orice proiect din clasa AAA. Numele ei este HDR rendering. Dacă e interesat, bine ai venit la Habrcut.
Dar mai întâi trebuie să vorbești. Bazându-mă pe ultimul articol - mi-am dat seama că publicul lui Habrahabra a îngropat și tehnologia Microsoft XNA. Face, presupus, cu ajutorul lui ceva - este ca și cum ai scrie jocuri pe ZX Spectrum. În exemplul am fost condus: "Există, de asemenea, SharpDX, SlimDX, OpenTK! "Chiar i-am citat pe Unity ca un exemplu. Dar să ne oprim la primele trei, toate aceste ambalaje DX'a de apă curată sub .NET. iar Unitatea este, în general, un motor de tip sandbox. Ce este DirectX10 +. Pentru că nu este și nu va fi în XNA. Astfel, numărul covârșitor de efecte, chips-uri și tehnologii este realizat tocmai pe baza DirectX9c. Și DirectX10 + introduce doar funcționalități suplimentare (SM4.0, SM5.0).
Luați, de exemplu, Crysis 2:
În aceste două capturi de ecran nu există directeX10 și DirectX11. Deci, de ce oamenii cred că fac ceva pe XNA - să se angajeze în necrofilie? Da, Microsoft a oprit suportul pentru XNA. dar stocul a ceea ce este acolo - suficient pentru 3 ani pentru sigur. În plus, acum există un monogam. este open-source, cross-platform (câștigă, unix, mac, android, ios etc.) și salvează întreaga arhitectură XNA. Apropo, FeZ din ultimul articol este scris folosind monogame. Și, în sfârșit - întregul articol care vizează grafica pe calculator în trei dimensiuni (aceste prevederi sunt valabile și pentru OpenGL și DirectX.), În loc de XNA - așa cum s-ar putea crede. XNA în cazul nostru este doar un instrument.
Bine, hai să mergem
De obicei, jocurile utilizează randarea LDR (Range Dynamic Range). Aceasta înseamnă că culoarea tamponului spate este limitată la 0 ... 1. În cazul în care fiecare canal este dat pe 8 biți, iar acesta este 256 gradări. De exemplu: 255, 255, 255 - culoare albă, toate cele trei canale (RGB) sunt egale cu gradarea maximă. Conceptul de LDR este nedrept să se aplice conceptului de redare realistă, deoarece În lumea reală, culoarea nu este stabilită de zero și de unitate. Pentru a ne ajuta să vină tehnologia, cum ar fi HDRR. Pentru început, ce este HDR. Difuzare dinamică ridicată. uneori doar "High Dynamic Range" - un efect grafic folosit în jocurile pe calculator pentru redarea imaginilor mai expresive în iluminarea scenelor contrastante. Care este esența acestei abordări? Faptul că atragem geometria noastră (și iluminat) nu este limitat la zero și unu: o sursă de lumină poate da luminozitatea pixelului la 0,5 unități, și alte 100 de unități. Dar cum pot înlocui la prima vedere, atunci ecranul nostru reproduce exact același format LDR. Și dacă împărțim toate valorile culorii tamponului spate la luminozitatea maximă din scenă - se va obține același LDR. și o sursă de lumină de 0,5 unități nu va fi aproape vizibilă pe fundalul celui de-al doilea. Și tocmai pentru aceasta a fost inventată o metodă specială numită Tonificare. Esența acestei abordări este aceea că aducem intervalul dinamic la LDR, în funcție de luminozitatea medie a scenei. Și pentru a înțelege ce vorbesc, ia în considerare scena: două camere, o cameră în interior. un altul în aer liber. Prima cameră - are o sursă de lumină artificială, a doua cameră - are o sursă de lumină sub formă de soare. Luminozitatea soarelui este cu un ordin de magnitudine mai mare decât luminozitatea unei surse de lumină artificială. Și în lumea reală, când suntem în prima cameră - ne adaptăm la acest iluminat, când intrăm în cealaltă cameră, ne adaptăm la un nivel diferit de iluminare. Când privim din prima cameră în al doilea - ne va părea prea luminos, iar atunci când privim de la al doilea la primul - negru.
Un alt exemplu: o cameră în aer liber. În această cameră există soarele însuși și difuzează lumina de la soare. Luminozitatea soarelui este un ordin de mărime mai mare decât lumina sa împrăștiată. În cazul LDR, valorile luminanței luminii ar fi egale. Prin urmare, folosind HDR, puteți obține o strălucire realistă de pe diferite suprafețe. Acest lucru este foarte vizibil pe apă:
Sau pe strălucirea de pe suprafață:
Ei bine, contrastul scenei în ansamblu (HDR stânga, dreapta LDR):
Împreună cu HDR, se utilizează tehnologia Bloom. zonele luminoase sunt neclare și suprapuse peste imaginea principală:
Acest lucru face lumina chiar mai moale.
De asemenea, sub forma unui bonus - vă voi spune despre clasificarea culorilor. Această campanie este aplicată universal în jocurile din clasa AAA.
Clasificarea culorilor
Foarte des în jocuri, scena trebuie să aibă propriul ton de culoare, acest ton de culoare poate fi comun pentru întregul joc și pentru anumite părți ale scenei. Și pentru a evita să aveți 100 de shadere postprocesor de fiecare dată - utilizați abordarea Color Grading. Care este esența acestei abordări?
Literele celebre RGB - spațiu tridimensional color, unde fiecare canal este un fel de coordonate. În cazul formatului R8G8B8: 255 gradări pe canal. Deci, ce se va întâmpla dacă aplicăm operațiile obișnuite de procesare (de exemplu, curbe sau contrast) în acest spațiu? Spațiul nostru se va schimba și în viitor putem să atribuim oricărui pixel - un pixel din acest spațiu.
Crearea unui spatiu simplu de culoare RGB (vreau să înlocuiască ceea ce vom lua fiecare pixel al optulea, pentru că dacă vom lua toate 256 de niveluri, dimensiunea textura va fi foarte mare)
Aceasta este o textura tridimensionala, in care fiecare axa are propriul canal.
Și să luăm o scenă care trebuie modificată (adăugând spațiul nostru imaginii):
Desfășurați transformările necesare (după ochi):
Și extrageți spațiul nostru modificabil:
Acum, în acest spațiu - putem aplica toate modificările cu culoarea oricărei imagini. Doar comparând culoarea originală cu spațiul de culoare modificat.
punerea în aplicare
Ei bine, pe scurt despre punerea în aplicare a HDR în XNA. În XNA, formatul tamponului spate este specificat (în cea mai mare parte) de R8G8B8A8. deoarece redarea direct pe ecran nu poate suporta HDR a priori. Pentru această soluție, trebuie să creați un nou RenderTarget (anterior, am descris lucrarea aici) cu un format special: HalfVector4 *. Acest format acceptă valori flotante pentru RenderTarget.
* - în XNA există un astfel de format - ca HDRBlendable. este totuși același HalfVector4 - dar RT în sine ocupă mai puțin spațiu (pentru că nu avem nevoie de un punct plutitor pe canalul alfa).
Să începem RenderTarget cerut:
Crearea unui nou RT, cu dimensiuni spate tampon (rezoluția ecranului) cu mipmap deconectat (deoarece această textură este desenată pe quads de afișare) format surfeysa - HdrBlendable (sau HalfVector4) și 24-biți adâncime ex-tampon / tampoane stencil 8 biți . De asemenea, dezactivați multisamblarea.
Este important ca acest RenderTarget să includă un tampon de adâncime (spre deosebire de RT obișnuit post-proces), deoarece ne vom desena geometria acolo.
Mai mult - la fel ca în LDR. Desenăm o scenă, abia acum nu trebuie să ne limităm la desenarea luminozității [0. 1].
Adăugați un cerc cu o luminozitate nominală înmulțită cu trei și un ceainic clasic Utah cu o iluminare Directional Light și o suprafață reflectorizantă.
Scena este creată și acum avem nevoie să formăm cumva HDR conducând la LDR. Luați cea mai simplă ToneMapping - împărțiți toate aceste valori cu valoarea condiționată max.
Răsuceam camera și înțelegem că scena are încă un caracter static, iar o imagine similară poate fi ușor realizată prin aplicarea contrastului cu imaginea.
În viața reală - ochii se adapteze la acoperirea dorită: într-o încăpere slab luminată, vom vedea în continuare, dar atâta timp cât nu există în fața ochilor noștri o sursă de lumină puternică. Aceasta se numește adaptare ușoară. Și cel mai tare lucru este că HDR și adaptarea culorilor sunt perfect potrivite unul cu celălalt.
Acum trebuie să calculam valoarea medie a culorii pe ecran. Acest lucru este destul de problematic, pentru că Formatul punctului variabil nu acceptă filtrarea. Să facem acest lucru: a crea numărul N de RT, în cazul în care fiecare următor mai mic decât cel precedent:
Și vom trage fiecare RT anterioară în următoarea RT, aplicând unele neclarități. După aceste cicluri, obținem textura 1x1. care de fapt va conține culoarea medie.
Dacă totul este început acum, atunci adaptarea culorilor va fi într-adevăr, dar va fi instantanee, dar nu se întâmplă. Trebuie să privim, atunci când privim dintr-o zonă întunecoasă și întunecată la o lumină puternică - la început ne-am simțit orbi (sub formă de luminozitate crescută) și apoi totul a revenit la normal. Pentru a face acest lucru, este suficient să începeți un alt RT 1x1. care va fi responsabil pentru valoarea curentă a adaptării, fiecare cadru urmând să se adapteze la actuala culoare calculată. Valoarea acestei aproximări ar trebui legată de același jocTime.ElapsedGameTime. astfel încât FPS să nu afecteze rata de adaptare.
Ei bine și acum ca parametru max pentru _toneSimple, este posibil să transferăm culoarea medie.
Există o mulțime de formule ToneMapping, aici sunt câteva dintre ele: