Psychadelic
From Adobe Labs
This AIF filter lets you create some trippy psychadelic images. It is Flash-compliant (if the AIF compiler is to be trusted in that regard).
Check out this example (a before/after of the band Olivia Tremor Control getting a little extra psyched).
/*****************************************************************************
*
* 2007 Brett Walker (brett at brettwalker dot net)
*
****************************************************************************/
// psychadelic
// Create some transcendental images.
kernel psychadelic
{
// A boolean input parameter used to specify whether we should use the
// overlay image or not.
parameter bool isDoubleImage;
// An input parameter to specify the radius of the swoosh effect.
// For this parameter, we're using metadata to indicate the minimum,
// maximum, and default values, so that the tools can set the values
// in the correctly in the UI for the filter.
parameter float radius
<
minValue:float(0.1);
maxValue:float(4096.0);
defaultValue:float(500.0);
>;
// An input parameter to specify the center of the swoosh effect.
// As above, we're using metadata to indicate the minimum,
// maximum, and default values, so that the tools can set the values
// in the correctly in the UI for the filter.
parameter float2 center
<
minValue:float2(0.0, 0.0);
maxValue:float2(2048.0, 2048.0);
defaultValue:float2(1475.0, 0.0);
>;
parameter float4 color1
<
minValue:float4(0.0, 0.0, 0.0, 0.0);
maxValue:float4(100.0, 100.0, 100.0, 10.0);
defaultValue:float4(10.0, 10.0, 10.0, 10.0);
>;
// evaluatePixel(): The function of the filter that actually does the
// processing of the image. This function is called once
// for each pixel of the output image.
void
evaluatePixel(in image4 inputImage, out float4 dst)
{
// Convert the dimension into a floating point value for use in
// arithmetic. To avoid sinister issues, all type conversions are
// required to be explicit.
float dimAsFloat = float(1);
// calculate where we are relative to the center of the twirl
float2 relativePos = outCoord() - center;
float distFromCenter = length( relativePos );
distFromCenter /= radius;
// Truncate the pixel location to the value at the top right corner of
// the square.
float2 sc = floor(outCoord() / float2(dimAsFloat, dimAsFloat));
sc *= dimAsFloat * distFromCenter;
// sample the input at the location and set the output to the sampled
// value.
pixel4 outputPixel = sampleNearest(inputImage, sc);
float denominator = 0.0;
float4 colorAccumulator = float4(0.0, 0.0, 0.0, 0.0);
// Access the nine pixels surrounding the current coordinate location.
// We access the pixels in the following order assuming that the
// current coordinate is located in the center of the matrix:
// 1 4 7
// 2 5 8
// 3 6 9
colorAccumulator += sampleNearest(inputImage,
outCoord() + float2(-1.0, -1.0));
denominator++;
colorAccumulator += sampleNearest(inputImage,
outCoord() + float2(-1.0, 0.0));
denominator++;
colorAccumulator += sampleNearest(inputImage,
outCoord() + float2(-1.0, 1.0));
denominator++;
colorAccumulator += sampleNearest(inputImage,
outCoord() + float2(0.0, -1.0));
denominator++;
colorAccumulator += sampleNearest(inputImage,
outCoord());
denominator++;
colorAccumulator += sampleNearest(inputImage,
outCoord() + float2(0.0, 1.0));
denominator++;
colorAccumulator += sampleNearest(inputImage,
outCoord() + float2(1.0, -1.0));
denominator++;
colorAccumulator += sampleNearest(inputImage,
outCoord() + float2(1.0, 0.0));
denominator++;
colorAccumulator += sampleNearest(inputImage,
outCoord() + float2(1.0, 1.0));
denominator++;
// calculate the resultant pixel value which is the accumulated color
// divided by the total number of pixels.
// In this case, the denominator is 9.
colorAccumulator *= color1;
float4 colorMod = isDoubleImage ? (colorAccumulator) : color1;
dst = ( colorMod * outputPixel / denominator);
}
}
Brett Walker 03:45, 2 Oct 2007 (PDT)
