Лучший способ позволить игрокам «красить» изображения без потери качества цвета?

41

Я создаю 2.5D изометрическую (2D изображения) игру.

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

Персонажи в моей игре не имеют огромного разнообразия экипировки. Игра ближе к тому, как League of Legends обрабатывает персонажей и графику. Может быть один тип персонажа (например, герой), но несколько вариантов для персонажа в качестве опций. Я хочу, чтобы игроки могли иметь как можно больше настроек в ограниченном количестве «нарядов» и персонажей.

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

Если бы я мог использовать оттенки серого, не теряя некоторые цвета, я бы так и сделал.

Вот пример того, о чем я говорю:

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

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

Тем не менее, это выглядит намного лучше, если я не буду использовать оттенки серого, а вместо этого просто применю цвет "HUE" к исходному (красному / желтому) изображению.

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

Фиолетовый оттенок введите описание изображения здесь

Теперь игроки могут покрасить Дракон в ЛЮБОЙ цвет, и он все равно будет выглядеть великолепно! (Желтый становится белым, а красный превращается в любой цвет радуги.)

Означает ли это, что БЕЛЫЙ или ЧЕРНЫЙ лучший вторичный цвет? Затем используйте какой-нибудь метод или шейдер, чтобы изменить белый (вторичный) цвет на что-то другое?

Есть ли какие-нибудь статьи об этом сложном методе съемки одного изображения, основанные на раскраске, красящие разные пиксели?

Для Дракона, лучше ли он будет работать как белый / черный высококонтрастный дракон? Красный / Желтый лучший набор цветов? Получается намного лучше для изображений, чем несколько других цветов, которые я пробовал. Оттенки серого все еще лучше?

Разве в Photoshop «Параметры смешивания» не включен метод для надлежащего «окрашивания» изображений для видеоигры? Существуют ли сложные шейдеры / методы, которые позволяют мне достичь большего успеха?

Примечание. Если GrayScale позволяет мне уменьшить потребление ОЗУ моих изображений или предотвратить потерю качества при сжатии с потерями, я бы серьезно об этом подумал.

Carter81
источник
5
Это законно интересно. Я собираюсь проголосовать за это и надеюсь, что это привлечет больше внимания. Теория цвета - отличная тема.
Эван
Поворот оттенка возможен, хотя и для 2D - я не знаю, будет ли он работать в 3D.
ashes999
Спасибо, Эван. Я также согласен, что это чрезвычайно интересно, и одна из лучших тем, которые я исследовал в свое время. Этот вид работы, я полагаю, редко делается, потому что он требует художника, а не просто художника, художника, который имеет дело с теорией цвета, шейдерами видеоигр или даже художником-кодером. Я могу только предположить, что найти кого-то, кто преуспевает и в искусстве и в программировании, редко. По этому вопросу практически нет исследований в Google. Особенно для тех, кто не знает, какие ключевые термины для исследования. Я, конечно, не художник.
Carter81

Ответы:

19

Сдвиг оттенка - это одна из возможностей, которая позволит вам получить диапазон цветов без потери цветовых деталей. Основная идея состоит в том, чтобы преобразовать каждый пиксель из RGB в пространство HSV, затем сместить оттенок на определенную пользователем величину, а затем преобразовать обратно в RGB. На самом деле, это можно сделать более эффективно, применяя матрицу вращения к значениям RGB: создайте матрицу, которая вращается вокруг оси (1, 1, 1) на определенный пользователем угол оттенка. Затем вы можете просто применить эту матрицу к каждому значению RGB в вашем пиксельном шейдере.

Это позволит сместить красно-желтого дракона на желто-зеленого, зелено-голубого, голубо-синего, сине-пурпурного или пурпурно-красного дракона. Это немного ограничительно, так как при таком подходе два цвета не могут быть изменены независимо. Они сохранят свой относительный оттенок, поскольку они созданы в исходном изображении. Есть также некоторые цвета, к которым вы не можете получить доступ, например, вы не можете сделать черно-белого дракона таким образом. Тем не менее, этого может быть достаточно для ваших целей.

Другая возможность, если ваши модели имеют два или три «ключевых цвета» (здесь красный и желтый), вы можете создать оригинальное изображение, используя отдельный цветовой канал для каждого ключевого цвета. В этом случае вы будете писать дракона красным и зеленым вместо красного и желтого, а если у вас будет третий цвет, вы можете написать его синим. Затем вы можете позволить пользователю выбрать три ключевых цвета и использовать красные, зеленые и синие значения в изображении в качестве количества этих пользовательских цветов, чтобы смешаться. Таким образом, ваш пиксельный шейдер будет выглядеть примерно так:

finalColor = image.r * userColor1 + image.g * userColor2 + image.b * userColor3;

Это позволило бы пользователям выбирать любую цветовую комбинацию, которую они хотели, включая такие вещи, как черный и белый или фиолетовый и золотой.

Натан Рид
источник
1
+1 за не только хороший ответ, но и ответ на редкую тему (теория цвета). Я понятия не имею, почему я не думал об этом раньше. RGB. Красный Зеленый Синий. ДУХ! Вероятно, лучше всего использовать именно эти три цвета из-за способности манипулировать отдельными каналами.
Carter81
1
Сдвиг цвета - очень сложная тема, потому что большая часть информации изображения передается по яркости, а простое смещение оттенка не сохраняет яркость. Различные оттенки имеют разные значения яркости. Вам нужны более сложные алгоритмы для этого.
API-Beast
10

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

Таким образом, вам нужно разложить изображение на составляющие.

Пример :

Деконструированное изображение Тонированные примеры

В этом случае у нас есть 3 слоя:

  • Фон - содержит элементы, которые не должны быть окрашены.
  • Часть, которая должна быть окрашена - это умножается на цвет. (OpenGL умножается по умолчанию, если вы указываете цвет, отличный от белого.)
  • Основные моменты - они нарисованы аддитивно по всему изображению. Это не белый, а желтый, чтобы подражать изменению оттенка. Объекты не просто одного цвета, цвет меняется вместе с яркостью.
API-Beast
источник
+1. Но "вы не можете просто" подкрасить "весь образ" немного вводит в заблуждение. Все зависит от выбора ОП для его игры. Например, Diablo II сделал это. Так что я не был бы настолько строг с частями "ты не можешь / тебе нужен". Это всего лишь один из вариантов, более привлекательный, но потребляющий больше оперативной памяти.
Кромстер говорит, что поддерживает Монику
1
@ KromStern Точка, это выглядит ужасно, если вы делаете это всегда.
API-Beast
Отличный ответ. Возможно ли это через автоматизацию? Если у одного персонажа есть тысячи анимированных изображений, невозможно вручную выбрать каждый слой или разложить изображение по одному. Тем не менее, я вижу некоторые обходные пути, чтобы помочь автоматизировать его, если рендеринг из 3D с использованием маскирования, но, тем не менее, это все еще отличный ответ.
Carter81
Потенциально возможно автоматизировать его, находя доминирующие цвета и извлекая их (используя обратный алгоритм «цвет-альфа»). Но не то, чтобы я когда-либо реализовывал что-то подобное.
API-Beast
Для извлечения бликов вы можете взять ранее выделенную маску и отфильтровать ее, чтобы у вас остались только самые яркие компоненты.
API-Beast
3

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

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

входы: MainTexture (RGB), Mask1Texture (A), Mask2Texture (A), Colour1 (плавать), Colour2 (плавать)

вывод: (Mask1Texture + Mask2Texture) -MainTexture + Colour1 * Mask1Texture + Colour2 * Mask2Texture

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

Я использовал эту технику для мобильных игр, и она не повлияет на вашу общую производительность. Это может стоить вам на 33% больше ОЗУ на текстуру, но компромисс за качество, вероятно, того стоит.

Ps Если вы думаете только об использовании одного пользовательского цвета, вы можете просто использовать альфа-канал вашей основной текстуры RGBA32 в качестве маски.

MrXee
источник
2

Вы можете использовать цветовые палитры и позволить игроку редактировать палитру. Если вы используете шейдеры, вы можете использовать 1D текстуры в качестве палитр и исходное значение серого в качестве индекса.

Чтобы преобразовать настоящее цветное изображение в изображение с 255 цветами, вы можете взять все значения цвета вашего пикселя и сгруппировать их в трехмерном цветовом пространстве в 255 кластеров с помощью алгоритма k-средних. Или используйте универсальные инструменты преобразования изображений. Затем важно отметить, что интерполяция текстуры значения серого будет интерполяцией индексов в ваших цветовых текстурах. Это может привести к получению нескольких цветов между двумя текселями исходного изображения. Эту проблему можно решить, отключив интерполяцию (я думаю, вы не хотите этого делать) или с помощью полезной сортировки вашей цветовой палитры.

Arne
источник
Это в основном то, о чем я думал. Вы можете расширить ответ на что-то более полное. По сути, вы позволяете пользователю выбрать два цвета (или больше или меньше, но ради аргумента, 2), создать 1D текстуру, которая исчезает из двух цветов. Используйте текстуру в градациях серого для геометрии, которая служит ссылкой в ​​1D текстуре. Пользователь по-прежнему может устанавливать некрасивые цвета, но, по крайней мере, у него есть возможность сделать хороший выбор контрастных цветов.
wrosecrans
да, вы также можете получить полную 255 цветовую палитру из меньшего количества пользовательских цветов, но здесь я могу только посоветовать вам попробовать. Я знаю, что многие старые игры использовали изменения в цветовой палитре, чтобы изменять своих монстров. Я думаю, что Diablo сделал это.
Арне
1

Вы можете преобразовать изображение в серое изображение, но сохранить его с помощью каналов RGBA. сохраните значение веса в альфа-канале, затем используйте его, чтобы решить, сколько красителя нанести на пиксель. этот вес можно рассчитать исходя из того, насколько близок цвет к белому. чем ближе к белому пиксель, тем меньше красителя следует наносить или тем меньше должен быть вес. это оставит большинство основных моментов с их оригинальной легкостью, но примените немного краски к этому. Окончательный цвет пикселя затем можно найти, рассчитав каждый канал Ro + (Rd * Ao), где Ro - это красный оригинал, Rd - это красный в цвете красителя, а Ao - это альфа-канал оригинала. поэтому все белые пиксели не получают новый цвет, а все черные пиксели принимают цвет красителя.

Фил
источник