Created
September 9, 2014 02:22
-
-
Save Coridyn/67a0ff75afaa0163f673 to your computer and use it in GitHub Desktop.
Bitwise XOR two images in PixelBender
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
<languageVersion : 1.0;> | |
kernel Crossfade | |
< namespace : "AIF"; | |
vendor : "Coridyn - https://github.com/Coridyn"; | |
version : 2; | |
description : "Perform a bitwise XOR of two images"; > | |
{ | |
input image4 inputImage; | |
input image4 diffImage; | |
output pixel4 dst; | |
// Getting an error in Pixel Bender Toolkit when this | |
// is a bool parameter so changing to int instead. | |
parameter int ignoreAlpha | |
< | |
defaultValue: 1; | |
minValue: 0; | |
maxValue: 1; | |
description: "If 1 then ignore the alpha channel when diffing."; | |
>; | |
// Bitwise algorithm was adapted from the "mathematical equivalents" formula on Wikipedia: | |
// http://en.wikipedia.org/wiki/Bitwise_operation#Mathematical_equivalents | |
// Macro for 2^n (it needs to be done a lot). | |
#define POW2(n) pow(2.0, n) | |
// Slight optimisation for the zeroth case - 2^0 = 1 is redundant so remove it. | |
#define XOR_i_0(x, y) ( mod( mod(floor(x), 2.0) + mod(floor(y), 2.0), 2.0 ) ) | |
// Calculations for a given "iteration". | |
#define XOR_i(x, y, i) ( POW2(i) * ( mod( mod(floor(x / POW2(i)), 2.0) + mod(floor(y / POW2(i)), 2.0), 2.0 ) ) ) | |
// Flash doesn't support loops. | |
// Unroll the loop by defining macros that call the next macro in the sequence. | |
// Adapted from: http://www.simppa.fi/blog/category/pixelbender/ | |
// http://www.simppa.fi/source/LoopMacros2.pbk | |
#define XOR_0(x, y) XOR_i_0(x, y) | |
#define XOR_1(x, y) XOR_i(x, y, 1.0) + XOR_0(x, y) | |
#define XOR_2(x, y) XOR_i(x, y, 2.0) + XOR_1(x, y) | |
#define XOR_3(x, y) XOR_i(x, y, 3.0) + XOR_2(x, y) | |
#define XOR_4(x, y) XOR_i(x, y, 4.0) + XOR_3(x, y) | |
#define XOR_5(x, y) XOR_i(x, y, 5.0) + XOR_4(x, y) | |
#define XOR_6(x, y) XOR_i(x, y, 6.0) + XOR_5(x, y) | |
#define XOR_7(x, y) XOR_i(x, y, 7.0) + XOR_6(x, y) | |
// Entry point for XOR function. | |
// This will calculate the XOR the current pixels. | |
#define XOR(x, y) XOR_7(x, y) | |
// PixelBender uses floats from 0.0 to 1.0 to represent 0 to 255 | |
// but the bitwise operations above work on ints. | |
// These macros convert between float and int values. | |
#define FLOAT_TO_INT(x) float(x) * 255.0 | |
#define INT_TO_FLOAT(x) float(x) / 255.0 | |
#define FLOAT_TO_INT_3(x) float3(x) * 255.0 | |
#define INT_TO_FLOAT_3(x) float3(x) / 255.0 | |
void evaluatePixel() | |
{ | |
// Acquire the pixel values from both images at the current location. | |
float4 frontPixel = sampleNearest(inputImage, outCoord()); | |
float4 backPixel = sampleNearest(diffImage, outCoord()); | |
// Set up the output variable - RGBA. | |
pixel4 result = pixel4(0.0, 0.0, 0.0, 1.0); | |
// In CPU mode we can "swizzle" the values to pass all three channels at once - cool! | |
// result.rgb = INT_TO_FLOAT_3 ( XOR(FLOAT_TO_INT_3(frontPixel.rgb), FLOAT_TO_INT_3(backPixel.rgb)) ); | |
// In Flash we need to calculate each channel separately. | |
result.r = INT_TO_FLOAT ( XOR(FLOAT_TO_INT(frontPixel.r), FLOAT_TO_INT(backPixel.r)) ); | |
result.g = INT_TO_FLOAT ( XOR(FLOAT_TO_INT(frontPixel.g), FLOAT_TO_INT(backPixel.g)) ); | |
result.b = INT_TO_FLOAT ( XOR(FLOAT_TO_INT(frontPixel.b), FLOAT_TO_INT(backPixel.b)) ); | |
if (ignoreAlpha == 0){ | |
// Don't diff alpha channel so we can actually see the result on screen! (because FF ^ FF = 0) | |
result.a = INT_TO_FLOAT ( XOR(FLOAT_TO_INT(frontPixel.a), FLOAT_TO_INT(backPixel.a)) ); | |
} | |
dst = result; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment