topical media & game development
graphic-flex-image-effects-12-source-funhouseMirror.pbk / pbk
<languageVersion : 1.0;>
kernel FunhouseMirror
< namespace : "com.bobs27";
vendor : "Todd Yard";
version : 1;
description : "Distorts image like a warped funhouse mirror.";
>
{
input image4 source;
output pixel4 result;
parameter int warpBeginX
<
minValue: 0;
maxValue: 1024;
defaultValue: 0;
description: "The start of the image warp on the x axis.";
>;
parameter int warpEndX
<
minValue: 0;
maxValue: 1024;
defaultValue: 512;
description: "The end of the image warp on the x axis.";
>;
parameter float warpRatioX
<
minValue: 0.0;
maxValue: 1.0;
defaultValue: 0.5;
description: "The percent of the curved warp distortion weighted towards the beginning on the x axis.";
>;
parameter float distortionX
<
minValue: 0.0;
maxValue: 1.0;
defaultValue: 0.5;
description: "The amount of distortion to apply on the x axis.";
>;
parameter int warpBeginY
<
minValue: 0;
maxValue: 1024;
defaultValue: 0;
description: "The start of the image warp on the y axis.";
>;
parameter int warpEndY
<
minValue: 0;
maxValue: 1024;
defaultValue: 512;
description: "The end of the image warp on the y axis.";
>;
parameter float warpRatioY
<
minValue: 0.0;
maxValue: 1.0;
defaultValue: 0.5;
description: "The percent of the curved warp distortion weighted towards the beginning on the y axis.";
>;
parameter float distortionY
<
minValue: 0.0;
maxValue: 1.0;
defaultValue: 0.5;
description: "The amount of distortion to apply on the y axis.";
>;
void
evaluatePixel()
{
float2 coord = outCoord();
int firstHalf;
// only run this if we have distortion to apply on x axis
if (distortionX > 0.0) {
int x = int(coord.x);
float tX;
float fullWarpX = float(warpEndX - warpBeginX);
// only run this if pixel is within full warp range
if (x > warpBeginX && x < warpEndX) {
// find difference between pixel position and beginning of effect
tX = float(x - warpBeginX);
firstHalf = 0;
// this means we are in first half of effect
if (tX/fullWarpX <= warpRatioX) {
// we need to know the ration of just first half of effect
fullWarpX *= warpRatioX;
firstHalf = 1;
} else {
// we need to know the ration of second half of effect
fullWarpX = fullWarpX-(fullWarpX*warpRatioX);
// determine distance of pixel from end of effect
tX = float(warpEndX - x);
}
// taken from Robert Penner's easing equations
tX /= (fullWarpX/2.0);
if (tX < 1.0) {
tX = (fullWarpX/2.0)*tX*tX;
} else {
tX = -(fullWarpX/2.0)*((--tX)*(tX - 2.0) - 1.0);
}
// for first half of effect, add translation to beginning position of warp effect
if (firstHalf == 1) {
tX += float(warpBeginX);
// otherwise subtract it from end of effect
} else {
tX = float(warpEndX) - tX;
}
// final pixel position is interpolated between original and transformed position based on distortion amount
coord.x = mix(coord.x, tX, distortionX);
}
}
// only run this if we have distortion to apply on y axis
if (distortionY > 0.0) {
int y = int(coord.y);
float tY;
float fullWarpY = float(warpEndY - warpBeginY);
// only run this if pixel is within full warp range
if (y > warpBeginY && y < warpEndY) {
// find difference between pixel position and beginning of effect
tY = float(y - warpBeginY);
firstHalf = 0;
// this means we are in first half of effect
if (tY/fullWarpY <= warpRatioY) {
// we need to know the ration of just first half of effect
fullWarpY *= warpRatioY;
firstHalf = 1;
} else {
// we need to know the ration of second half of effect
fullWarpY = fullWarpY-(fullWarpY*warpRatioY);
// determine distance of pixel from end of effect
tY = float(warpEndY - y);
}
// taken from Robert Penner's easing equations
tY /= (fullWarpY/2.0);
if (tY < 1.0) {
tY = (fullWarpY/2.0)*tY*tY;
} else {
tY = -(fullWarpY/2.0)*((--tY)*(tY - 2.0) - 1.0);
}
// for first half of effect, add translation to beginning position of warp effect
if (firstHalf == 1) {
tY += float(warpBeginY);
// otherwise subtract it from end of effect
} else {
tY = float(warpEndY) - tY;
}
// final pixel position is interpolated between original and transformed position based on distortion amount
coord.y = mix(coord.y, tY, distortionY);
}
}
result = sampleNearest(source, coord);
}
}
(C) Æliens
18/6/2009
You may not copy or print any of this material without explicit permission of the author or the publisher.
In case of other copyright issues, contact the author.