OSL карта-конвертер NCS в HSV
1740

В архитектурной визуализации постоянно приходится иметь дело с каталогами цветов. Обычно это RAL или NCS. К сожалению RAL - это именно что каталог, некая картотека где цвета имеют свой инвентарный номер и уникальное название. Математически точно конвертировать это дело в понятные цветовые модели, такие как RGB или HSV нельзя. Можно проводить колориметрию, и записывать результат в табличку в виде RGB или HEX. Что делают многие ресурсы в интернете. Проблема такого подхода в том, что у каждого измерения свои особенности, и на разных сайтах цвета существенно отличаются. Что делать в подобной ситуации каждый решает для себя сам: кто-то выбирает один ресурс и принимает его измерения за эталон. Кто-то добывает печатный каталог и буквально прикладывает к монитору.

NCS же в отличии от RAL - это цветовая модель. Существуют здоровые печатные каталоги NCS, где как и в RAL, за сложной маркировкой кроется конкретный цвет. Однако можно заключить, что раз мы имеем дело с моделью, то можно сделать конвертер из одной цветовой модели в другую. Что я и попытался сделать средствами OSL в 3dsMax. По идее, с небольшой доработкой, скрипт должен завестись во всех пакетах понимающих OSL.

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

В модели NCS, как во многих других, цвет состоит из трех составляющих.

Чернота - первые две цифры в номере цвета;

Хроматичность - следующие две цифры; 

Оттенок - состоящий из буквы и двух цифр. Буква указывает начальный базовый цвет из четырех: желтый, красный, синий или зеленый - расположенных на круге. А цифры - процент отклонения от одного чистого цвета вправо или по часовой стрелке в сторону следующего. Обычно этот следующий цвет указан после цифр, хотя следуя правилам смещения строго вправо - это избыточная информация, но для контроля полезно.

Таким образом рассмотрим, к примеру цвет 3040-Y80R. Что можно о нем сказать не открывая каталог.

30 - это относительно светлый цвет, его чернота 30%

40 - не особо насыщенный, хотя уже далеко не серый, оттенок будет очень хорошо заметен.

Y80R - видно что оттенок смещен на 80% вправо от желтого к красному. Т.е. по сути это больше красный чем желтый. 

Как же это конвертировать и во что? 

Чернота - обратно-пропорциональна светлоте, Храматичность - это в чистом виде насыщенность, а оттенок - это оттенок, только записанный в необычном для других моделей формате. Таким образом наиболее удобный вариант для конвертации - HSV, тем более что он прекрасно понимается Max'ом и дальше ни во что его переводить не будет нужды. Некоторая сложность возникает с оттенками, т.к. в модели NCS равные расстояния между базовыми четырьмя цветами. А в модели HSV три базовых цвета, так же расположенных в кольце. А это значит, что потребуется учесть, что желтый цвет, располагаясь между красным и зеленым имеет меньшее расстояние чем между зеленым и синим и синим и красным. А именно не 33.3(3)% от полного кольца, а 16,6(6)%.

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

Насколько можно доверять такой конвертации вопрос дискуссионный. Математически - перевод столь же корректен как перевод из RGB скажем в CMY(K). Можно без проблем при желании перегонять туда-сюда. Но стоит помнить что NCS как и CMY(K) - модель для отраженного цвета, в то время как HSV или RGB - для излучения. Поэтому восприятие может отличаться. 

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

И так две OSL'ки:

Первая - версия где каждый компонент цвета вводится вручную.

Вторая - версия, куда можно просто скопировать цвет. 

Почему две? Все просто. Вторая безусловно удобнее. Но я не смог совладать с парсером, он сложнее самого конвертера, если учитывать все возможные варианты ввода. По этому, к сожалению, в нем присутствует существенный баг.  NCS допускает такие цвета как 3040-Y - т.е. без указания смещения, когда имеется ввиду чистый базовый цвет. В этом случае парсер не справляется с задачей (я пробовал обходить баг разными способами, но увы) и Макс может вылететь с ошибкой. Что бы такого не произошло - добавляйте 00 после буквы, т.е. 3040-Y00 вторая буква не нужна. Она игнорируется во всех версиях, т.к. это просто напоминание куда происходит смещение (а оно всегда вправо).

Код, разумеется, открытый - модифицируйте, кто умеет и желает.

UPD от 24.06.2022:

1. Математика математикой, но кое что в модели NCS оказалось сложнее. Оказывается что Сине-красные и зелено-синие оттенки в этой модели существенно отличаются от математики. В нее вносят какую-то поправку. И я не нашел информацию как именно. Разработчиками модели это объясняется тем, что человек якобы ощущает синие оттенки иначе и по этому их модель это учитывает. К сожалению здесь я вторгаюсь в область не познанного, однако чисто эмпирически я заметил следующую корреляцию - чем больше синего в оттенке, тем больше нужно смещать оттенок в.... Зеленый. Кол-во определяется как 1/10 от Значения Hue в системе NCS, т.е. было B20G - значит нужно сделать сдвиг в сторону зеленого 10-20/10, т.е. на 8 пунктов. Для красных еще сверху добавляю 1/2 от этого смещения - так получается точнее. 

Допускаю, что есть более точное приближение, но пока я лучше не нашел.

2. Добавил альтернативный метод расчета насыщенности и светлоты.  Несмотря на его альтернативность, с точки зрения модели он более корректный. Формулы расчета опять же легко увидеть в самом скрипте. Обратите внимание - цвет становится гораздо плотнее - на визе это смотрится корректнее. Так же такой расчет отвечает правилу NCS - Хроматичность и чернота в сумме не могут быть больше 100, а светлота собственно высчитывается по формуле W=100-Chomatness-Blackness - т.е. в модели NCS цвет 6040-XXXX будет черным, как и 2080-XXXX и 8020-XXXX

3. NCS как и RAL - промышленные стандарты. И уже давно конвертированы друг в друга. Вернее для RAL подобраны как точные значения по NCS, так и не точные, но максимально близкие из каталога. А это значит, что можно взять такой каталог с точными цветам и использовать как конвертер из RAL в NCS (я сравнил каталоги печатные - точность отличная, разница не больше чем между двумя разными каталогами RAL Classic). Я постараюсь это сделать. 

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

PS почему-то в 19 максе нет вылета из-за бага с парсингом... а в 22 и 23 вылетает 

UPD от 28.06.2022

Исправил некоторые ошибки конвертации, местами немного переписал код.

В первой версии добавил коррекцию синего и альтернативный расчет

Добавил третий вариант - с выбором параметров из списка с шагом 10%

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

+3
grdesigner
Очень любопытно выглядит. Пока нет возможности потестить, но идея отличная.

ПС в названии темы не опечатка "NSC"?
+2
Zava
Опечатка, конечно, спасибо. Столько слов из трех букв в одном предложении, не мудрено опечататься :D
+1
grdesigner
Кстати, вот это видели? https://www.artstation.com/artwork/zARQGZ 

Я давно засматриваюсь, но у автора беда какая то, сайт время от времени мертвый лежит, и под вирей нет версии.
+1
Zava
Любопытно, нет, не видел такого. Спасибо
+1
grdesigner
Вдруг на мысли натолкнет и в будущем выльется в скрипт. Я бы купил.
+1
Pavel_Ushakov
Поменял местами строки - переместил вверх заголовок с описанием
shader NCStoRGB
[[ string help="NCS to HSV converter by ZAVA (c) 2022" ]]

стало выдавать ошибку.https://c2n.me/4g1c5vj 

Если код не править, то все работает на 22 максеhttps://c2n.me/4g1cjUb 

С точки зрения реализации мне не нравится, что нужно вводить значения вручную. Муторно. Я бы спрятал всё под "капот" и завел бы в код или отдельным файлом список с кодировкой всей палитры, к которому бы обращался код. Конечный бы пользователь только бы выбирал кодировку, а шейдер бы сам компилировал нужный цвет.

Типа как здесьhttps://c2n.me/4g1cEah 
0
Zava
Спасибо!
про перенос заголовка - вы его разместили над функцией pars - это не корректно, функции объявляются перед заголовком шейдера.

Выбор из палитры не реализован сознательно по ряду причин:
1. в каталоге NCS как минимум 1950 цветов, сделать одной таблицей - это убийство.
2. если есть желание выбирать частями, отдельно темноту, отдельно насыщенность и оттенок, то для этого есть реализация. Я периодически вношу правки и пару раз случайно сохранил не верно. Возможно вы скачали в момент этого моего косяка - проверьте сейчас.
3. NCS как каталог - это одно, но NCS как модель - другое. Модель допускает ввод таких значений, которых нет в каталоге, но которые существуют в рамках модели. И к примеру каталог соответствий с RAL имеет цвета типа 4426-G28Y, что соответствует RAL 6011 с бОльшей точностью чем любой каталожный вариант. Если предложить выбор со списком через 5-10% - то собрать такой цвет будет невозможно.
0
Zava
Есть и 4 пункт - в каталоге NCS есть цвета типа 0205-Y Изначально там действительно все было кратно 10 на самой заре модели )), но сейчас это уже не так, и, похоже, что от ручного ввода полностью не отказаться... Хотя можно сделать отдельный скрипт с ограниченным набором цветов но, с шагом 10%, что бы в принципе не трогать клавиатуру... Надо? Добавил. Я вас правильно понял - так вы хотели?
0
Pavel_Ushakov
Про перенос заголовка, почему так? Просто я сам ковыряюсь немного с OSL, за основу беру примеры дефолтных решений 3ds max. У них заголовки всегда в начале.https://c2n.me/4g1rMXe 
+1
Zava
Потому что у них нет функций, весь код в теле шейдера. Я использовал функцию, так как одна и таже операция должна вызываться несколько раз и повторять код в таких случаях неуместно. В OSL есть штатные функции stoi() и stof() для перевода строки в число. Но реализация OSL в максе их не понимает. Пришлось сделать свою примитивную.
0
Pavel_Ushakov
ясно, буду знать.
+1
Pavel_Ushakov
В код можно добавить вот эту опцию, что бы выключить слоты подключения, как защиту от "дурака", да и меню шейдера будет выглядеть чищеhttps://c2n.me/4g1tbiw 
+3
Azazelo
ColorsForCGArtists-ToolsForCorona-V5 - лежит на персии. А были ещё такие скрипты как "SIGERTEXMAPS RAL Color Solid" и "DG PaintPot"
http://www.scriptspot.com/3ds-max/scripts/sigertexmaps-sikkens-color-solid 
http://www.daveandgoliath.com/paint-pot-3dsmax-database-of-paint-codes/ 

А по OSL, подымалась тема для Арнольда: https://forums.autodesk.com/t5/arnold-for-maya-forum/need-a-simple-osl-for-ral-color/td-p/11048415 
0
grdesigner
О, здорово. Качну побалуюсь. Спасибо.
+1
Pavel_Ushakov
Хромая реализация, я купил в свое время, но не пользуюсь. Связывался с автором, баг поправил, но в целом у него не полные палитры.
PS Под вирей у него есть реализация, детали не помню, но иначе бы я не купил.
0
grdesigner
Видимо я пропустил, но раз снято с продажи значит действительно работающий не так как надо.

Вы если будете тестить эту OSL карту, напишите пожалуйста свое мнение.
+2
D-d_Man
Спасибо за труд - будем пробовать в деле!
+1
LadaBullo
Полезная штуковина, спасибо!