Created
December 17, 2013 10:06
-
-
Save jpsarda/8002682 to your computer and use it in GitHub Desktop.
GPUImageSaturationExposureGammaRGBFilter is a combined GPUImageFilter. You use only one filter (one FBO) instead of using 4 chained filters (4 FBO) which is much better for memory usage. ( see why I did this https://github.com/BradLarson/GPUImage/issues/1346 )
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// GPUSaturationExposureGammaRGBFilter.h | |
// bonnemine | |
// | |
// Created by Jean-Philippe SARDA on 12/17/13. | |
// Copyright (c) 2013 My Little Paris. All rights reserved. | |
// | |
#import "GPUImageFilter.h" | |
@interface GPUImageSaturationExposureGammaRGBFilter : GPUImageFilter | |
{ | |
GLint redUniform; | |
GLint greenUniform; | |
GLint blueUniform; | |
GLint gammaUniform; | |
GLint saturationUniform; | |
GLint exposureUniform; | |
} | |
// Normalized values by which each color channel is multiplied. The range is from 0.0 up, with 1.0 as the default. | |
@property (readwrite, nonatomic) CGFloat red; | |
@property (readwrite, nonatomic) CGFloat green; | |
@property (readwrite, nonatomic) CGFloat blue; | |
// Gamma ranges from 0.0 to 3.0, with 1.0 as the normal level | |
@property(readwrite, nonatomic) CGFloat gamma; | |
// Saturation ranges from 0.0 (fully desaturated) to 2.0 (max saturation), with 1.0 as the normal level | |
@property(readwrite, nonatomic) CGFloat saturation; | |
// Exposure ranges from -10.0 to 10.0, with 0.0 as the normal level | |
@property(readwrite, nonatomic) CGFloat exposure; | |
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// GPUSaturationExposureGammaRGBFilter.m | |
// bonnemine | |
// | |
// Created by Jean-Philippe SARDA on 12/17/13. | |
// Copyright (c) 2013 My Little Paris. All rights reserved. | |
// | |
#import "GPUImageSaturationExposureGammaRGBFilter.h" | |
#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE | |
NSString *const kGPUImageSaturationExposureGammaRGBFragmentShaderString = SHADER_STRING | |
( | |
varying highp vec2 textureCoordinate; | |
uniform sampler2D inputImageTexture; | |
uniform highp float redAdjustment; | |
uniform highp float greenAdjustment; | |
uniform highp float blueAdjustment; | |
uniform lowp float gamma; | |
uniform lowp float saturation; | |
uniform highp float exposure; | |
// Values from "Graphics Shaders: Theory and Practice" by Bailey and Cunningham | |
const mediump vec3 luminanceWeighting = vec3(0.2125, 0.7154, 0.0721); | |
void main() | |
{ | |
//rgb | |
highp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); | |
gl_FragColor = vec4(textureColor.r * redAdjustment, textureColor.g * greenAdjustment, textureColor.b * blueAdjustment, textureColor.a); | |
//gamma | |
textureColor = gl_FragColor; //texture2D(inputImageTexture, textureCoordinate); | |
gl_FragColor = vec4(pow(textureColor.rgb, vec3(gamma)), textureColor.w); | |
//exposure | |
textureColor = gl_FragColor; //texture2D(inputImageTexture, textureCoordinate); | |
gl_FragColor = vec4(textureColor.rgb * pow(2.0, exposure), textureColor.w); | |
//saturation | |
textureColor = gl_FragColor; //texture2D(inputImageTexture, textureCoordinate); | |
lowp float luminance = dot(textureColor.rgb, luminanceWeighting); | |
lowp vec3 greyScaleColor = vec3(luminance); | |
gl_FragColor = vec4(mix(greyScaleColor, textureColor.rgb, saturation), textureColor.w); | |
} | |
); | |
#else | |
// NOT TESTED | |
// NOT TESTED | |
// NOT TESTED | |
// NOT TESTED | |
// NOT TESTED | |
// NOT TESTED | |
NSString *const kGPUImageSaturationExposureGammaRGBFragmentShaderString = SHADER_STRING | |
( | |
varying vec2 textureCoordinate; | |
uniform sampler2D inputImageTexture; | |
uniform float redAdjustment; | |
uniform float greenAdjustment; | |
uniform float blueAdjustment; | |
uniform float gamma; | |
uniform float saturation; | |
uniform float exposure; | |
// Values from "Graphics Shaders: Theory and Practice" by Bailey and Cunningham | |
const vec3 luminanceWeighting = vec3(0.2125, 0.7154, 0.0721); | |
void main() | |
{ | |
//rgb | |
vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); | |
gl_FragColor = vec4(textureColor.r * redAdjustment, textureColor.g * greenAdjustment, textureColor.b * blueAdjustment, textureColor.a); | |
//gamma | |
textureColor = gl_FragColor; | |
gl_FragColor = vec4(pow(textureColor.rgb, vec3(gamma)), textureColor.w); | |
//exposure | |
textureColor = gl_FragColor; | |
gl_FragColor = vec4(textureColor.rgb * pow(2.0, exposure), textureColor.w); | |
//saturation | |
textureColor = gl_FragColor; | |
float luminance = dot(textureColor.rgb, luminanceWeighting); | |
vec3 greyScaleColor = vec3(luminance); | |
gl_FragColor = vec4(mix(greyScaleColor, textureColor.rgb, saturation), textureColor.w); | |
} | |
); | |
#endif | |
@implementation GPUImageSaturationExposureGammaRGBFilter | |
@synthesize red = _red, blue = _blue, green = _green; | |
@synthesize exposure = _exposure; | |
@synthesize saturation = _saturation; | |
@synthesize gamma = _gamma; | |
#pragma mark - | |
#pragma mark Initialization and teardown | |
- (id)init; | |
{ | |
if (!(self = [super initWithFragmentShaderFromString:kGPUImageSaturationExposureGammaRGBFragmentShaderString])) | |
{ | |
return nil; | |
} | |
redUniform = [filterProgram uniformIndex:@"redAdjustment"]; | |
self.red = 1.0; | |
greenUniform = [filterProgram uniformIndex:@"greenAdjustment"]; | |
self.green = 1.0; | |
blueUniform = [filterProgram uniformIndex:@"blueAdjustment"]; | |
self.blue = 1.0; | |
gammaUniform = [filterProgram uniformIndex:@"gamma"]; | |
self.gamma = 1.0; | |
saturationUniform = [filterProgram uniformIndex:@"saturation"]; | |
self.saturation = 1.0; | |
exposureUniform = [filterProgram uniformIndex:@"exposure"]; | |
self.exposure = 0.0; | |
return self; | |
} | |
#pragma mark - | |
#pragma mark Accessors | |
- (void)setExposure:(CGFloat)newValue; | |
{ | |
_exposure = newValue; | |
[self setFloat:_exposure forUniform:exposureUniform program:filterProgram]; | |
} | |
- (void)setSaturation:(CGFloat)newValue; | |
{ | |
_saturation = newValue; | |
[self setFloat:_saturation forUniform:saturationUniform program:filterProgram]; | |
} | |
- (void)setGamma:(CGFloat)newValue; | |
{ | |
_gamma = newValue; | |
[self setFloat:_gamma forUniform:gammaUniform program:filterProgram]; | |
} | |
- (void)setRed:(CGFloat)newValue; | |
{ | |
_red = newValue; | |
[self setFloat:_red forUniform:redUniform program:filterProgram]; | |
} | |
- (void)setGreen:(CGFloat)newValue; | |
{ | |
_green = newValue; | |
[self setFloat:_green forUniform:greenUniform program:filterProgram]; | |
} | |
- (void)setBlue:(CGFloat)newValue; | |
{ | |
_blue = newValue; | |
[self setFloat:_blue forUniform:blueUniform program:filterProgram]; | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment