Как создать «ретро» пиксельный шейдер для преобразованных 2D спрайтов, который поддерживает точность пикселей?

10

Изображение ниже показывает два спрайта, визуализированных с точечной выборкой поверх фона:

введите описание изображения здесь

  • К левому черепу не применяется вращение / масштабирование, поэтому каждый пиксель идеально соответствует фону.
  • Правый череп поворачивается / масштабируется, и это приводит к большим пикселям , которые больше не выровнены по оси .

Как я могу разработать пиксельный шейдер, который бы отображал преобразованный спрайт справа с выровненными по оси пикселями того же размера, что и остальная часть сцены?

Это может быть связано с тем, как масштабирование спрайтов было реализовано в старых играх, таких как Monkey Island, потому что это тот эффект, которого я пытаюсь достичь, но с добавленной ротацией.


редактировать

Согласно предложениям kaoD, я попытался решить проблему как пост-процесс. Самый простой подход состоял в том, чтобы сначала выполнить рендеринг в отдельную цель рендеринга (с понижением дискретизации, чтобы соответствовать желаемому размеру пикселя), а затем увеличить его при рендеринге во второй раз. Это действительно отвечало моим требованиям выше.

Сначала я попытался сделать это, Linear -> Pointи результат был такой:

введите описание изображения здесь

Искажений нет, но результат выглядит размытым, и он теряет большинство ярких цветов. На мой взгляд, это нарушает стиль ретро, ​​который мне был нужен.

Второй раз я попробовал, Point -> Pointи результат был такой:

введите описание изображения здесь

Несмотря на искажения, я думаю, что это может быть достаточно для моих нужд, хотя выглядит как неподвижное изображение лучше, чем в движении.

Чтобы продемонстрировать, вот видео эффекта, хотя YouTube отфильтровал пиксели из этого:

http://youtu.be/hqokk58KFmI

Однако я оставлю вопрос открытым еще на несколько дней на случай, если кто-то придумает лучшее решение для выборки, которое сохранит четкий внешний вид и уменьшит количество искажений при движении.

Дэвид Гувея
источник
Это должен быть череп ...?
DeadMG
@DeadMG Череп быка, наверное?
Дэвид Гувейя
Хороший эффект, выглядит лучше, чем я думал (я попробовал это на ЧРЕЗВЫЧАЙНОМ низком разрешении и палитре, 40x30 EGA.) Это почти то же самое, что вы получите, создавая свой собственный шейдер postfx. Кстати, я сомневаюсь, что есть лучшее решение для выборки, которое сохраняет эффект, как вы и предполагали. NN - это почти то, что дает этот четкий вид, любая другая выборка размывает окончательное изображение (в любом случае, просто угадывая)
kaoD
@kaoD Но помни, что я делаю два прохода. Второй проход, который увеличивает изображение, все равно будет ближайшим соседом, чтобы сохранить ощущение ретро. Но я думаю, что может быть какая-то польза от проб разных методов отбора проб для первого прохода. В настоящее время я изучаю Scale2x!
Дэвид Гувейя
@kaoD Нет, я сдаюсь. Изменение параметров шейдера между каждым вызовом спрайта SpriteBatchтребует от меня использования немедленного режима, так что это не стоит хлопот. Я пойду с этим :)
Дэвид Гувея

Ответы:

3

Вы должны применять свой шейдер ПОСЛЕ того, как ваш спрайт был повернут.

Если вся сцена еще не была затенена, а ваши спрайты фактически пикселированы, вам нужен какой-то пост-FX фильтр для всей вашей сцены. Усреднение областей пикселей будет работать нормально. Это не совсем то, что вы намереваетесь (это будет выглядеть немного странно при движении / вращении), но это может помочь.

Единственный способ сохранить правдивость этого ретро-стиля в том, что вы хотите, - это на самом деле нарисовать свои вращения спрайтов самостоятельно. Это не имеет никакого отношения к тому, как было реализовано масштабирование: разрешение было на самом деле плохим, говоря о том, пробовали ли вы с крайне низкими разрешениями? Это также может помочь, и будет выглядеть более естественно, так как, на самом деле, именно это и привело к тому эффекту, который вы ищете. И это дешево! Очень дешевый! На самом деле это будет дешевле, чем то, что у вас уже есть (меньше выполнения фрагмента шейдера.)

Эффект разрушен в вашем образце изображения, потому что ваше разрешение выше по сравнению с вашими спрайтами, поэтому он позволяет вам видеть реальные пиксели на сцене.

kaoD
источник
Да, я пока не использую шейдеры. Это просто обычные спрайты с текстурами очень низкого разрешения, визуализируемые по умолчанию в XNA с включенной SpriteBatchточечной выборкой. Но пост-FX может действительно сработать. Для начала я попробую сделать рендеринг с линейной выборкой для цели рендеринга, а затем отрендерить всю цель рендеринга в буферный буфер с точечной выборкой.
Дэвид Гувея
@DavidGouveia не упустите возможность занизить ваше разрешение. Если вы действительно хотите добиться оригинального эффекта, это ваш лучший снимок. Если вам нужно высокое разрешение (если часть вашего GFX имеет высокое разрешение или вы хотите соответствовать исходному разрешению), вы все равно можете выполнить рендеринг в неэкранный буфер с низким разрешением, а затем закрасить его в свой кадровый буфер высокого разрешения в качестве полного экран с отключенной фильтрацией. Имейте в виду, что вы должны соответствовать пропорциям, чтобы избежать прямоугольных пикселей, конечно.
2012 г.
Проверьте мое редактирование :) Я думаю, что это решило большую часть проблемы, хотя мне все еще любопытно, есть ли лучшее решение выборки, которое является ближайшим соседом для этой проблемы. Я оставлю вопрос на некоторое время дольше.
Дэвид Гувейя