В процессе разработки игры в текстовом режиме, мне пришлось нарисовать больше сотни анимационных ASCII спрайтов. После релиза игра получила неожиданно хорошие отзывы и было принято решение делать продолжение. Рисуя спрайты для первой части и перепробовав с десяток вариантов выбора цвета и несколько десятков различных палитр, я понял, что нужен свой, «идеальный» набор цветов на все времена. За сотни и сотни часов рисования, сложились следующие критерии идеальности палитры:

  • Краткость: небольшое количество цветов в палитре. Весь набор цветов можно охватить одним взглядом.
  • Полнота: цвета палитры должны равномерно и достаточно плотно заполнять цветовое пространство.
  • Дискретность: цвета палитры должны отличаться друг от друга на глаз.
  • Группировка: цвета должны быть удобно сгруппированы для быстрого нахождения нужного.

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

Начиная отбирать цвета, взглянем на все цветовое пространство. Его можно представить в виде RGB куба, HSB цилиндра/конуса — и это только самые популярные аддитивные модели.



Выбирать цвет из «внутренностей» этих трехмерных фигур не удобно. Поэтому графические редакторы придумывают различные удобные и красивые способы выбрать произвольный цвет. Но обратите внимание, что в каждой цветовой модели все равно как минимум три измерения.



Для ASCII графики весь этот «континуум» цветов не нужен. Выбор произвольного цвета только затрудняет редактирование. Дело в том, что каждый символ занимает достаточно большую площадь на экране и символы как правило не соприкасаются. Чтобы заметить разницу, цвета символов должны отличаться на глаз.



Итак, нужна дискретная палитра. Различных палитр — великое множество. Это как современные палитры, так и ретро палитры, пришедшие из прошлого компьютерной техники.



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

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

Процедурная палитра?


Что, если равномерно распределить точки-цвета палитры внутри цветового пространства? Например, каждую компоненту цвета в модели RGB разделить на 6 частей. Получится 216 цветов.

Проблема в том, что человек воспринимает цвета не линейно. Зеленые оттенки палитры «сольются», а синие будут слишком дискретны. Вот интересный материал, посвященный цветам:

Poynton's Color FAQ

Только ручной отбор!


Разработанная в 70-ых годах модель HSB, являющаяся нелинейным преобразованием модели RGB, позволяет намного более интуитивно выбирать цвета. Первым компонентом модели является Hue – Цветовой тон. Какие бывают цветовые тона? Например, как в мнемонической фразе: «Каждый охотник желает знать, где сидит фазан».

7 цветовых тонов: Красный, Оранжевый, Желтый, Зеленый, Голубой, Синий, Фиолетовый

Этого явно мало! А где, например, розовый или бирюзовый? Более полный набор из 12-ти тонов дает палитра «циферблата», где каждому часу на циферблате соответствует свой цвет.

12 цветовых тонов: Красный, Оранжевый, Желтый, Лайм, Зеленый, Аквамарин, Бирюзовый, Голубой, Синий, Фиолетовый, Розовый, Малиновый

Полученные значения Hue все еще слишком дискретны. Я добавил несколько тонов, чтобы разница на глаз между соседними тонами была одинакова. Теперь результат меня устроил.

15 цветовых тонов: Красный, Оранжевый, Золотой, Желтый, Лайм, Зеленый, Аквамарин, Бирюзовый, Голубой, Синий, Ультрамарин, Фиолетовый, Розовый, Малиновый, Алый



Для каждого из 15-ти цветовых тонов можно задавать компоненты Saturation – Насыщенность и Brightness – Яркость. Вот, например, множества значений насыщенности и яркости для оранжевого, фиолетового и лайма.



Существует известная палитра, в которой компоненты насыщенности и яркости вытянуты в одну линию.



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

Интересно, что цвета этой палитры образуют поверхность цилиндра/конуса модели HSB. Цвета из внутренних частей цилиндра/конуса — отсутствуют.

Вернемся к нашим 15-ти цветовым тонам. Построим для каждого дискретную раскладку по компонентам яркости и насыщенности. Значения компонент выберем равномерно следующим образом: 100%, 80%, 60%, 40%, 20%.



Часто, пространство значений яркости и насыщенности представляют не в виде квадрата, а в виде треугольника. Дело в том, что глаз человека хуже различает изменение насыщенности при более низкой яркости.

В нашем случае, треугольник получается так: для ряда с более низкой яркостью предоставляется меньше вариантов насыщенности.



Неплохо! Теперь приступим к более тонкой настройке. Для каждого тона, компоненты яркости и насыщенности были распределены равномерно. Но глаз человека воспринимает яркость нелинейно. Более того, для разных цветовых тонов восприятие яркости — разное.

Одной, наиболее часто применяемой формулой для оценки яркости цвета, является следующая:



Надо понимать, что яркость цвета зависит как от типа монитора, так и от индивидуальных особенностей зрения человека, а эта формула была выведена еще для CRT мониторов. Тем не менее, она отражает тот факт, что вклад в общую яркость синего компонента меньше чем вклад красного, который, в свою очередь, меньше вклада зеленого. Это видно невооруженным взглядом, достаточно, например, сравнить синий цвет с яркостью 20% и зеленый с яркостью 20%. Синий гораздо темнее!

Для того, чтобы выровнять темные цвета и сделать визуальное уменьшение яркости более линейным, я применил следующее преобразование:





Формула выглядит слегка громоздко, но на самом деле она простая. На вход подается уровень яркости Y, цветовой тон (r, g, b), а так же количество градаций яркости n. Внутри больших скобок происходит выравнивание темных цветов в зависимости от тона. Возведение в степень 0.7 делает изменение яркости более равномерным визуально. Степени 0.15 и 0.7 я подбирал вручную, пытаясь добиться лучшего результата.

Для выравнивания насыщенности мне было достаточно следующего простого преобразования:



Степень 0.65 так же подбиралась вручную. На представленной ниже GIF анимации приводится вариант до преобразования и после. Фон я сделал черным, чтобы лучше были видны темные цвета. Судите сами, стали ли цвета по яркости и насыщенности более равномерно распределены. На мой взгляд — да, стало лучше.



Осталось добавить оттенки серого и сгруппировать полученные цвета. В итоге получилась такая палитра.



Я получил 233 орешка для золушки — 233 цвета для редактора ASCII графики, которая — прекрасна!

RGB представление цветов палитры в виде JSON
{
    "Алый": [
        [
            {"r": 255, "g": 0, "b": 85},
            {"r": 179, "g": 0, "b": 59},
            {"r": 131, "g": 0, "b": 43},
            {"r": 91, "g": 0, "b": 30},
            {"r": 54, "g": 0, "b": 18}
        ],
        [
            {"r": 255, "g": 79, "b": 138},
            {"r": 179, "g": 55, "b": 96},
            {"r": 131, "g": 41, "b": 71},
            {"r": 91, "g": 28, "b": 49}
        ],
        [
            {"r": 255, "g": 124, "b": 168},
            {"r": 179, "g": 87, "b": 118},
            {"r": 131, "g": 64, "b": 86}
        ],
        [
            {"r": 255, "g": 162, "b": 193},
            {"r": 179, "g": 114, "b": 135}
        ],
        [
            {"r": 255, "g": 195, "b": 215}
        ]
    ],
    "Малиновый": [
        [
            {"r": 255, "g": 0, "b": 162},
            {"r": 178, "g": 0, "b": 113},
            {"r": 130, "g": 0, "b": 82},
            {"r": 89, "g": 0, "b": 56},
            {"r": 52, "g": 0, "b": 33}
        ],
        [
            {"r": 255, "g": 79, "b": 191},
            {"r": 178, "g": 55, "b": 133},
            {"r": 130, "g": 40, "b": 97},
            {"r": 89, "g": 27, "b": 67}
        ],
        [
            {"r": 255, "g": 124, "b": 207},
            {"r": 178, "g": 87, "b": 145},
            {"r": 130, "g": 63, "b": 106}
        ],
        [
            {"r": 255, "g": 162, "b": 221},
            {"r": 178, "g": 113, "b": 154}
        ],
        [
            {"r": 255, "g": 195, "b": 233}
        ]
    ],
    "Розовый": [
        [
            {"r": 255, "g": 0, "b": 255},
            {"r": 177, "g": 0, "b": 177},
            {"r": 129, "g": 0, "b": 129},
            {"r": 87, "g": 0, "b": 87},
            {"r": 50, "g": 0, "b": 50}
        ],
        [
            {"r": 255, "g": 79, "b": 255},
            {"r": 177, "g": 55, "b": 177},
            {"r": 129, "g": 40, "b": 129},
            {"r": 87, "g": 27, "b": 87}
        ],
        [
            {"r": 255, "g": 124, "b": 255},
            {"r": 177, "g": 86, "b": 177},
            {"r": 129, "g": 63, "b": 129}
        ],
        [
            {"r": 255, "g": 162, "b": 255},
            {"r": 177, "g": 113, "b": 177}
        ],
        [
            {"r": 255, "g": 195, "b": 255}
        ]
    ],
    "Фиолетовый": [
        [
            {"r": 170, "g": 0, "b": 255},
            {"r": 119, "g": 0, "b": 179},
            {"r": 88, "g": 0, "b": 132},
            {"r": 61, "g": 0, "b": 92},
            {"r": 37, "g": 0, "b": 56}
        ],
        [
            {"r": 196, "g": 79, "b": 255},
            {"r": 138, "g": 56, "b": 179},
            {"r": 102, "g": 41, "b": 132},
            {"r": 71, "g": 28, "b": 92}
        ],
        [
            {"r": 211, "g": 124, "b": 255},
            {"r": 149, "g": 88, "b": 179},
            {"r": 110, "g": 65, "b": 132}
        ],
        [
            {"r": 224, "g": 162, "b": 255},
            {"r": 158, "g": 114, "b": 179}
        ],
        [
            {"r": 235, "g": 195, "b": 255}
        ]
    ],
    "Ультрамарин": [
        [
            {"r": 98, "g": 0, "b": 255},
            {"r": 70, "g": 0, "b": 182},
            {"r": 52, "g": 0, "b": 136},
            {"r": 37, "g": 0, "b": 98},
            {"r": 24, "g": 0, "b": 63}
        ],
        [
            {"r": 146, "g": 79, "b": 255},
            {"r": 105, "g": 56, "b": 182},
            {"r": 78, "g": 42, "b": 136},
            {"r": 56, "g": 30, "b": 98}
        ],
        [
            {"r": 174, "g": 124, "b": 255},
            {"r": 124, "g": 89, "b": 182},
            {"r": 93, "g": 67, "b": 136}
        ],
        [
            {"r": 198, "g": 162, "b": 255},
            {"r": 141, "g": 116, "b": 182}
        ],
        [
            {"r": 218, "g": 195, "b": 255}
        ]
    ],
    "Синий": [
        [
            {"r": 0, "g": 0, "b": 255},
            {"r": 0, "g": 0, "b": 187},
            {"r": 0, "g": 0, "b": 145},
            {"r": 0, "g": 0, "b": 109},
            {"r": 0, "g": 0, "b": 76}
        ],
        [
            {"r": 79, "g": 79, "b": 255},
            {"r": 58, "g": 58, "b": 187},
            {"r": 45, "g": 45, "b": 145},
            {"r": 34, "g": 34, "b": 109}
        ],
        [
            {"r": 124, "g": 124, "b": 255},
            {"r": 91, "g": 91, "b": 187},
            {"r": 71, "g": 71, "b": 145}
        ],
        [
            {"r": 162, "g": 162, "b": 255},
            {"r": 119, "g": 119, "b": 187}
        ],
        [
            {"r": 195, "g": 195, "b": 255}
        ]
    ],
    "Голубой": [
        [
            {"r": 0, "g": 145, "b": 255},
            {"r": 0, "g": 100, "b": 176},
            {"r": 0, "g": 72, "b": 128},
            {"r": 0, "g": 49, "b": 86},
            {"r": 0, "g": 27, "b": 48}
        ],
        [
            {"r": 79, "g": 179, "b": 255},
            {"r": 55, "g": 124, "b": 176},
            {"r": 39, "g": 90, "b": 128},
            {"r": 26, "g": 60, "b": 86}
        ],
        [
            {"r": 124, "g": 198, "b": 255},
            {"r": 86, "g": 137, "b": 176},
            {"r": 62, "g": 99, "b": 128}
        ],
        [
            {"r": 162, "g": 215, "b": 255},
            {"r": 112, "g": 149, "b": 176}
        ],
        [
            {"r": 195, "g": 229, "b": 255}
        ]
    ],
    "Бирюзовый": [
        [
            {"r": 0, "g": 255, "b": 255},
            {"r": 79, "g": 255, "b": 255},
            {"r": 124, "g": 255, "b": 255},
            {"r": 162, "g": 255, "b": 255},
            {"r": 195, "g": 255, "b": 255}
        ],
        [
            {"r": 0, "g": 173, "b": 173},
            {"r": 62, "g": 173, "b": 173},
            {"r": 97, "g": 173, "b": 173},
            {"r": 127, "g": 173, "b": 173}
        ],
        [
            {"r": 0, "g": 121, "b": 121},
            {"r": 53, "g": 121, "b": 121},
            {"r": 83, "g": 121, "b": 121}
        ],
        [
            {"r": 0, "g": 78, "b": 78},
            {"r": 44, "g": 78, "b": 78}
        ],
        [
            {"r": 0, "g": 38, "b": 38}
        ]
    ],
    "Аквамарин": [
        [
            {"r": 0, "g": 255, "b": 170},
            {"r": 79, "g": 255, "b": 196},
            {"r": 124, "g": 255, "b": 211},
            {"r": 162, "g": 255, "b": 224},
            {"r": 195, "g": 255, "b": 235}
        ],
        [
            {"r": 0, "g": 173, "b": 115},
            {"r": 62, "g": 173, "b": 136},
            {"r": 98, "g": 173, "b": 148},
            {"r": 127, "g": 173, "b": 158}
        ],
        [
            {"r": 0, "g": 122, "b": 81},
            {"r": 53, "g": 122, "b": 99},
            {"r": 83, "g": 122, "b": 109}
        ],
        [
            {"r": 0, "g": 79, "b": 52},
            {"r": 44, "g": 79, "b": 67}
        ],
        [
            {"r": 0, "g": 40, "b": 26}
        ]
    ],
    "Зеленый": [
        [
            {"r": 0, "g": 255, "b": 0},
            {"r": 79, "g": 255, "b": 79},
            {"r": 124, "g": 255, "b": 124},
            {"r": 162, "g": 255, "b": 162},
            {"r": 195, "g": 255, "b": 195}
        ],
        [
            {"r": 0, "g": 174, "b": 0},
            {"r": 62, "g": 174, "b": 62},
            {"r": 98, "g": 174, "b": 98},
            {"r": 128, "g": 174, "b": 128}
        ],
        [
            {"r": 0, "g": 124, "b": 0},
            {"r": 54, "g": 124, "b": 54},
            {"r": 84, "g": 124, "b": 84}
        ],
        [
            {"r": 0, "g": 81, "b": 0},
            {"r": 46, "g": 81, "b": 46}
        ],
        [
            {"r": 0, "g": 42, "b": 0}
        ]
    ],
    "Лайм": [
        [
            {"r": 196, "g": 255, "b": 0},
            {"r": 214, "g": 255, "b": 79},
            {"r": 224, "g": 255, "b": 124},
            {"r": 233, "g": 255, "b": 162},
            {"r": 241, "g": 255, "b": 195}
        ],
        [
            {"r": 131, "g": 171, "b": 0},
            {"r": 146, "g": 171, "b": 61},
            {"r": 154, "g": 171, "b": 97},
            {"r": 161, "g": 171, "b": 126}
        ],
        [
            {"r": 91, "g": 119, "b": 0},
            {"r": 104, "g": 119, "b": 52},
            {"r": 110, "g": 119, "b": 81}
        ],
        [
            {"r": 57, "g": 75, "b": 0},
            {"r": 67, "g": 75, "b": 42}
        ],
        [
            {"r": 27, "g": 35, "b": 0}
        ]
    ],
    "Желтый": [
        [
            {"r": 255, "g": 255, "b": 0},
            {"r": 255, "g": 255, "b": 79},
            {"r": 255, "g": 255, "b": 124},
            {"r": 255, "g": 255, "b": 162},
            {"r": 255, "g": 255, "b": 195}
        ],
        [
            {"r": 170, "g": 170, "b": 0},
            {"r": 170, "g": 170, "b": 61},
            {"r": 170, "g": 170, "b": 96},
            {"r": 170, "g": 170, "b": 125}
        ],
        [
            {"r": 118, "g": 118, "b": 0},
            {"r": 118, "g": 118, "b": 51},
            {"r": 118, "g": 118, "b": 80}
        ],
        [
            {"r": 73, "g": 73, "b": 0},
            {"r": 73, "g": 73, "b": 41}
        ],
        [
            {"r": 33, "g": 33, "b": 0}
        ]
    ],
    "Золотой": [
        [
            {"r": 255, "g": 170, "b": 0},
            {"r": 255, "g": 196, "b": 79},
            {"r": 255, "g": 211, "b": 124},
            {"r": 255, "g": 224, "b": 162},
            {"r": 255, "g": 235, "b": 195}
        ],
        [
            {"r": 173, "g": 115, "b": 0},
            {"r": 173, "g": 136, "b": 62},
            {"r": 173, "g": 148, "b": 98},
            {"r": 173, "g": 157, "b": 127}
        ],
        [
            {"r": 122, "g": 81, "b": 0},
            {"r": 122, "g": 99, "b": 53},
            {"r": 122, "g": 109, "b": 83}
        ],
        [
            {"r": 78, "g": 52, "b": 0},
            {"r": 78, "g": 67, "b": 44}
        ],
        [
            {"r": 39, "g": 26, "b": 0}
        ]
    ],
    "Оранжевый": [
        [
            {"r": 255, "g": 94, "b": 0},
            {"r": 255, "g": 144, "b": 79},
            {"r": 255, "g": 172, "b": 124},
            {"r": 255, "g": 196, "b": 162},
            {"r": 255, "g": 217, "b": 195}
        ],
        [
            {"r": 175, "g": 64, "b": 0},
            {"r": 175, "g": 104, "b": 63},
            {"r": 175, "g": 127, "b": 99},
            {"r": 175, "g": 146, "b": 129}
        ],
        [
            {"r": 126, "g": 46, "b": 0},
            {"r": 126, "g": 81, "b": 54},
            {"r": 126, "g": 100, "b": 86}
        ],
        [
            {"r": 83, "g": 30, "b": 0},
            {"r": 83, "g": 60, "b": 47}
        ],
        [
            {"r": 45, "g": 16, "b": 0}
        ]
    ],
    "Красный": [
        [
            {"r": 255, "g": 0, "b": 0},
            {"r": 255, "g": 79, "b": 79},
            {"r": 255, "g": 124, "b": 124},
            {"r": 255, "g": 162, "b": 162},
            {"r": 255, "g": 195, "b": 195}
        ],
        [
            {"r": 180, "g": 0, "b": 0},
            {"r": 180, "g": 64, "b": 64},
            {"r": 180, "g": 101, "b": 101},
            {"r": 180, "g": 132, "b": 132}
        ],
        [
            {"r": 133, "g": 0, "b": 0},
            {"r": 133, "g": 57, "b": 57},
            {"r": 133, "g": 90, "b": 90}
        ],
        [
            {"r": 93, "g": 0, "b": 0},
            {"r": 93, "g": 52, "b": 52}
        ],
        [
            {"r": 57, "g": 0, "b": 0}
        ]
    ]
}

Буду рад видеть вас в своей группе textpuzzlelab на Фейсбуке, где можно посмотреть как я применяю цвета этой палитры в изображениях в стиле ASCII.



Работа над палитрой еще не закончена. Текущая версия 0.8. Одной из проблем является то, что при изменении насыщенности, критерий дискретности не совсем выполняется для желтого, лайма, зеленого, аквамарина и бирюзового. Пока не придумал как быть.

С радостью приму замечания и предложения. Одна пара глаз хорошо, а две и больше — лучше!
Поделиться с друзьями
-->

Комментарии (43)


  1. xtala
    17.10.2016 00:17
    +2

    У меня ASCII графика всегда вызывает теплые воспоминания о Turbo Pascal 6.0 =)


    1. Idot
      17.10.2016 09:02
      +1

      А у меня воспоминания о тёплом ламповом Бейсике с зелёной псевдографикой на чёрном экране.


      1. DuhaTheBest
        17.10.2016 09:10

        Делаю в игре зеленый спец. режим:


        1. Idot
          17.10.2016 10:04

          Спасибо! :)


  1. dva
    17.10.2016 00:35

    А саму игру можно увидеть?


    1. DuhaTheBest
      17.10.2016 00:39

      Да, вот на Стиме:
      Proto Raider


      1. CheeseMaster
        17.10.2016 10:37

        Вопрос немного не по теме, но почему решили работать со стимом через издателя, а не самостоятельно?


        1. DuhaTheBest
          17.10.2016 10:38

          Первый раз тогда выходил на Стим — сам побоялся. Теперь планирую самостоятельно.


          1. Idot
            17.10.2016 12:17
            +1

            А издатель как-то финансировал разработку?


            1. DuhaTheBest
              17.10.2016 12:26

              Нет


  1. Zagrebelion
    17.10.2016 06:17

    > Существует известная палитра, в которой компоненты насыщенности и яркости вытянуты в одну линию.

    А существует ли для этой палитры раскладка RGB цветов для элементов дискретного пространства? Или может быть там как-то алгебраически можно рассчитать цвет?


    1. DuhaTheBest
      17.10.2016 08:26

      Палитра устроена так:

      • Hue меняется по горизонтали от 0 до 360 градусов
      • Saturation — уменьшение вверх до 0
      • Brightness — уменьшение вниз до 0

      Далее, HSB в RGB можно перевести так:
      Ссылка


  1. synedra
    17.10.2016 07:02
    +2

    Расскажите, пожалуйста, как у вас устроены сами спрайты? Это именно спрайты, то есть картинки, которые вы рисовали в фотошопе, люстре или чём там и потом вставляли в движок, или используется какой-нибудь аналог curses с честным выводом текста?


    1. DuhaTheBest
      17.10.2016 08:37
      +1

      ASCII спрайты — это честные символы с дополнительной информацией о цвете каждого. Спрайты я делал в обычном текстовом редакторе с моноширинным шрифтом. Выводятся в игре они уже движком, посимвольно с помощью шрифта, который можно выбирать. Вот, например, как храниться спрайт:

      javascript
      var bossDoctor = {
      	frameTime: 500,       // Duration of one frame in msec.
      	sprites: [[                  // Array of frames
      		".--.",                // Each frame is array of regular strings
      		"'oO'",
      		' "| ',
      		"/[]|",
      		" TT "
      	],[
      		".--.",
      		"'Oo'",
      		' "| ',
      		"/[]|",
      		" TT "
      	]],
      	colorsPattern: [[  // Array of colors of frames
      		"wwww",      // Each frame is an array of regular strings
      		"wggw",      // Characters in the strins are indexes of colors from "colorPresets"
      		" g. ",
      		" aa ",
      		" ss "
      	],[
      		"wwww",
      		"wggw",
      		" g. ",
      		" aa ",
      		" ss "
      	]],
      	colorPresets: {			// Colors indexes
      		"a": "888888", 
      		"s": "FF4400", 
      		"g": "00CCFF", 
      		"w": "FFFFFF", 
      		".": "444444"},
      	defaultColor: "FF8800"		// Default color for spaces in "colorsPattern"
      }
      


  1. Blooderst
    17.10.2016 09:15
    +3

    Очень приличная палитра. Жаль, что не вы создавали палитру для xterm. В то время не заморачивались и тупо порезали RGB-пространство на равномерные куски. В итоге номинально там 216 цветов, но половина из них сливается между собой и практически полностью отсутствуют темные тона. В консоле цвета — это боль…


    1. Sirikid
      17.10.2016 09:47
      +1

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


      1. Idot
        17.10.2016 11:11

        Смахивает на знаменитое «озвучено лучшими программистами» ©


        1. perfect_genius
          18.10.2016 19:45

          Профессиональными.


      1. DistortNeo
        17.10.2016 12:41
        +1

        И я так же делал, когда с VGA игрался: 16 основных цветов для совместимости + куб 6х6х6. Многие простые игры такую палитру использовали. Ещё нравился вариант 8х8х4 (по 3 бита на красный и зелёный, 2 бита на синий). Очень удобно для приближённого представления произвольного цвета, например, для вывода фотографий на экран.

        Понимания, что для многих задач лучше и естественнее использовать HSV в качестве универсальной палитры, а не RGB, у меня тогда ещё не было. Да и негде было посмотреть: не то, что интернета — телефона не было.


  1. napa3um
    17.10.2016 09:23
    +1

    Похожая работа для палитр в 16 и 32 цвета:
    http://pixeljoint.com/forum/forum_posts.asp?TID=12795
    http://pixeljoint.com/forum/forum_posts.asp?TID=16247


  1. daggert
    17.10.2016 09:40
    +1

    Спасибо вам огромное за статью! Делаю на данный момент небольшую игру в ASCII-art и проблема с созданием палитры встала уже давно.


  1. vovkasolovev
    17.10.2016 10:04
    +4

    Делал для своих задач палитру, подобрал на глаз, исходя из регулярных востребованных комбинаций.
    Описание и расширенная версия.

    image


    1. Refridgerator
      19.10.2016 07:48
      +1

      Очень красивая палитра! В своё время я пытался собрать палитру из предопределённых цветов PANTONE в фотошопе, но безуспешно, а готовые наборы были либо чересчур объёмные, либо просто (субъективно) некрасивые. Тут всё же нужен талант художника, чтобы комбинировать цвета исходя из их эмоционального восприятия, а не численного описания.


      1. vovkasolovev
        19.10.2016 20:05

        Спасибо!


  1. DeXPeriX
    17.10.2016 12:13
    +1

    Я в Winter Novel использовал только 16 цветов, т.к. изначально движок был только консольным и изображение выводилось в системный терминал. Палитра терминала Windows, кхм, не очень подходит для вывода таких картинок. Поэтому в OpenGL каждый цвет потом уже вытягивали вручную. И если зелёный/синий смотрятся ещё нормально, то красный/оранжевый так и остались излишне попугаистыми. Наверное, стоило изначально отказаться от Windows терминала и использовать большее количество цветов…
    image


    Кстати, а почему Proto Raider распространяется только под Windows? Если движок написан на JS, то вероятно его будет не сложно портировать под другие платформы.


    1. DuhaTheBest
      17.10.2016 12:28

      Proto Raider еще на старом движке написан, что позволило запустить его только под Windows и iOS. Сейчас перехожу на Cocos2d-js.


  1. gresolio
    17.10.2016 13:31
    +2

    Ох уж эта живучая легаси формула… Прочитал вашу статью и сразу о ней вспомнил :)
    Там очень много толковой информации, возможно будет полезно при апгрейде вашей палитры.


    1. DuhaTheBest
      17.10.2016 13:34
      +1

      Да, я привел ее с оговорками, не вдаваясь в подробности т.к. конкретные числа не принципиальны ввиду последующей ручной подборки цветов «на глаз».


    1. DistortNeo
      17.10.2016 14:29
      +1

      Да и гамма-коррекцию стоило бы упомянуть вместо магических коэффициентов 0.15 и 0.7.


      1. DuhaTheBest
        17.10.2016 14:41

        В принципе, можно было бы упомянуть, согласен.


    1. Orky
      18.10.2016 13:40

      Тоже вспомнил про эту статью.
      Действительно, старые заблуждения могут жить вечно.


  1. Vitalez
    17.10.2016 17:42
    +1

    Как по мне Золотой цвет однообразен, предлагаю его в ручную пересмотреть, а после пускать эту палитру в массы, ибо действительно хорошо составлена.

    P.S. Такие игры веют гиговской ноткой, и это хорошо. Хочется добавить, что неплохо поддержку 2К — 4К дисплеев и под них режим, где большинство уровней сразу на экране. Как на обоях, что в Facebook выложили.


    1. DuhaTheBest
      17.10.2016 17:43

      Спасибо! Попробую поработать над золотым.


  1. DistortNeo
    17.10.2016 20:51
    +2

    Забацал вот такой генератор:
    https://htmlpreview.github.io/?https://github.com/e673/vga-palette-gen/blob/master/color.html

    Видно сильную нелинейность цветового пространства LAB, особенно в синих тонах.

    P.S. По рукам не бейте — я на JS вообще не умею писать.


    1. Refridgerator
      18.10.2016 18:42
      +1

      Я только хотел про LAB написать, а вы уже готовый генератор сделали! LAB довольно интересное пространство.


  1. xtala
    17.10.2016 22:14

    А почему не стали игру делать кроссплатформенной? Пользователи *nix обычно с удовольствием покупают такие игры, а так вы потеряли часть доходов, может и не так уж много, но все же. Или есть трудности в реализации кроссплатформенного решения которые не видно на первый взгляд?


    1. DuhaTheBest
      17.10.2016 22:20

      Игра Proto Raider запущена на Стиме и iOS т.ч. он кросплатформенная. Другое дело, что платформ могло быть и побольше. Все дело во времени. Такие игры не приносят прибыль — это как хобби. Поэтому сложно иногда выделать время.


      1. xtala
        17.10.2016 23:44

        А на каком языке игра написана? Java же вроде дает кроссплатформенное решение сразу? Я чайник =) могу и ошибаться =)


        1. DuhaTheBest
          17.10.2016 23:58

          Это я следующую игру на Cosos2d-js пишу, а та игра была написана на самодельном движке.


  1. Orky
    18.10.2016 14:07
    +1

    По теме статьи: мне кажется, стоит использовать разные корректировки насыщенности и яркости для левой и правой частей получившейся палитры.

    Или, возможно, просто уменьшить количество оттенков зеленого, если мы его так плохо различаем.


    1. DuhaTheBest
      18.10.2016 14:46

      Да, для зеленого тона и некоторых других, плохо различается насыщенность. Как не корректируй — ничего не помогает. Действительно, единственным способом решения проблемы является уменьшение количества градаций насыщенности. Но это испортит визуальную структуру палитры — будут дырки. Вот я и на распутье. Но скорее всего я таки «продрежу» палитру.


  1. phoenixweiss
    19.10.2016 04:08
    +1

    Просто замечательная статья и очень крутая графика в играх (как бы парадоксально это не звучало для графонозависимых).


    1. DuhaTheBest
      19.10.2016 04:27

      Спасибо!