Created
August 21, 2014 20:46
-
-
Save ccgus/40b91ce357a4456561ad to your computer and use it in GitHub Desktop.
Color Wheel Thing
This file contains hidden or 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
var filter = [JSTQuickCIFilter quickFilterWithKernel:""" | |
bool isOdd(int v) { | |
float dividend = float(v) / 2.0; | |
return dividend != floor(dividend); | |
} | |
vec4 hsvToRgb(vec4 hsv) { | |
float h = hsv.r; | |
float s = hsv.g; | |
float v = hsv.b; | |
int i = int(floor(h)); | |
float f = isOdd(i) ? h - float(i) : 1.0 - (h - float(i)); | |
float m = v * (1.0 - s); | |
float n = v * (1.0 - s * f); | |
vec4 result = (i == 0) ? vec4(v, n, m, hsv.a) : ((i == 1) ? | |
vec4(n, v, m, hsv.a) : ((i == 2) ? vec4(m, v, n, hsv.a) : ((i == 3) ? | |
vec4(m, n, v, hsv.a) : ((i == 4) ? vec4(n, m, v, hsv.a) : ((i == 5) ? | |
vec4(v, m, n, hsv.a) : vec4(v, n, m, hsv.a)))))); | |
return (h == -1.0) ? vec4(v, v, v, hsv.a) : result; | |
} | |
kernel vec4 colorWheel(float radius, float segmentCount) { | |
float pi = 3.14159265; | |
vec2 center = vec2(radius, radius); | |
vec2 v0 = destCoord(); | |
vec2 v1 = vec2(v0.x, radius); | |
float a = distance(v0, v1); | |
float b = distance(v1, center); | |
float angle = atan(a,b); | |
angle = 1.570796326794897; | |
angle = (v0.x>radius)?((v0.y>radius)? | |
(atan(b,a)+pi/2.0):atan(a,b)+pi): | |
(v0.y<radius)?(atan(b,a)+(pi*1.5)):atan(a,b); | |
vec4 theColor = vec4(1.0); | |
float c = 360.0 / segmentCount; | |
float dist = length(destCoord() - center); | |
angle = dist < radius * 0.8 ? angle : (floor((angle*(180.0/pi) + c / 2.0) / c) * c) * (pi/180.0); | |
//angle = angle*(180.0/pi); | |
//angle = floor(angle / c) * c; | |
//angle = angle*(pi/180.0); | |
theColor.r = (angle * 3.0) / pi; | |
// make it a cirlce | |
theColor.a = clamp(radius - dist, 0.0, 1.0); | |
// cut out the middle | |
theColor.a = theColor.a - clamp(radius - (radius * .4) - dist, 0.0, theColor.a); | |
vec4 f = hsvToRgb(theColor); | |
// give it a white background. | |
vec4 D = vec4(1.0, 1.0, 1.0, 1.0); | |
vec4 S = f; | |
vec4 R = S + D*(1.0 - S.a); | |
f = R; | |
return premultiply(f); | |
} | |
"""]; | |
var radius = 400; | |
[filter addKernelArgument:[NSNumber numberWithInt:radius]]; | |
[filter addKernelArgument:[NSNumber numberWithInt:18]]; | |
var img = [filter outputImage]; | |
var f = [CIFilter filterWithName:@"CILanczosScaleTransform"]; | |
[f setDefaults]; | |
[f setValue:[NSNumber numberWithFloat:.5] forKey:@"inputScale"]; | |
[f setValue:img forKey:@"inputImage"]; | |
img = [f valueForKey:@"outputImage"]; | |
img = [img imageByApplyingTransform:CGAffineTransformMakeTranslation(10, 10)]; | |
//[JSTImageTools setShouldUseCICPURenderer:false]; | |
//[JSTImageTools setShouldUseCICPURenderer:true]; | |
[JSTImageTools viewCIImage:img inWindowNamed:"test" extent:CGRectMake(0, 0, radius*2, radius*2)]; | |
Given that GPUs hate branching conditionals in code (of which there appear to be 7 in your hsvToRgb function) you might want to take a look at branch-less HSV<->RGB conversion.
OpenGL-specific, but should be possible to translate to OpenCL in some way, I think:
http://lolengine.net/blog/2013/07/27/rgb-to-hsv-in-glsl
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Makes this guy: https://dl.dropboxusercontent.com/u/2115834/wheel2.png