Anet & Nejno
Nejno Nejno
Привет, Аня! Знаешь, задумалась тут о том, как меняется цвет, когда свет падает на бумагу – как яркая лампа может сделать краску теплее или холоднее. Ты когда-нибудь пытаешься это как-то воссоздать в коде, чтобы создать цифровую "полотно", которое реагирует на свет, как настоящее произведение искусства?
Anet Anet
Да, я сделала несколько шейдеров, которые в реальном времени меняют цветовую температуру. Я пропускаю RGB-значения через простую спектральную таблицу и смешиваю это с источником света сцены. Главное – правильно поддерживать гамма-кривую и позволить цвету света управлять интерполяцией. В итоге получается цифровой холст, который реально ощущает, как меняется настроение мазка от света. Хочешь разобраться в математике?
Nejno Nejno
Звучит очень интересно. Просто чтобы убедиться, что я ничего не упустила — когда ты переносишь RGB в таблицу спектральных значений, ты сначала преобразуешь каждый канал в оценку длины волны, а потом смешиваешь это со спектральным распределением освещения сцены? И насчёт гаммы — ты применяешь преобразование из линейного формата в sRGB до смешивания или после? И ещё, как ты добиваешься плавности интерполяции, когда оттенок света немного скачет? Было бы здорово увидеть уравнения, которые ты используешь.
Anet Anet
Конечно, вот суть в простых математических формулах, чтобы ты могла сразу подставить это в шейдер или небольшой скрипт. Сначала линеаризуй цвет, потому что в большинстве изображений RGB закодирован гаммой. **Линеаризация RGB** R_lin = R^γ G_lin = G^γ B_lin = B^γ где γ ≈ 2.2 для sRGB. **Оценка доминирующей длины волны** (очень грубая "псевдо-спектральная" карта). Ты можешь использовать взвешенную сумму, которая больше учитывает красный канал для низкого конца спектра и синий – для высокого. λ_est = a·R_lin + b·G_lin + c·B_lin Типичные веса: a≈0.4, b≈0.3, c≈0.3. Это даст тебе число в диапазоне 400–700 нм, если ты масштабируешь его соответствующим образом. **Смешивание со спектральным распределением света** Предположим, L(λ) – это спектр света (таблица интенсивности против длины волны). Отражательная способность пигмента S_p(λ) – это другая таблица (или простая модель). Вычисли спектр отражённого света при оценённой длине волны: S_out(λ) = S_p(λ) · L(λ) Если тебе нужно одно значение RGB, то выбери значения S_out(λ) при трёх ключевых длинах волн, которые соответствуют R, G, B (примерно 700 нм, 546 нм, 435 нм) и переведи их обратно в линейный RGB: R' = S_out(700 нм) G' = S_out(546 нм) B' = S_out(435 нм) **Гамма-коррекция** Примени гамму, чтобы вернуть цвет в цветовое пространство дисплея: R_disp = (R')^(1/γ) G_disp = (G')^(1/γ) B_disp = (B')^(1/γ) **Плавная интерполяция при скачках оттенка света** Используй линейную интерполяцию в спектральной области, а не в RGB. Если твой свет переключается с одной доминирующей λ на другую, делай так: S_out_interp(λ) = (1‑t)·S_out_prev(λ) + t·S_out_new(λ) где t∈[0,1] – это фактор интерполяции во времени. Это сохраняет плавное изменение спектральной формы, поэтому воспринимаемый цвет меняется постепенно, а не скачками. Сложив всё вместе, ты получишь цепочку: 1. Линеаризуй входной RGB. 2. Оцени λ_est. 3. Выбери спектр пигмента при этой λ и умножь на спектр света. 4. Интерполируй, если свет меняется. 5. Переведи полученную спектральную выборку обратно в RGB. 6. Примени гамму к результату. Это основа шейдера для светочувствительной краски. Не стесняйся подстраивать веса или добавлять более сложную модель отражения, если хочешь больше реализма. Удачи с хакингом.
Nejno Nejno
Wow, that’s a lot of detail—thanks for the step‑by‑step. I’ll try plugging it into my shader and see how the colors shift with a changing lamp. Maybe I’ll tweak the weights a bit, just to keep my canvas from feeling too flat. Let me know if you notice any “jump” in the hue when the light changes; I’m hoping the interpolation will keep it smooth. Good luck experimenting!