# How to make a volume CUDA rendering isometric?

I just realized that the output of CUDAVolumetricRender[] uses (quite marked) perspective, which I do not want (for scientific data representation, it can be very misleading). How do I turn it off? (i.e. make it use an isometric projection)

-
Do you really need CUDAVolumetricRender? If you have version 9, you can use Image3D and related functions. It would be a simpler solution. – Szabolcs Apr 3 '13 at 14:03
The source code of CUDAVolumetricRender is the file "volumeRender_kernel.cu", written in Cuda C. By me, the file is in \$InstallationDirectory <> \ "\\SystemFiles\\Links\\CUDALink\\CSource\\volumeRender_kernel.cu" – andre Apr 3 '13 at 18:13
I can"t find information about "heavy perspective". Is there a synonym (or a link) ? – andre Apr 3 '13 at 22:05

I believe what you mean when you speak of heavy perspective is the difference between orthogonal and perspective projection.

t = TransformationMatrix[
RescalingTransform[{{-3, 3}, {-3, 3}, {-3, 3}}].RotationTransform[
Pi/5, {1, 0, 0}].RotationTransform[-Pi/4, {0, 0, 1}]];
p = {{1, 0, 0, 0}, {0, 0, 1, 0}, {0, 1, 0, 0}, {0, 0, 0, 1}};
GraphicsRow[
With[{lines =
Table[{i, j}, {i, -2, 2, .3}, {j, -2, 2, .3}] /. {x_, y_} :> {x,
y, 0}},
Graphics3D[{Thick, Line[lines], Line[Transpose[lines]], Cuboid[]},
Boxed -> False, ViewMatrix -> #]
] & /@ {Automatic, {t, p}}, ImageSize -> 500]


The difference is rather subtle but when you observe the images closer then you see that in the left (perspective) image the parallel lines of the grid will meet somewhere if they would be longer. In the right image (orthogonal) this is not the case. Furthermore, you see that in the perspective projection distant grid-squares are smaller than the ones in the front. In the right image, all squares which are of the same size.

Let's look at the behavior of Image3D

data = Table[
If[z == 0 && (Mod[x, 8] == 0 || Mod[y, 8] == 0) || (Abs[x] < 8 &&
Abs[y] < 8 && -16 < z < 0), 255, 0], {z, -50, 50}, {y, -50,
50}, {x, -50, 50}];
Image3D[data, "Byte"]


I wouldn't call this heavy perspective. At most it looks similar to the projection of the normal Graphics3D. Let's see what happens in the cuda renderer

CUDAVolumetricRender[data, Height -> 400, Width -> 400]


This doesn't look so bad at all. Unfortunately, the control of the CUDAVolumetricRender is implemented differently so I could not get the same viewpoint as in the Image3D but you could play yourself.

Let's say you really want to change the perspective in the CUDAVolumetricRender then I'm pretty sure you have to code it yourself. To give you a starting point: I would strongly advise to investigate in the iNewFrame function at line 663 of volumeRender_kernel.cu. Looks like this is the function which calculates the final projection:

static void iNewFrame() {
mint ii, jj;
mint pixel;

#define PI 3.14159265f
float theta, psi;
theta = -viewRotation.x*PI/180.0f;
psi   = -viewRotation.y*PI/180.0f;

invViewMatrix[0] = cos(psi);
invViewMatrix[4] = sin(theta)*sin(psi);
invViewMatrix[8] = -cos(theta)*sin(psi);

invViewMatrix[1] = 0.0f;
invViewMatrix[5] = cos(theta);
invViewMatrix[9] = sin(theta);

invViewMatrix[2] = sin(psi);
invViewMatrix[6] = -sin(theta)*cos(psi);
invViewMatrix[10]= cos(theta)*cos(psi);

invViewMatrix[3] = -invViewMatrix[0]*viewTranslation.x -  \
invViewMatrix[1]*viewTranslation.y - invViewMatrix[2]*viewTranslation.z;
invViewMatrix[7] = -invViewMatrix[4]*viewTranslation.x -\
invViewMatrix[5]*viewTranslation.y - invViewMatrix[6]*viewTranslation.z;
invViewMatrix[11] = -invViewMatrix[8]*viewTranslation.x -\
invViewMatrix[9]*viewTranslation.y - invViewMatrix[10]*viewTranslation.z;
/* ... */
}

-