// PoVRay 3.8 Scene File "sky_vector.pov" // author: Josh English // date: 2023-05-15 /* Tutorial for explaining the sky vector of the camera object. Use the following line to render each frame. // +KFI0 +KFF8 +W640 +H480 Explanations for each frame are in the switch statement below. Each frame also has a command line option to render only that frame. You can play with diffeernt tilts by changing the `adjusted_sky_vector`. For best results keep on the XY plane */ //-------------------------------------------------------------------------- #version 3.8; //-------------------------------------------------------------------------- #include "colors.inc" #include "transforms.inc" //-------------------------------------------------------------------------- global_settings{ assumed_gamma 1.0 } #default{ finish{ ambient 0.1 diffuse 0.9 }} //-------------------------------------------------------------------------- // camera ------------------------------------------------------------------ #declare Camera_0 = camera {perspective angle 43 // front view location <2.0 , 8.0 ,-6.0> right x*image_width/image_height look_at <2.0 , 0.0 , 1.0>} camera{Camera_0} // sun ---------------------------------------------------------------------- light_source{< 3000,3000,-3000> color White} // sky ---------------------------------------------------------------------- sky_sphere { pigment { gradient <0,1,0> color_map { [0.00 rgb <0.6,0.7,1.0>] [0.35 rgb <0.1,0.0,0.8>] [0.65 rgb <0.1,0.0,0.8>] [1.00 rgb <0.6,0.7,1.0>] } scale 2 } // end of pigment } //end of skysphere // ground ------------------------------------------------------------------- plane{ <0,1,0>, 0 texture{ pigment{ checker Gray60 Gray40 } //normal { bumps 0.75 scale 0.025} finish { phong 0.1} } // end of texture } // end of plane //--------------------------------------------------------------------------- //---------------------------- objects in scene ---------------------------- //--------------------------------------------------------------------------- // Origin Markers cylinder { <-2, 0, 0> <2, 0, 0> 0.05 pigment { red 1 } finish { phong 1 } } cylinder { <0, 0, -2> <0, 0, 2> 0.05 pigment { red 1 blue 1 } finish { phong 1 } } // Stuff to look at // Yellow Sphere (target) #declare target_location = <0.25, 0.75, 1.25>; sphere { target_location 0.25 pigment { red 1 green 1 } finish { phong 1 } } cone { <1.5, 0, 2.5> 0.45 <1.5, 2, 2.5> 0 pigment { Gray90 } finish { phong 1 } } box { <-0.5,0, 2> <0, 0.5, 2.5> pigment { red 1 } finish { phong 1 } } torus { 1.5, 0.1 pigment { green 1 blue 1 } translate <0.75,0,1.75> } #macro RotationArrow(norm, dist, rot, col, pos, clockwise) union { intersection { torus {0.5, 0.03} box { <-1.1, -0.1, -1.1> <0, 0.1, 1.1> } } cone { <0, 0, -0.5> 0.06 <0.15,0,-0.5> 0 } #if(clockwise) scale <-1, 1, 1> #end pigment { col } finish { phong 1 } rotate rot*y Point_At_Trans(norm) translate dist*norm translate pos no_shadow } #end #declare Camera_Model = union { box { <-0.15, -0.25, -0.25> <0.15, 0.2, .2> pigment { Gray80 } } cone { <0,0,0.2> 0.06 <0,0,0.4> 0.13 pigment { Gray80 } } cylinder { <-0.5, 0, 0> <0.5, 0, 0> 0.05 pigment { red 1 } } cylinder { <0, -0.5, 0> <0, 0.5, 0> 0.05 pigment { green 1 } } cylinder { <0,0,-0.5> <0, 0, 0> 0.05 pigment { blue 1 } } cylinder { <0,0,0> <0,0,50> 0.05 pigment { green 1 blue 1 } } finish { phong 1 } no_shadow } #declare camera_location = <4, 2, -1>; #declare camera_sky_vector = y; #declare adjusted_sky_vector = vnormalize(<-0.15,1,0>); // Show where the camera is in space #declare camera_position_guide = union { cylinder { <0,0,0> 0.03 } cylinder { 0.03 } cylinder { camera_location 0.03 } pigment { red 1 green 1 } finish { phong 1 } no_shadow } #switch(frame_number) #case(0) // +KFI0 /* Playground. We have a few things to look at and a camera. The checkered plane has a scale of 1. The red and purple cylinders mark the origin. The camera has some axes and a long cyan cylinder showing it's direction. We want to aim the camera at the target yellow sphere. */ object { Camera_Model translate camera_location } object { camera_position_guide } #break #case(1) // +KFI1 /* The first step the camera takes is to rotate around the sky vector (the green cylinder) until it aims at the yellow sphere. We'll add a cyan cylinder leading from the target. Note in the first step the camera is not pointing at the target yellow sphere, but at the line going from the target yellow sphere along the sky vector (y). */ cylinder { target_location ((target_location)+(5*camera_sky_vector)) 0.05 pigment { green 0.25 blue 1 } finish { phong 1 } } #declare z_angle = VRotationD(z, (target_location-camera_location)*<1,0,1>, camera_sky_vector); object { Camera_Model transform { Axis_Rotate_Trans(camera_sky_vector, z_angle) } //transform { Reorient_Trans(z, (target_location-camera_location)*<1,0,1>) } translate camera_location } object { camera_position_guide } RotationArrow(y, 0.2, z_angle-90, green 1 , camera_location, no) #break #case(2) // +KFI2 /* The second step is to rotate the camera along its new local right vector until it is looking at the target. */ cylinder { target_location ((target_location)+(5*camera_sky_vector)) 0.05 pigment { green 0.25 blue 1 } finish { phong 1 } } object { camera_position_guide } #declare z_angle = VRotationD(z, VProject_Plane(target_location-camera_location, camera_sky_vector), camera_sky_vector); #declare new_right = vaxis_rotate(x, camera_sky_vector, z_angle); #declare x_angle = VRotationD(vaxis_rotate(z, camera_sky_vector, z_angle), (target_location-camera_location), camera_sky_vector); object { Camera_Model transform { Axis_Rotate_Trans(camera_sky_vector, z_angle) } transform { Axis_Rotate_Trans(new_right, x_angle) } translate camera_location } RotationArrow(new_right, 0.5, x_angle-90, red 1 , camera_location, yes) #break #case(3) // +KFI3 /* This is a view from the camera after it has been positioned. */ camera { location camera_location look_at target_location right x*image_width/image_height angle 60 } cylinder { target_location ((target_location)+(5*camera_sky_vector)) 0.05 pigment { green 0.25 blue 1 } finish { phong 1 } } #break #case(4) // +KFI4 /* Now we add a custom sky vector to the camera. The dark cyan cylinder on the target yellow sphere now points to this new sky vector. */ #declare camera_sky_vector = adjusted_sky_vector; cylinder { target_location ((target_location)+(5*camera_sky_vector)) 0.05 pigment { green 0.25 blue 1 } finish { phong 1 } } object { camera_position_guide } object { Camera_Model translate camera_location } #break #case(5) // +KFI5 /* Now we align the camera's sky vector to our custom vector */ #declare camera_sky_vector = adjusted_sky_vector; cylinder { target_location ((target_location)+(5*camera_sky_vector)) 0.05 pigment { green 0.25 blue 1 } finish { phong 1 } } object { camera_position_guide } object { Camera_Model Reorient_Trans(y, camera_sky_vector) translate camera_location } RotationArrow(-z, 0.5, -90, blue 1 , camera_location, no) #break #case(6) // +KFI6 /* Now we perform the same translations as before, rotating around the sky vector until the camera is pointed towards (but not necessarily at) the target. It makes sense to keep the sky vector in the XY plane. The current algorithm can handle some deviation on the XZ plane, but too much and the camera jumps off by 90 degrees. */ #declare camera_sky_vector = adjusted_sky_vector; cylinder { (target_location-2*camera_sky_vector) ((target_location)+(5*camera_sky_vector)) 0.05 pigment { green 0.25 blue 1 } finish { phong 1 } } object { camera_position_guide } #declare z_angle = VRotationD(z, VProject_Plane(target_location-camera_location, camera_sky_vector), camera_sky_vector); object { Camera_Model Point_At_Trans( camera_sky_vector) transform { Axis_Rotate_Trans(camera_sky_vector, z_angle) } translate camera_location } RotationArrow(camera_sky_vector, 0.25, -z_angle/2, green 1, camera_location, yes) #break #case(7) // +KFI7 /* Finally we rotate the camera along its new x vector until it is pointed at the target yellow sphere. */ #declare camera_sky_vector = adjusted_sky_vector; cylinder { (target_location-2*camera_sky_vector) ((target_location)+(5*camera_sky_vector)) 0.05 pigment { green 0.25 blue 1 } finish { phong 1 } } object { camera_position_guide } #declare cam_dir = target_location-camera_location; #declare cam_dir_projection = VProject_Plane(cam_dir, camera_sky_vector); #declare z_angle = VRotationD(z, cam_dir_projection, camera_sky_vector); #declare new_right = vnormalize(vcross(cam_dir, cam_dir_projection)); //#declare x_angle = VRotationD(vaxis_rotate(z, camera_sky_vector, z_angle), VProject_Plane(target_location-camera_location, new_right), camera_sky_vector); #declare x_angle = VRotationD(VProject_Plane(cam_dir_projection, new_right), cam_dir, new_right); object { Camera_Model Point_At_Trans( camera_sky_vector) transform { Axis_Rotate_Trans(camera_sky_vector, z_angle) } transform { Axis_Rotate_Trans(new_right, x_angle) } translate camera_location } #break #case(8) // +KFI8 /* Here is the view from the camera adjusted to the sky vector. Notice the dark cyan cylinder is vertical, but the horizon is skewed. */ #declare camera_sky_vector = adjusted_sky_vector; camera { location camera_location look_at target_location right x*image_width/image_height sky camera_sky_vector angle 60 } cylinder { (target_location-2*camera_sky_vector) ((target_location)+(5*camera_sky_vector)) 0.05 pigment { green 0.25 blue 1 } finish { phong 1 } } #break #end