##########
Viewpoints
##########

.. toctree::
    :maxdepth: 1
    :titlesonly:
    :hidden:

    bk_ba_v/bk_ba_matrix_transforms_in_a_cluster

The viewpoint is the HOOPS Luminate camera. Viewpoint creation and basic operation is detailed just below. Of course, to be used, the viewpoint must be added to a ``RED::IViewpointRenderList``, or added to the default VRL using the ``RED::IWindow::InsertViewpoint`` helper. In the HOOPS Luminate documentation we'll either use the word 'viewpoint' or 'camera' to refer to HOOPS Luminate viewpoints.

.. include:: /tasks/ta_ca/ta_ca_application/tk_creating_a_viewpoint_and_visualizing_shapes.rst

The base axis system of a camera is manipulated and accessed using:

    * ``RED::IViewpoint::SetEye``, ``RED::IViewpoint::SetSight``, ``RED::IViewpoint::SetTop``, ``RED::IViewpoint::SetRight`` for the main three camera axis, and the corresponding "Get" methods.
    * ``RED::IViewpoint::GetNearFar`` to access the viewpoint's near and far clip distances.

Other methods can be used to setup the viewpoint's matrix as a whole, such as:
    
    * ``RED::IViewpoint::SetViewingAxis`` or ``RED::IViewpoint::SetViewingMatrix``.

This chapter covers a number of different topics, among which:
    
    * The description of all HOOPS Luminate supported projection models. All of them are reviewed down this page: **Perspective Camera**; **Orthographic Camera**, and **Custom Camera**.
    * All the details on the HOOPS Luminate matrix transformation pipeline can be found there: :doc:`/book/subjects/bk_ba/bk_ba_v/bk_ba_matrix_transforms_in_a_cluster`. References that are familiar to OpenGL programmers are provided there.

.. include:: /tasks/ta_ca/ta_ca_application/tk_setting_up_a_simple_camera.rst


*******************
Applying a Layerset
*******************

Layersets are visibility masks. ``RED::LayerSet`` objects are detailed in the doc :doc:`/book/subjects/bk_sgo/bk_sg_shape_attributes` under the section **Layersets**. There are two main usages for layersets:

    1. Visibility filtering. Layersets are used to discard objects from the visibility, as pointed out by the task ":doc:`/tasks/ta_ca/ta_ca_scenegraph/tk_change_a_shape_visibility_using_layersets`".
    2. Material configuration. Shaders in materials are set for specific layersets configurations (see :doc:`/book/subjects/bk_bm/bk_bm_material_layersets`).

All the layerset configuration system starts by the specification of the ``RED::LayerSet`` instance which is set at the camera level. Changing this layerset can affect the entire visibility of the scene graph. Call ``RED::IViewpoint::ApplyLayerSet`` to change the ``RED::LayerSet instance`` used for the visualization of the entire scene graph linked "under" the viewpoint.


******************************************
Sharing a Viewpoint Among Windows and VRLs
******************************************

There's no restriction on sharing a viewpoint among different VRLs. The same viewpoint can be added to different VRLs for display. This is rarely used feature, that can be leveraged for instance to display the same scene with different rendering options, or to use different backgrounds or other VRL level informations for the same dataset.


*******************************
Defining a Viewpoint's Viewport
*******************************

The viewport region in which a viewpoint will be rendered is defined at the ``RED::IViewpointRenderList`` level. A viewpoint gets inserted into a window using ``RED::IViewpointRenderList::InsertViewpoint``. This method defines the exact area that'll be covered by the viewpoint in the window rendering area. See also :doc:`/tutorials/workflows/wf_realtime/wf_anchoring_viewpoints_in_a_window`.


***********************************
Viewpoint Level Material Parameters
***********************************

This is an important feature of the viewpoint. It has the capability to hold a set of ``RED::RenderShaderParameter`` objects, that can be assigned to IDs. Materials in scene graphs can then point to these parameters that are identified by their IDs. Therefore, the same material used by a shape that is viewed by two different cameras can have different values for the same material parameters.

All the details can be found in the documentation of the ``RED::IViewpoint::AddRenderShaderParameter`` method.


******************
Perspective Camera
******************

The ``RED::IViewpoint`` interface implements the pinhole perspective camera projection model:

.. figure:: perspective_camera.png 
    :align: center
    
    **The perspective camera projection model**

A perspective camera projection model is set using ``RED::IViewpoint::SetFrustumPerspective``. A perspective camera uses the ``RED::VPT_PERSPECTIVE`` projection type, that can be retrieved using ``RED::IViewpoint::GetProjection``. The perspective camera projection model implements perspective foreshortening, using homogenous matrix transformations. 

HOOPS Luminate supports asymmetry in its projection models. Asymmetric cameras are mainly used for stereoscopy setup and for tile based rendering of large images.

An asymmetric perspective camera can be specified using ``RED::IViewpoint::SetAsymmetricFrustumPerspective``, using the following specification:

.. figure:: perspective_camera_asymmetric.png 
    :align: center
    
    **The asymmetric perspective camera projection model**

As quoted in the method's documentation, the definition of each field of view angle is oriented from the screen center. 


*******************
Orthographic Camera
*******************

The ``RED::IViewpoint`` interface implements the orthographic camera projection model:

.. figure:: orthographic_camera.png 
    :align: center
    
    **The orthographic camera projection model**

An orthographic (or parallel) camera projection model is set using ``RED::IViewpoint::SetFrustumParallel``. A parallel camera uses the ``RED::VPT_PARALLEL`` projection type, that can be retrieved using ``RED::IViewpoint::GetProjection``.

Similarly, orthographic cameras can be set asymmetric, using ``RED::IViewpoint::SetAsymmetricFrustumParallel``:

.. figure:: orthographic_camera_asymmetric.png 
    :align: center
    
    **The asymmetric orthographic camera projection model**

As quoted in the method's documentation, the definition of each distance is measured from the screen center.


*************
Custom Camera
*************

HOOPS Luminate lets the application specify its own projection model using ``RED::IViewpoint::SetFrustumCustom``. In this case, the ``RED::IViewpoint::GetProjection`` will return the  ``RED::VPT_CUSTOM`` camera projection type, to indicate that the user has the control over the camera projection model being used.


******************************************
Orthographic Camera Automatic Eye Shifting
******************************************

Many shader programs use the eye position internally to define directions or graphic effects. In the case of an orthographic camera projection model, the eye position may remain placed in the center of the scene (and negative near clip distances are allowed in this case!). Therefore, this can cause problems in shading calculations, with some graphic effects that may appear distorted.

.. figure:: orthographic_parallax_error.png 
    :align: center
    
    **Orthographic viewpoint parallax errors and the automatic eye shifting applied to counter this effect**

HOOPS Luminate counter this effect in applying a dynamic shifting of the eye position, negatively along the camera sight vector axis. The eye position is shift backwards of 10.000 model units, unless the ``RED::OPTIONS_VIEWPOINT_ORTHOGRAPHIC_EYE_AUTO_OFFSET`` is being disabled for the rendered camera. Note that the shifting does not appear on calling ``RED::IViewpoint::GetEye``. It only appears in the value of the ``RED::RenderShaderParameter::REF_EYE_POS_WCS`` reference or in the ``RED::ISoftRayContext::GetCamera`` object that can be returned during a software shader query.



