Ранее я перепечатывал статью о Чжиху:
Автор: Это Божий шедевр 链接:https://zhuanlan.zhihu.com/p/344110917
В статье подробно объясняется идея шейдера для достижения эффекта «тепловидения», но не приводится полный код реализации. Читатели в фоновом режиме много раз убеждали меня, надеясь, что я смогу реализовать это и дать полный код. кода, поэтому я потратил этот вечер. Чтобы просто добиться такого эффекта, потребовалось время.
По идее той статьи,Основные шаги::Нечеткий->светиться->Оценка яркости->Заменить цвет , шаг освещения не очень важен.
Вы можете наблюдать цвет эффекта «тепловизионного изображения», который представляет собой сочетание синего (холодного) и красного (горячего) цветов, затем сортировать цвета и заменять соответствующие цвета по уровню яркости.
Что касается размытия, то оно на самом деле просто для усиления ощущения наслоения. Вы можете сравнить два изображения ниже. Слева изображен «эффект тепловидения» без размытия.
Создайте массив поиска цветов на основе цветового спектра тепловидения:
vec3 colorLevels[9] = vec3[9](
vec3(234.0,51.0,61.0),
vec3(235.0,70.0,105.0),
vec3(178.0,119.0,37.0),
vec3(247.0,206.0,70.0),
vec3(149.0,232.0,71.0),
vec3(103.0,200.0,250.0),
vec3(68.0,132.0,245.0),
vec3(40.0,3.0,143.0),
vec3(18.0,5.0,62.0)
);
Далее преобразуем RGB в значение оттенков серого. Мы делим значение оттенков серого на 9 уровней, а затем выбираем соответствующий цвет на основе текущего значения оттенков серого.
float lum = dot(color.rgb, vec3(0.3, 0.59, 0.11));
lum = 1.0 - lum;
float d = 1.0 / 9.0;//Разделим значение серого на 9 индивидуальный level
int i = int(lum / d);
i = clamp(i, 0, 8);
fragColor = vec4(colorLevels[i]/255.0, 1.0);
Конечный эффект следующий:
Полный код реализации:
vec3 colorLevels[9] = vec3[9](
vec3(234.0,51.0,61.0),
vec3(235.0,70.0,105.0),
vec3(178.0,119.0,37.0),
vec3(247.0,206.0,70.0),
vec3(149.0,232.0,71.0),
vec3(103.0,200.0,250.0),
vec3(68.0,132.0,245.0),
vec3(40.0,3.0,143.0),
vec3(18.0,5.0,62.0)
);
float blur_gauss(float bhqp, float x) {
return exp (-(x * x) / (2.0 * bhqp * bhqp));
}
vec4 blur(vec2 uv, sampler2D source, float Intensity) {
const int iterations = 4;
int halfIterations = iterations / 2;
float sigmaX = 0.1 + Intensity * 0.5;
float sigmaY = sigmaX;
float total = 0.0;
vec4 ret = vec4 (0., 0., 0., 0.);
float step = 0.00390625;
for (int iy = 0; iy < iterations; ++iy) {
float fy = blur_gauss(sigmaY, float (iy - halfIterations));
float offsety = float (iy - halfIterations) * step;
for (int ix = 0; ix < iterations; ++ix) {
float fx = blur_gauss(sigmaX, float (ix - halfIterations));
float offsetx = float (ix - halfIterations) * step;
total += fx * fy;
vec4 a = texture2D (source, uv + vec2 (offsetx, offsety));
a.rgb *= a.a;
ret += a * fx * fy;
}
}
return ret / total;
}
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
vec2 uv = fragCoord.xy / iResolution.xy;
//vec4 color = texture2D(iChannel0, uv);
vec4 color = blur(uv, iChannel0, 3.0);//Размыто
color.rgb += vec3(1.0,0.0,0.5)*color.rgb*0.2;//Свечение
float lum = dot(color.rgb, vec3(0.3, 0.59, 0.11));
lum = 1.0 - lum;
float d = 1.0 / 9.0;
int i = int(lum / d);
i = clamp(i, 0, 8);
fragColor = vec4(colorLevels[i]/255.0, 1.0);
}
Справочная статья:
https://zhuanlan.zhihu.com/p/344110917
Получите соответствующую информацию и исходный код
рекомендую:
Android FFmpeg реализует функцию записи короткого видео WeChat с фильтром
Самая полная коллекция аудио- и видеоматериалов для Android и OpenGL ES в Интернете. Все здесь.
Освойте базовую обработку YUV-изображений в одной статье.
Как реализован специальный эффект конвейерной ленты Доуиня?
Все эффекты перехода изображения, которые вам нужны, находятся здесь.
Я использовал OpenGL ES, чтобы сделать несколько фильтров Douyin для своей младшей сестры.