我已经使用 GPUImage 框架来实现类似于 Instagram 应用程序的模糊效果,在该应用程序中,我创建了一个视图,用于从照片库中获取图片,然后对其进行效果。
其中一种效果是选择性模糊效果,其中只有一小部分图像清晰,其余部分模糊。GPUImageGaussianSelectiveBlurFilter 选择图像的圆形部分不被模糊。
我怎样才能改变它以使尖锐区域的形状改为矩形?
因为 Gill 的回答并不完全正确,而且这似乎被一遍又一遍地问到,所以我将在上面澄清我的评论。
默认情况下,选择性模糊的片段着色器具有以下代码:
varying highp vec2 textureCoordinate;
varying highp vec2 textureCoordinate2;
uniform sampler2D inputImageTexture;
uniform sampler2D inputImageTexture2;
uniform lowp float excludeCircleRadius;
uniform lowp vec2 excludeCirclePoint;
uniform lowp float excludeBlurSize;
uniform highp float aspectRatio;
void main()
{
lowp vec4 sharpImageColor = texture2D(inputImageTexture, textureCoordinate);
lowp vec4 blurredImageColor = texture2D(inputImageTexture2, textureCoordinate2);
highp vec2 textureCoordinateToUse = vec2(textureCoordinate2.x, (textureCoordinate2.y * aspectRatio + 0.5 - 0.5 * aspectRatio));
highp float distanceFromCenter = distance(excludeCirclePoint, textureCoordinateToUse);
gl_FragColor = mix(sharpImageColor, blurredImageColor, smoothstep(excludeCircleRadius - excludeBlurSize, excludeCircleRadius, distanceFromCenter));
}
该片段着色器从原始清晰图像和图像的高斯模糊版本中获取像素颜色值。然后它根据最后三行的逻辑在这些之间进行混合。
这些行中的第一行和第二行计算从您指定的中心坐标(图像死点默认为标准化坐标中的 (0.5, 0.5))到当前像素坐标的距离。最后一行使用smoothstep()
GLSL 函数在距中心点的距离在两个阈值之间行进时在 0 和 1 之间进行平滑插值,即内部清晰圆和外部完全模糊圆。操作员然后从模糊和锐利的颜色像素颜色之间mix()
获取输出并淡化以产生适当的输出。smoothstep()
如果您只想修改它以生成方形而不是圆形,则需要调整片段着色器中的两条中心线,以使距离基于线性 X 或 Y 坐标,而不是与中心点的毕达哥拉斯距离。为此,请将着色器更改为:
varying highp vec2 textureCoordinate;
varying highp vec2 textureCoordinate2;
uniform sampler2D inputImageTexture;
uniform sampler2D inputImageTexture2;
uniform lowp float excludeCircleRadius;
uniform lowp vec2 excludeCirclePoint;
uniform lowp float excludeBlurSize;
uniform highp float aspectRatio;
void main()
{
lowp vec4 sharpImageColor = texture2D(inputImageTexture, textureCoordinate);
lowp vec4 blurredImageColor = texture2D(inputImageTexture2, textureCoordinate2);
highp vec2 textureCoordinateToUse = vec2(textureCoordinate2.x, (textureCoordinate2.y * aspectRatio + 0.5 - 0.5 * aspectRatio));
textureCoordinateToUse = abs(excludeCirclePoint - textureCoordinateToUse);
highp float distanceFromCenter = max(textureCoordinateToUse.x, textureCoordinateToUse.y);
gl_FragColor = mix(sharpImageColor, blurredImageColor, smoothstep(excludeCircleRadius - excludeBlurSize, excludeCircleRadius, distanceFromCenter));
}
Gill 提到的这些行只是过滤器的输入参数,根本不控制它的循环性。
我将进一步修改它以生成一个通用的矩形形状作为读者的练习,但这应该为你如何做到这一点提供一个基础,并更多地解释这个着色器中的线条做什么。
做到了吗...矩形效果的代码就在这两行
blurFilter = [[GPUImageGaussianSelectiveBlurFilter alloc] init];
[(GPUImageGaussianSelectiveBlurFilter*)blurFilter setExcludeCircleRadius:80.0/320.0];
[(GPUImageGaussianSelectiveBlurFilter*)blurFilter setExcludeCirclePoint:CGPointMake(0.5f, 0.5f)];
// [(GPUImageGaussianSelectiveBlurFilter*)blurFilter setBlurSize:0.0f]; [(GPUImageGaussianSelectiveBlurFilter*)blurFilter setAspectRatio:0.0f];