Sunset Lake Software - Comments for "iPhone Differences" http://www.sunsetlakesoftware.com/forum/iphone-differences Comments for "iPhone Differences" en Here is a corrected fragment http://www.sunsetlakesoftware.com/forum/iphone-differences#comment-1559 <p>Here is a corrected fragment shader that works on iPhone 3GS and iPad1</p> <p><div class="geshifilter"><pre class="geshifilter-cocoa">NSString *const kBox8BlurFilterFragmentShaderString = SHADER_STRING ( precision highp float; &nbsp; uniform sampler2D inputImageTexture; &nbsp; varying highp vec2 centerTextureCoordinate; varying highp vec2 oneStepLeftTextureCoordinate; varying highp vec2 oneStepRightTextureCoordinate; varying highp vec2 twoStepsLeftTextureCoordinate; varying highp vec2 twoStepsRightTextureCoordinate; varying highp vec2 threeStepsLeftTextureCoordinate; varying highp vec2 threeStepsRightTextureCoordinate; varying highp vec2 fourStepsLeftTextureCoordinate; varying highp vec2 fourStepsRightTextureCoordinate; &nbsp; void main() { highp vec4 fragmentColor = texture2D(inputImageTexture, centerTextureCoordinate) * 0.5; fragmentColor += texture2D(inputImageTexture, oneStepLeftTextureCoordinate); fragmentColor += texture2D(inputImageTexture, oneStepRightTextureCoordinate); fragmentColor += texture2D(inputImageTexture, twoStepsLeftTextureCoordinate); fragmentColor += texture2D(inputImageTexture, twoStepsRightTextureCoordinate); &nbsp; fragmentColor += texture2D(inputImageTexture, threeStepsLeftTextureCoordinate); fragmentColor += texture2D(inputImageTexture, threeStepsRightTextureCoordinate); fragmentColor += texture2D(inputImageTexture, fourStepsLeftTextureCoordinate); fragmentColor += texture2D(inputImageTexture, fourStepsRightTextureCoordinate); &nbsp; gl_FragColor = fragmentColor / 8.5; } );</pre></div></p> pubDate Wed, 22 Aug 2012 13:03:03 +0000 dc:creator vipersnake guid false comment 1559 at http://www.sunsetlakesoftware.com Can someone double check this http://www.sunsetlakesoftware.com/forum/iphone-differences#comment-1544 <p>Can someone double check this code and see if there is something wrong with precision or rounding. It is just a super basic 8 radius box blur. On iPhone 4S it works flawlessly with 1 pass and radius of 1 (radius is actually a multiplier that reduces quality when higher than 1 and not really needed but I added it for convenience) however on 3GS you can see bands where it looks like it is skipping rows of pixels and it gets banded in gradients like blue sky. Bump it up to 2 passes and it compounds the banding (although it hides the striping)</p> <p>Blurpasses is used to run through the filter multiple times. </p> <p><div class="geshifilter"><pre class="geshifilter-cocoa">@interface GPUImageBox8BlurFilter : GPUImageTwoPassTextureSamplingFilter { GLint firstBlurSpreadUniform, secondBlurSpreadUniform; } &nbsp; @property(readwrite, nonatomic) NSUInteger blurPasses; @property(readwrite, nonatomic) float blurSpread; &nbsp; - (id)initWithFragmentShaderFromString:(NSString *)fragmentShaderString; &nbsp; &nbsp; @end &nbsp; &nbsp; NSString *const kBox8BlurFilterVertexShaderString = SHADER_STRING ( attribute highp vec4 position; attribute highp vec2 inputTextureCoordinate; &nbsp; uniform highp float texelWidthOffset; uniform highp float texelHeightOffset; &nbsp; uniform highp float blurSpread; &nbsp; varying highp vec2 centerTextureCoordinate; varying highp vec2 oneStepLeftTextureCoordinate; varying highp vec2 oneStepRightTextureCoordinate; varying highp vec2 twoStepsLeftTextureCoordinate; varying highp vec2 twoStepsRightTextureCoordinate; varying highp vec2 threeStepsLeftTextureCoordinate; varying highp vec2 threeStepsRightTextureCoordinate; varying highp vec2 fourStepsLeftTextureCoordinate; varying highp vec2 fourStepsRightTextureCoordinate; &nbsp; void main() { gl_Position = position; &nbsp; vec2 firstOffset = vec2(1.5 * texelWidthOffset, 1.5 * texelHeightOffset) * blurSpread; vec2 secondOffset = vec2(3.5 * texelWidthOffset, 3.5 * texelHeightOffset) * blurSpread; vec2 thirdOffset = vec2(5.5 * texelWidthOffset, 5.5 * texelHeightOffset) * blurSpread; vec2 fourthOffset = vec2(7.5 * texelWidthOffset, 7.5 * texelHeightOffset) * blurSpread; &nbsp; centerTextureCoordinate = inputTextureCoordinate; oneStepLeftTextureCoordinate = inputTextureCoordinate - firstOffset; oneStepRightTextureCoordinate = inputTextureCoordinate + firstOffset; twoStepsLeftTextureCoordinate = inputTextureCoordinate - secondOffset; twoStepsRightTextureCoordinate = inputTextureCoordinate + secondOffset; &nbsp; threeStepsLeftTextureCoordinate = inputTextureCoordinate - thirdOffset; threeStepsRightTextureCoordinate = inputTextureCoordinate + thirdOffset; fourStepsLeftTextureCoordinate = inputTextureCoordinate - fourthOffset; fourStepsRightTextureCoordinate = inputTextureCoordinate + fourthOffset; &nbsp; } ); &nbsp; &nbsp; NSString *const kBox8BlurFilterFragmentShaderString = SHADER_STRING ( precision highp float; &nbsp; uniform sampler2D inputImageTexture; &nbsp; varying highp vec2 centerTextureCoordinate; varying highp vec2 oneStepLeftTextureCoordinate; varying highp vec2 oneStepRightTextureCoordinate; varying highp vec2 twoStepsLeftTextureCoordinate; varying highp vec2 twoStepsRightTextureCoordinate; varying highp vec2 threeStepsLeftTextureCoordinate; varying highp vec2 threeStepsRightTextureCoordinate; varying highp vec2 fourStepsLeftTextureCoordinate; varying highp vec2 fourStepsRightTextureCoordinate; &nbsp; void main() { highp vec4 fragmentColor = texture2D(inputImageTexture, centerTextureCoordinate) * 0.06; fragmentColor += texture2D(inputImageTexture, oneStepLeftTextureCoordinate) * 0.1175; fragmentColor += texture2D(inputImageTexture, oneStepRightTextureCoordinate) * 0.1175; fragmentColor += texture2D(inputImageTexture, twoStepsLeftTextureCoordinate) * 0.1175; fragmentColor += texture2D(inputImageTexture, twoStepsRightTextureCoordinate) * 0.1175; &nbsp; fragmentColor += texture2D(inputImageTexture, threeStepsLeftTextureCoordinate) * 0.1175; fragmentColor += texture2D(inputImageTexture, threeStepsRightTextureCoordinate) * 0.1175; fragmentColor += texture2D(inputImageTexture, fourStepsLeftTextureCoordinate) * 0.1175; fragmentColor += texture2D(inputImageTexture, fourStepsRightTextureCoordinate) * 0.1175; &nbsp; gl_FragColor = fragmentColor; } ); &nbsp; &nbsp; @implementation GPUImageBox8BlurFilter &nbsp; @synthesize blurPasses = _blurPasses; @synthesize blurSpread = _blurSpread; &nbsp; - (id)init; { if (!(self = [self initWithFragmentShaderFromString:kBox8BlurFilterFragmentShaderString])) { return nil; } &nbsp; &nbsp; &nbsp; return self; } &nbsp; - (id)initWithFragmentShaderFromString:(NSString *)fragmentShaderString; { if (!(self = [super initWithFirstStageVertexShaderFromString:kBox8BlurFilterVertexShaderString firstStageFragmentShaderFromString:fragmentShaderString secondStageVertexShaderFromString:kBox8BlurFilterVertexShaderString secondStageFragmentShaderFromString:fragmentShaderString])) { return nil; } &nbsp; firstBlurSpreadUniform = [filterProgram uniformIndex:@&quot;blurSpread&quot;]; secondBlurSpreadUniform = [secondFilterProgram uniformIndex:@&quot;blurSpread&quot;]; &nbsp; self.blurSpread = 1.0; &nbsp; &nbsp; return self; } &nbsp; &nbsp; - (void)renderToTextureWithVertices:(const GLfloat *)vertices textureCoordinates:(const GLfloat *)textureCoordinates sourceTexture:(GLuint)sourceTexture; { [super renderToTextureWithVertices:vertices textureCoordinates:textureCoordinates sourceTexture:sourceTexture]; &nbsp; for (NSUInteger currentAdditionalBlurPass = 1; currentAdditionalBlurPass &lt; _blurPasses; currentAdditionalBlurPass++) { [super renderToTextureWithVertices:vertices textureCoordinates:[[self class] textureCoordinatesForRotation:kGPUImageNoRotation] sourceTexture:secondFilterOutputTexture]; } } &nbsp; - (void)setBlurSpread:(CGFloat)newValue; { _blurSpread = newValue; &nbsp; [GPUImageOpenGLESContext useImageProcessingContext]; [filterProgram use]; glUniform1f(firstBlurSpreadUniform, _blurSpread); &nbsp; [secondFilterProgram use]; glUniform1f(secondBlurSpreadUniform, _blurSpread); } &nbsp; &nbsp; @end</pre></div></p> pubDate Mon, 06 Aug 2012 20:33:37 +0000 dc:creator vipersnake guid false comment 1544 at http://www.sunsetlakesoftware.com Reducing the shader precision http://www.sunsetlakesoftware.com/forum/iphone-differences#comment-1504 <p>Reducing the shader precision definitely can introduce rounding artifacts on the various devices. They all handle rounding slightly different from one another, and lowering the precision to 8 bits in the lowp case could be exposing some of these differences.</p> pubDate Mon, 16 Jul 2012 17:30:09 +0000 dc:creator Brad Larson guid false comment 1504 at http://www.sunsetlakesoftware.com