GPUImage滤镜中的shader代码分析,及自定义滤镜
2014-05-27 10:08
507 查看
GPUImage由于使用GPU,顾其在滤镜染色的时候真正使用的是Open GL的shader语言。下面我们就GPUImagePinchDistortionFilter分析这些shader语言。
GPUImagePinchDistortionFilter是一个实现收缩失真,凹面镜效果的滤镜,头文件代码如下:
我们来分析一下。
首先,这个类必须继承于GPUImageFilter(这个必须,要不然就没法用)。
其次,这个类有三个参数:center表示效果所在圆的中心点,radius表示所在圆的半径(注意范围是-2.0到2.0),scale表示缩放倍数(当scale小于0的时候,中间缩小,周围放大;当scale大于0的时候,中间放大,周围缩小)。
最后,我们需要关注一个单位(这个很重要,要不然后面的shader代码就很迷茫了)。细心的朋友肯定会发现圆半径的范围是-2.0到2.0。很显然,这不是像素单位,要不然这了滤镜效果范围也太小了,和没有效果一样)。事实上,在shader语言中,半径是真实半径除以图片矩形的宽(横着图片的为高),记realRadio/targetWidth(横着的图片为realRadio/targetHeight);
源文件中,我们重点分析shader语句kGPUImagePinchDistortionFragmentShaderString。在这里,我直接加注释。
上面我在shader中加了注释,实际的shader代码不要加注释(因为代码长度占GPU内存,且中文可能会出问题)。
从上面我们可以到,我们可以通过修改第三方的库来增加自己的滤镜。事实上,GPUImage已经提供了滤镜扩展的接口,我们不需要修改它的库。类GPUImageFilter有一个初始化函数initWithFragmentShaderFromFile:可以加载自定义以fsh为后缀文件中的shader代码。例如:
而Shader.fsh的代码为:
GPUImagePinchDistortionFilter是一个实现收缩失真,凹面镜效果的滤镜,头文件代码如下:
#import "GPUImageFilter.h" /** Creates a pinch distortion of the image */ @interface GPUImagePinchDistortionFilter : GPUImageFilter { GLint aspectRatioUniform, radiusUniform, centerUniform, scaleUniform; } /** The center about which to apply the distortion, with a default of (0.5, 0.5) */ @property(readwrite, nonatomic) CGPoint center; /** The radius of the distortion, ranging from 0.0 to 2.0, with a default of 1.0 */ @property(readwrite, nonatomic) CGFloat radius; /** The amount of distortion to apply, from -2.0 to 2.0, with a default of 0.5 */ @property(readwrite, nonatomic) CGFloat scale; @end
我们来分析一下。
首先,这个类必须继承于GPUImageFilter(这个必须,要不然就没法用)。
其次,这个类有三个参数:center表示效果所在圆的中心点,radius表示所在圆的半径(注意范围是-2.0到2.0),scale表示缩放倍数(当scale小于0的时候,中间缩小,周围放大;当scale大于0的时候,中间放大,周围缩小)。
最后,我们需要关注一个单位(这个很重要,要不然后面的shader代码就很迷茫了)。细心的朋友肯定会发现圆半径的范围是-2.0到2.0。很显然,这不是像素单位,要不然这了滤镜效果范围也太小了,和没有效果一样)。事实上,在shader语言中,半径是真实半径除以图片矩形的宽(横着图片的为高),记realRadio/targetWidth(横着的图片为realRadio/targetHeight);
源文件中,我们重点分析shader语句kGPUImagePinchDistortionFragmentShaderString。在这里,我直接加注释。
NSString *const kGPUImagePinchDistortionFragmentShaderString = SHADER_STRING ( varying highp vec2 textureCoordinate;/*变形后的图片的坐标*/ uniform sampler2D inputImageTexture;/*需要变形的图片*/ uniform highp float aspectRatio;/*坐标变换的系数,在shader坐标系中width永远是1.0,height做相应的等比缩放*/ uniform highp vec2 center;/*参数,中心点*/ uniform highp float radius;/*参数,圆半径*/ uniform highp float scale;/*参数,缩放倍数*/ void main() { highp vec2 textureCoordinateToUse = vec2(textureCoordinate.x, (textureCoordinate.y * aspectRatio + 0.5 - 0.5 * aspectRatio));/*计算可以用于计算到中心距离的坐标*/ highp float dist = distance(center, textureCoordinateToUse);/*计算到中心的距离*/ textureCoordinateToUse = textureCoordinate;/*将坐标恢复到shader坐标系*/ if (dist < radius)/*在圆内*/ { textureCoordinateToUse -= center;/*需要相对中心的坐标*/ highp float percent = 1.0 + ((0.5 - dist) / 0.5) * scale;/*缩放的程度*/ textureCoordinateToUse = textureCoordinateToUse * percent;/*坐标缩放*/ textureCoordinateToUse += center;/*需要绝对坐标*/ gl_FragColor = texture2D(inputImageTexture, textureCoordinateToUse );/*gl_FragColor表示变形后坐标textureCoordinate的颜色*/ </span> } else/*不再园内*/ { gl_FragColor = texture2D(inputImageTexture, textureCoordinate );/*gl_FragColor表示变形后坐标textureCoordinate的颜色*/ } } );
上面我在shader中加了注释,实际的shader代码不要加注释(因为代码长度占GPU内存,且中文可能会出问题)。
从上面我们可以到,我们可以通过修改第三方的库来增加自己的滤镜。事实上,GPUImage已经提供了滤镜扩展的接口,我们不需要修改它的库。类GPUImageFilter有一个初始化函数initWithFragmentShaderFromFile:可以加载自定义以fsh为后缀文件中的shader代码。例如:
GPUImageFilter *filter1 = [[[GPUImageFilter alloc] initWithFragmentShaderFromFile:@"Shader1"] autorelease];
而Shader.fsh的代码为:
varying highp vec2 textureCoordinate; uniform sampler2D inputImageTexture; void main() { lowp vec3 tc = vec3(1.0, 0.0, 0.0); lowp vec3 pixcol = texture2D(inputImageTexture, textureCoordinate).rgb; lowp vec3 colors[3]; colors[0] = vec3(0.0, 0.0, 1.0); colors[1] = vec3(1.0, 1.0, 0.0); colors[2] = vec3(1.0, 0.0, 0.0); mediump float lum = (pixcol.r + pixcol.g + pixcol.b) / 3.0; int ix = (lum < 0.5)? 0:1; tc = mix(colors[ix], colors[ix + 1], (lum - float(ix) * 0.5) / 0.5); gl_FragColor = vec4(tc, 1.0); }
相关文章推荐
- GPUImage滤镜中的shader代码分析,及自定义滤镜
- GPUImage滤镜中的shader代码分析,及自定义滤镜
- GPUImage滤镜中的shader代码分析,及自定义滤镜
- iOS GPUImage之自定义滤镜
- GPUImage 自定义滤镜
- GPUImage做滤镜
- AMD兼容图像处理器(GPU)代码生成用于Java:案例分析
- 转载 :Android中ImageButton自定义按钮的按下效果的代码实现方法,附网上2种经典解决方法。
- Android中ImageButton自定义按钮的按下效果的代码实现方法
- 用自定义代码分析来标准开发人员的开发规范
- FFmpeg滤镜代码级分析
- FFmpeg滤镜代码级分析
- struts2自定义拦截器实现的分析说明附带代码
- Android中ImageButton自定义按钮的按下效果的代码实现方法,附网上2种经典解决方法。
- iOS 第三方自定义Alertview项目MBProcessHud中的重要代码分析
- Android ImageButton自定义按钮的按下效果的代码实现方法
- 用GPUImage开启相机并且开启滤镜效果
- 自定义MembershipProvider,asp.net2.0 Forms验证-代码及分析
- Track Image Loading效果代码分析
- Android中ImageButton自定义按钮的按下效果的代码实现方法,附网上2种经典解决方法。