// vr.diderot // // volume rendering example in Diderot // input string dataFile; // name of dataset input real stepSz; // size of steps input vec3 lightDir; input vec3 lightRGB; input vec3 eye; // location of eye point input vec3 orig; // location of pixel (0,0) input vec3 cVec; // vector between pixels horizontally input vec3 rVec; // vector between pixels vertically input real ka; input real kd; input real ks; input real sh; image(3)[] img = load (dataFile); //field#1(3)[] F = convolve (bspln3, img); field#2(3)[] F = convolve (bspln3, img); field#0(1)[4] txf = convolve (tent, load("txf-rgba.nrrd")); actor RayCast (int row, int col) { //// * : int x vec3 -> vec3 //// + : vec3 x vec3 -> vec3 vec3 pos = orig + real(row)*rVec + real(col)*cVec; //// |()| : vec -> real //// - : vec3 x vec3 -> vec3 //// / : vec3 x real -> vec3 vec3 dir = (pos - eye)/|pos - eye|; real t = 0.0; vec3 rayRGB = [0.0, 0.0, 0.0]; real rayTransp = 1.0; update { if (inside (pos,F)) { //// @ : field x vec3 -> real real val = F@pos; //// D : field -> field vec3 grad = (D F)@pos; vec3 norm = grad/|grad|; vec3 halfDir = (lightDir - dir)/|lightDir - dir|; vec4 matRGBA = txf@[val]; vec3 matRGB = [matRGBA[0],matRGBA[1],matRGBA[2]]; //// dot : vec3 x vec3 -> real real ldotn = dot(lightDir, norm); real hdotn = dot(halfDir, norm); // hey the per-component multiplication is in matRGB*lightRGB //// * : real x vec3 -> vec3 //// modulate : vec3 x vec3 -> vec3 //// + : vec3 x vec3 -> vec3 //// pow : real x real -> real vec3 pntRGB = (ka + kd*ldotn)*modulate(matRGB,lightRGB) + ks*pow(hdotn,sh)*lightRGB; rayRGB = rayRGB + rayTransp*matRGBA[3]*pntRGB; //// * : real x real -> real //// - : real x real -> real rayTransp = rayTransp*(1.0 - matRGBA[3]); } //// > : real x real -> bool //// < : real x real -> bool //// || : bool x bool -> bool if (t > 1.0 || rayTransp < 0.01) // a little odd; ray terminates at length=1 stabilize; pos = pos + stepSz*dir; t = t + stepSz; } } initially [ RayCast(r, c) | r in 0..1023, c in 0..1023 ];