2011-02-08 1 views
1

Je travaille sur un programme de shader GLSL de niveau débutant. Je suis this tutoriel. Mais ma sphère apparaît toujours en niveaux de gris et n'est pas colorée en rouge comme je m'y attendais.Problème d'ombrage GLSL: Pourquoi ma sphère est-elle en niveaux de gris au lieu de rouge? (voir code)

Vertex Shader:

varying vec3 normal, lightDir; 

void main() { 

    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; 

    normal = gl_NormalMatrix * gl_Normal; 

    vec4 vertex_in_modelview_space = gl_ModelViewMatrx * gl_Vertex; 

    lightDir = vec3(gl_LightSource[0].position – vertex_in_modelview_space); 

} 

Frag Shader:

varying vec3 normal, lightDir; 

void main() 
{ 

    const vec4 AmbientColor = vec4(0.1, 0.0, 0.0, 1.0); 
    const vec4 DiffuseColor = vec4(1.0, 0.0, 0.0, 1.0); 

    vec3 normalized_normal = normalize(normal); 
    vec3 normalized_lightDir = normalize(lightDir); 

    float DiffuseTerm = clamp(dot(normal, lightDir), 0.0, 1.0); 
    gl_FragColor = AmbientColor + DiffuseColor * DiffuseTerm; 
} 

Le code est juste et copier coller de ce tutoriel. A partir du fragment de shader, la couleur diffuse est rouge, mais ma sphère est en niveaux de gris. Je sais que les shaders sont chargés correctement car si je supprime le code dans le fragmentage et utilise ce qui suit:

gl_FragColor = vec4 (0.0,1.0,0.0,1.0);

alors ma sphère est verte comme prévu. Je ne sais pas si c'est quelque chose dans le code openGL (comme, Renderer.cpp) qui provoque un conflit, ou s'il y a autre chose qui ne va pas.

Ceci est mon premier codage dans GLSL, et je suis assez confus au sujet de ce que gl_Enable je dois activer/désactiver pour que le shader fonctionne correctement.

Merci pour vos commentaires!

EDIT: Ok, si j'appelle glColor3f avant le rendu, je peux obtenir la bonne couleur. Mais la couleur de la lumière n'entraîne-t-elle pas directement un changement de couleur dans la sphère? Je suis inquiet que je ne suis pas fait appeler les fonctions dans le shader ...

EDIT2: Il se trouve que chaque fois que je mets un code dans le shader vertex shader ou frag (autre que gl_Color = ...), la couleur solide que je reçois disparaît ... Je suppose que cela signifie qu'il y a quelque chose de terriblement mauvais avec mes shaders?

EDIT3: Voici le code pour la mise en place de mon shader (fourni par mon TA):

char *vs = NULL,*fs = NULL; 

v = glCreateShader(GL_VERTEX_SHADER); 

f = glCreateShader(GL_FRAGMENT_SHADER); 

vs = textFileRead(vert); 
fs = textFileRead(frag); 

const char * ff = fs; 
const char * vv = vs; 

glShaderSource(v, 1, &vv,NULL); 
glShaderSource(f, 1, &ff,NULL); 

free(vs); 
free(fs); 

glCompileShader(v); 
glCompileShader(f); 

p = glCreateProgram(); 
glAttachShader(p,f); 
glAttachShader(p,v); 

glLinkProgram(p); 

int infologLength = 0; 
int charsWritten = 0; 
char *infoLog; 

glGetProgramiv(p, GL_INFO_LOG_LENGTH,&infologLength); 
if (infologLength > 0) 
{ 
    infoLog = (char *)malloc(infologLength); 
    glGetProgramInfoLog(p, infologLength, &charsWritten, infoLog); 
    printf("%s\n",infoLog); 
    free(infoLog); 
} 

EDIT4: Utilisation des journaux de shaders comme suggéré par kvark, je réussi à corriger les bugs dans les shaders (il y a eu quelques erreurs). Si vous souhaitez voir le code final, s'il vous plaît laissez un commentaire ou un message moi (cette question devient longue).

+0

w.r.t. EDIT2: Vérifiez-vous les erreurs de compilation/configuration shader? Il existe des appels GL spécifiques pour obtenir une telle sortie pour les shaders. – Macke

+0

Quelle version de GL ciblez-vous? – Tommy

+0

Tommy: Je code dans Ubuntu. Comment puis-je savoir quelle version de GL j'ai? – confusedKid

Répondre

2

Il est une bonne idée de vérifier non seulement le journal des liens, mais aussi compiler les journaux pour chaque shader et compiler/résultat du lien:

glGetShaderInfoLog(...) 
glGetShaderiv(...,GL_COMPILE_STATUS,...) 
glGetProgramiv(...,GL_LINK_STATUS,...) 

Assurez-vous que les résultats sont positifs et les journaux sont vides (ou bien).

Le terme diffus est calculé incorrectement dans votre exemple. Il doit avoir la valeur suivante:

float DiffuseTerm = max(0.0, dot(normalized_normal,normalized_lightDir)); 

Vous n'avez pas besoin pince() que le résultat point() des vecteurs normalisés ne peut pas dépasser 1.

Si vous avez fait que le programme de shaders est lié correctement, il activé sur un match nul et le résultat est toujours bizarre, essayez de sélectionner différents composants de votre équation de couleur finale pour découvrir le mauvais:

gl_FragColor = DiffuseColor;  //can't be grayscale 
gl_FragColor = vec4(DiffuseTerm); //should be diffuse grayscale 

BTW, glColor3f ne devrait rien avoir à faire avec votre shader car vous n'utilisez pas gl_Color à l'intérieur. Si le résultat change lorsque vous l'appelez, cela signifie que l'activation du shader a échoué (elle n'a pas été liée ou n'a pas été utilisée du tout).

Bonne chance!

+0

où devrais-je mettre le glGetShaderInfoLog, etc? Où j'initialise les shaders? – confusedKid

+0

@kvark. Pourquoi dites-vous que le terme diffus est incorrect? Il peut être sous-optimal, mais les résultats obtenus sont les mêmes que ceux de votre formulation? Est-ce que je manque quelque chose? – rotoglup

+0

@confuseKid. Mettez glGetShaderiv (..) et glGetShaderInfoLog (..) après avoir appelé glCompileShader() pour chaque shader. Et n'oubliez pas de vérifier les valeurs renvoyées comme état de compilation/liaison – kvark

0

Peut-être que est dû à un comportement indésirable avec le résultat de votre canal alpha.

Vous calcul fait l'éclairage sur votre canal alpha, ayant quelque chose comme en fait: g

gl_FragColor.a = 1,0 + 1,0 * DiffuseTerm

qui vous donnera> = 1.0 valeurs .

Vous devez veiller à ne pas inclure votre canal alpha dans votre sortie (ou même dans vos calculs).

Essayez de faire que votre mélange est désactivé, ou fixer shader à quelque chose comme:

varying vec3 normal, lightDir; 

void main() 
{ 
    const vec3 AmbientColor = vec3(0.1, 0.0, 0.0); 
    const vec3 DiffuseColor = vec3(1.0, 0.0, 0.0); 

    vec3 normalized_normal = normalize(normal); 
    vec3 normalized_lightDir = normalize(lightDir); 

    float DiffuseTerm = clamp(dot(normal, lightDir), 0.0, 1.0); 
    gl_FragColor = vec4(AmbientColor + DiffuseColor * DiffuseTerm, 1.0); 
} 
+0

J'ai essayé comme vous l'avez suggéré, mais il n'y avait pas de différence dans les résultats. Merci pour les conseils si. – confusedKid