视觉特效之马赛克滤镜

GPUImagePixellateFilter

马赛克滤镜。
我们先来看mod函数的定义:

m o d ( x , y ) = x − y ∗ f l o o r ( x y ) mod(x,y) = x - y * floor(\frac xy) mod(x,y)=xyfloor(yx)

假设 y = 1 y=1 y=1,即 m o d ( x , 1 ) = x − 1 ∗ f l o o r ( x 1 ) mod(x,1)= x - 1 * floor(\frac x{1}) mod(x,1)=x1floor(1x),生成图像如下:

在这里插入图片描述
从图像中可以看出mod(x,y)的结果增量和x的增量在变量周期范围内是相同的。所以对于下面的代码:

 vec2 uv = fragCoord/iResolution.xy;
 // 马赛克的尺寸 
 vec2 sampleFactor = vec2(.05,.05);
 // 采样位置
 vec2 samplePos= uv - mod(uv,sampleFactor);
 fragColor = texture(iChannel0,samplePos);

samplePos在一个采样周期内是不变的,samplePos始终等于每一个采样周期开始时uv的值。

使用 mod函数还可以生成黑白马赛克:

 vec2 uv = fragCoord/iResolution.xy;
 float m = mod(floor(uv.x * 10.) + floor(uv.y * 10.),2.);
 vec3 col = vec3(0.);
 col += m;
 fragColor = vec4(col,1.0);

在这里插入图片描述

GPUImagePixellatePositionFilter

环形范围马赛克滤镜。
有了上面的分析,GPUImagePixellatePositionFilter的实现就很简单了:

 vec2 uv = fragCoord/iResolution.xy;
 // 获取和中心点的距离
 float d = length(uv - .5);
 // 环形半径为0.3
 if (d < 0.3){  // 显示马赛克
   // 马赛克的尺寸 
   vec2 sampleFactor = vec2(.05,.05);
   // 采样位置
   vec2 samplePos= uv - mod(uv,sampleFactor);
   fragColor = texture(iChannel0,samplePos);
 }else{
   // 显示原图像
   fragColor = texture(iChannel0,uv);
 }
GPUImagePolarPixellateFilter

旋转马赛克滤镜。
上述两种马赛克的实现都是在纹理坐标下生成的,这次要在极坐标下来生成马赛克。

网络图片
纹理坐标极坐标

 // 坐标范围扩充为 [-1,1] 
 vec2 uv = (2. * fragCoord - iResolution.xy)/iResolution.xy;
 // 利用反正切函数获取角度 θ  范围 [-π,π]
 float phi = atan(uv.y,uv.x);
 // 获取半径 r
 float r = length(uv);
 // 获取x、y
 uv.x = r * cos(phi);
 uv.y = r * sin(phi);

在极坐标下可以绘制出很多漂亮的图形,如三叶草:

在这里插入图片描述
在极坐标下绘制马赛克即是旋转形态的马赛克。

 // [-1,1]
 vec2 uv = (2. * fragCoord - iResolution.xy)/iResolution.xy;
 float r = length(uv);
 float phi = atan(uv.y,uv.x);

 // 采样像素
 float samplePixel = 0.05;
 // 加0.03是防止 r = 0时 留出空白区域
 r = r - mod(r,samplePixel) + 0.03;
 phi = phi - mod(phi,samplePixel);

 uv.x = r * cos(phi);
 uv.y = r * sin(phi);
 // (uv * 0.5 + 0.5):水平和垂直方向扩大2倍并向左下角移动0.5个单位长度
 fragColor = texture(iChannel0,uv * 0.5 + 0.5);
总结

在马赛克的绘制中mod函数起到了很关键的作用,谨记之。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值