Deferred Rendering este o tehnica avansata, extensibila si versatila de sinteza in timp real de imagini ale obiectelor dintr-o scena 3D. Modul in care randati pana acum(cu iluminare imediata in vertex/fragment shader) se numeste forward rendering.
Cu un nume sugestiv, 'intarziat' sau 'amanat', tehnica se bazeaza pe randarea de informatie geometrica(pozitie in world space, normala in world space) si texturala(diffuse, specular, etc.) in render targets separate intr-un prim pas, amanand procesul de iluminare pentru un pas urmator, utilizand alte render targets pentru iluminare iterativa respectiv compozitie finala cu texturare, de data aceasta desenand un simplu quad ce se mapeaza peste intreg ecranul, quad texturat cu imaginea compusa din texturile diffuse specular si iluminarea calculata separat.
Forward: for (obiect in obiecte): for (lumina in lumini): render(lumina, obiect)
Deferred: for (obiect in obiecte): render(obiect, Gbuffer) for (lumina in lumini): render(lumina)
In forward rendering culoarea finala a unui pixel se obtine prin contributia fiecarui fragment afisat in acel pixel, iar pentru culoarea fragmentelor se evalueaza contributia de la fiecare lumina din scena. Din cauza aceasta, sunt evaluate fragmente ce vor fi ocludate ulterior sau se calculeaza contributia neglijabila a unei lumini indepartate.
In deferred rendering, ecuatia de iluminare nu se mai executa pentru fiecare combinatie posibila (obiect, lumina), ci doar pentru luminile ce garantat au o contributie ne-neglijabila.
Acest lucru se face in 3 etape:
Din cauza ca deferred rendering se bazeaza pe faptul ca un singur obiect va fi vizibil per pixel, algoritmul functioneaza atata timp cat obiectele din scena sunt opace, in cazul in care aceasta asertiune este falsa algoritmul nu mai are sens.
Pentru a implementa deferred rendering, vom folosi un frame buffer mare, denumit Geometry Buffer, sau G-Buffer. Acesta are atasate mai multe render textures utilizand GL_COLOR_ATTACHMENT_i.
In aceasta etapa sunt completate urmatoarele render targets din G-buffer:
In aceasta etapa sunt completate intrarile din G-buffer pentru acumularea de lumina.
Pentru a calcula intersectia intre oiecte si lumini vom folosi obiecte geometrice aferente luminilor: sfera cu raza egala cu distanta maxima de influenta pentru lumina omnidirectionala, con cu sfera in baza pentru spot light(nu e implementat in laborator).
Pentru fiecare fragment de obiect ce reprezinta o lumina se incarca pozitia si normala din G-buffer si se evalueaza ecuatia de iluminare. Rezultatul este acumulat in bufferul de acumulare din G-buffer.
In aceasta etapa se calculeaza rezultatul final per pixel. Ouptut-ul nu se mai face in G-buffer, ci direct in framebufferul default sau in vreun altul pregatit pentru postprocesare. Se combina culoarea pixelului cu iluminarea calculata si cu lumina ambientala.