¿Cómo crear un sombreador de píxeles "retro" para sprites 2D transformados que mantenga la fidelidad de píxeles?

10

La siguiente imagen muestra dos sprites renderizados con muestreo de puntos en la parte superior de un fondo:

ingrese la descripción de la imagen aquí

  • El cráneo izquierdo no tiene rotación / escala aplicada, por lo que cada píxel coincide perfectamente con el fondo.
  • El cráneo derecho se gira / escala, y esto da como resultado píxeles más grandes que ya no están alineados en el eje .

¿Cómo podría desarrollar un sombreador de píxeles que representara el sprite transformado a la derecha con píxeles alineados a los ejes del mismo tamaño que el resto de la escena?

Esto podría estar relacionado con la forma en que se implementó el escalado de sprites en juegos antiguos como Monkey Island, porque ese es el efecto que estoy tratando de lograr, pero con la rotación agregada.


Editar

Según las sugerencias de kaoD, traté de abordar el problema como un proceso posterior. El enfoque más sencillo era primero renderizar a un objetivo de renderizado separado (muestreado de forma descendente para que coincida con el tamaño de píxel deseado) y luego aumentar la escala cuando se renderiza por segunda vez. Abordó mis requisitos anteriores.

Primero intenté hacerlo Linear -> Pointy el resultado fue este:

ingrese la descripción de la imagen aquí

No hay distorsión, pero el resultado se ve borroso y pierde la mayoría de los colores resaltados. En mi opinión, rompe el aspecto retro que necesitaba.

La segunda vez que lo intenté Point -> Pointy el resultado fue este:

ingrese la descripción de la imagen aquí

A pesar de la distorsión, creo que podría ser lo suficientemente bueno para mis necesidades, aunque se ve mejor como una imagen fija que en movimiento.

Para demostrarlo, aquí hay un video del efecto, aunque YouTube filtró los píxeles:

http://youtu.be/hqokk58KFmI

Sin embargo, dejaré la pregunta abierta durante unos días más en caso de que a alguien se le ocurra una mejor solución de muestreo que mantenga la apariencia nítida mientras disminuye la cantidad de distorsión al moverse.

David Gouveia
fuente
¿Se supone que es una calavera ...?
DeadMG
@DeadMG ¿Un cráneo de buey, supongo?
David Gouveia
Buen efecto, se ve mejor de lo que pensé que se vería (lo probé en EXTREMADAMENTE baja resolución y paleta, 40x30 EGA). Ese es el aspecto que obtendrás haciendo tu propio sombreador postfx. Por cierto, dudo que haya una mejor solución de muestreo que mantenga el efecto tal como lo desea. NN es más o menos lo que le da un aspecto nítido y cualquier otra toma de muestras será borrosa la imagen final (sólo una suposición de todos modos.)
kaoD
@kaoD Pero recuerda que estoy aplicando dos pases. El segundo pase que muestrea la imagen seguirá siendo el vecino más cercano para preservar la sensación retro. Pero creo que puede haber algún beneficio al probar diferentes técnicas de muestreo para el primer pase. Actualmente estoy buscando en Scale2x!
David Gouveia
@kaoD Nah, me rindo. Cambiar los parámetros del sombreador entre cada llamada de sprite SpriteBatchrequiere que use el modo Inmediato, por lo que no vale la pena. Iré con esto :)
David Gouveia

Respuestas:

3

Debes aplicar tu sombreador DESPUÉS de que tu sprite haya sido girado.

Si toda la escena aún no ha sido sombreada y tus sprites están realmente pixelados, lo que necesitas es algún tipo de filtro post-FX para toda tu escena. El promedio de regiones de píxeles funcionará bien. No es exactamente lo que pretendes (se verá un poco aturdido al mover / rotar), pero podría ser el truco.

La única forma de mantener ese aspecto retro fiel a lo que quieres es dibujar tus rotaciones de sprites tú mismo. No tiene nada que ver con la forma en que se implementó el escalado: la resolución fue realmente pobre, y hablando de eso, ¿intentó con resoluciones extremadamente bajas? También podría hacer el truco y se verá más natural ya que, bueno, en realidad es lo que causó el efecto que estás buscando. ¡Y es barato! ¡Muy barato! De hecho, será más barato de lo que ya tiene (menos ejecuciones de sombreadores de fragmentos).

El efecto se arruina en su imagen de muestra porque su resolución es alta en comparación con sus sprites, por lo que le permite ver los píxeles reales de la escena.

kaoD
fuente
Sí, todavía no estoy usando ningún sombreador. Son solo sprites regulares con texturas de muy baja resolución, renderizados con el valor predeterminado de XNA SpriteBatchcon el muestreo de puntos activado. Pero un post-fx realmente podría funcionar. Para empezar, intentaré renderizar con muestreo lineal en un objetivo de renderizado, y luego renderizaré todo el objetivo de renderizado en el backbuffer con muestreo de puntos.
David Gouveia
@DavidGouveia no pierdas la oportunidad de rebajar tu resolución. Si realmente quieres lograr el efecto original, es tu mejor tiro. Si necesita su alta resolución (si una parte de su GFX es de alta resolución o desea igualar las resoluciones nativas), aún puede renderizar en un búfer fuera de la pantalla de baja resolución y luego pintarlo en su búfer de fotogramas de alta resolución como un completo -pantalla cuádruple con filtrado desactivado. Tenga en cuenta que, por supuesto, debe hacer coincidir las relaciones de aspecto para evitar píxeles rectangulares.
kaoD
Verifique mi edición :) Creo que resolvió la mayoría del problema, aunque todavía tengo curiosidad por saber si hay una mejor solución de muestreo que el vecino más cercano para este problema. Dejaré que la pregunta dure un poco más.
David Gouveia