2016-12-23 2 views
0

Je du mal à trouver l'erreur dans ma fonction d'éclairage ultra-simpliste dans mon vertex shader:Quel est le problème avec ma fonction d'éclairage dans le shader?

in vec4 position;   /* Homogenized input vertex position.   */ 
in vec4 color;    /* Input color information.      */ 
in vec3 normal;    /* Normal vector to the surface.    */ 

uniform mat4 ortho;   /* Orthographic matrix.   */ 
uniform mat4 model;   /* Modelling matrix.   */ 
uniform mat4 view;   /* View transformation.   */ 
uniform mat4 project;  /* Projection matrix.   */ 

out vec4 color_out;   /* Color passed to the fragment shader. */ 

float light() 
{ 
    mat3 normat = transpose(inverse(mat3(view * model))); 
    vec3 norm = normalize(normat * normalize(normal)); 
    vec3 light = normalize(vec3(1.0f, 1.0f, 1.0f)); 
    return max(dot(norm, light), 0.0f); 
} 
void main() 
{ 
    gl_Position = ortho * project * view * model * position; 
    color_out = vec4(color.rgb * light(), color.a); 
} 

Cette fonction est utilisée pour éclairer les faces d'un icosphere rotatif. Depuis que je l'ai produit manuellement les sommets du icosphere et je peux y accéder à tout moment, j'ai essayé de reproduire la même opération dans le code CPU montrant le résultat d'une face, par exemple:

Normal Matrix:     Normal vectors for face 10: 
[ 0.08  0.59 -0.81]  { 3936}[-0.58  0.61 -0.54] --> light: 0.694 
[-0.00  0.81  0.59]  { 3937}[-0.58  0.61 -0.54] --> light: 0.694 
[ 1.00 -0.04  0.06]  { 3938}[-0.58  0.61 -0.54] --> light: 0.694 

Malgré la les vecteurs normaux étant corrects ou non, la valeur de la lumière change avec la rotation de la sphère. Cependant, si je cours le code (et laisse le shader calculer la valeur), les faces triangulaires résultantes apparaissent complètement sombres.

Voici comment copier les données de sommet dans la mémoire tampon et comment je signale les attributs:

/* (...) Bind shader, and get attribute locations. */ 
/* (...) Create VBO. */ 
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vertex), vertices.data(), GL_DYNAMIC_DRAW); 
/* (...) */ 

glVertexAttribPointer(position_id, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0); 
glVertexAttribPointer(color_id, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void *)sizeof(glm::vec3)); 
glVertexAttribPointer(normal_id, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void *)(sizeof(glm::vec3) + sizeof(glm::vec4))); 

/* For reference: vertices is a std::vector<Vertex>, where Vertex 
* is defined as: 
* 
* struct Vertex { 
*  glm::vec3 p; ---> Position. 
*  glm::vec4 c; ---> Color.  
*  glm::vec3 n; ---> Normal. 
* }; 
**/ 

Répondre

0

me Silly, j'oublié d'activer l'attribut sommet normal ... Ceci est la ligne que j'étais manquant:

glEnableVertexAttribArray(normal_id); 

Lorsque le normal_id avait précédemment été lié avec glGetAttribLocation.