topical media & game development
graphic-shader-sphere.pbj / pbk
<languageVersion : 1.0;>
kernel NewFilter
< namespace : "Sphere";
vendor : "Mr.doob";
version : 1;
description : "Sphere effect";
>
{
input image4 src;
output pixel4 dst;
parameter float2 imgSize
<
defaultValue : float2(512.0, 512.0);
minValue : float2(0.0,0.0);
maxValue : float2(512.0,512.0);
>;
parameter float2 center
<
defaultValue : float2(256.0, 256.0);
minValue : float2(0.0,0.0);
maxValue : float2(512.0,512.0);
>;
parameter float2 offset;
void evaluatePixel()
{
float2 pos = (outCoord() - center) / imgSize;
float pi = 3.141592653589793;
float a = atan(pos.y,pos.x);
float r = sqrt(pow(pos.x,2.0)+pow(pos.y,2.0));
float u = 0.0;
float v = 0.0;
float w = 0.0;
u += offset.x;
v += offset.y;
// This is where the magic happens
u += pos.x*(3.0-sqrt(4.0-5.0*r*r))/(r*r+1.0);
v += pos.y*(3.0-sqrt(4.0-5.0*r*r))/(r*r+1.0);
w += 1.7*(pos.x+pos.y+r*r-(pos.x+pos.y-1.0)*sqrt(4.0-5.0*r*r)/3.0)/(r*r+1.0);
// End of the magic
u *= imgSize.x;
v *= imgSize.y;
if (u < 0.0) u += imgSize.x * ceil(-u / imgSize.x);
if (v < 0.0) v += imgSize.y * ceil(-v / imgSize.y);
if (u > imgSize.x) u -= imgSize.x * floor(u / imgSize.x);
if (v > imgSize.y) v -= imgSize.y * floor(v / imgSize.y);
dst = sampleNearest(src,float2(u, v));
dst.rgb *= w;
}
}
(C) Æliens
20/2/2008
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.