I’ve just remembered- it’s possible to use curly-brace ( { } ) conditionals in GLSL, rather than the annoying ternary-style conditionals you have to use in CI Kernel Slang.
Having come to this exciting realisation this morning, I immediately set about modifying the polarPixellate code, taking the opportunity to add an extra function that would have been tricky to implement in a CIFilter.
This is the modified Fragment Shader I came up with:
// Control inputs
uniform float Angle;
uniform float AngleMin;
uniform float AngleWidth;
uniform float Radius;
uniform float RadiusMin;
uniform float RadiusWidth;
uniform vec2 Center;
uniform bool HideBg;
// Texture input
uniform sampler2D Texture;
void main()
{
bool bg = false;
// Normalised texture coords
vec2 texCoord = gl_TexCoord[0].xy;
// Shift origin to texture centre
vec2 normCoord;
normCoord.x = 2.0 * texCoord.x - Center.x;normCoord.y = 2.0 * texCoord.y - Center.y;
// Convert Cartesian to Polar coords
float r = length(normCoord);
float theta = atan(normCoord.y, normCoord.x);
// THE ACTUAL EFFECT
if (r > RadiusMin && r < (RadiusMin + RadiusWidth)) {
r = ceil(r / Radius) * Radius;
} else {
r = r;bg = true;
}
if (theta > AngleMin && theta < (AngleMin + AngleWidth)) {
theta = floor(theta / Angle) * Angle;
} else {
theta = theta;bg = true;
}
// Convert Polar back to Cartesian coords
normCoord.x = r * cos(theta);
normCoord.y = r * sin(theta);
// Shift origin back to bottom-left
texCoord.x = normCoord.x / 2.0 + (Center.x / 2.0);
texCoord.y = normCoord.y / 2.0 + (Center.y / 2.0);
// Output
if (bg == true && HideBg == true) {
gl_FragColor = vec4(0.0,0.0,0.0,0.0);
} else {
gl_FragColor = texture2D(Texture, texCoord);
}
}
The extra boolean variables ‘HideBg’ and ‘bg’ give the option of rendering transparency instead of the uneffected part of the image.
Having said how annoying I find using the ternary operator to do conditionals, it does make for neater-looking code. The traditional style of conditionals I’ve used above are so much easier to read, though, and have the big advantage that you can carry out more than one operation at a time (in this case, setting the values of r and bg and theta and bg within the conditionals).