Foros - Stratos

Programadores => Programación gráfica => Mensaje iniciado por: Pogacha en 13 de Octubre de 2004, 05:16:05 PM

Título: Especular
Publicado por: Pogacha en 13 de Octubre de 2004, 05:16:05 PM
 No consigo dar con el especular en el FragmentProgram!:

Actualmente uso esto suponiendo una luz (pseudo codigo):

Atenuacion = 1 - (DIstanciaDeLuz ^ 2 / PotenciaDeLuz ^ 2);

// Luz y Ojo en tangent space.
AnguloMedio = (Luz.Normalizado() + Ojo.Normalizado()) / 2.0;

ColorFinalEspecular = Potencia(Saturar( AnguloMedio . NormalLocal ), 4.0) * Atenuacion * TexuraEspecular;

ColorFinalDifusa = Saturar(Luz.Normalizado() . NormalLocal) *  Atenuacion * TexturaDifusa;

ColorFinal = ColorFinalDifusa + ColorFinalEspecular;

Pero esto me devuelve algo bastante irreal.

Tengo dos problemas :
1 -  Cuando estoy muy lejos de la superficie, la especularidad se agranda pues el angulo medio varia muy
poco.
Cuando estoy muy cerca de la superficie, la especularidad se transforma en un pequeño circulo, pues el angulo medio varía demasiado.
Supuestamente esto es normal pero no estoy seguro, talvez esto sea por el problema numero dos.

2 - Parece que la posicion a la superficie no varia en el Z del tangent-space, no se si el tangent space tiene componente z o que pasa?.
Hay que activar GL_TEXTURE3D para que a partir del Vertex-Program interpole las tres componentes vectoriales que se pasan al fragment-program o que?
La verda es que se me queman los papeles.  (nooo)

Saludos y gracias.
Título: Especular
Publicado por: BeRSeRKeR en 13 de Octubre de 2004, 07:25:34 PM
 Así a simple vista, el halfvector no hay que dividirlo entre 2. Sería:

AnguloMedio = Luz.Normalizado() + Ojo.Normalizado();

Y con respecto a si se interpolan las 3 componentes de los vectores que pases del vertex al fragment program, sí, se interpolan sin necesidad de hacer nada especial.

Saludos.
Título: Especular
Publicado por: Pogacha en 14 de Octubre de 2004, 12:49:37 AM
 
CitarAsí a simple vista, el halfvector no hay que dividirlo entre 2. Sería:

AnguloMedio = Luz.Normalizado() + Ojo.Normalizado();
No creo ..., trendria modulo de 0 a 2, la misma direccion, pero lo que si alteraria es al produto punto.

Ahora mi duda recae sobre como creo las tangentes, binormales y normales y como convierto a tangent-space, ¿conoces algún ejemplo por ahí que lo explique bién?
Título: Especular
Publicado por: BeRSeRKeR en 14 de Octubre de 2004, 01:27:58 AM
 
Cita de: "Pogacha"No creo ..., trendria modulo de 0 a 2, la misma direccion, pero lo que si alteraria es al produto punto.
Bueno, efectivamente el half way vector propiamente dicho se calcularía como tú dices pero para agilizar un poco las cosas, lo que se solía hacer es HalfVector = View + Eye y luego, a la hora de calcular la componente especular, se utiliza una potencia specular alta. Eso compensa la división entre 2. Yo lo hacía así y funcionaba bien. Y digo que lo hacía porque ahora que las aceleradoras tienen más potencia de cálculo, utilizo el vector "reflection" para calcular el specular. Porque realmente el half vector es otro truquillo que se sacó de la manga Jim Blinn para evitar los cálculos del vector reflexión.

En cuanto al cálculo del tangent space, yo utilizaba el template MeshMender de nVidia . Tienes el código disponible así que te podría ayudar a entender el proceso. Lo puedes descargar de aquí.

Saludos.
Título: Especular
Publicado por: Pogacha en 14 de Octubre de 2004, 02:28:52 AM
 Es muy parecido a lo que hago, pero tiene unas variantes y unas cosas que no entiendo, despues probare eso.
Gracias
Título: Especular
Publicado por: Pogacha en 15 de Octubre de 2004, 11:08:44 PM
 Bien, sigo teniendo problemas con la transformación al Tangent Space, mas bien el error esta en como encuentro las tangentes y binormales, pero bueno, ya encontre el error de la componente especular, que por cierto era conceptual:

AnguloMedio = (Luz.Normalizado() + Ojo.Normalizado()) / 2.0;  (nooo)  (nooo)  (nooo)  (nooo)  (nooo)

Corregido:
Atenuacion = 1 - (DIstanciaDeLuz ^ 2 / PotenciaDeLuz ^ 2);

// Luz y Ojo en tangent space.
AnguloMedio = (Luz.Normalizado() + Ojo.Normalizado()).Normalizado();

ColorFinalEspecular = Potencia(Saturar( AnguloMedio . NormalLocal ), 4.0) * Atenuacion * TexuraEspecular;

ColorFinalDifusa = Saturar(Luz.Normalizado() . NormalLocal) * Atenuacion * TexturaDifusa;

ColorFinal = ColorFinalDifusa + ColorFinalEspecular;


Notese que dividiendo por dos no renormalizo el vector.
No se por que se me dio que solo divida por dos!!!  (grrr)  (nooo)  (grrr)  (nooo) .
La suma vectorial no es distrivutiva respecto al modulo y fase. :P
Me siento ridiculo!

Saludos

PD: Por cierto ..., que les parece el Pogacha High Level Shading Languaje?