「这是我参与2022首次更文挑战的第16天,活动详情查看:2022首次更文挑战」
马赛克原理
马赛克,指现行广为使用的一种图像(视频)处理手段,此手段将影像特定区域的色阶细节劣化并造成色块打乱的效果,因为这种模糊看上去有一个个的小格子组成,便形象的称这种画面为马赛克。其目的通常是使之无法辨认,通常出现在新闻报道里,用来遮挡人物面貌。
引用一段介绍马赛克的说明,马赛克在日常中的目的是为了遮挡不希望展示的内容,让图片部分内容模糊看不起具体是什么。其效果又不同于常见的模糊效果而是一个个方格子形成的特效。
马赛克效果原理就是将图片一块区域取其中一个点像素色值作为该区域色值,简单理解马赛克就是改变图片“分辨率”把高清图变“模糊”了。例如一张有100x100像素点的图片,通过马赛克处理后变成还是100x100像素点的图片。之前说的改变图片“分辨率”其实是改变像素点的色值而非改变图片像素点总数,马赛克处理并不会减少图片本身分辨率的大小而是改变色值让图片能够表达细节变少。
原图 | 马赛克 |
---|---|
以上对比图可以发现通过马赛克处理后像素点密度变小了。
马赛克实现
马赛克实现过程:
- 根据
mosaicSizeRatio
马赛克占比算出totalXY一共马赛克格子数。vec2(0.005, 0.005)
大概就是200x200
个格子了。 eachXY
表示顶点坐标的位置是按照马赛克比例来计算得出。eachXY
和totalXY
相除计算得出当前马赛克uv
顶点坐标。- 新的顶点坐标和纹理作用生成新的马赛克纹理。
const vec2 mosaicSizeRatio = vec2(0.005, 0.005);
void main() {
vec2 uv = gl_FragCoord.xy / iResolution.xy;
vec2 totalXY = vec2(1.0 / mosaicSizeRatio.x, 1.0 / mosaicSizeRatio.y);
vec2 eachXY = vec2(floor(uv.x / mosaicSizeRatio.x), floor(uv.y /mosaicSizeRatio.y));
vec2 UVMosaic = vec2(eachXY.x / totalXY.x, eachXY.y / totalXY.y);
vec4 color = texture(iChannel2, UVMosaic);
gl_FragColor = color;
}
原图 | 马赛克 |
---|---|
马赛克动画效果
通过增加一个time
入参来变化mosaicSizeRatio
参数,当mosaicSizeRatio
向量比例越小,马赛克格子数就越多就越接近原图效果。这样就实现一个马赛克渐渐变清晰动画效果了。
vec2 mosaicSizeRatio = vec2(0.05, 0.05);
#define time iTime
void main() {
float vigAmt = sin(time);
mosaicSizeRatio *= vigAmt;
vec2 uv = gl_FragCoord.xy / iResolution.xy;
vec2 totalXY = vec2(1.0 / mosaicSizeRatio.x, 1.0 / mosaicSizeRatio.y);
vec2 eachXY = vec2(floor(uv.x / mosaicSizeRatio.x), floor(uv.y /mosaicSizeRatio.y));
vec2 UVMosaic = vec2(eachXY.x / totalXY.x, eachXY.y / totalXY.y);
vec4 color = texture(iChannel2, UVMosaic);
gl_FragColor = color;
}