Salut! Acesta este ultimul articol din seria noastră despre elementele de bază ale sistemelor grafice 3D software și de această dată vom căuta în iluminat dinamic! Înainte de a vă face prea entuziasmat sau prea îngrijorat de cât de dificil poate fi o sarcină precum iluminatul dinamic, relaxați-vă. Vom încerca să acoperim acum cea mai de bază formă de iluminare dinamică (de vreme ce întregul subiect în sine este uriaș, iar alții au reușit să umple cărți întregi cu privire la acest concept).
Mai exact, vom construi un singur sistem de iluminat dinamic, cu o singură culoare, cu o rază de iluminare fixă, care ne va permite să începem să dabluim în subiect. Înainte de a intra în asta, să aruncăm o privire asupra unora dintre cursurile făcute anterior pe care le vom folosi.
Lumina noastră dinamică va fi tratată în mod punctual, deoarece acestea sunt pregătite pentru a fi trase la ecran. Aceasta înseamnă că vom folosi în mod extensiv două dintre clasele noastre anterioare: Punct
clasa și aparat foto
clasă. Iata cum arata:
Clasa de puncte Variabile: număr [3]; // (x, y, z) Operatori: Point AddVectorToPoint (Vector); Punctul SubtractVectorFromPoint (Vector); Vector SubtractPointFromPoint (punct); Null SetPointToPoint (punct); Funcții: drawPoint; // desenați un punct la poziția sa tuple Clasa camerei Vars: int minX, maxX; int minY, maxY; int minZ, maxZ; obiecte arrayInWorld; // o matrice a tuturor obiectelor existente Funcții: null drawScene (); // atrage toate obiectele necesare pe ecran
Folosind aceste informații, să punem împreună clasa noastră de iluminat de bază.
Clasa noastră de iluminare va avea nevoie de câteva lucruri pentru ao face funcțională - și anume o poziție, o culoare, un tip și o intensitate (sau raza de iluminare).
Așa cum am spus mai devreme, iluminarea noastră va fi calculată pe o bază punct cu punct înainte de fiecare punct de tragere. Neajunsurile sunt că este mai simplu pentru modul în care avem motorul nostru organizat și, de asemenea, că se schimbă mai mult din sarcina programului nostru către procesorul sistemului. Dacă doriți să calculați în prealabil iluminarea dvs., aceasta ar schimba încărcarea în hard disk-ul sistemului dvs. și, în funcție de modul în care este proiectat motorul, poate fi mai simplu sau mai complex.
Cu toate acestea, clasa noastră ar putea arăta astfel:
Clasa de iluminare Variabile: num poziția [3]; // (x, y, z) num = 255; // ce să adăugăm la valoarea r a unui punct la intensitatea completă num verde = 255; // ce să adăugăm la valoarea g unui punct la intensitatea completă num albastru = 255; // ce să adăugăm la valoarea b unui punct la sirul de intensitate plină lightType = "punct"; // tipul de iluminare num raza = 50; // raza luminii în pixeli
În prezent, vom lăsa toate valorile sale codate greu pentru simplitate, dar dacă descoperiți că doriți să extindeți funcționalitatea clasei de iluminare, puteți avea cu ușurință fiecare dintre valori modificabile prin intermediul fiecărui funcțional, constructor etc..
Toate matematica importanta pentru iluminarea noastra dinamica se vor intampla in clasa noastra de camere, de aceea, haideti sa aruncam o privire la asta.
Vom adăuga o nouă variabilă la clasa camerei noastre acum, pe care o vom folosi pentru stocarea sursei noastre de lumină. Deocamdată, variabila va stoca numai o singură scenă de iluminare, dar ar putea fi ușor redusă pentru a permite mai multe puncte de lumină.
Chiar înainte de tragerea unui punct, vom verifica dacă se află în raza luminii noastre. Odată ce știm că se află în raza luminii, atunci trebuie să găsim distanța dintre punctul și poziția luminii și apoi trebuie să ajustăm culoarea punctului pe baza acestei distanțe.
Cu toate acestea în minte, putem adăuga un cod similar cu acesta camerei noastre drawScene ()
funcţie:
dacă (currentPoint.x> = (light.x - light.radius)) // dacă punctul este în limita stângă a luminii dacă (currentPoint.x <= (light.x + light.radius)) //if the point is within the light's right bound if(currentPoint.y >= (light.y - light.radius)) // dacă punctul se află în interiorul liniei de sus a luminii dacă (currentPoint.y <= (light.y + light.radius)) //if the point is within the light's bottom bound //calculate distance between point and light (distance) //calculate percentage of light to apply (percentage = distance / radius) point.red += (light.red * percentage); //add the light's red, scaled to distance point.green += (light.green * percentage); //add the light's green, scaled to distance point.blue += (light.blue * percentage); //add the light's blue, scaled to distance
După cum puteți vedea, metoda noastră de ajustare a culorii unui punct în prezent nu este tot atât de avansat (există însă multe care sunt, dacă doriți să le utilizați în schimb). În funcție de distanța punctului față de centrul luminii, ne ușurează culoarea cu un procentaj. Metoda noastră de iluminare nu are în vedere umbrirea, în prezent, astfel încât zonele îndepărtate de lumină nu vor deveni mai întunecate, iar obiectele nu vor bloca lumina de la alte obiecte care ar putea fi în spatele lor.
Pentru programul nostru de data aceasta, vom avea cateva forme pre-redate pe ecran. Acestea pot fi orice doriți, dar pentru exemplul nostru, voi folosi doar câteva puncte simple. Acum, atunci când un utilizator face clic pe oriunde pe ecran, vom crea o sursă de lumină în acel moment. Data viitoare când fac clic, vom muta punctul în acea poziție și așa mai departe. Acest lucru ne va permite să vedem lumina noastră dinamică în acțiune!
Iată cum arată programul dvs.:
main // setup pentru grafica API preferată aici // configurare pentru introducerea tastaturii (poate să nu fie necesară) aici var camera = new Camera (); // creați o instanță a clasei camerei // setați camera de vizualizare a camerei camera.minX = 0; camera.maxX = ecranWidth; camera.minY = 0; camera.maxY = screenHeight; camera.minZ = 0; camera.maxZ = 100; // trageți obiectele inițiale și le setați în spațiul camerei în timp ce (key! = esc) if (mouseClick) if (firstClick) // crea obiectul inițial de lumină la poziția mouse-ului altceva // modificați poziția obiectului luminos camera.drawScene ();
Acum ar trebui să puteți experimenta iluminarea dinamică în acțiune și, sperăm, veți vedea cât de mult mai adânc poate adăuga la un motor de joc. Vedeți demo-ul meu aici - utilizați A și S chei la scară, și Y, H, U, J, eu și K tastele să se rotească.
În timp ce iluminarea dinamică este simplă, cu siguranță vă putem îmbunătăți dacă vă simțiți înclinați să faceți acest lucru. Unele lucruri care ar fi destul de cool și, de asemenea, destul de simplu de adăugat sunt:
Vă mulțumim că ați verificat seria noastră, Să construim un motor 3D de jocuri. A fost minunat să scrieți aceste articole și să vă aduceți aminte, dacă aveți întrebări, nu ezitați să le întrebați în comentariile de mai jos!
Puteți obține, de asemenea, ajutor suplimentar la Envato Studio, unde puteți găsi o mulțime de servicii fantastice de design și modelare 3D pentru prețuri accesibile.
Proiectare și modelare 3D pe Envato Studio