10
$\begingroup$

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)

$\endgroup$
2
  • 1
    $\begingroup$ Do you really need CUDAVolumetricRender? If you have version 9, you can use Image3D and related functions. It would be a simpler solution. $\endgroup$
    – Szabolcs
    Apr 3, 2013 at 14:03
  • $\begingroup$ 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" $\endgroup$
    – andre314
    Apr 3, 2013 at 18:13

1 Answer 1

13
+50
$\begingroup$

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]

Mathematica graphics

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"]

Mathematica graphics

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]

Mathematica graphics

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;
/* ... */
}
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.