Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Fragment Program (Lighting)

Iniciado por davidgf, 18 de Septiembre de 2008, 04:17:41 PM

« anterior - próximo »

davidgf

Hola a todos,

And liado haciendo un shader de los "viejos", los ARB_fragment_program.
Quisiera que fuera pixel lighting en vez de per vertex, ya que en mi mundo 3d hay polígonos enormes que me da palo cortar además de que es poco práctico.
De momento el shader debería hacer atenuación por distancia:


!!ARBfp1.0



# Fragment inputs

ATTRIB inTexCoord = fragment.texcoord[0];      # First set of texture coordinates

ATTRIB inColor    = fragment.color.primary; # Diffuse interpolated color
ATTRIB inPosition    = fragment.position; # 2D position on screen

# Fragment outputs

OUTPUT outColor   = result.color;
TEMP texelColor;
TEMP RealPos;
TEMP LightVec1;
TEMP Temp;

MOV RealPos, inPosition;
MOV Temp.x, 0.0025;
MOV Temp.y, 0.003333333;
MAD RealPos.x, inPosition.x, Temp.x, -1;
MAD RealPos.y, inPosition.y, Temp.y, -1;
ADD RealPos.z, inPosition.z, -1;
MOV RealPos.w , 1;


DP4 RealPos.x, state.matrix.mvp.inverse.row[0], RealPos;

DP4 RealPos.y, state.matrix.mvp.inverse.row[1], RealPos;

DP4 RealPos.z, state.matrix.mvp.inverse.row[2], RealPos;

DP4 RealPos.w, state.matrix.mvp.inverse.row[3], RealPos;
RCP RealPos.w,RealPos.w;
MUL RealPos, RealPos, RealPos.w;


ADD LightVec1, program.local[1], -RealPos;
DP3 LightVec1.w, LightVec1, LightVec1;
RSQ LightVec1.w, LightVec1.w;
RCP Temp.w, LightVec1.w;  # Temp.w its the distance 
#MUL LightVec1, LightVec1, LightVec1.w; # LightVec1 is normalized

MUL Temp.x, Temp.w, program.local[3].x;
MUL Temp.x, Temp.w, 0;
MUL Temp.y, Temp.w, Temp.w;
#MAD Temp.x, program.local[3].y, Temp.y, Temp.x;
MAD Temp.x, 0.0000002, Temp.y, Temp.x;
RCP Temp.x, Temp.x;
MIN Temp.x, Temp.x, 1;


TXP texelColor, inTexCoord, texture, 2D;
MUL texelColor,texelColor, Temp.x;

MOV outColor, texelColor;




END


Lo que hago es leer la position en la pantalla del fragmento i la transformo al espacio de world basandome en la implementacion de la funcion gluUnProject. Pero no funciona nada bien. Además en algun momento que el shader había funcionado bien, sólo lo hacía un fotograma, luego se volvia negro todo.

En fin, alguna sugerencia? Hacerlo de una manera diferente??

Gracias a todos

David
Tàrraco: una aventura por la Tarragona romana (http://tarraco.davidgf.net)

Pogacha

En realidad lo que se hace es calcular la posicion en el mundo en el vertex shader y luego solo tomar la interpolada en el vertex shader.
Incluso mas, la posicion se convierte al mundo del light en el vertex shader.
Saludos!

tamat

y por qué no usar GLSL? es que yo veo ASM y me dan escalofrios, ademas que será más dificil de mantener.
Por un stratos menos tenso

davidgf

Hey,

Prefiero usar ASM puesto que tiene mayor compatibilidad. Si puedo hacer lo mismo y soportar más PCs... no? Para las cosas más avanzadas pues GLSL.
Pochaga, si hago lo que me dices tu eso es vertex lighting. Si tengo un poly muy largo, al interpolar linealmente me queda una iluminación claramente incorrecta. Eso sólo vale para polígonos pequeños. Me gustaría poder hacer pixel lighting de verdad.

Gracias!

David
Tàrraco: una aventura por la Tarragona romana (http://tarraco.davidgf.net)

tamat

lo que dice pogacha es que interpolas la coordenada del vertice así como la normal. Luego por pixel haces las operaciones de iluminacion.

sigo sin ver claro lo que dices de tener más compatibilidad por usar ASM, a fin de cuentas GLSL se compila a ASM en tiempo de ejecución usando el driver que tiene instalado el usuario. no es eso más compatible que hacer tú el ASM?
Por un stratos menos tenso

davidgf

A pues no lo sabia, es que mi portatil sólo soporta ARB_fragment_program, y no ARB-fragment_shader. Tenía entendido que era un requisito para usar GLSL, pero bueno. Lo que me preocupa es la implementacion.

Si yo interpolo la coordenada así como la normal el resultado será (a mi juicio) erróneo. Puesto que la interpolación será lineal. Eso me lleva a que puntos muy alejados de un triangulo que tenga un vertice cercano a la luz i otros muy alejados de ésta calcularán algo de iluminación que no les pertoca. No sé si me explico. (mirad esta imagen, el cubo http://gchen.sdf-eu.org/Chengine/Images/Screenshots/Shadows.jpg, no es mía eh?)

Me gustaría que de cada pixel de la pantalla (fragmento vamos) se calculara la distancia a la luz i se calculara la atenuación. SI lo hago por vértice e interpolo es verte lighting no?

Gracias

David
Tàrraco: una aventura por la Tarragona romana (http://tarraco.davidgf.net)

tamat

que sí, que si calculas la luz por vertice e interpolas salen errores (sombreado gouraud), por eso te estamos diciendo que interpoles LA COORDENADA DE LOS VERTICES, es decir, que pases la coordenada de los vertices desde los vertex shaders hasta  los fragment shaders y luego para cada fragmento coge esa coordenada y la normal y haces el calculo de la luz.
Por un stratos menos tenso

davidgf

Ah! aora pillo. Y eso como se puede hacer.
Se me ocurre pasarle al fragment las posiciones de los tres vértices, pero como interpolo luego?
Y por qué no lo puedo hacer desproyectando el pixel de la pantalla??

Gracias tamat por la paciencia!

David
Tàrraco: una aventura por la Tarragona romana (http://tarraco.davidgf.net)

davidgf

Ya está!!!

Simplemente guardo la coordenada en world en una texcoord, y él sólo me lo interpola a lo largo del triángulo!

Así que lo calculo sin ningún problema!!!! Muchas gracias por todo, no se me había ocurrido antes!!!

Saludos!

David
Tàrraco: una aventura por la Tarragona romana (http://tarraco.davidgf.net)

tamat

en teoria no hace falta usar el texcoord, bueno, tal vez dependa de la version que uses, pero en glsl puedes pasar variables desde el vertex shader y la tarjeta te las interpola. lo puedes usar para vectores, floats, etc. Igual que te hace con las coordenadas de textura, de hecho si usas fixed pipeline no existen canales especificos, todo lo pasas así, como variables.
Por un stratos menos tenso

davidgf

#10
Si precisamente me fije en lo que me dijiste y busqué por internet cómo se hacía en GLSL. Me fijé que se usa una variable varyng o asi que la interpola y la pasa el shader él solito. Así que en ARB program se me ocurrió pasarla como texcoord (o color) ya que estos parámetros te los interpola él solito con los de los otros vértices.

Muchas gracias. Espero que sirva a alguien más, ya que no hay mucha info que digamos. Todo el mundo usa GLSL, que está bien, pero para qué usarlos si se pueden usar unos más viejos e igual de efectivos!

Saludos

David

PD: Tamat, he visto que eres profe de la FIB? Puede ser o me lo invento??
Tàrraco: una aventura por la Tarragona romana (http://tarraco.davidgf.net)

tamat

Pero lo bueno de usar GLSL es que el codigo es más legible y otros pueden beneficiarse de él, no hay mucha gente que pueda leer ASM (yo por ejemplo no podría) ademas de que resulta más comodo y nada te asegura que tu ASM sea mejor que el ASM que genera la ultima versión del driver de la tarjeta. En fin, suerte con lo que te traigas entre manos.

soy profe de la UPF, pero no lo digas muy alto...
Por un stratos menos tenso

davidgf

Ok, perdona.

Es que estoy buscando desde hace tiempo un chico que fue el que me entrevistó e hizo de jurado en el concurso de Treballs de Recerca de la Salle, y me dijo que conocía el foro este y por lo visto sabía un montón de videojuegos y programación.

Saludos y gracias

David
Tàrraco: una aventura por la Tarragona romana (http://tarraco.davidgf.net)






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.