/* compiling with: ../../bin/diderotc --exec bug042.diderot produces error: uncaught exception Fail [Fail: lookup(_, l__t_217)] raised at common/phase-timer.sml:78.50-78.52 raised at common/phase-timer.sml:78.50-78.52 raised at c-util/tree-to-c.sml:69.29-69.70 */ // set camera, image, and rendering parameters input vec3 camEye = [0.09, 0, 10]; input vec3 camAt = [0.09, 0, 0]; input vec3 camUp = [-1, 0, 0]; input real camNearAtRel = -0.45; input real camFarAtRel = 0.45; input real camFOV = 4.85; input int iresU = 450; input int iresV = 200; input real refStep = 0.005; input real rayStep = 0.005; input vec3 lightVsp = [-2, -3, -4]; input real phongKa = 0.3; input real phongKd = 0.7; input real thickness = 0.017; input real isoval = -0.1; field#2(3)[] F = c4hexic ⊛ image("../data/wee-torus.nrrd"); function real alpha(real v, real g) = max(0, 1 - |v/g|/thickness); // (boilerplate) computation of camera and light info real camDist = |camAt - camEye|; real camNear = camNearAtRel + camDist; real camFar = camFarAtRel + camDist; vec3 camN = normalize(camAt - camEye); // away vec3 camU = normalize(camN × camUp); // right vec3 camV = camU × camN; // up real camVmax = tan(camFOV*π/360)*camDist; real camUmax = camVmax*iresU/iresV; vec3 light = transpose([camU,camV,camN])•normalize(lightVsp); strand raycast(int ui, int vi) { real rayU = lerp(-camUmax, camUmax, -0.5, ui, iresU-0.5); real rayV = lerp(camVmax, -camVmax, -0.5, vi, iresV-0.5); real rayN = camNear; vec3 rayVec = camN + (rayU*camU + rayV*camV)/camDist; real transp = 1; vec3 rgb = [0,0,0]; output vec4 rgba = [0,0,0,0]; update { vec3 x = camEye + rayN*rayVec; if (inside(x,F)) { vec3 grad = -∇F(x); real a = 0; real val = F(x) - isoval; a = alpha(val, |grad|); if (a > 0) { // we have some opacity a = 1 - pow(1-a, rayStep*|rayVec|/refStep); real depth = lerp(1.3, 0.6, camNear, rayN, camFar); real shade = max(0, normalize(grad)•light); rgb += transp*depth*a*(phongKa + phongKd*shade)*[1,1,1]; transp *= 1 - a; } } if (transp < 0.01) { // early ray termination transp = 0; stabilize; } if (rayN > camFar) { stabilize; } rayN = rayN + rayStep; } stabilize { real a = 1-transp; if (a > 0) rgba = [rgb[0]/a, rgb[1]/a, rgb[2]/a, a]; } } initially [ raycast(ui, vi) | vi in 0..iresV-1, ui in 0..iresU-1 ];