Extract values for ViewMatrix from a Graphics3D

The documentation is wrong. It should have been fixed, but AbsoluteOptions does not work with ViewMatrix (on all platforms). M- introduced interactive 3D graphics since V6, and after that getting values through AbsoluteOptions (which is an old function) becomes very tricky since the Kernel (who evaluates the option) cannot fully know what is happening on FrontEnd side. To compare, before V6, the Kernel was solely responsible for rendering 3D scene (Postscript!), and of course it could tell every matrix value.

Instead, you can try to use 5 values that can define the matrix using Dynamic: ViewPoint, ViewAngle, ViewVertical, ViewCenter, and ViewRange.

enter image description here

For instance, the following example takes those 5 values from one graphics, and use it for another:

DynamicModule[
 {point = {1.3, -2.4, 2}, angle = N[35 Degree], vertical = {0, 0, 1}, 
  center = Automatic},
 Grid[{{
    Framed[
     Graphics3D[{
       (* Objects *)
       EdgeForm[], Specularity[White, 20],
       FaceForm[Red], Sphere[{-0.2, -0.1, -0.3}, .2],
       FaceForm[Blue], Cylinder[{{0., 0.3, -.5}, {0., 0.3, 0.}}, .1],
       FaceForm[Green], Cone[{{0.2, 0., -0.5}, {0.2, 0., -0.1}}, .2]
       },
      Boxed -> True, Lighting -> "Neutral",
      ImageSize -> 300, RotationAction -> "Clip",

      (* View control *)
      ViewPoint -> Dynamic[point],
      ViewAngle -> Dynamic[angle],
      ViewVertical -> Dynamic[vertical],
      ViewCenter -> Dynamic[center]
      ],
     FrameStyle -> LightGray],

    (* The second object *)
    Framed[
     Plot3D[Sin[x y], {x, 0, 3}, {y, 0, 3},
      ImageSize -> 300, Axes -> False,
      (* View control *)
      ViewPoint -> Dynamic[point],
      ViewAngle -> Dynamic[angle],
      ViewVertical -> Dynamic[vertical],
      ViewCenter -> Dynamic[center]
      ],
     FrameStyle -> LightGray]
    }}]
 ]

Examples: Mathematica graphics

and

Mathematica graphics

This free course explains about the values in vary detail (with some cool demos--OK. shameless self-promotion :) ):

Wolfram Training: Visualization: Advanced 3D Graphics

Also, in essence, you can reconstruct the view matrix and projection matrix out of those values, but I need to take a look at an old textbook to make sure that I am not saying something wrong :)


It got a bit out of hand, but here's a way to construct a ViewMatrix pair from the triple ViewVector, ViewAngle, and ViewVertical. The left figure is the Graphics3D object using ViewVector, ViewAngle, and ViewVertical and the right is the one using ViewMatrix. If you rotate the left figure or scale it (by dragging the figure while keeping Alt depressed), the ViewMatrix is updated automatically.

DynamicModule[{tt, pp, bb, gr, center, scale, v1, vv,
  theta, phi, alpha, vert, viewAngle},
 gr = {Cuboid[{-1, -1, -1}, {0, 0, 0}], 
   Cuboid[], {Red, Cuboid[{-1, 0, 0}, {0, 1, 1}]},
   {Blue, Cuboid[{2, 0, 1}, {3, 1, 2}]}};
 bb = PlotRange[Graphics3D[gr]];
 scale = 1/Abs[#1 - #2] & @@@ bb;
 center = Mean /@ bb;
 vv = {{6, 5, 2}, Mean /@ bb};
 v1 = (vv[[1]] - center);
 vert = {0, 0, 1} - {0, 0, 1}.v1 v1;
 viewAngle = 50 Degree;

 theta[v1_] := ArcTan[v1[[3]], Norm[v1[[;; 2]]]];
 phi[v1_] := If[Norm[v1[[;; 2]]] > .0001, ArcTan[v1[[1]], v1[[2]]], 0];
 alpha[vert_, v1_] := ArcTan[{-Sin[phi[v1]], Cos[phi[v1]], 0}.vert, 
   Cross[v1/Norm[v1], {-Sin[phi[v1]], Cos[phi[v1]], 0}].vert];

 tt[v1_, vert_, center_, r_] := TransformationMatrix[
   RotationTransform[-alpha[vert/scale, v1], {0, 0, 1}].
    RotationTransform[-theta[v1], {0, 1, 0}].
    RotationTransform[-phi[v1], {0, 0, 1}].
    ScalingTransform[r {1, 1, 1}].
    TranslationTransform[-center]];

 pp[ang_] := {{1, 0, - Tan[ang], 1}, {0, 1, - Tan[ang ], 1}, {0, 
    0, -Tan[ang ], 0}, {0, 0, -2 Tan[ang] , 2}};

 Panel[Column[{Labeled[#, 
       Style["Transforming ViewVector/ViewVertical/ViewAngle to ViewMatrix", 
       15, FontFamily -> "Helvetica", Bold], 
       Top, Background -> White, Frame -> True, FrameStyle -> Gray] &@
     Grid[{
       {Labeled[Dynamic@
          Graphics3D[{gr}, Axes -> True, AxesLabel -> {"x", "y", "z"},
           ViewAngle -> Dynamic[viewAngle], 
           ViewVector -> Dynamic[vv, (vv = #; center = vv[[2]]; v1 = vv[[1]] - center) &],
           ViewVertical -> Dynamic[vert],
           ImageSize -> 270],
         Style["ViewVector, ViewVertical, ViewAngle", FontFamily -> "Helvetica", Bold], 
         Top, Frame -> True],

        Labeled[Dynamic@Graphics3D[{gr},
            ViewMatrix -> {tt[v1, vert, center, Cot[viewAngle/2]/Norm[v1]], pp[viewAngle/2]}, 
            Axes -> True, AxesLabel -> {"x", "y", "z"}, ImageSize -> 270],
         Style["ViewMatrix", Bold, FontFamily -> "Helvetica"], Top, 
         Frame -> True]},

       {Dynamic@ Labeled[N[{tt[v1, vert, center, Cot[viewAngle/2]/Norm[v1]], 
              pp[viewAngle/2]}] /. {a_?NumericQ :> NumberForm[a, 3]} //
            MatrixForm[#, TableDirections -> Row] &,
          Style["ViewMatrix", 12, FontFamily -> "Helvetica", Bold], Left], SpanFromLeft}},
      Spacings -> {1, 2}],
    Button["Print ViewMatrix",
     Print[N[{tt[v1, vert, center, Cot[viewAngle/2]/Norm[v1]], pp[viewAngle/2]}]],
     ImageSize -> 150]},
   Alignment -> Left]
  ]
 ]

Mathematica graphics