Estoy haciendo un rasterizador de software, y me he encontrado con un pequeño inconveniente: parece que no puedo obtener un mapeo de texturas correcto en perspectiva para que funcione.Correlación de textura correcta de perspectiva; z El cálculo de la distancia z puede ser incorrecto
Mi algoritmo es primero ordenar las coordenadas para trazar por y
. Esto devuelve un punto más alto, más bajo y central. entonces camino a través de las líneas de exploración utilizando el delta:
// ordering by y is put here
order[0] = &a_Triangle.p[v_order[0]];
order[1] = &a_Triangle.p[v_order[1]];
order[2] = &a_Triangle.p[v_order[2]];
float height1, height2, height3;
height1 = (float)((int)(order[2]->y + 1) - (int)(order[0]->y));
height2 = (float)((int)(order[1]->y + 1) - (int)(order[0]->y));
height3 = (float)((int)(order[2]->y + 1) - (int)(order[1]->y));
// x
float x_start, x_end;
float x[3];
float x_delta[3];
x_delta[0] = (order[2]->x - order[0]->x)/height1;
x_delta[1] = (order[1]->x - order[0]->x)/height2;
x_delta[2] = (order[2]->x - order[1]->x)/height3;
x[0] = order[0]->x;
x[1] = order[0]->x;
x[2] = order[1]->x;
Y entonces podremos dar order[0]->y
-order[2]->y
, el aumento de la x_start
y x_end
por un delta. Al representar la parte superior, los delta son x_delta[0]
y x_delta[1]
. Al representar la parte inferior, los delta son x_delta[0]
y x_delta[2]
. Luego, interpolamos linealmente entre x_start y x_end en nuestra línea de exploración. Las coordenadas UV se interpolan de la misma manera, ordenadas por y, comenzando al principio y al final, a las cuales se aplican delta en cada paso.
Esto funciona bien, excepto cuando trato de hacer un mapeo de UV correcto en perspectiva. El algoritmo básico es tomar UV/z
y 1/z
para cada vértice e interpolar entre ellos. Para cada píxel, la coordenada UV se convierte en UV_current * z_current
. Sin embargo, este es el resultado:
La parte Inversed le dice a donde el delta de se voltean. Como puede ver, los dos triángulos parecen dirigirse hacia diferentes puntos en el horizonte.
Esto es lo que uso para el cálculo de la Z en un punto en el espacio:
float GetZToPoint(Vec3 a_Point)
{
Vec3 projected = m_Rotation * (a_Point - m_Position);
// #define FOV_ANGLE 60.f
// static const float FOCAL_LENGTH = 1/tanf(_RadToDeg(FOV_ANGLE)/2);
// static const float DEPTH = HALFHEIGHT * FOCAL_LENGTH;
float zcamera = DEPTH/projected.z;
return zcamera;
}
Estoy en lo cierto, ¿es un problema de memoria intermedia z?
Otro consejo para la depuración, calcule cada punto de textura utilizando las anticuadas coordenadas U y V no incrementales para cada píxel y compárelas con los valores incrementales calculados por su algoritmo (lo que permite algunas fallas debido al error de redondeo). –
Guau ... ¡eso es una respuesta y media! : D – Goz
goz: ahora solo espero que sea útil, ya que probablemente ya tiene la mayor parte de este código establecido a juzgar por la imagen. Estoy pensando que probablemente calculó mal uno de los valores de interpolación. Pero, con un poco de suerte, si pone su algoritmo al lado del mío, puede descubrir cuál es; ^) – Toad