kernel cubes_02 < namespace : "OMINO"; vendor : "omino.com"; version : 2; description : "cross sections of a cubical space, v2"; > { parameter float3 spin ; parameter float zoom ; parameter float4 translate ; parameter float perspective ; parameter float thickness ; output pixel4 dst; //input image4 unused; // during PBT debugging, un-comment this. // 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() { // start with simple x- and y-unit vectors float3 axis1 = float3(1.0,0.0,0.0); float3 axis2 = float3(0.0,1.0,0.0); // 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; // rotate around the x, y, and z axes, according to the parameters. axis1 *= spinM; axis2 *= spinM; 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 = oc.x * axis1 + oc.y * axis2; // perp is our viewing line, straight down from the screen, at 0,0 float3 perp = cross(axis1,axis2); // shift around in xyz, and the fourth param is directly away from YOU. p += translate.xyz; p += translate.w * perp; /* To get perspective, we dont cast along perp. * Rather, we cast from the eye-point through the * screen, and onward. */ float3 ray = (perspective * perp) - p; ray = normalize(ray); // which unit cell are we in? float3 pCell = floor(p); float3 pFrac = 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,ray); pFrac = perpStep - pFrac; pFrac = abs(pFrac); ray = abs(ray); float3 t = pFrac / ray; // 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); // a little trick -- make the planes have a thickness... if(pFrac.x < thickness || pFrac.y < thickness || pFrac.z < thickness) { float g = 1.0 - length(p) / 20.0; dst.rgb = float3(g,g,g); } dst.a = 1.0; } }