2011-06-17 23 views
7

Próbuję zrobić niestandardowy lekki shader i próbowałem wiele różnych rzeczy w czasie. Niektóre z rozwiązań, które znalazłem działają lepiej, inne gorzej. Na to pytanie używam rozwiązania, które do tej pory działało najlepiej.Dlaczego kod oświetlenia GLSL przesuwa punkt świetlny w aparacie?

Mój problem polega na tym, że jeśli przesuniemy "kamerę", pozycje świateł również się poruszają. To rozwiązanie ma bardzo nieznaczny, ale zauważalny ruch, a pozycja światła wydaje się być powyżej tego, gdzie powinno być.

Domyślne oświetlenie OpenGL (bez żadnych modułów cieniujących) działa dobrze (stabilne pozycje światła), ale potrzebuję modułu cieniującego do multiteksturowania i zamierzam użyć jego fragmentów do efektów świetlnych po uruchomieniu.

Vertex Źródło:

varying vec3 vlp, vn; 

void main(void) 
{ 
    gl_Position = ftransform(); 

    vn = normalize(gl_NormalMatrix * -gl_Normal); 
    vlp = normalize(vec3(gl_LightSource[0].position.xyz) - vec3(gl_ModelViewMatrix * -gl_Vertex)); 

    gl_TexCoord[0] = gl_MultiTexCoord0; 
} 

Fragment Źródło:

uniform sampler2D baseTexture; 
uniform sampler2D teamTexture; 
uniform vec4 teamColor; 

varying vec3 vlp, vn; 

void main(void) 
{ 
    vec4 newColor = texture2D(teamTexture, vec2(gl_TexCoord[0])); 
    newColor = newColor * teamColor; 
    float teamBlend = newColor.a; 

    // mixing the textures and colorizing them. this works, I tested it w/o lighting! 
    vec4 outColor = mix(texture2D(baseTexture, vec2(gl_TexCoord[0])), newColor, teamBlend); 

    // apply lighting 
    outColor *= max(dot(vn, vlp), 0.0); 
    outColor.a = texture2D(baseTexture, vec2(gl_TexCoord[0])).a; 

    gl_FragColor = outColor; 
} 

Co robię źle?

+1

Kilka zdjęć, a nawet link do filmu z Youtube problemu, pomoże nam zdiagnozować problem. –

Odpowiedz

5

Nie mogę być pewny, że którykolwiek z nich stanowi problem, ale może spowodować jeden.

Po pierwsze, trzeba znormalizować swoje per-vertex vn i vlp (BTW, spróbuj użyć bardziej opisowych nazw zmiennych. viewLightPosition jest o wiele łatwiejsze do zrozumienia niż vlp). Wiem, że znormalizowałeś je w module cieniującym wierzchołków, ale interpolacja fragmentów shormera spowoduje ich denormalizację.

Po drugie, nie jest szczególnie źle, jak zbędne. vec3(gl_LightSource[0].position.xyz). "Position.xyz" jest już vec3, ponieważ maska ​​"swizzle" (".xyz") ma tylko 3 komponenty. Nie musisz ponownie przesyłać go do vec3.

+1

Wow. Znormalizowany ponownie dwie zmienne w shaderze fragmentu, wyjął negację dla 'gl_Normal' i' gl_Vertex' w vertex shader i działa. Wielkie dzięki! –