模仿Flickr 使用GPUImage的实时相机滤镜(iOS源代码)

from: http://code1.okbase.net/codefile/GPUImagePoissonBlendFilter.m_2016011433675_220.htm


  1. #import "GPUImagePoissonBlendFilter.h"

  2. #if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE
  3. NSString *const kGPUImagePoissonBlendFragmentShaderString = SHADER_STRING
  4. (
  5. precision mediump float;

  6. varying vec2 textureCoordinate;
  7. varying vec2 leftTextureCoordinate;
  8. varying vec2 rightTextureCoordinate;
  9. varying vec2 topTextureCoordinate;
  10. varying vec2 bottomTextureCoordinate;

  11. varying vec2 textureCoordinate2;
  12. varying vec2 leftTextureCoordinate2;
  13. varying vec2 rightTextureCoordinate2;
  14. varying vec2 topTextureCoordinate2;
  15. varying vec2 bottomTextureCoordinate2;

  16. uniform sampler2D inputImageTexture;
  17. uniform sampler2D inputImageTexture2;

  18. uniform lowp float mixturePercent;

  19. void main()
  20. {
  21. vec4 centerColor = texture2D(inputImageTexture, textureCoordinate);
  22. vec3 bottomColor = texture2D(inputImageTexture, bottomTextureCoordinate).rgb;
  23. vec3 leftColor = texture2D(inputImageTexture, leftTextureCoordinate).rgb;
  24. vec3 rightColor = texture2D(inputImageTexture, rightTextureCoordinate).rgb;
  25. vec3 topColor = texture2D(inputImageTexture, topTextureCoordinate).rgb;

  26. vec4 centerColor2 = texture2D(inputImageTexture2, textureCoordinate2);
  27. vec3 bottomColor2 = texture2D(inputImageTexture2, bottomTextureCoordinate2).rgb;
  28. vec3 leftColor2 = texture2D(inputImageTexture2, leftTextureCoordinate2).rgb;
  29. vec3 rightColor2 = texture2D(inputImageTexture2, rightTextureCoordinate2).rgb;
  30. vec3 topColor2 = texture2D(inputImageTexture2, topTextureCoordinate2).rgb;

  31. vec3 meanColor = (bottomColor + leftColor + rightColor + topColor) / 4.0;
  32. vec3 diffColor = centerColor.rgb - meanColor;

  33. vec3 meanColor2 = (bottomColor2 + leftColor2 + rightColor2 + topColor2) / 4.0;
  34. vec3 diffColor2 = centerColor2.rgb - meanColor2;

  35. vec3 gradColor = (meanColor + diffColor2);

  36. gl_FragColor = vec4(mix(centerColor.rgb, gradColor, centerColor2.a * mixturePercent), centerColor.a);
  37. }
  38. );
  39. #else
  40. NSString *const kGPUImagePoissonBlendFragmentShaderString = SHADER_STRING
  41. (
  42. varying vec2 textureCoordinate;
  43. varying vec2 leftTextureCoordinate;
  44. varying vec2 rightTextureCoordinate;
  45. varying vec2 topTextureCoordinate;
  46. varying vec2 bottomTextureCoordinate;

  47. varying vec2 textureCoordinate2;
  48. varying vec2 leftTextureCoordinate2;
  49. varying vec2 rightTextureCoordinate2;
  50. varying vec2 topTextureCoordinate2;
  51. varying vec2 bottomTextureCoordinate2;

  52. uniform sampler2D inputImageTexture;
  53. uniform sampler2D inputImageTexture2;

  54. uniform float mixturePercent;

  55. void main()
  56. {
  57. vec4 centerColor = texture2D(inputImageTexture, textureCoordinate);
  58. vec3 bottomColor = texture2D(inputImageTexture, bottomTextureCoordinate).rgb;
  59. vec3 leftColor = texture2D(inputImageTexture, leftTextureCoordinate).rgb;
  60. vec3 rightColor = texture2D(inputImageTexture, rightTextureCoordinate).rgb;
  61. vec3 topColor = texture2D(inputImageTexture, topTextureCoordinate).rgb;

  62. vec4 centerColor2 = texture2D(inputImageTexture2, textureCoordinate2);
  63. vec3 bottomColor2 = texture2D(inputImageTexture2, bottomTextureCoordinate2).rgb;
  64. vec3 leftColor2 = texture2D(inputImageTexture2, leftTextureCoordinate2).rgb;
  65. vec3 rightColor2 = texture2D(inputImageTexture2, rightTextureCoordinate2).rgb;
  66. vec3 topColor2 = texture2D(inputImageTexture2, topTextureCoordinate2).rgb;

  67. vec3 meanColor = (bottomColor + leftColor + rightColor + topColor) / 4.0;
  68. vec3 diffColor = centerColor.rgb - meanColor;

  69. vec3 meanColor2 = (bottomColor2 + leftColor2 + rightColor2 + topColor2) / 4.0;
  70. vec3 diffColor2 = centerColor2.rgb - meanColor2;

  71. vec3 gradColor = (meanColor + diffColor2);

  72. gl_FragColor = vec4(mix(centerColor.rgb, gradColor, centerColor2.a * mixturePercent), centerColor.a);
  73. }
  74. );
  75. #endif

  76. @implementation GPUImagePoissonBlendFilter

  77. @synthesize mix = _mix;
  78. @synthesize numIterations = _numIterations;

  79. - (id)init;
  80. {
  81. if (!(self = [super initWithFragmentShaderFromString:kGPUImagePoissonBlendFragmentShaderString]))
  82. {
  83. return nil;
  84. }

  85. mixUniform = [filterProgram uniformIndex:@"mixturePercent"];
  86. self.mix = 0.5;

  87. self.numIterations = 10;

  88. return self;
  89. }

  90. - (void)setMix:(CGFloat)newValue;
  91. {
  92. _mix = newValue;

  93. [self setFloat:_mix forUniform:mixUniform program:filterProgram];
  94. }

  95. //- (void)setOutputFBO;
  96. //{
  97. // if (self.numIterations % 2 == 1) {
  98. // [self setSecondFilterFBO];
  99. // } else {
  100. // [self setFilterFBO];
  101. // }
  102. //}

  103. - (void)renderToTextureWithVertices:(const GLfloat *)vertices textureCoordinates:(const GLfloat *)textureCoordinates;
  104. {
  105. // Run the first stage of the two-pass filter
  106. [GPUImageContext setActiveShaderProgram:filterProgram];

  107. [super renderToTextureWithVertices:vertices textureCoordinates:textureCoordinates];

  108. for (int pass = 1; pass < self.numIterations; pass++) {

  109. if (pass % 2 == 0) {

  110. [GPUImageContext setActiveShaderProgram:filterProgram];

  111. // TODO: This will over-unlock the incoming framebuffer
  112. [super renderToTextureWithVertices:vertices textureCoordinates:[[self class] textureCoordinatesForRotation:kGPUImageNoRotation]];
  113. } else {
  114. // Run the second stage of the two-pass filter
  115. secondOutputFramebuffer = [[GPUImageContext sharedFramebufferCache] fetchFramebufferForSize:[self sizeOfFBO] textureOptions:self.outputTextureOptions onlyTexture:NO];
  116. [secondOutputFramebuffer activateFramebuffer];

  117. [GPUImageContext setActiveShaderProgram:filterProgram];

  118. glClearColor(backgroundColorRed, backgroundColorGreen, backgroundColorBlue, backgroundColorAlpha);
  119. glClear(GL_COLOR_BUFFER_BIT);

  120. glActiveTexture(GL_TEXTURE2);
  121. glBindTexture(GL_TEXTURE_2D, [outputFramebuffer texture]);
  122. glUniform1i(filterInputTextureUniform, 2);

  123. glActiveTexture(GL_TEXTURE3);
  124. glBindTexture(GL_TEXTURE_2D, [secondInputFramebuffer texture]);
  125. glUniform1i(filterInputTextureUniform2, 3);

  126. glVertexAttribPointer(filterPositionAttribute, 2, GL_FLOAT, 0, 0, vertices);
  127. glVertexAttribPointer(filterTextureCoordinateAttribute, 2, GL_FLOAT, 0, 0, [[self class] textureCoordinatesForRotation:kGPUImageNoRotation]);
  128. glVertexAttribPointer(filterSecondTextureCoordinateAttribute, 2, GL_FLOAT, 0, 0, [[self class] textureCoordinatesForRotation:inputRotation2]);

  129. glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
  130. }
  131. }
  132. }

  133. @end// 鐗堟潈灞炰簬鍘熶綔鑰?// http://code4app.com (cn) http://code4app.net (en)
  134. // 鍙戝竷浠g爜浜庢渶涓撲笟鐨勬簮鐮佸垎浜綉绔? Code4App.com
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值