kernel crazySpots < namespace : "OMINO"; vendor : "omino.com"; version : 1; description : "cubes with dots?"; > { parameter float3 spin ; parameter float zoom ; parameter float4 translate ; input image4 unused; 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() { // concatenate three simple rotations to spinM float3x3 spinXM = float3x3(1,0,0,0,cos(spin.x),spin.x,0,-sin(spin.x),cos(spin.x)); float3x3 spinYM = float3x3(cos(spin.y),0,sin(spin.y),0,1,0,-sin(spin.y),0,cos(spin.y)); float3x3 spinZM = float3x3(cos(spin.z), sin(spin.z), 0,-sin(spin.z), cos(spin.z), 0, 0, 0, 1 ); float3x3 spinM = spinXM * spinYM * spinZM; float2 center = float2(400,500) / 2.0; // YUCK! hardcoded for my blog entry. float2 oc = (outCoord() - center) / zoom; // adjust "input coordinates" // we rotate the requested coordinate by 3 axes, giving the // R3 point on the plane of the screen (after the mesh is turnt) float3 p = float3(oc.x,oc.y,0) * spinM; // perp is our viewing line, straight down from the screen. float3 perp = float3(0,0,1) * spinM; // shift around in xyz, and the fourth param is directly away from YOU. p += translate.xyz; p += translate.w * perp; // which unit cell are we in? 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) float z; // which of 3 planes do we intersect? if(t.x >= 0.0) z = t.x; if(t.y >= 0.0 && t.y < t.x) z = t.y; if(t.z >= 0.0 && t.z < t.x && t.z < t.y) z = t.z; // depth cueing id done by distance into the cell. dst.rgb = float3(1,1,1) * (1.0 - z/1.7); dst.a = 1.0; // but forget all that. Are we in the inner sphere or no? float r = distance(p,float3(.5,.5,.5)); if(r < .4) dst.rgb = float3(0,0,0); } }