Probabil că toată lumea a auzit despre modelele de iluminare, ne înconjoară pretutindeni: de exemplu, luați orice obiect, aceeași pahar pe masă. O anumită lumină cade pe ea, dacă este mai precis, este lumină de la soare sau de la orice altă sursă de iluminare, acest lucru se numește un anumit model de iluminare. În practică, nimeni nu încearcă de obicei să programeze toate principiile fizice ale luminii, deoarece calculul lor este foarte costisitor. Cu toate acestea, au fost inventate multe modele care dau un rezultat realist pentru calculele mici.
Să analizăm mai detaliat, vom crea un model simplu de iluminare - iluminare uniformă.
1. Iluminare uniformă.
Iluminarea uniformă (iluminarea ambientală) asigură iluminarea inițială constantă pentru întreaga scenă. Iluminează toate vârfurile obiectelor în mod egal, deoarece nu depinde de alți factori de iluminare. Acesta este cel mai simplu și cel mai rapid tip de iluminat, dar oferă cel mai puțin realist rezultat. Formula pentru calcularea acestui model de iluminat este, de asemenea, foarte simplă, deoarece există o singură operație aritmetică - multiplicare. Pentru a calcula, este suficient să multiplicați culoarea materialului prin intensitatea luminii.
Vertex Shader pentru calculul unui model uniform de iluminat:
Acest shader simplu calculează pur și simplu poziția obiectului în spațiul mondial, dar în acest model de iluminare nu poate fi folosit, deoarece nu avem nevoie de alte componente (normale etc.) de la vârf pentru a calcula.
Aici, de asemenea, nu este nimic complicat, doar returnați produsul vectorului la compilator, la un anumit număr, în acest caz ambient_intensity. El o face astfel:
Modelul uniform de iluminat:
Pentru a calcula lumina și componentele difuze ale luminii, este necesar să găsim trei vectori:
• Normal N la fragment.
• Specia vector V este un vector care este îndreptat spre observator.
• Poziția sursei de lumină L.
Unghiurile dintre aceste vectori formează intensitatea iluminării.
2. Modelul difuz de iluminare.
Modelul de iluminare difuză este un model de iluminare care depinde de poziția sursei de lumină și de obiectul normal față de suprafață. Deoarece radiația luminii este aceeași în toate direcțiile, vectorul speciilor nu contează, adică v = 0. Această metodă necesită mai multe calcule, deoarece se schimbă pentru fiecare vârf al obiectului, dar acesta umple obiectele bine și le dă volum. Lumina cade, fără a umple întreaga suprafață cu aceeași culoare (ca în cazul iluminării timpurii), dar se pare că lumina este îndreptată către o anumită suprafață.
Dacă vectorul de poziție al sursei de lumină este perpendicular pe suprafață, nu se va observa nici o ceață, deoarece intensitatea luminii depinde de unghiul # 945;. Pentru a calcula modelul difuz de iluminare, formula este utilizată (conform legii lui Lambert):
Să facem rezumat - să creăm shadere pentru calculul iluminării.
Și shader pixel:
Model de iluminare difuză:
3.Blikovaya model de iluminat.
Este dificil să-ți imaginezi un astfel de model de iluminare fără să-l vezi. Dar, de fapt, putem vedea acest model aproape pretutindeni. De exemplu, o suprafață metalică dreaptă lustruită (cu mișcări circulare), îndreptată spre sursa de lumină și cu un unghi care nu este perpendicular pe suprafață. Ca rezultat, vom vedea strălucirea pe suprafață, ceea ce va spori semnificativ realismul imaginii. Aceste reflexii reprezintă o reflectare a sursei de lumină de pe suprafață. În acest model de iluminare, în plus față de vectorii poziției sursei de lumină și normală (ca în cazul modelului de iluminare difuză), sunt utilizați încă doi vectori: vectorul de vedere și vectorul de reflexie. Un model de iluminare speculară a fost propus de Bui-Tuong Fong.
Unghiul dintre vectorul de specie și vectorul de reflecție - # 946; Cu cât unghiul este mai mare # 946; cu atât iluminarea este mai luminată. Prin urmare, modelul de iluminare a iluminării se calculează după următoarea formulă:
unde R = reflectă (-orm (V), N)
n este coeficientul de luminanță al luminiscenței.
Dependența luminozității luminiscente pe unghi # 946;:
Cu creșterea n, reflexia devine din ce în ce mai mare și se concentrează tot mai mult de-a lungul direcției vectorului de reflexie R.
Nu este necesar să se calculeze vectorul de vizualizare în shader, îl puteți calcula în program și îl puteți pune în shaderul de vârfuri. Pentru a face acest lucru, trebuie să inversați matricea de vizualizare și să înmulțiți vectorul D3DXVECTOR4 (0.0.0.0.0.0,1.0) - poziția la care vectorul este perpendicular pe suprafață (se uită la noi). Se pare ca aceasta:
Model de iluminat:
Modificarea iluminării orb la Blinn.
Jim Blinn a venit cu o modalitate alternativă de a calcula iluminarea strălucirii, ceea ce elimină calculele scumpe pe vectorul de reflecție. El a introdus un vector intermediar, care este valoarea medie între vectorul de specie și vectorul de poziție al sursei de lumină: H = (L + V) / (| L + V |)
Formula generală este:
Prin urmare, shaderul fragmentului va fi deja astfel:
Accelerarea calculării luminozității luminiscenței.
Schlick a propus înlocuirea gradului n. Fie produsul scalar D: D = (N • H) n. Apoi, conform metodei sale, luminozitatea strălucirii va fi calculată după cum urmează:
Grafice comparative ale legilor privind energia:
De fapt, semnificația fizică a reflexiei luminii de lumină este mult mai complicată decât se presupune în modelul de iluminare Fong. Într-un model mai realist, Is depinde de lungimea de undă l și de unghiul de incidență al luminii (N • L). Această dependență se numește coeficientul Fresnel.
Combinarea elementelor de iluminat.
Acum putem adăuga trei modele de lumină (constantă, difuză și flare) pentru a obține cantitatea totală de lumină pe care am primit-o de la ochi:
Shaderul de pixeli va arăta astfel:
Iluminat realist bazat pe Cook-Torrance
În modelele de iluminare mai realiste, accentul se pune pe distribuția energiei a luminii incidente. O parte din acesta este absorbită de material și transformată în căldură, o altă parte este împrăștiată ca lumină difuză, a treia parte stabilește suprafața iluminării orbitoare. Prin urmare, pentru diferite materiale, separarea luminii incidente are loc în moduri diferite și depinde de:
• Funcții de distribuție normală
• Umbrirea și ecranarea
• Coeficientul Fresnel
Funcția de distribuție normală
Această funcție descrie o posibilă abatere a normalei de suprafață față de cea normală normală N. Cu cât această funcție este mai puțin superioară, cu atât mai mari sunt abaterile și cu atât este mai mare magnitudinea punctului reflectat reflectat. Normalele necesare sunt situate de-a lungul vectorului L + V și sunt vizibile în direcția V și sunt la un unghi (H • N) către vizualizator. Cook și Torrence au folosit formula de distribuție Beckmann:
unde d = H • N
m este gradul de rugozitate al obiectului. 0.2f este o suprafață netedă, 0.6f este o suprafață dură. Setarea implicită este 0.3f.
Programul de distribuție al lui Beckmann:
Umbrirea și ecranarea
Modelul Cook-Torrance ia în considerare și efecte cum ar fi umbrirea și mascarea, care determină intensitatea componentei de orbire.
Lumina neecranată este:
Lumina netedă este egală cu:
Apoi, factorul final al lui G este:
Acest factor determină fracția de lumină reflectată și este specificat de funcție:
unde f este unghiul de incidență, a cărui cosinus este c = (N • H)
n este indicele de refracție al materialului, g = sqrt (n 2 + c 2 -1)
De fapt, în shader vom folosi o altă formulă pentru a calcula coeficientul Fresnel din cauza limitărilor instrucțiunilor. Înlocuirea a fost oferită de Schlick:
F = Rs + (1-Rs) x (1-E · N) n
unde R este reflexia flarei,
E este vectorul observatorului,
N este normal de la harta normală.
O astfel de aproximare nu ia în considerare componentele f și n, respectiv, dar are gradul n, cu creșterea căreia nu se pot obține rezultate negative. Schlick a folosit n = 5.
Combinând toți multiplicatorii
Torrence și Sparrow au combinat acești factori și au derivat o formulă pentru calcularea strălucirii:
Se introduce numitorul N • V pentru a controla intensitatea luminii.
Formula generală pentru calcularea cantității de lumină este:
A trebuit să simplificăm formula, deoarece, în original, fiecare componentă a iluminării (cu excepția flarei) este înmulțită și cu F (0, n). Acest lucru se datorează utilizării aproximării Schlick.
Shaderul pixelilor pentru acest efect: