This shows you the differences between two versions of the page.
|
egc:laboratoare:08 [2020/12/11 18:07] bogdan.teaca [Iluminare Spot-light] |
egc:laboratoare:08 [2023/12/06 12:29] (current) anca.cristea [Iluminare Spot-light] |
||
|---|---|---|---|
| Line 2: | Line 2: | ||
| **Video Laborator 8**: https://youtu.be/QuhUGAhrXUQ \\ | **Video Laborator 8**: https://youtu.be/QuhUGAhrXUQ \\ | ||
| - | **Autori**: [[Ph.Dumitru@gmail.com | Philip Dumitru]], [[andrei.lapusteanu@upb.ro | Andrei Lăpușteanu]] | + | **Autori**: [[Ph.Dumitru@gmail.com | Philip Dumitru]], [[andrei.lapusteanu@upb.ro | Andrei Lăpușteanu]], [[caragicu_r@outlook.com | Robert Caragicu]] |
| + | |||
| ==== Modelarea reflexiei luminii ==== | ==== Modelarea reflexiei luminii ==== | ||
| Line 31: | Line 33: | ||
| Totuși, trebuie să menționăm că modelul complet urmărește formula de mai sus, unde constantele de material $K_e, K_a, K_d, K_s$ sunt diferite și au 3 canale $(R,G,B)$, iar intensitatea luminii ambientale și intensitatea sursei de lumină au de asemenea 3 canale. Expresia luminii se evaluează separat pentru cele trei canale. | Totuși, trebuie să menționăm că modelul complet urmărește formula de mai sus, unde constantele de material $K_e, K_a, K_d, K_s$ sunt diferite și au 3 canale $(R,G,B)$, iar intensitatea luminii ambientale și intensitatea sursei de lumină au de asemenea 3 canale. Expresia luminii se evaluează separat pentru cele trei canale. | ||
| + | |||
| + | |||
| ==== Iluminare Phong in Fragment Shader ==== | ==== Iluminare Phong in Fragment Shader ==== | ||
| Line 105: | Line 109: | ||
| Astfel, punctul **P** se afla in conul de lumina (primeste lumina) daca conditia urmatoare este indepilita: | Astfel, punctul **P** se afla in conul de lumina (primeste lumina) daca conditia urmatoare este indepilita: | ||
| <code glsl> | <code glsl> | ||
| - | float cut_off = radians(30); | + | float cut_off = radians(30.0f); |
| float spot_light = dot(-L, light_direction); | float spot_light = dot(-L, light_direction); | ||
| if (spot_light > cos(cut_off)) | if (spot_light > cos(cut_off)) | ||
| Line 117: | Line 121: | ||
| <code glsl> | <code glsl> | ||
| - | float cut_off = radians(30); | + | float cut_off = radians(30.0f); |
| float spot_light = dot(-L, light_direction); | float spot_light = dot(-L, light_direction); | ||
| float spot_light_limit = cos(cut_off); | float spot_light_limit = cos(cut_off); | ||
| Line 127: | Line 131: | ||
| </code> | </code> | ||
| + | |||
| + | ==== Iluminarea suprafețelor folosind mai multe lumini ==== | ||
| + | |||
| + | Pentru a simula mai multe lumini, putem scrie un shader care să calculeze contribuția fiecărei lumini în parte. Pentru a fi ușor să scriem codul de shadere, acesta poate fi modularizat. | ||
| + | |||
| + | În GLSL se pot defini funcții similar ca în limbajul C. Putem scrie o funcție pentru a calcula pentru o sursă de lumină culoarea rezultată din componentele difuze și speculare. | ||
| + | Un exemplu de funcție ar fi: | ||
| + | <code glsl> | ||
| + | vec3 point_light_contribution(vec3 light_pos, vec3 light_color) | ||
| + | { | ||
| + | vec3 color; | ||
| + | //calculele componentelor difuze si speculare din modelul Phong de iluminare pentru lumina punctiforma. | ||
| + | return color; | ||
| + | } | ||
| + | </code> | ||
| + | |||
| + | Putem accesa orice variabilă globală din orice funcție din cod, inclusiv uniforme. Astfel putem citi în funcția ''point_light_contribution'' normala suprafeței primită ca variabilă de intrare la fragment shader și uniformele cu constante de material, fără să le trimitem ca parametri. | ||
| + | |||
| + | Putem specifica ce tip de parametrii are funcția: | ||
| + | * ''in'' înseamnă că valoarea va fi copiată când se apelează funcția. Funcția poate modifica parametrul cum dorește | ||
| + | * ''out'' înseamnă că valoarea nu fi inițializată de apelant și după ce funcția modifică parametrul valoarea va fi copiată în variabila corespunzătoare apelantului | ||
| + | * ''inout'' le combină pe cele două | ||
| + | Cuvintele cheie ''in'', ''out'' si ''inout'' se scriu înainte de tipul de data al parametrului funcției. | ||
| + | De exemplu, dacă dorim separat contribuția difuză și cea speculară, un exemplu de semnatură de funcție ar fi: | ||
| + | <code glsl> | ||
| + | void point_light_contribution(vec3 light_pos, vec3 light_color, out vec3 diffuse_contribution, out vec3 specular_contribution); | ||
| + | </code> | ||
| + | |||
| + | Dacă nu se specifică, parametrul este de tip ''in''. Astfel, putem construi funcții ce întorc mai multe valori. | ||
| + | |||
| + | Metoda de declarare și definiție a funcțiilor este similară cu cea din C. | ||
| + | |||
| + | <code glsl> | ||
| + | vec3 point_light_contribution(vec3 light_pos, vec3 light_color); | ||
| + | |||
| + | void main() | ||
| + | { | ||
| + | //... | ||
| + | } | ||
| + | |||
| + | vec3 point_light_contribution(vec3 light_pos, vec3 light_color) | ||
| + | { | ||
| + | //... | ||
| + | } | ||
| + | </code> | ||
| + | |||
| + | |||
| + | **Nu este permisă recursivitate în GLSL.** | ||
| + | |||
| + | |||
| + | Pentru a trimite ușor multe surse de lumină, putem defini vectori de uniforme. | ||
| + | De exemplu, pentru a trimite mai multe surse de lumină punctiforme se declară în shader un vector de uniforme: | ||
| + | |||
| + | <code glsl> | ||
| + | uniform vec3 point_light_pos[9]; | ||
| + | uniform vec3 point_light_color[9]; | ||
| + | </code> | ||
| + | |||
| + | Pe urmă putem trimite uniformele cu un apel în cod: | ||
| + | |||
| + | <code cpp> | ||
| + | glm::vec3 point_light_pos[9]; | ||
| + | glm::vec3 point_light_color[9]; | ||
| + | |||
| + | GLuint location = glGetUniformLocation(program, "point_light_pos"); | ||
| + | glUniform3fv(location, 9, glm::value_ptr(point_light_pos[0])); | ||
| + | //glm::value_ptr intoarce adresa de memorie unde se gasesc datele unui vector, matrici etc. | ||
| + | </code> | ||
| + | |||
| + | O altă variantă este declararea unei structuri în shader | ||
| + | <code glsl> | ||
| + | struct light_source | ||
| + | { | ||
| + | int type; | ||
| + | vec3 position; | ||
| + | vec3 color; | ||
| + | vec3 direction; | ||
| + | }; | ||
| + | |||
| + | uniform light_source lights[9]; | ||
| + | </code> | ||
| + | |||
| + | În GLSL structura este doar o definiție a unei agregări de tipuri de dată. Nu se poate obține locația unei structuri sau a unui vector de structuri. În schimb, putem interoga locația fiecărui membru din fiecare element din vectorul de structuri. De exemplu, se poate găsi locația uniformei ''lights[0].position''. | ||
| + | |||
| + | Următorul cod C++ trimite pozițiile surselor de lumină în shader: | ||
| + | <code cpp> | ||
| + | light_source light_sources[9]; //light_source e o structura declarata similar cu cea scrisa in shader. | ||
| + | for (int i = 0;i < 9;++i) | ||
| + | { | ||
| + | std::string name = std::string("lights[") + std::to_string(i) + std::string("].position"); | ||
| + | GLuint location = glGetUniformLocation(program, name.c_str()); | ||
| + | glUniform3fv(location, 1, glm::value_ptr(light_sources[i].position)); | ||
| + | } | ||
| + | </code> | ||
| ==== Cerinte laborator ==== | ==== Cerinte laborator ==== | ||
| Line 143: | Line 241: | ||
| * Directia de ilumiare este transmisa ca ''uniform vec3 light_direction'' | * Directia de ilumiare este transmisa ca ''uniform vec3 light_direction'' | ||
| * Nu uitati sa aplicati un model de atenuare al luminii in functie de apropierea fragmentelor de unghiul de cut-off | * Nu uitati sa aplicati un model de atenuare al luminii in functie de apropierea fragmentelor de unghiul de cut-off | ||
| + | - Sa se adauge în scenă o nouă sursă de lumină si sa se calculeze iluminarea | ||
| **[Bonus]** | **[Bonus]** | ||
| - | - Sa se modifice directia si unghiul de cut-off al luminii spotlight de la tastatura | + | * Sa se modifice directia si unghiul de cut-off al luminii spotlight de la tastatura |
| * logica in ''OnInputUpdate'' | * logica in ''OnInputUpdate'' | ||
| * rotirea spotului: **sus, jos, stanga, dreapta** | * rotirea spotului: **sus, jos, stanga, dreapta** | ||
| * 2 taste pentru a creste/micsora unghiul de iluminare al spot-ului | * 2 taste pentru a creste/micsora unghiul de iluminare al spot-ului | ||
| + | |||
| + | |||
| + | <hidden> | ||
| - Modelul de iluminare Phong, folosind 3 canale de culoare: | - Modelul de iluminare Phong, folosind 3 canale de culoare: | ||
| Line 159: | Line 261: | ||
| {{ :egc:laboratoare:phong.png?500 |}} | {{ :egc:laboratoare:phong.png?500 |}} | ||
| + | |||
| + | </hidden> | ||