Skip to content

Instantly share code, notes, and snippets.

@jpsarda
Created December 17, 2013 10:06
Show Gist options
  • Save jpsarda/8002682 to your computer and use it in GitHub Desktop.
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 )
//
// 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
//
// 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