kernel sphereSection < namespace : "AIF"; vendor : "omino.com"; version : 2; description : "spheresection"; > { parameter float3 xAxisColor; parameter float3 yAxisColor; parameter float3 zAxisColor; parameter float3 edgeColor; parameter float edgeThickness; parameter float invert; parameter float2 dstsize ; parameter float3 spin; parameter float plunge ; parameter float cellDensity ; parameter float radius ; input image4 unused; // only to establish the input size output pixel4 dst; // 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() { float3 axis1 = float3(1.0,0.0,0.0); float3 axis2 = float3(0.0,1.0,0.0); float3x3 elevR = float3x3(1,0,0,0,cos(spin.x),sin(spin.x),0,-sin(spin.x),cos(spin.x)); float3x3 bearR = float3x3(cos(spin.y), sin(spin.y), 0,-sin(spin.y), cos(spin.y), 0, 0, 0, 1 ); float3x3 yamR = float3x3(cos(spin.z),0,sin(spin.z),0,1,0,-sin(spin.z),0,cos(spin.z)); axis1 *= elevR * bearR * yamR; axis2 *= elevR * bearR * yamR; float cellDensity2 = cellDensity / 2000.0; float2 oc = (outCoord() - dstsize / 2.0) * cellDensity2; //oc -= outSize/2.0; float3 p = oc.x * axis1 + oc.y * axis2; float3 perp = cross(axis1,axis2); float radiusInPixels = radius * dstsize.x; float plungeMore = radiusInPixels * radiusInPixels * cellDensity2 * cellDensity2 - oc.x * oc.x - oc.y * oc.y; if(plungeMore < 0.0) plungeMore = 0.0; plungeMore = sqrt(plungeMore); // Strangely, PBT and Flash have opposite senses here. // Some sort of arithmetic bug, probably, making them // behave differently. if(invert > 0.0) plungeMore = -plungeMore; p += (plunge - plungeMore) * perp; float3 pCell = floor(p); p = mod(p,1.0); /* Our cell size, here, is 1x1x1. Perp is a unit vector representing the direction we're now looking, the ray cast if you will. We like to cast to the planes x=0, y=0, z=0, because it's easy. So first we'll see if each element of perp is negative, and, if so, flip it and reposition our starting point, like p.x := 1-p.x. */ /* this is the cleanest way, but Flash doesn't allow bools, and ?: doesn't seem to work in this mixed-dimension way either bool3 perpNeg = lessThan(perp,float3(0,0,0)); p = perpNeg ? 1.0 - p : p; perp = abs(perp); */ /* We can be clever with step and abs, though. */ float3 perpStep = 1.0 - step(0.0,perp); p = perpStep - p; p = abs(p); perp = abs(perp); float3 t = p / perp; // casts from p, in direction of perp, to zero. T is how far to each plane (x,y, or z) float3 co = float3(0,0,0); float z; if(t.x >= 0.0) { co = xAxisColor; z = t.x; } if(t.y >= 0.0 && t.y < t.x) { co = yAxisColor; z = t.y; } if(t.z >= 0.0 && t.z < t.x && t.z < t.y) { co = zAxisColor; z = t.z; } dst.rgb = co * (1.0 - z/1.2); dst.a = 1.0; if(t.x < edgeThickness || t.y < edgeThickness || t.z < edgeThickness) dst.rgb = edgeColor; if(plungeMore == 0.0) dst.xyz *= 0.0; } }