日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

GPUImage滤镜中的shader代码分析,及自定义滤镜

發布時間:2025/7/25 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 GPUImage滤镜中的shader代码分析,及自定义滤镜 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

from:?http://blog.csdn.net/vegerjiangsir/article/details/27172143


GPUImage由于使用GPU,顧其在濾鏡染色的時候真正使用的是Open GL的shader語言。下面我們就GPUImagePinchDistortionFilter分析這些shader語言。

GPUImagePinchDistortionFilter是一個實現收縮失真,凹面鏡效果濾鏡,頭文件代碼如下:

[objc]?view plaincopyprint?
  • #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。在這里,我直接加注釋。

    [objc]?view plaincopyprint?
  • 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代碼。例如:

    [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代码分析,及自定义滤镜的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。