PageRenderTime 28ms CodeModel.GetById 0ms RepoModel.GetById 0ms app.codeStats 0ms

/Dependencies/GPUImage/Source/GPUImageDilationFilter.m

https://gitlab.com/Mr.Tomato/VideoEffects
Objective C | 431 lines | 355 code | 76 blank | 0 comment | 4 complexity | e221ff1b0609b67573de2de4dfc82d17 MD5 | raw file
  1. #import "GPUImageDilationFilter.h"
  2. @implementation GPUImageDilationFilter
  3. NSString *const kGPUImageDilationRadiusOneVertexShaderString = SHADER_STRING
  4. (
  5. attribute vec4 position;
  6. attribute vec2 inputTextureCoordinate;
  7. uniform float texelWidthOffset;
  8. uniform float texelHeightOffset;
  9. varying vec2 centerTextureCoordinate;
  10. varying vec2 oneStepPositiveTextureCoordinate;
  11. varying vec2 oneStepNegativeTextureCoordinate;
  12. void main()
  13. {
  14. gl_Position = position;
  15. vec2 offset = vec2(texelWidthOffset, texelHeightOffset);
  16. centerTextureCoordinate = inputTextureCoordinate;
  17. oneStepNegativeTextureCoordinate = inputTextureCoordinate - offset;
  18. oneStepPositiveTextureCoordinate = inputTextureCoordinate + offset;
  19. }
  20. );
  21. NSString *const kGPUImageDilationRadiusTwoVertexShaderString = SHADER_STRING
  22. (
  23. attribute vec4 position;
  24. attribute vec2 inputTextureCoordinate;
  25. uniform float texelWidthOffset;
  26. uniform float texelHeightOffset;
  27. varying vec2 centerTextureCoordinate;
  28. varying vec2 oneStepPositiveTextureCoordinate;
  29. varying vec2 oneStepNegativeTextureCoordinate;
  30. varying vec2 twoStepsPositiveTextureCoordinate;
  31. varying vec2 twoStepsNegativeTextureCoordinate;
  32. void main()
  33. {
  34. gl_Position = position;
  35. vec2 offset = vec2(texelWidthOffset, texelHeightOffset);
  36. centerTextureCoordinate = inputTextureCoordinate;
  37. oneStepNegativeTextureCoordinate = inputTextureCoordinate - offset;
  38. oneStepPositiveTextureCoordinate = inputTextureCoordinate + offset;
  39. twoStepsNegativeTextureCoordinate = inputTextureCoordinate - (offset * 2.0);
  40. twoStepsPositiveTextureCoordinate = inputTextureCoordinate + (offset * 2.0);
  41. }
  42. );
  43. NSString *const kGPUImageDilationRadiusThreeVertexShaderString = SHADER_STRING
  44. (
  45. attribute vec4 position;
  46. attribute vec2 inputTextureCoordinate;
  47. uniform float texelWidthOffset;
  48. uniform float texelHeightOffset;
  49. varying vec2 centerTextureCoordinate;
  50. varying vec2 oneStepPositiveTextureCoordinate;
  51. varying vec2 oneStepNegativeTextureCoordinate;
  52. varying vec2 twoStepsPositiveTextureCoordinate;
  53. varying vec2 twoStepsNegativeTextureCoordinate;
  54. varying vec2 threeStepsPositiveTextureCoordinate;
  55. varying vec2 threeStepsNegativeTextureCoordinate;
  56. void main()
  57. {
  58. gl_Position = position;
  59. vec2 offset = vec2(texelWidthOffset, texelHeightOffset);
  60. centerTextureCoordinate = inputTextureCoordinate;
  61. oneStepNegativeTextureCoordinate = inputTextureCoordinate - offset;
  62. oneStepPositiveTextureCoordinate = inputTextureCoordinate + offset;
  63. twoStepsNegativeTextureCoordinate = inputTextureCoordinate - (offset * 2.0);
  64. twoStepsPositiveTextureCoordinate = inputTextureCoordinate + (offset * 2.0);
  65. threeStepsNegativeTextureCoordinate = inputTextureCoordinate - (offset * 3.0);
  66. threeStepsPositiveTextureCoordinate = inputTextureCoordinate + (offset * 3.0);
  67. }
  68. );
  69. NSString *const kGPUImageDilationRadiusFourVertexShaderString = SHADER_STRING
  70. (
  71. attribute vec4 position;
  72. attribute vec2 inputTextureCoordinate;
  73. uniform float texelWidthOffset;
  74. uniform float texelHeightOffset;
  75. varying vec2 centerTextureCoordinate;
  76. varying vec2 oneStepPositiveTextureCoordinate;
  77. varying vec2 oneStepNegativeTextureCoordinate;
  78. varying vec2 twoStepsPositiveTextureCoordinate;
  79. varying vec2 twoStepsNegativeTextureCoordinate;
  80. varying vec2 threeStepsPositiveTextureCoordinate;
  81. varying vec2 threeStepsNegativeTextureCoordinate;
  82. varying vec2 fourStepsPositiveTextureCoordinate;
  83. varying vec2 fourStepsNegativeTextureCoordinate;
  84. void main()
  85. {
  86. gl_Position = position;
  87. vec2 offset = vec2(texelWidthOffset, texelHeightOffset);
  88. centerTextureCoordinate = inputTextureCoordinate;
  89. oneStepNegativeTextureCoordinate = inputTextureCoordinate - offset;
  90. oneStepPositiveTextureCoordinate = inputTextureCoordinate + offset;
  91. twoStepsNegativeTextureCoordinate = inputTextureCoordinate - (offset * 2.0);
  92. twoStepsPositiveTextureCoordinate = inputTextureCoordinate + (offset * 2.0);
  93. threeStepsNegativeTextureCoordinate = inputTextureCoordinate - (offset * 3.0);
  94. threeStepsPositiveTextureCoordinate = inputTextureCoordinate + (offset * 3.0);
  95. fourStepsNegativeTextureCoordinate = inputTextureCoordinate - (offset * 4.0);
  96. fourStepsPositiveTextureCoordinate = inputTextureCoordinate + (offset * 4.0);
  97. }
  98. );
  99. #if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE
  100. NSString *const kGPUImageDilationRadiusOneFragmentShaderString = SHADER_STRING
  101. (
  102. precision lowp float;
  103. varying vec2 centerTextureCoordinate;
  104. varying vec2 oneStepPositiveTextureCoordinate;
  105. varying vec2 oneStepNegativeTextureCoordinate;
  106. uniform sampler2D inputImageTexture;
  107. void main()
  108. {
  109. float centerIntensity = texture2D(inputImageTexture, centerTextureCoordinate).r;
  110. float oneStepPositiveIntensity = texture2D(inputImageTexture, oneStepPositiveTextureCoordinate).r;
  111. float oneStepNegativeIntensity = texture2D(inputImageTexture, oneStepNegativeTextureCoordinate).r;
  112. lowp float maxValue = max(centerIntensity, oneStepPositiveIntensity);
  113. maxValue = max(maxValue, oneStepNegativeIntensity);
  114. gl_FragColor = vec4(vec3(maxValue), 1.0);
  115. }
  116. );
  117. NSString *const kGPUImageDilationRadiusTwoFragmentShaderString = SHADER_STRING
  118. (
  119. precision lowp float;
  120. varying vec2 centerTextureCoordinate;
  121. varying vec2 oneStepPositiveTextureCoordinate;
  122. varying vec2 oneStepNegativeTextureCoordinate;
  123. varying vec2 twoStepsPositiveTextureCoordinate;
  124. varying vec2 twoStepsNegativeTextureCoordinate;
  125. uniform sampler2D inputImageTexture;
  126. void main()
  127. {
  128. float centerIntensity = texture2D(inputImageTexture, centerTextureCoordinate).r;
  129. float oneStepPositiveIntensity = texture2D(inputImageTexture, oneStepPositiveTextureCoordinate).r;
  130. float oneStepNegativeIntensity = texture2D(inputImageTexture, oneStepNegativeTextureCoordinate).r;
  131. float twoStepsPositiveIntensity = texture2D(inputImageTexture, twoStepsPositiveTextureCoordinate).r;
  132. float twoStepsNegativeIntensity = texture2D(inputImageTexture, twoStepsNegativeTextureCoordinate).r;
  133. lowp float maxValue = max(centerIntensity, oneStepPositiveIntensity);
  134. maxValue = max(maxValue, oneStepNegativeIntensity);
  135. maxValue = max(maxValue, twoStepsPositiveIntensity);
  136. maxValue = max(maxValue, twoStepsNegativeIntensity);
  137. gl_FragColor = vec4(vec3(maxValue), 1.0);
  138. }
  139. );
  140. NSString *const kGPUImageDilationRadiusThreeFragmentShaderString = SHADER_STRING
  141. (
  142. precision lowp float;
  143. varying vec2 centerTextureCoordinate;
  144. varying vec2 oneStepPositiveTextureCoordinate;
  145. varying vec2 oneStepNegativeTextureCoordinate;
  146. varying vec2 twoStepsPositiveTextureCoordinate;
  147. varying vec2 twoStepsNegativeTextureCoordinate;
  148. varying vec2 threeStepsPositiveTextureCoordinate;
  149. varying vec2 threeStepsNegativeTextureCoordinate;
  150. uniform sampler2D inputImageTexture;
  151. void main()
  152. {
  153. float centerIntensity = texture2D(inputImageTexture, centerTextureCoordinate).r;
  154. float oneStepPositiveIntensity = texture2D(inputImageTexture, oneStepPositiveTextureCoordinate).r;
  155. float oneStepNegativeIntensity = texture2D(inputImageTexture, oneStepNegativeTextureCoordinate).r;
  156. float twoStepsPositiveIntensity = texture2D(inputImageTexture, twoStepsPositiveTextureCoordinate).r;
  157. float twoStepsNegativeIntensity = texture2D(inputImageTexture, twoStepsNegativeTextureCoordinate).r;
  158. float threeStepsPositiveIntensity = texture2D(inputImageTexture, threeStepsPositiveTextureCoordinate).r;
  159. float threeStepsNegativeIntensity = texture2D(inputImageTexture, threeStepsNegativeTextureCoordinate).r;
  160. lowp float maxValue = max(centerIntensity, oneStepPositiveIntensity);
  161. maxValue = max(maxValue, oneStepNegativeIntensity);
  162. maxValue = max(maxValue, twoStepsPositiveIntensity);
  163. maxValue = max(maxValue, twoStepsNegativeIntensity);
  164. maxValue = max(maxValue, threeStepsPositiveIntensity);
  165. maxValue = max(maxValue, threeStepsNegativeIntensity);
  166. gl_FragColor = vec4(vec3(maxValue), 1.0);
  167. }
  168. );
  169. NSString *const kGPUImageDilationRadiusFourFragmentShaderString = SHADER_STRING
  170. (
  171. precision lowp float;
  172. varying vec2 centerTextureCoordinate;
  173. varying vec2 oneStepPositiveTextureCoordinate;
  174. varying vec2 oneStepNegativeTextureCoordinate;
  175. varying vec2 twoStepsPositiveTextureCoordinate;
  176. varying vec2 twoStepsNegativeTextureCoordinate;
  177. varying vec2 threeStepsPositiveTextureCoordinate;
  178. varying vec2 threeStepsNegativeTextureCoordinate;
  179. varying vec2 fourStepsPositiveTextureCoordinate;
  180. varying vec2 fourStepsNegativeTextureCoordinate;
  181. uniform sampler2D inputImageTexture;
  182. void main()
  183. {
  184. float centerIntensity = texture2D(inputImageTexture, centerTextureCoordinate).r;
  185. float oneStepPositiveIntensity = texture2D(inputImageTexture, oneStepPositiveTextureCoordinate).r;
  186. float oneStepNegativeIntensity = texture2D(inputImageTexture, oneStepNegativeTextureCoordinate).r;
  187. float twoStepsPositiveIntensity = texture2D(inputImageTexture, twoStepsPositiveTextureCoordinate).r;
  188. float twoStepsNegativeIntensity = texture2D(inputImageTexture, twoStepsNegativeTextureCoordinate).r;
  189. float threeStepsPositiveIntensity = texture2D(inputImageTexture, threeStepsPositiveTextureCoordinate).r;
  190. float threeStepsNegativeIntensity = texture2D(inputImageTexture, threeStepsNegativeTextureCoordinate).r;
  191. float fourStepsPositiveIntensity = texture2D(inputImageTexture, fourStepsPositiveTextureCoordinate).r;
  192. float fourStepsNegativeIntensity = texture2D(inputImageTexture, fourStepsNegativeTextureCoordinate).r;
  193. lowp float maxValue = max(centerIntensity, oneStepPositiveIntensity);
  194. maxValue = max(maxValue, oneStepNegativeIntensity);
  195. maxValue = max(maxValue, twoStepsPositiveIntensity);
  196. maxValue = max(maxValue, twoStepsNegativeIntensity);
  197. maxValue = max(maxValue, threeStepsPositiveIntensity);
  198. maxValue = max(maxValue, threeStepsNegativeIntensity);
  199. maxValue = max(maxValue, fourStepsPositiveIntensity);
  200. maxValue = max(maxValue, fourStepsNegativeIntensity);
  201. gl_FragColor = vec4(vec3(maxValue), 1.0);
  202. }
  203. );
  204. #else
  205. NSString *const kGPUImageDilationRadiusOneFragmentShaderString = SHADER_STRING
  206. (
  207. varying vec2 centerTextureCoordinate;
  208. varying vec2 oneStepPositiveTextureCoordinate;
  209. varying vec2 oneStepNegativeTextureCoordinate;
  210. uniform sampler2D inputImageTexture;
  211. void main()
  212. {
  213. float centerIntensity = texture2D(inputImageTexture, centerTextureCoordinate).r;
  214. float oneStepPositiveIntensity = texture2D(inputImageTexture, oneStepPositiveTextureCoordinate).r;
  215. float oneStepNegativeIntensity = texture2D(inputImageTexture, oneStepNegativeTextureCoordinate).r;
  216. float maxValue = max(centerIntensity, oneStepPositiveIntensity);
  217. maxValue = max(maxValue, oneStepNegativeIntensity);
  218. gl_FragColor = vec4(vec3(maxValue), 1.0);
  219. }
  220. );
  221. NSString *const kGPUImageDilationRadiusTwoFragmentShaderString = SHADER_STRING
  222. (
  223. varying vec2 centerTextureCoordinate;
  224. varying vec2 oneStepPositiveTextureCoordinate;
  225. varying vec2 oneStepNegativeTextureCoordinate;
  226. varying vec2 twoStepsPositiveTextureCoordinate;
  227. varying vec2 twoStepsNegativeTextureCoordinate;
  228. uniform sampler2D inputImageTexture;
  229. void main()
  230. {
  231. float centerIntensity = texture2D(inputImageTexture, centerTextureCoordinate).r;
  232. float oneStepPositiveIntensity = texture2D(inputImageTexture, oneStepPositiveTextureCoordinate).r;
  233. float oneStepNegativeIntensity = texture2D(inputImageTexture, oneStepNegativeTextureCoordinate).r;
  234. float twoStepsPositiveIntensity = texture2D(inputImageTexture, twoStepsPositiveTextureCoordinate).r;
  235. float twoStepsNegativeIntensity = texture2D(inputImageTexture, twoStepsNegativeTextureCoordinate).r;
  236. float maxValue = max(centerIntensity, oneStepPositiveIntensity);
  237. maxValue = max(maxValue, oneStepNegativeIntensity);
  238. maxValue = max(maxValue, twoStepsPositiveIntensity);
  239. maxValue = max(maxValue, twoStepsNegativeIntensity);
  240. gl_FragColor = vec4(vec3(maxValue), 1.0);
  241. }
  242. );
  243. NSString *const kGPUImageDilationRadiusThreeFragmentShaderString = SHADER_STRING
  244. (
  245. varying vec2 centerTextureCoordinate;
  246. varying vec2 oneStepPositiveTextureCoordinate;
  247. varying vec2 oneStepNegativeTextureCoordinate;
  248. varying vec2 twoStepsPositiveTextureCoordinate;
  249. varying vec2 twoStepsNegativeTextureCoordinate;
  250. varying vec2 threeStepsPositiveTextureCoordinate;
  251. varying vec2 threeStepsNegativeTextureCoordinate;
  252. uniform sampler2D inputImageTexture;
  253. void main()
  254. {
  255. float centerIntensity = texture2D(inputImageTexture, centerTextureCoordinate).r;
  256. float oneStepPositiveIntensity = texture2D(inputImageTexture, oneStepPositiveTextureCoordinate).r;
  257. float oneStepNegativeIntensity = texture2D(inputImageTexture, oneStepNegativeTextureCoordinate).r;
  258. float twoStepsPositiveIntensity = texture2D(inputImageTexture, twoStepsPositiveTextureCoordinate).r;
  259. float twoStepsNegativeIntensity = texture2D(inputImageTexture, twoStepsNegativeTextureCoordinate).r;
  260. float threeStepsPositiveIntensity = texture2D(inputImageTexture, threeStepsPositiveTextureCoordinate).r;
  261. float threeStepsNegativeIntensity = texture2D(inputImageTexture, threeStepsNegativeTextureCoordinate).r;
  262. float maxValue = max(centerIntensity, oneStepPositiveIntensity);
  263. maxValue = max(maxValue, oneStepNegativeIntensity);
  264. maxValue = max(maxValue, twoStepsPositiveIntensity);
  265. maxValue = max(maxValue, twoStepsNegativeIntensity);
  266. maxValue = max(maxValue, threeStepsPositiveIntensity);
  267. maxValue = max(maxValue, threeStepsNegativeIntensity);
  268. gl_FragColor = vec4(vec3(maxValue), 1.0);
  269. }
  270. );
  271. NSString *const kGPUImageDilationRadiusFourFragmentShaderString = SHADER_STRING
  272. (
  273. varying vec2 centerTextureCoordinate;
  274. varying vec2 oneStepPositiveTextureCoordinate;
  275. varying vec2 oneStepNegativeTextureCoordinate;
  276. varying vec2 twoStepsPositiveTextureCoordinate;
  277. varying vec2 twoStepsNegativeTextureCoordinate;
  278. varying vec2 threeStepsPositiveTextureCoordinate;
  279. varying vec2 threeStepsNegativeTextureCoordinate;
  280. varying vec2 fourStepsPositiveTextureCoordinate;
  281. varying vec2 fourStepsNegativeTextureCoordinate;
  282. uniform sampler2D inputImageTexture;
  283. void main()
  284. {
  285. float centerIntensity = texture2D(inputImageTexture, centerTextureCoordinate).r;
  286. float oneStepPositiveIntensity = texture2D(inputImageTexture, oneStepPositiveTextureCoordinate).r;
  287. float oneStepNegativeIntensity = texture2D(inputImageTexture, oneStepNegativeTextureCoordinate).r;
  288. float twoStepsPositiveIntensity = texture2D(inputImageTexture, twoStepsPositiveTextureCoordinate).r;
  289. float twoStepsNegativeIntensity = texture2D(inputImageTexture, twoStepsNegativeTextureCoordinate).r;
  290. float threeStepsPositiveIntensity = texture2D(inputImageTexture, threeStepsPositiveTextureCoordinate).r;
  291. float threeStepsNegativeIntensity = texture2D(inputImageTexture, threeStepsNegativeTextureCoordinate).r;
  292. float fourStepsPositiveIntensity = texture2D(inputImageTexture, fourStepsPositiveTextureCoordinate).r;
  293. float fourStepsNegativeIntensity = texture2D(inputImageTexture, fourStepsNegativeTextureCoordinate).r;
  294. float maxValue = max(centerIntensity, oneStepPositiveIntensity);
  295. maxValue = max(maxValue, oneStepNegativeIntensity);
  296. maxValue = max(maxValue, twoStepsPositiveIntensity);
  297. maxValue = max(maxValue, twoStepsNegativeIntensity);
  298. maxValue = max(maxValue, threeStepsPositiveIntensity);
  299. maxValue = max(maxValue, threeStepsNegativeIntensity);
  300. maxValue = max(maxValue, fourStepsPositiveIntensity);
  301. maxValue = max(maxValue, fourStepsNegativeIntensity);
  302. gl_FragColor = vec4(vec3(maxValue), 1.0);
  303. }
  304. );
  305. #endif
  306. #pragma mark -
  307. #pragma mark Initialization and teardown
  308. - (id)initWithRadius:(NSUInteger)dilationRadius;
  309. {
  310. NSString *fragmentShaderForThisRadius = nil;
  311. NSString *vertexShaderForThisRadius = nil;
  312. switch (dilationRadius)
  313. {
  314. case 0:
  315. case 1:
  316. {
  317. vertexShaderForThisRadius = kGPUImageDilationRadiusOneVertexShaderString;
  318. fragmentShaderForThisRadius = kGPUImageDilationRadiusOneFragmentShaderString;
  319. }; break;
  320. case 2:
  321. {
  322. vertexShaderForThisRadius = kGPUImageDilationRadiusTwoVertexShaderString;
  323. fragmentShaderForThisRadius = kGPUImageDilationRadiusTwoFragmentShaderString;
  324. }; break;
  325. case 3:
  326. {
  327. vertexShaderForThisRadius = kGPUImageDilationRadiusThreeVertexShaderString;
  328. fragmentShaderForThisRadius = kGPUImageDilationRadiusThreeFragmentShaderString;
  329. }; break;
  330. case 4:
  331. {
  332. vertexShaderForThisRadius = kGPUImageDilationRadiusFourVertexShaderString;
  333. fragmentShaderForThisRadius = kGPUImageDilationRadiusFourFragmentShaderString;
  334. }; break;
  335. default:
  336. {
  337. vertexShaderForThisRadius = kGPUImageDilationRadiusFourVertexShaderString;
  338. fragmentShaderForThisRadius = kGPUImageDilationRadiusFourFragmentShaderString;
  339. }; break;
  340. }
  341. if (!(self = [super initWithFirstStageVertexShaderFromString:vertexShaderForThisRadius firstStageFragmentShaderFromString:fragmentShaderForThisRadius secondStageVertexShaderFromString:vertexShaderForThisRadius secondStageFragmentShaderFromString:fragmentShaderForThisRadius]))
  342. {
  343. return nil;
  344. }
  345. return self;
  346. }
  347. - (id)init;
  348. {
  349. if (!(self = [self initWithRadius:1]))
  350. {
  351. return nil;
  352. }
  353. return self;
  354. }
  355. @end