2011-04-18 59 views
7

He asumido un desafío bastante difícil para mí. En mi juego XNA, quiero implementar Blargg's NTSC filter. Esta es una biblioteca de C que transforma un mapa de bits para que parezca que salió en un TV CRT con el estándar NTSC. Es bastante preciso, realmente.Traducir C a C# y HLSL: ¿será esto posible?

Lo primero que intenté, hace un tiempo, era simplemente usar la biblioteca C llamándola como dll. Aquí tuve dos problemas: 1. No pude obtener algunos de los datos para copiarlos correctamente, así que la imagen se dañó, pero lo más importante, 2. fue extremadamente lenta. Se requirió obtener los datos del mapa de bits XNA Texture2D, pasarlo a través del filtro y luego volver a establecer los datos a la textura. La velocidad de fotogramas se arruinó, así que no pude seguir esta ruta.

Ahora estoy tratando de traducir el filtro en un sombreador de píxeles. El problema aquí (si eres aventurero para mirar el código, estoy usando el SNES porque es el más simple) es que maneja matrices muy grandes y depende de operaciones de puntero interesantes. He trabajado mucho reescribiendo el algoritmo para trabajar independientemente por píxel, como lo requerirá un sombreador de píxeles. Pero no sé si esto funcionará alguna vez. He venido a ver si terminar esto es posible.

  1. Hay matriz precalculada involucrada que contiene 1,048,576 enteros. ¿Está esto solo más allá de los límites del sombreador de píxeles? Solo necesita establecerse una vez, no una vez por cuadro.
  2. Incluso si eso está bien, sé que HLSL no puede indexar matrices por una variable. Tiene que desenrollarlo en un millón de sentencias if para obtener el elemento de matriz correcto. ¿Esto matará el rendimiento y lo convertirá en un esfuerzo infructuoso de nuevo? Hay múltiples accesos de matriz por píxel.
  3. ¿Hay alguna posibilidad de que mi plan original para usar la biblioteca como sea podría funcionar? Solo necesito que sea rápido.
  4. Nunca he escrito un sombreador antes. ¿Hay algo más que deba tener en cuenta?

editar: Addendum to # 2. Acabo de leer en algún lugar que no solo no puede acceder a las matrices por variable, sino que incluso para desenrollarlo, el índice debe ser calculable en tiempo de compilación. ¿Es esto cierto, o el "desenrollar" resuelve esto? Si es verdad, creo que estoy jodido. De cualquier manera alrededor de eso? Mi algoritmo es básicamente una versión glorificada de "el píxel de entrada es de este color, así que busca los valores de mi píxel de salida en esta matriz gigante".

Respuesta

2

Por mi limitado conocimiento de los lenguajes de sombreado, su problema se puede resolver fácilmente mediante el uso de texturas en lugar de una matriz.

  1. Pregenerar en la CPU y luego guardar como textura. 1024x1024 en tu caso.
  2. Utilice las funciones de acceso a la textura estándar como si la textura fuera la matriz. Posiblemente usando el vecino más cercano para limitar el mezclado de píxeles individuales.
  3. No creo que esto sea posible si quieres velocidad.
+0

Entonces, ¿puedo usar una textura como una matriz? ¿Podrías elaborar? Mi matriz gigante no es directamente datos de píxeles. Son solo números, no estoy seguro de lo que representan. El píxel de salida se encuentra agregando un conjunto de valores de este conjunto, sujetándolo y transformándolo en rgb con alguna fórmula. – Tesserex

+0

¿No es la textura en sí misma una serie de números? Entonces puede usarlo como una ordenación dentro de un sombreador. – Euphoric