Skip to content

Commit

Permalink
Levels: put values into the shader as vectors
Browse files Browse the repository at this point in the history
Feels like that might be more performant.

Signed-off-by: Karl von Randow <[email protected]>
  • Loading branch information
karlvr committed Oct 18, 2012
1 parent c0eeadc commit fe2f55a
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 27 deletions.
10 changes: 7 additions & 3 deletions framework/Source/GPUImageLevelsFilter.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@

@interface GPUImageLevelsFilter : GPUImageFilter
{
GLint redUniform;
GLint greenUniform;
GLint blueUniform;
GLint minUniform;
GLint midUniform;
GLint maxUniform;
GLint minOutputUniform;
GLint maxOutputUniform;

GPUVector3 minVector, midVector, maxVector, minOutputVector, maxOutputVector;
}

- (void)setRedMin:(CGFloat)min gamma:(CGFloat)mid max:(CGFloat)max minOut:(CGFloat)minOut maxOut:(CGFloat)maxOut;
Expand Down
69 changes: 45 additions & 24 deletions framework/Source/GPUImageLevelsFilter.m
Original file line number Diff line number Diff line change
Expand Up @@ -12,25 +12,27 @@
** Details: http://blog.mouaif.org/2009/01/28/levels-control-shader/
*/

#define LevelsControlInputRange(color, minInput, maxInput) min(max(color - vec3(minInput), vec3(0.0)) / (vec3(maxInput) - vec3(minInput)), vec3(1.0))
#define LevelsControlInputRange(color, minInput, maxInput) min(max(color - minInput, vec3(0.0)) / (maxInput - minInput), vec3(1.0))
#define LevelsControlInput(color, minInput, gamma, maxInput) GammaCorrection(LevelsControlInputRange(color, minInput, maxInput), gamma)
#define LevelsControlOutputRange(color, minOutput, maxOutput) mix(vec3(minOutput), vec3(maxOutput), color)
#define LevelsControlOutputRange(color, minOutput, maxOutput) mix(minOutput, maxOutput, color)
#define LevelsControl(color, minInput, gamma, maxInput, minOutput, maxOutput) LevelsControlOutputRange(LevelsControlInput(color, minInput, gamma, maxInput), minOutput, maxOutput)

NSString *const kGPUImageLevelsFragmentShaderString = SHADER_STRING
(
varying highp vec2 textureCoordinate;

uniform sampler2D inputImageTexture;
uniform lowp float red[5];
uniform lowp float green[5];
uniform lowp float blue[5];
uniform lowp vec3 min;
uniform lowp vec3 mid;
uniform lowp vec3 max;
uniform lowp vec3 minOutput;
uniform lowp vec3 maxOutput;

void main()
{
lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);

gl_FragColor = vec4(LevelsControl(textureColor.rgb, vec3(red[0], green[0], blue[0]), vec3(red[1], green[1], blue[1]), vec3(red[2], green[2], blue[2]), vec3(red[3], green[3], blue[3]), vec3(red[4], green[4], blue[4])), textureColor.a);
gl_FragColor = vec4(LevelsControl(textureColor.rgb, min, mid, max, minOutput, maxOutput), textureColor.a);
}
);

Expand All @@ -46,9 +48,11 @@ - (id)init;
return nil;
}

redUniform = [filterProgram uniformIndex:@"red"];
greenUniform = [filterProgram uniformIndex:@"green"];
blueUniform = [filterProgram uniformIndex:@"blue"];
minUniform = [filterProgram uniformIndex:@"min"];
midUniform = [filterProgram uniformIndex:@"mid"];
maxUniform = [filterProgram uniformIndex:@"max"];
minOutputUniform = [filterProgram uniformIndex:@"minOutput"];
maxOutputUniform = [filterProgram uniformIndex:@"maxOutput"];

[self setRedMin:0.0 gamma:1.4 max:1.0 minOut:0.0 maxOut:1.0];
[self setGreenMin:0.0 gamma:0.8 max:1.0 minOut:0.0 maxOut:1.0];
Expand All @@ -57,6 +61,17 @@ - (id)init;
return self;
}

#pragma mark -
#pragma mark Helpers

- (void)updateUniforms {
[self setVec3:minVector forUniform:minUniform program:filterProgram];
[self setVec3:midVector forUniform:midUniform program:filterProgram];
[self setVec3:maxVector forUniform:maxUniform program:filterProgram];
[self setVec3:minOutputVector forUniform:minOutputUniform program:filterProgram];
[self setVec3:maxOutputVector forUniform:maxOutputUniform program:filterProgram];
}

#pragma mark -
#pragma mark Accessors

Expand All @@ -71,35 +86,41 @@ - (void)setMin:(CGFloat)min gamma:(CGFloat)mid max:(CGFloat)max {
}

- (void)setRedMin:(CGFloat)min gamma:(CGFloat)mid max:(CGFloat)max minOut:(CGFloat)minOut maxOut:(CGFloat)maxOut {
[self setFloat:min forUniform:redUniform program:filterProgram];
[self setFloat:mid forUniform:redUniform + 1 program:filterProgram];
[self setFloat:max forUniform:redUniform + 2 program:filterProgram];
[self setFloat:minOut forUniform:redUniform + 3 program:filterProgram];
[self setFloat:maxOut forUniform:redUniform + 4 program:filterProgram];
minVector.one = min;
midVector.one = mid;
maxVector.one = max;
minOutputVector.one = minOut;
maxOutputVector.one = maxOut;

[self updateUniforms];
}

- (void)setRedMin:(CGFloat)min gamma:(CGFloat)mid max:(CGFloat)max {
[self setRedMin:min gamma:mid max:max minOut:0.0 maxOut:1.0];
}

- (void)setGreenMin:(CGFloat)min gamma:(CGFloat)mid max:(CGFloat)max minOut:(CGFloat)minOut maxOut:(CGFloat)maxOut {
[self setFloat:min forUniform:greenUniform program:filterProgram];
[self setFloat:mid forUniform:greenUniform + 1 program:filterProgram];
[self setFloat:max forUniform:greenUniform + 2 program:filterProgram];
[self setFloat:minOut forUniform:greenUniform + 3 program:filterProgram];
[self setFloat:maxOut forUniform:greenUniform + 4 program:filterProgram];
minVector.two = min;
midVector.two = mid;
maxVector.two = max;
minOutputVector.two = minOut;
maxOutputVector.two = maxOut;

[self updateUniforms];
}

- (void)setGreenMin:(CGFloat)min gamma:(CGFloat)mid max:(CGFloat)max {
[self setGreenMin:min gamma:mid max:max minOut:0.0 maxOut:1.0];
}

- (void)setBlueMin:(CGFloat)min gamma:(CGFloat)mid max:(CGFloat)max minOut:(CGFloat)minOut maxOut:(CGFloat)maxOut {
[self setFloat:min forUniform:blueUniform program:filterProgram];
[self setFloat:mid forUniform:blueUniform + 1 program:filterProgram];
[self setFloat:max forUniform:blueUniform + 2 program:filterProgram];
[self setFloat:minOut forUniform:blueUniform + 3 program:filterProgram];
[self setFloat:maxOut forUniform:blueUniform + 4 program:filterProgram];
minVector.three = min;
midVector.three = mid;
maxVector.three = max;
minOutputVector.three = minOut;
maxOutputVector.three = maxOut;

[self updateUniforms];
}

- (void)setBlueMin:(CGFloat)min gamma:(CGFloat)mid max:(CGFloat)max {
Expand Down

0 comments on commit fe2f55a

Please sign in to comment.