Viewport render and camera FOV



  • Hi!
    In my renderer plugin, I use the following code to get the camera FOV:

    Float aperture = camera->GetAperture();
    Float focus = camera->GetFocus();
    float horizontal_fov = (float)RadToDeg(2 * ATan(0.5*aperture / focus));

    This matches perfectly when rendering to the picture viewer, but when I render to the viewport there is a slight mismatch in the camera FOV.

    Any suggestions on how to get the correct camera field of view for viewport rendering?

    (I should add that I am determining render resolution by the size of the buffers obtained in the renderer videopost, like this:

    VPBuffer* colorBuf = vps->render->GetBuffer(VPBUFFER_RGBA, NOTOK);

    maxon::Int32 const xres = colorBuf->GetInfo(VPGETINFO::XRESOLUTION);
    maxon::Int32 const yres = colorBuf->GetInfo(VPGETINFO::YRESOLUTION);

    )



  • Hi again,
    Thanks for your input! I have found the solution now:

    The issue was not the camera field of view, but how I calculated the bounds of the viewplane (image plane). C4d fits the aspect ratio of the final render resolution into the size of the viewport in a specific way, that I reverse engineered. Here is the code for my solution, in case anyone else has the same problem:

    double f=double(resolution[1])/double(resolution[0]);
    double f2 =double(renderdata_resolution[1])/double(renderdata_resolution[0]);
    double c = f2 / f;
    
    double screen_window[4];
    screen_window[0] = -1*c;
    screen_window[1]=-f*c;
    screen_window[2] = 1*c;
    screen_window[3]=f*c;
    

    In the above code, "resolution" is the resolution, in pixels, of the viewport and "renderdata_resolution" is the resolution we would have if rendering to the picture viewer.

    /Filip



  • hello,

    From the execute command you can retrieve the RayCamera using the VolumeData stored inside the VideoPostStruct

    const RayCamera* cam = vps->vd->GetRayCamera();
    

    You can get the off parameter of the RayCamera that is the offset of the camera (so double it to have the resolution)

    Using the zoom factor should help you to retrieve the aperture and determine the ray direction.

    This RayCamera will change depending on where the render is done, (viewport or picture viewer)

    in the Execute Function :

    	       const RayCamera* cam = vps->vd->GetRayCamera();
    	       
    	       	if (cam == nullptr)
    	         	return RENDERRESULT::OUTOFMEMORY;
    	       
    	       		
    		ppx_ = cam->off.x;
    		ppy_ = cam->off.y;
    		zoomRatio_ = 1.0 / cam->zoom;
    

    in the CalculateRay function

    						
    			maxon::Float newx = x - ppx_;
    			maxon::Float newy = y - ppy_;
    
    			maxon::Vector focalPoint;
    		
    			
    			// Sets the value of the focal point in local space, the plan is put at the image size * ration in Z axis
    			focalPoint =  Vector(newx, -newy, xres_ /  zoomRatio_);
    			
    			// go to goal space
    			focalPoint = camMg_ * focalPoint;
    			
    			// remove the camera position so we have a direction
    			focalPoint -= camMg_.off;
    			
    			// set the ray position
    			dst.p = camMg_.off;
    			
    			// set the ray direction
    			dst.v =  focalPoint;
    			dst.v.Normalize();
    			
    

    Hope this help a bit.

    Cheers,
    Manuel



  • Hi again,
    Thanks for your input! I have found the solution now:

    The issue was not the camera field of view, but how I calculated the bounds of the viewplane (image plane). C4d fits the aspect ratio of the final render resolution into the size of the viewport in a specific way, that I reverse engineered. Here is the code for my solution, in case anyone else has the same problem:

    double f=double(resolution[1])/double(resolution[0]);
    double f2 =double(renderdata_resolution[1])/double(renderdata_resolution[0]);
    double c = f2 / f;
    
    double screen_window[4];
    screen_window[0] = -1*c;
    screen_window[1]=-f*c;
    screen_window[2] = 1*c;
    screen_window[3]=f*c;
    

    In the above code, "resolution" is the resolution, in pixels, of the viewport and "renderdata_resolution" is the resolution we would have if rendering to the picture viewer.

    /Filip



  • Hello,

    while it's working and it's technically the same, we encourage you to use Maxon data type. In your case Float and not double.

    Cheers,
    Manuel



  • Well, in this case the double is being passed to an external library (the renderer) right after this code, and the library expects a double.

    Now, here comes a friendly rant: I have read the code style guide you linked to, but I'm actually not quite sure how to interpret it or what to think of it. To me it appears to be a mix of things that could potentially be important, and things that are just internal stylistic recommendations. And it makes no distinction between the two.

    Take these three examples:

    -"Always start a new line after the for statement."'
    -"Do not write to global structures from a thread."
    -"Do not use external libraries (e.g STL or BOOST) unless absolutely necessary".

    The first one is clearly just a preference from MAXON (and I don't see why I should follow it if I prefer to structure my code in another way...). The second one seems to be a serious warning, and it sounds likely that violating this rule could cause a bug. For the third one, I have no idea. Maybe it is just a suggestion as well, and maybe linking my plugin with STL or BOOST could cause bugs. The docs do not say.

    The recommendation for using MAXON datatypes also kind of falls into this category: I can't tell from the docs if it is just a style recommendation from MAXON, or something that could actually have an effect on my code.

    To me, the code guide would be much more useful if it only listed things that are actual rules (or at least clearly separated rules and important advice from purely stylistic recommendations).

    Cheers
    /Filip



  • Hello,

    That's a more wide discussion about how to code. We can say that as long as it compile and your plugin is working, your code is fine.

    Cinema 4D is provided for both Windows and OSX, so differences can be introduces. Using our datatype guaranty (unless a bug) that your code will work the same on both OS. (of course there's always exception, don't jump on them ;) )
    Same goes for external librairies.

    Another example is our thread/job system, some external librairies can interfere with cinema4D in a badly way.

    Cheers,
    Manuel