Начиная с
1) входное изображение в виде R, G, B и
2) текстура изображения, оттенки серого.
Изображения, скорее всего, представлены в байтах, от 0 до 255. Разделите их на 255,0, чтобы они были от 0,0 до 1,0. Это облегчает математику. Что касается производительности, вы бы на самом деле этого не делали, а использовали бы умную математику с фиксированной запятой - вопрос реализации, который я оставляю вам.
Во-первых, чтобы получить краевые эффекты между разноцветными областями, добавьте или вычтите некоторую долю каналов R, G и B к текстурному изображению:
texture_mod = texture - 0.2*R - 0.3*B
Вы можете полюбоваться с помощью нелинейных форумов, например, установление порогов каналов R, G и B или вычисление некоторого математического выражения с их участием. С этим всегда весело экспериментировать; Я не уверен, что лучше всего будет воссоздать твой пример.
Затем вычислите рельефную версию texture_mod, чтобы создать эффект освещения. В этом разница между текстурой, сдвинутой вверх и вправо на один пиксель (или сколько вам нравится), и той же текстурой, смещенной. Это дает эффект 3D освещения.
emboss = shift(texture_mod, 1,1) - shift(texture_mod, -1, -1)
(Вы должны использовать texture_mod или исходные данные текстуры в этой формуле? Поэкспериментируйте и посмотрите.)
Вот шаг силы. Преобразовать входное изображение в пространство HSV. (LAB или другие цветовые пространства могут работать лучше, или нет - экспериментируйте и смотрите.) Обратите внимание, что в вашем желаемом конечном изображении трещины между "mesas" темнее, поэтому мы будем использовать оригинальный texture_mod и тиснение, чтобы изменить V канал, с коэффициентами для контроля силы эффекта:
Vmod = V * ( 1.0 + C_depth * texture_mod + C_light * emboss)
И C_depth, и C_light должны быть в диапазоне от 0 до 1, возможно, меньшие доли, например, от 0,2 до 0,5 или около того. Вам понадобится коэффициент выдавливания, чтобы удержать Vmod от переполнения или фиксации на максимуме - делите на (1 + C_depth + C_light). Некоторые зажимы на ярком конце могут помочь бликам выглядеть ярче. Как всегда экспериментируй и посмотри ...
Как замечательно, вы также можете каким-то образом изменить канал насыщения, возможно, уменьшив его там, где texture_mod ниже.
Наконец, преобразуйте (H, S, Vmod) обратно в цветовое пространство RGB.
Если объем памяти ограничен или производительность критична, можно пропустить преобразование HSV и вместо этого применить формулу Vmod к отдельным каналам R, G, B, но это приведет к сдвигам оттенка и насыщенности. Это компромисс между скоростью и привлекательной внешностью.