Извините, этот вопрос немного эзотеричен, но я просто не могу выкинуть его из головы!
Я смотрю на алгоритм затухания, используемый в аркадной игре DoDonPachi (как и во многих других старых играх):
Я написал скрипт на Python, чтобы выделить несколько пикселей и отслеживать их на время затухания. Вот репрезентативная выборка результатов. Первая строка каждой группы - это начальное значение цвета, а каждая последующая строка - это разница между значением цвета текущего кадра и значением цвета предыдущего кадра.
Starting Value: (132, 66, 189)
Frame 1: [9, 9, 8]
Frame 2: [8, 8, 8]
Frame 3: [8, 8, 8]
Frame 4: [8, 8, 9]
Frame 5: [9, 9, 8]
Frame 6: [8, 8, 8]
Frame 7: [8, 8, 8]
Frame 8: [8, 8, 9]
Frame 9: [9, 0, 8]
Frame 10: [8, 0, 8]
Frame 11: [8, 0, 8]
Frame 12: [8, 0, 9]
Frame 13: [9, 0, 8]
Frame 14: [8, 0, 8]
Frame 15: [8, 0, 8]
Frame 16: [8, 0, 9]
Frame 17: [0, 0, 8]
Frame 18: [0, 0, 8]
Frame 19: [0, 0, 8]
Frame 20: [0, 0, 9]
Frame 21: [0, 0, 8]
Frame 22: [0, 0, 8]
Frame 23: [0, 0, 8]
Frame 24: [0, 0, 0]
Frame 25: [0, 0, 0]
Frame 26: [0, 0, 0]
Frame 27: [0, 0, 0]
Frame 28: [0, 0, 0]
Frame 29: [0, 0, 0]
Starting Value: (132, 0, 0)
Frame 1: [9, 0, 0]
Frame 2: [8, 0, 0]
Frame 3: [8, 0, 0]
Frame 4: [8, 0, 0]
Frame 5: [9, 0, 0]
Frame 6: [8, 0, 0]
Frame 7: [8, 0, 0]
Frame 8: [8, 0, 0]
Frame 9: [9, 0, 0]
Frame 10: [8, 0, 0]
Frame 11: [8, 0, 0]
Frame 12: [8, 0, 0]
Frame 13: [9, 0, 0]
Frame 14: [8, 0, 0]
Frame 15: [8, 0, 0]
Frame 16: [8, 0, 0]
Frame 17: [0, 0, 0]
Frame 18: [0, 0, 0]
Frame 19: [0, 0, 0]
Frame 20: [0, 0, 0]
Frame 21: [0, 0, 0]
Frame 22: [0, 0, 0]
Frame 23: [0, 0, 0]
Frame 24: [0, 0, 0]
Frame 25: [0, 0, 0]
Frame 26: [0, 0, 0]
Frame 27: [0, 0, 0]
Frame 28: [0, 0, 0]
Frame 29: [0, 0, 0]
Starting Value: (165, 156, 222)
Frame 1: [9, 8, 8]
Frame 2: [8, 8, 8]
Frame 3: [8, 8, 8]
Frame 4: [8, 9, 9]
Frame 5: [9, 8, 8]
Frame 6: [8, 8, 8]
Frame 7: [8, 8, 8]
Frame 8: [8, 9, 9]
Frame 9: [9, 8, 8]
Frame 10: [8, 8, 8]
Frame 11: [8, 8, 8]
Frame 12: [8, 9, 9]
Frame 13: [9, 8, 8]
Frame 14: [8, 8, 8]
Frame 15: [8, 8, 8]
Frame 16: [8, 9, 9]
Frame 17: [9, 8, 8]
Frame 18: [8, 8, 8]
Frame 19: [8, 8, 8]
Frame 20: [8, 0, 9]
Frame 21: [0, 0, 8]
Frame 22: [0, 0, 8]
Frame 23: [0, 0, 8]
Frame 24: [0, 0, 9]
Frame 25: [0, 0, 8]
Frame 26: [0, 0, 8]
Frame 27: [0, 0, 8]
Frame 28: [0, 0, 0]
Frame 29: [0, 0, 0]
Starting Value: (156, 90, 206)
Frame 1: [8, 8, 8]
Frame 2: [8, 8, 9]
Frame 3: [8, 8, 8]
Frame 4: [9, 9, 8]
Frame 5: [8, 8, 8]
Frame 6: [8, 8, 9]
Frame 7: [8, 8, 8]
Frame 8: [9, 9, 8]
Frame 9: [8, 8, 8]
Frame 10: [8, 8, 9]
Frame 11: [8, 8, 8]
Frame 12: [9, 0, 8]
Frame 13: [8, 0, 8]
Frame 14: [8, 0, 9]
Frame 15: [8, 0, 8]
Frame 16: [9, 0, 8]
Frame 17: [8, 0, 8]
Frame 18: [8, 0, 9]
Frame 19: [8, 0, 8]
Frame 20: [0, 0, 8]
Frame 21: [0, 0, 8]
Frame 22: [0, 0, 9]
Frame 23: [0, 0, 8]
Frame 24: [0, 0, 8]
Frame 25: [0, 0, 8]
Frame 26: [0, 0, 0]
Frame 27: [0, 0, 0]
Frame 28: [0, 0, 0]
Frame 29: [0, 0, 0]
Как вы можете видеть, 8 или 9 вычитаются из каждого цветового компонента в каждом кадре. Кроме того, 9 всегда появляется через три кадра после 8, даже если начальное вычитаемое значение отличается для каждого компонента цвета. Также обратите внимание, что каждый цветовой компонент достигает 0 (то есть черного) с разницей 8 или 9, а не некоторый произвольный остаток. Это означает, что вычтенный цикл значений 8,8,8,9 никогда не прерывается! (Этот алгоритм, вероятно, был написан для того, чтобы последний кадр замирания был таким же плавным, как и остальные.)
Теперь это озадачивает меня. Согласно моим расчетам, если вы перевернете процесс, то есть возьмете цикл 8,8,8,9 и суммируете его, чтобы найти все возможные комбинации в 29 кадрах, вы получите только 52 уникальных числа. Но, как это происходит, каждый компонент цвета является членом этого набора! Это означает, что либо цвета были выбраны специально для этого алгоритма затухания (маловероятно), либо что алгоритм затухания был разработан вокруг цветовой палитры игры. Но с какой стати кто-то мог понять, что если вы возьмете 8,8,8,9, сместите цикл соответствующим образом и продолжите вычитать числа из каждого цветового компонента в своей палитре, вы в конечном итоге достигнете 0 для каждого отдельного цвета? ! Должен быть какой-то математический трюк, который мне не хватает. Что это?
Ответы:
На самом деле, за паттерном 8-8-8-9 стоит простая логика. Это естественно, если вы используете только 32 уровня интенсивности (5 бит на компонент), но хотите визуализировать их на 8-битном дисплее.
Подумайте, есть ли у вас 5-битный уровень интенсивности и вы хотите увеличить его до 8 бит. Самое простое, что можно сделать, это просто сдвинуть влево и оставить младшие три бита равными нулю. Беда в том, что это не доходит до чистого белого. Максимальный уровень интенсивности, который вы можете достичь, - 11111000 или 248. Таким образом, вы не используете полный диапазон интенсивности 8-битного дисплея.
На самом деле, вы бы хотели сделать такой расчет
intensity8 = round(intensity5 * 255.0 / 31.0)
, чтобы изменить масштаб диапазона [0, 31] до [0, 255]. Тем не менее, есть хитрый способ сделать это без математических вычислений или делений с плавающей запятой: установите младшие три бита равными старшим трем битам. То есть, чтобы преобразовать интенсивность из 5-битной в 8-битную, вы должны сделатьТогда интенсивность 11111 отобразится на 11111111 (31 - на 255), а промежуточные результаты также сделают что-то вменяемое, например, 10000 -> 10000100 (16 -> 132).
Этот набор чисел именно то, что у вас есть. Взяв красный компонент вашего первого примера, вы получите:
Обратите внимание, что младшие три бита всегда равны старшим трем битам. Разница в 9 возникает, когда оба бита 0 и 3 переворачиваются одновременно.
Я не уверен, почему 5-битные уровни интенсивности были бы использованы в этой ситуации; возможно, это был предел аппаратной части аркадного автомата? Примечательно, что 5-битное значение RGB составляет 15 бит, что хорошо вписывается в 16-битное слово. В любом случае, это объясняет странную модель 8-8-8-9.
источник
Вы должны смотреть в режим 13h или 256 затухания цветовой палитры. В то время у вас было столько цветов, а то, что вы делали, возилось со всей палитрой, так как вы не могли рассчитать новые цвета, которых не было в ней.
источник