Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Normalizar En Pixel Shaders

Iniciado por Helius, 02 de Febrero de 2005, 03:18:37 PM

« anterior - próximo »

Helius

 No sé si estoy haciendo algo mal pero el caso es que tengo un vector en un Vertex Shader que lo saco por su salida y le llega como entrada a un Pixel Shader.

Si normalizo el vector en el VS y lo paso al PS no funciona, pero si lo paso sin normalizar y lo normalizo en el PS me funciona bien  :blink:

¿Alguien sabe por qué sucede esto?

Estoy tratando de optimizar mis shaders y mover una normalizacion de un PS a un VS estaría muy bien.

Saludos
Geardome Devlog
Tutoriales sobre DirectX 9, Nintendo DS y PSP.

Pogacha

 Si el recorrido de la normal entre vertex a vertex es pequeña, menor a 5º, practicamente es imperceptible y se puede normalizar en el vertex, pero si en cambio la diferencia es mayor a esta, lamentablemente, quedara muy denormalizado pues la interpolacion entre pixeles es lineal.
Saludos

Pogacha

 Para mas información hay un articulo de nvidia llamado "heuristicas de normalización" o "Normalization heutistics" o algo así, que lo deberia explicar, pues el sentido de la normalización es para este problema.
Saludos

Helius

 
Cita de: "Pogacha"Si el recorrido de la normal entre vertex a vertex es pequeña, menor a 5º, practicamente es imperceptible y se puede normalizar en el vertex, pero si en cambio la diferencia es mayor a esta, lamentablemente, quedara muy denormalizado pues la interpolacion entre pixeles es lineal.
Saludos
Oohhh es cierto, que gran verdad, gracias Pogacha  ;)

Tengo otro problema con la normalización... tengo un shader con especular (sin bump) y todo me resulta bien pero cuando me acerco a una superficie su brillo especular va desapareciendo hasta que desaparece completamente cuando el observador está muy cerca.

Esto debe ser porque tendré algún vector sin normalizar en el cálculo ¿no?  :blink:  El caso es que los tengo todos normalizados  :ph34r:

VS:struct VS_INPUT
{
float4 Pos:   POSITION;
float2 Tex0:  TEXCOORD0;
float4 Normal:  NORMAL;
float3 Tangent:     TANGENT0;
float3 Binormal:    BINORMAL0;
};

struct VS_OUTPUT
{
float4 Pos:    POSITION;
float2 Tex0:   TEXCOORD0;
float3 L_vector:  TEXCOORD1;
float3 N_vector:  TEXCOORD2;
float4 V_vector:  TEXCOORD3;
};

VS_OUTPUT Main(VS_INPUT In)
{
VS_OUTPUT Out = (VS_OUTPUT)0;

Out.Pos = mul(view_proj_matrix, In.Pos);

Out.Tex0 = In.Tex0;

Out.L_vector = (light_position - In.Pos) * inv_radius;

Out.N_vector = In.Normal;

Out.V_vector = (eye_position - In.Pos);

return Out;
}


PS:
float3 light_color;
float3 specular_color;
float specular_exp;
float atten_power;

sampler base_map;
sampler gloss_map;

struct PS_INPUT_STRUCT
{
float2 tex_coord:  TEXCOORD0;
float3 light_vector: TEXCOORD1;
float3 normal_vector: TEXCOORD2;
float4 view_vector:  TEXCOORD3;
};

struct PS_OUTPUT_STRUCT
{
float4 color0:       COLOR0;
};

PS_OUTPUT_STRUCT Main(PS_INPUT_STRUCT psInStruct)
{
PS_OUTPUT_STRUCT psOutStruct;

float atten = saturate(1 - dot(psInStruct.light_vector, psInStruct.light_vector));

float3 normalized_light_vector = normalize(psInStruct.light_vector);
float3 normalized_view_vector = normalize(psInStruct.view_vector);
float3 normalized_normal_vector = normalize(psInStruct.normal_vector);

float4 base = tex2D(base_map, psInStruct.tex_coord);
float4 gloss = tex2D(gloss_map, psInStruct.tex_coord);

float3 final_diffuse = base * light_color * saturate(dot(normalized_normal_vector, normalized_light_vector));
float3 final_specular = gloss * specular_color * pow(saturate(dot(reflect(-normalized_view_vector, normalized_normal_vector), normalized_light_vector)), specular_exp);

psOutStruct.color0.rgb = (final_diffuse + final_specular) * atten * atten_power;
     
psOutStruct.color0.a = base.a;

return psOutStruct;
}


Sin embargo, tengo otro con bump que me funciona correctamente y lo único que cambia es que en el cálculo del especular uso la normal que me da el mapa de normales y los vectores light y view transformados al tangent space :blink: ¿Por qué utilizando la normal del vértice no me funcionará bien?

Geardome Devlog
Tutoriales sobre DirectX 9, Nintendo DS y PSP.

Pogacha

 Si usas la luz transformada al tangent space las normales del vertice tambien deben ser transformadas al tangent space.
Todo debe estar en el mismo espacio, o sea, las normales de los vertices generalmente estan en object-space, la luz esta en world-space o object-space y las normales estan en texture-space o tangent-space.
No veo otro problema que puedas tener aparte de este que es bastante complicado de resolver pues implica algebra matricial.
Edit: en el codigo de arriba estas cometiendo ese error, las normales no estan en el mismo space.
Saludos.

Helius

 Pero en ese código no estoy usando el tangent space para nada, no uso bump luego la normal que utilizo es la del vértice del objeto.

¿Esta normal no está en el mismo space que el light_vector y el view_vector?

¿debería multiplicarla por la matriz world?

Ahora si que estoy liado  :unsure:

Edit: De todas formas el cálculo del specular es correcto, aparece en su lugar correcto, la única pega es que cuando te acercas mucho se va difuminando hasta que desaparece.
Geardome Devlog
Tutoriales sobre DirectX 9, Nintendo DS y PSP.

Helius

 Dejo aquí un ejemplo de lo que me pasa: http://www.geardome.com/files/ejemplo.zip

Se maneja con los cursores y el ratón. Acercaros al brillo especular y observareis que desaparece. AvPag y RePag para el eje Y.

A ver si os funciona a alguno  :huh:
Geardome Devlog
Tutoriales sobre DirectX 9, Nintendo DS y PSP.

Helius

 Bueno, perdonad que os diera tanto la bara pero ya he encontrado el fallo  (ole)

Está en el view vector que se pasa desde el VS al PS, resulta que por algún motivo extraño puse que sea un float4 cuando debe ser un float3 para que coincida con los demás cálculos.

Ahora me gustaría dar la bara con otra cosa  :P , el offset mapping.

En el ejemplo que he puesto antes vereis el offset mapping funcionando pero no se por qué razón cuando acercas mucho la cámara a la cara inferior del objeto (el suelo) se nota una deformación en las coordenadas de textura, pero sólo me sucede con esa cara  :blink:  ¿alguna idea de qué puede ser?
Geardome Devlog
Tutoriales sobre DirectX 9, Nintendo DS y PSP.

Pogacha

 
CitarPero en ese código no estoy usando el tangent space para nada
Tienes razon, no se por que pense que pasabas al object-space la luz.

Aquí no tengo una maquina con capacidad de shaders pero vere mañana si puedo ayudarte ... si no es muy grande el archivo me lo llevaré en un disco a mi casa.

Saludos

martiño

 Hola,

Los calculos de luz hay que hacerlos siempre con los vectores en el mismo espacio. En el shader que pones ahí las posiciones de los vértices estan en espacio del objeto (porque no los has multiplicado por la matriz de vista), y me temo que la posicion de la luz esta en el espacio de vista (porque uno intuitivamente suele colocar las luces con respecto al origen de coordenadas, no con respecto a los objetos que iluminan).

Si este es el problema, la solucion rápida de hacer es pasar los vectores al espacio de vista, que en el caso de los vertices se haría multiplicando por la matriz de vista (en el shader), y en el caso de las normales por la inversa (en el shader). Sin embargo con esto estas realizando muchas transformaciones innecesarias, porque esto equivalería a pasar la luz al espacio del objeto, multiplicando por la matriz de vista inversa una sola vez para cada objeto (en la CPU).

Por ejemplo, si el objeto (sin rotar) tiene como centro la posicion (0, 1, 0) y la luz esta en (0, 5, 0), la posicion de luz que has de pasar sería (0, 4, 0).

Saludos.






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.