Как раскрасить определенные части модели - как в играх RTS эти командные цвета?

16

Мне нужно реализовать то, что мы видим в играх RTS: командные цвета. В основном, я ищу способ раскрасить определенные части модели. Как бы я этого достиг? Я понятия не имею, с чего начать. Нужно ли сначала вносить некоторые изменения в 3d-модель?

RFactor
источник

Ответы:

18

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

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

Таким образом, в вашем шейдере вы можете перейти (для наиболее простого пути):

float3 finalColor;
if (colorFromTex.a > 0)
 finalColor = colorFromTex.rgb;
else
 finalColor = colorFromTex.rgb*myTintColor.rgb;

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

float3 finalColor = lerp(colorFromTex.rgb, 
    colorFromTex.rgb*myTintColor.rgb, colorFromTex.a);
Лукас
источник
Вы случайно не знаете, как получить шейдер DirectX для 3d-моделей в 3ds Max? Когда я попытался установить материал с типом шейдера и установить шейдер на ReplaceColor.fx и экспортировал модель, результат был Error 1 Missing asset "C:\Users\Kai\AppData\Local\Temp\fbx.shader.temp.1064.2756\ReplaceColor.fx". Я не понимаю, как я могу получить это правильно.
rFactor
Это когда ты его загружаешь? Кажется странным, что путь в FBX будет указывать на временную папку. Этот файл существует? Я не очень знаком с экспортом FBX из 3ds Max, но, возможно, вам нужно отредактировать файлы (или установить опцию), чтобы сделать пути относительными.
Лукас
Хорошая техника, но если вы используете альфа-канал для обозначения «тинтабильности», не забудьте сбросить альфа-компонент в вашем finalColor.
charstar
3

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

Очевидно, это работает, только если у вас всего две команды. Хотя вам это может сойти с рук больше двух, оно начинает становиться неэффективным.

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

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

ChrisF
источник
2

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

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

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

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

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

bmcnett
источник
1

Моя техника будет такой: иметь 2 текстуры: одну основную текстуру, вторую текстуру, перекрывающую основную, но только те части, которые вы хотите закрасить. Измените цвет второй текстуры, как вы хотите.

daemonfire300
источник