jump to navigation

Renderizando con altivec February 20, 2005

Posted by winden in coding, demoscene.
trackback

Bueno, ayer por fin terminé de preparar el nuevo renderizador de triángulos usando Altivec. Toda la película de usar ecuaciones implícitas con la que empecé este blog iba encaminada a terminar con esta implementación, asi que no estaría mal tener un resumen de lo conseguido.El modo de dibujo usado es flat-shading con zbuffer, con la particularidad de usar z constante para cada triángulo. Esto último parece un poco raro, pero tiene sentido para triángulos muy pequeños, que son los que yo quiero manejar.

El sistema de dibujo se basa en procesar los triángulos de 8 en 8, así que pasamos de tener una estructura de datos escalar:

struct tri{
  s16 x0,x1,x2;
  s16 y0,y1,y2;
  u16 z,c;
}

a una de vectores:

struct tri8{
  vs16 x0,x1,x2;
  vs16 y0,y1,y2;
  vu16 z,c;
}

“s16” es mi abreviatura para el “short int” standard de enteros de 16 bits y “vs16” sería el “vector short int” que en altivec se corresponde a un array de 8 elementos de 16bits.El rasterizador trabaja siempre por cajas de 16×16 pixels, esto quiere decir que su trabajo no se pide por el número de pixels que ocupe el triángulo sino por el número de cajas de 16×16 pixels. Con esto los bucles de dibujado se simplifican muchísimo ya que con un solo código común de tamaño fijo es muy facil estructurar el código de forma óptima. Como pega tiene que si un triángulo tiene parte en una caja y parte en otra, debemos procesarlo en los dos sitios teniendo por tanto el doble de trabajo.

Cuando se va a rasterizar un paquete de triángulos, los parámetros son un puntero a un paquete, y la posición de pantalla donde se va a dibujar esa caja de 16×16 pixels. El primer paso es calcular los coeficientes de ecuaciones implícitas de los triángulos, usando las mismas fórmulas que en el método escalar. La ventaja aquí es que si antes gastábamos N operaciones para un solo triángulo, ahora esas N operaciones sirven para los 8 triángulos del paquete, aprovechando que el tiempo de ejecución de las operaciones de vectores y de escalares es la misma. De esta forma pasamos a tener estas variables:

vs16 a0,b0,c0;
vs16 a1,b1,c1;
vs16 a2,b2,c2;

Con esto hecho, pasamos a un detalle importante del proceso de vectores. Para procesar de forma eficiente interesa coger los datos de un triángulo y calcular todos los pixels de la scanline a la vez. Pongamos por ejemplo estos valores:

a0 = (2,3,3,5,6,7,8,9)
b0 = (5,4,2,8,9,4,2,4)
c0 = (4,3,7,8,4,2,6,9)

Si estamos procesando el tercer triángulo, primero expandimos la tercera columna usando la instrucción “vec_splat”:

a = (3,3,3,3,3,3,3,3)
b = (2,2,2,2,2,2,2,2)
c = (7,7,7,7,7,7,7,7)

Basandonos en la ecuación implícita “v(x,y) = A * x + B * y + C;”, para tener todos los valores del primer scanline habría que calcular:

v(0)  = A *  0 + C;
v(1)  = A *  1 + C;
v(2)  = A *  2 + C;
...
v(15) = A * 15 + C;

Para hacer esta operación usamos dos vectores auxiliares:

t1 = (0,1,2,3,4,5,6,7);
t2 = (8,9,10,11,12,13,14,15);

y aplicamos esta fórmula:

v0 = a * t1 + c;
v1 = a * t2 + c;

De esta forma tenemos en v0 y v1 los 16 valores de la scanline. Para pasar a la siguiente, hacemos:

v0 += b;
v1 += b;

Esto que he contado sirve para los datos de una de las ecuaciones. En la práctica se necesitan las tres ecuaciones de cada lado del triángulo pero se hacen de la misma forma.

Quedaría pendiente por tanto ver como usar los datos que tenemos en cada scanline para saber que pintar. La mezcla de los datos generados con los de la pantalla se basa en construir una máscara que tenga los bits a 1 donde queremos que se pinte el polígono y a 0 donde deba verse lo ya existente en la pantalla. De esta forma podemos usar la instrucción “vec_sel(a,b,c)” que elige los datos de las variables “a” y “b” según indique la máscara de “c”.

Comments»

No comments yet — be the first.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: