Differences

This shows you the differences between two versions of the page.

Link to this comparison view

egc:laboratoare:08 [2022/11/18 17:35]
andrei.lambru
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]] 
  
-<​hidden>​ 
 ==== Modelarea reflexiei luminii ==== ==== Modelarea reflexiei luminii ====
  
Line 34: Line 34:
 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.
  
-</​hidden>​+
  
 ==== Iluminare Phong in Fragment Shader ==== ==== Iluminare Phong in Fragment Shader ====
Line 109: 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 121: 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 131: 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 147: 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]**
Line 153: Line 248:
     * 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>​ <​hidden>​
egc/laboratoare/08.1668785715.txt.gz · Last modified: 2022/11/18 17:35 by andrei.lambru
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0