Adâncime 2-Pass simplă și rapidă de câmp

Gnome Depth-Of-Field Adâncimea de câmp este un efect fotografic cauzate de lungimea focală și deschidere. Un articol foarte interesant despre acest subiect a fost publicat în istockphoto.com . Acesta oferă o profunzime-tac de încredere pentru materiale de două-dimensional, proiectat. Cu alte cuvinte: Se face poze arata 3D în timp ce acestea sunt încă proiecții 2D.

În actuala generație de hardware-ul grafic, este posibil să se facă o mulțime de efecte de post-procesare de lux - un umbre pe lângă moi si motion blur, adâncimea câmpului (DOF), ar putea fi pe de efectul cel mai des folosite pentru a spori calitatea vizuală. Există o acoperire mare pe diferite tehnici de a crea efecte DOF plăcut - un simplu google pentru "profunzimea câmpului shader" mi-a dat-o despre 74.000 hit-uri. Pentru un demo am vrut să scriu, am decis să folosesc o abordare simplă, alfa-canal pe baza deoarece este simplu, rapid și arată frumos.

Ideea este simplu: Dacă aveți deja un shader care face lucruri, cum ar fi per-pixel-iluminat, a pus doar informații detaliate în canal alfa culoarea rezultată lui. Tot ceea ce trebuie să fie făcut în a doua trecere: reda imaginea din nou și estompa imaginea cu un nucleu potrivit. Ca nucleu, am ales un Poisson-disc-Filtru cu date de CPU-precalculate - acest lucru este mai puțin "jaggy" decât folosind un nucleu simplu pătratice, oferind o mai bună calitate vizuală de mai puțin probe. Pentru a preveni halouri urât în ​​jurul marginilor de zonele care au mare adancime diferențe, rezultatul nu este pur și simplu o imagine neclară, dar cu distanța focală, de asemenea, controlează cât de mult datele imaginilor neclare ajunge în rezultatul final.

  vec4 vColor = texture2D (sceneMap, gl_TexCoord [0] XY.);
 float fBlurAmount = ABS (vColor.a * 2.0-1.0);
 float fTexel = 16.0/mapSize;
 vec4 vResult;
 pentru (int i = 0; i <16; + + i) {
     vResult + = texture2D (blurMap, gl_TexCoord [0] xy + fBlurAmount * fTexel * Poisson [i] xy * Poisson [i] z...);
 }
 vResult / = 16,0;
 gl_FragColor = mix (vColor, vResult, fBlurAmount); 

Sunt conștient că această abordare este destul de limitat - de îndată ce este necesar canalul alfa pentru alte efecte (cum ar fi o strălucire-pass sau viteza), acesta nu poate fi folosit ca aceasta. Dar oricum, eu sunt fericit cu rezultatele. ;)

Această intrare a fost postat în Informatică și etichetat , , , . Semn de carte Permalink .

Comentariile sunt închise.