[PSP] PSPsdk: Dudas sobre "sceGuLight()"

Pues vereis, estoy trasteando con un sample de celshading del pspsdk que utiliza la funcion

void sceGuLight(int light, int type, int components, const ScePspFVector3* position);

pero por mas que intento entender en que se corresponde el vector que se le pasa a la funcion no lo consigo. No encuentro la relacion que tiene con la orientacion de la luz sobre el objeto, he probado mil cosas y me estoy volviendo loco...veo brillos por todas partes...jeje
En el sample usan estos vectores con estas intensidades de luz:

ScePspFVector3 envmapMatrixColumns[2] = {
{ 1.0f, 0.0f, 0.0f },
{ 0.0f, 1.0f, 0.0f }
};
sceGuLight( 0, GU_DIRECTIONAL, GU_DIFFUSE, &envmapMatrixColumns[0] );
sceGuLight( 1, GU_DIRECTIONAL, GU_DIFFUSE, &envmapMatrixColumns[1] );

y consiguen que la orientacion de la luz sea frontal(vamos, desde donde estoy yo mirando la psp).
Las intensidades son el primer parametro. Eso me deja todavia mas loco, ya que al eliminar la luz de intensidad 0 si que noto cambio(suponiendo que no influia al ser 0), y contribuye un poquito mas a la muerte prematura de mis neuronas...

Bueno, espero que no se os haga pesado de leer. A ver si alguien que ha ya trabajado con esta libreria(pspgu.h) me sepa contestar e indicarme un poco por donde van los tiros.
Un saludo
Primero decirte que no he programado con esta librería en la psp, pero echando una mirada rápida creo que te equivocas. Viendo el prototipo de la función el tercer parámetro lo que indica es la posición de la fuente de luz en la escena. Por el ejemplo que has puesto, está añadiendo dos fuentes de luz direccionales, una en la posición x=1,y=0,z=0 y la otra en x=0,y=1,z=0. A estas luces luego les tendrás que especificar otras características, como la intensidad de color y la dirección, al ser fuentes direccionales. Si no lo has hecho supongo que estará cogiendo los valores por defecto. Es normal que si desactivas la segunda fuente de luz notes el cambio.
Espero haber sido de ayuda. Saludos.
bueno, ante todo gracias por contestar e intentar ayudar, un par de cosillas:

si la fuente de luz es direccional supongo yo que no hay que posicionarla en ningun lugar sino que, cual luz solar, yega al objeto en forma de haces paralelos ( de ahí que solo haya que especificar la dirección), y de hecho es así porque funciona a la perfección.

la intensidad de la luz según la mínima documentación del pspsdk es el primer parámetro, entonces lo que no entiendo es por qué influye en la iluminación una luz de intensidad 0...entonces...jeje...para mi que no es normal...

no consigo entender de que manera lógica, o no, influye el vector en la iluminación, ya que he probado por ejemplo dándole una luz de (1, 0, 0) y el resultado es una luz amorfa, que para nada se corresponde con una iluminación desde ninguno de los ejes

mmmm...si alguno tiene idea de como funciona exactamente la función agradecería su ayuda y si no almenos unas pistillas o reflexiones que siempre pueden venir bien como ha hecho Delroy
Vamos a ver, yo no he tocado la programacin en 3D en PSP y no se muy bien como va la cosa... segun lo que tienes puesto ahí, la iluminacion es direccional y difusa, asi que el color que tenga el pixel del triangulo (bien obenido por el color de cada vertice o bien el del texel, si usas texturas) es atenuado en funcion al angulo con respecto al vector que especifiques al vertice.

Si lo que quieres es que la fuente de luz "marque" el objeto, tendrias que usar iluminacion especular.
Wow, parece que la lié un poco. Tienes toda la razón, confundí direccional con focalizada, sorry. Como dices, una fuente direccional no tiene punto de origen.

Ajandro escribió:la intensidad de la luz según la mínima documentación del pspsdk es el primer parámetro, entonces lo que no entiendo es por qué influye en la iluminación una luz de intensidad 0...entonces...jeje...para mi que no es normal...


¿Con primer parámetro te refieres al primer parámetro de la función en sí? Si es así creo que ese número es el identificador de luz. Supongo que habrá varias luces disponibles y con ese identificador puedes referirte a una de ellas. Algo parecido a OpenGL.

He estado googleando un poco y creo que la intensidad o color de la luz se pondría con esta función: void sceGuLightColor(int light, int component, unsigned int color )

Como te dije, no he programado con esta librería pero sí que tengo instalado el pspsdk. Si quieres me pasas los archivos y hago algunas pruebas.

Bueno, a ver si te he servido de algo esta vez XD. Saludos.
Mmm, creo que más o menos todos teneis razón. Yo tampoco estoy muy relacionado con este sdk, pero todo apunta a que se tiene que parecer al sdk de sony (supongo, yo no lo sé :-|) si realmente utiliza el motor gráfico de hardware que tiene la consola.
Os recomiendo que hagais una documentación con el doxygen a partir de vuestros ficheros .h de sdk/include. Yo le he echado un vistazo a estos y he sacado algunas conclusiones.

El primer parámetro de sceGuLight y de sceGuLightColor es el id de la luz. Tendrian que haber 4 por tanto de 0 a 3.
En cuanto a los tipos de luces hay 3. Direccional, puntual y spot: (GU_DIRECTIONAL, GU_POINTLIGHT y GU_SPOTLIGHT).

1) En el caso de usar un luz direccional el vector indica la dirección de la luz. Si no entiendes el concepto mirate algún tuto de la red sobre tipos de luces. Pero el tema es que para una luz direccional solo necesitas un vector de dirección (por ejemplo un sol).
2) En el caso de luz puntual y en el de spot el vector indica la posición de la luz.
3) Para el caso concreto de spot necesitamos su dirección (ya tenemos la posición), pues entonces utilizamos la función:
sceGuLightSpot(int light, const ScePspFVector3* direction, float exponent, float cutoff)
el primer parámetro, como siempre, es el id; el segundo la dirección, el tercero un coeficiente que bloquea la luz cuando se cumple una propiedad con un producto puntual de los vectores y blah, blah (o sea que limita el alcance del efecto spot, la formula es un poco compleja), y por ultimo tenemos el grado de corte en radianes del spot.
Lo cual nos deja practicamente igual, ya que realizar un spot (si era lo que querias decir con luz direccional) no es trivial, y quizás un poco complejo matematicamente. Mi recomendación es que hagas algunas pruebas, ya que en este caso puntual (spot, perdón XD) no te puedo echar una mano (aunque lo más complejo que veo es el factor de corte o 2o parámetro para los amigos). A mi no me suena ver demasiados ejemplos con luces spot, probaré a hacer alguno cuando saque un poco más de tiempo libre y si quiere te posteo mis conclusiones o mis códigos directamente para que puedas seguir con ello.

Además de esto también tenemos la atenuación sceGuLightAtt(int light, float atten0, float atten1, float atten2)
con valores constante (siempre se atenua por muy cerca del punto de iluminación que esté) y linear y cuadrática (influye la distancia). Si suponemos un distancia d tendriamos el siguiente resultado atenuación_final = (atten0 + atten1 * d + atten2 *d^2), donde d^2 significa distancia al cuadrado.

sceGuLightColor puede cambiar el componente ambiente, difuso, especular o dos a la vez dependiendo de lo que pongas en su segundo parámetro(GU_AMBIENT, GU_DIFFUSE, GU_SPECULAR, GU_AMBIENT_AND_DIFFUSE, GU_DIFFUSE_AND_SPECULAR).

En cuanto a sceGuLight tienes como 2o parámetro el tipo de luz que puede ser GU_AMBIENT_AND_DIFFUSE, GU_DIFFUSE_AND_SPECULAR o GU_UNKNOWN_LIGHT_COMPONENT, y este último me suena una especie de luz diffusa especial con la que podrias probar a experimentar si quieres :P

Pues eso, espero ser de alguna ayuda, por lo menos ami me ha servio para repasar un poco, a ver si cojo tiempo y comienzo a portar mi cutre-motor a psp :D

Un saludo
muxas gracias x las ayudas!
Ahora no que tengo exámenes pero cuando acabe me pondré de nuevo a investigar...ya os contaré.
Pero bueno, el hilo queda abierto para alguna sugerencia más.
Un saludo
6 respuestas