生活随笔
收集整理的這篇文章主要介紹了
GPUImage滤镜中的shader代码分析,及自定义滤镜
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
from:?http://blog.csdn.net/vegerjiangsir/article/details/27172143
GPUImage由于使用GPU,顧其在濾鏡染色的時候真正使用的是Open GL的shader語言。下面我們就GPUImagePinchDistortionFilter分析這些shader語言。
GPUImagePinchDistortionFilter是一個實現(xiàn)收縮失真,凹面鏡效果的濾鏡,頭文件代碼如下:
[objc]?view plaincopyprint?
#import?"GPUImageFilter.h"?? ?? ? ?? @interface?GPUImagePinchDistortionFilter?:?GPUImageFilter?? {?? ????GLint?aspectRatioUniform,?radiusUniform,?centerUniform,?scaleUniform;?? }?? ?? ? ?? @property(readwrite,?nonatomic)?CGPoint?center;?? ? ?? @property(readwrite,?nonatomic)?CGFloat?radius;?? ? ?? @property(readwrite,?nonatomic)?CGFloat?scale;?? ?? @end??
我們來分析一下。
首先,這個類必須繼承于GPUImageFilter(這個必須,要不然就沒法用)。
其次,這個類有三個參數(shù):center表示效果所在圓的中心點,radius表示所在圓的半徑(注意范圍是-2.0到2.0),scale表示縮放倍數(shù)(當scale小于0的時候,中間縮小,周圍放大;當scale大于0的時候,中間放大,周圍縮小)。
最后,我們需要關注一個單位(這個很重要,要不然后面的shader代碼就很迷茫了)。細心的朋友肯定會發(fā)現(xiàn)圓半徑的范圍是-2.0到2.0。很顯然,這不是像素單位,要不然這了濾鏡效果范圍也太小了,和沒有效果一樣)。事實上,在shader語言中,半徑是真實半徑除以圖片矩形的寬(橫著圖片的為高),記realRadio/targetWidth(橫著的圖片為realRadio/targetHeight);
源文件中,我們重點分析shader語句kGPUImagePinchDistortionFragmentShaderString。在這里,我直接加注釋。
[objc]?view plaincopyprint?
NSString?*const?kGPUImagePinchDistortionFragmentShaderString?=?SHADER_STRING?? (?? ?varying?highp?vec2?textureCoordinate;?? ??? ?uniform?sampler2D?inputImageTexture;?? ??? ?uniform?highp?float?aspectRatio;?? ?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;?? ??????? ?????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?);?? </span>?????}?? ?????else?? ?????{?? ?????????gl_FragColor?=?texture2D(inputImageTexture,?textureCoordinate?);?? ?????}?? ?}?? );??
上面我在shader中加了注釋,實際的shader代碼不要加注釋(因為代碼長度占GPU內存,且中文可能會出問題)。
從上面我們可以到,我們可以通過修改第三方的庫來增加自己的濾鏡。事實上,GPUImage已經提供了濾鏡擴展的接口,我們不需要修改它的庫。類GPUImageFilter有一個初始化函數(shù)initWithFragmentShaderFromFile:可以加載自定義以fsh為后綴文件中的shader代碼。例如:
[objc]?view plaincopyprint?
GPUImageFilter?*filter1?=?[[[GPUImageFilter?alloc]?initWithFragmentShaderFromFile:@"Shader1"]?autorelease];??
而Shader.fsh的代碼為:
[plain]?view plaincopyprint?
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代码分析,及自定义滤镜的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。