.. _plugin-sensor-hdistant:

Hemispherical distant radiancemeter sensor (:monosp:`hdistant`)
---------------------------------------------------------------

.. pluginparameters::

 * - to_world
   - |transform|
   - Sensor-to-world transformation matrix.
   - —

 * - target
   - |point| or nested :paramtype:`shape` plugin
   - *Optional.* Define the ray target sampling strategy.
     If this parameter is unset, ray target points are sampled uniformly on
     the cross section of the scene's bounding sphere.
     If a |point| is passed, rays will target it.
     If a shape plugin is passed, ray target points will be sampled from its
     surface.
   - —

 * - ray_offset
   - |float|
   - *Optional.* Define the ray origin offsetting policy.
     If this parameter is unset, ray origins are positioned at a far distance
     from the target. If a value is set, rays are offset by the corresponding
     distance.
   - —

This sensor plugin implements a distant directional sensor which records
radiation leaving the scene. It records the spectral radiance leaving the scene
in directions covering a hemisphere defined by its ``to_world`` parameter and
mapped to film coordinates. To some extent, it can be seen as the adjoint to
the ``envmap`` emitter.

The ``to_world`` transform is best set using a
:py:meth:`~mitsuba.core.Transform4f.look_at`. The default orientation covers a
hemisphere defined by the [0, 0, 1] direction, and the ``up`` film direction is
set to [0, 1, 0].

The following XML snippet creates a scene with a ``roughconductor``
surface illuminated by three ``directional`` emitter, each emitting in
a single RGB channel. A ``hdistant`` plugin with default orientation is
defined.

.. only:: not latex

   .. figure:: /fig/data/plugins/sensors/hdistant/sensor_hdistant_illumination_optimized.svg
      :width: 320px

      Example scene illumination setup.

.. code:: xml

    <scene version="2.1.0">
        <sensor type="hdistant" id="hdistant">
            <transform name="to_world">
                <lookat origin="0, 0, 0" target="0, 0, 1" up="0, 1, 0"/>
            </transform>
            <sampler type="independent">
                <integer name="sample_count" value="3200"/>
            </sampler>
            <film type="hdrfilm">
                <integer name="width" value="32"/>
                <integer name="height" value="32"/>
                <string name="pixel_format" value="rgb"/>
                <string name="component_format" value="float32"/>
                <rfilter type="box"/>
            </film>
        </sensor>
        <integrator type="path"/>

        <emitter type="directional">
            <vector name="direction" x="1" y="0" z="-1"/>
            <rgb name="irradiance" value="1, 0, 0"/>
        </emitter>
        <emitter type="directional">
            <vector name="direction" x="1" y="1" z="-1"/>
            <rgb name="irradiance" value="0, 1, 0"/>
        </emitter>
        <emitter type="directional">
            <vector name="direction" x="0" y="1" z="-1"/>
            <rgb name="irradiance" value="0, 0, 1   "/>
        </emitter>

        <shape type="rectangle">
            <bsdf type="roughconductor"/>
        </shape>
    </scene>

The following figures show the recorded exitant radiance with the default film
orientation (left, ``up = [0,1,0]``) and with a rotated film (right,
``up = [1,1,0]``). Colored dots on the plots materialize emitter directions.
The orange arrow represents the ``up`` direction on the film.
Note that on the plots, the origin of pixel coordinates is taken at the bottom
left.

.. only:: not latex

   .. figure:: /fig/data/plugins/sensors/hdistant/sensor_hdistant_film_default_optimized.svg
      :width: 320px

      Default film orientation.

   .. figure:: /fig/data/plugins/sensors/hdistant/sensor_hdistant_default.svg
      :width: 512px

      Exitant radiance with default film orientation.

   .. figure:: /fig/data/plugins/sensors/hdistant/sensor_hdistant_film_rotated_optimized.svg
      :width: 320px

      Rotated film.

   .. figure:: /fig/data/plugins/sensors/hdistant/sensor_hdistant_rotated.svg
      :width: 512px

      Exitant radiance with a rotated film.

By default, ray target points are sampled from the cross section of the scene's
bounding sphere. The ``target`` parameter can be set to restrict ray target
sampling to a specific subregion of the scene. The recorded radiance is averaged
over the targeted geometry.

Ray origins are positioned outside of the scene's geometry, such that it is
as if the sensor would be located at an infinite distance from the scene.

By default, ray target points are sampled from the cross section of the scene's
bounding sphere. The ``target`` parameter should be set to restrict ray target
sampling to a specific subregion of the scene using a flat surface. The recorded
radiance is averaged over the targeted geometry.

.. warning::

   * While setting ``target`` using any shape plugin is possible, only specific
     configurations will produce meaningful results. This is due to ray sampling
     method: when ``target`` is a shape, a point is sampled at its  surface,
     then shifted along the ``-direction`` vector by the diameter of the scene's
     bounding sphere, effectively positioning the ray origin outside of the
     geometry. The ray's weight is set to :math:`\frac{1}{A \, p}`, where
     :math:`A` is the shape's surface area and :math:`p` is the shape's position
     sampling PDF value. This weight definition is irrelevant when the sampled
     origin may corresponds to multiple points on the shape, *i.e.* when the
     sampled ray can intersect the target shape multiple times. From this
     follows that only flat surfaces should be used to set the ``target``
     parameter. Typically, one will rather use a ``rectangle`` or ``disk``
     shape.
   * If this sensor is used with a targeting strategy leading to rays not
     hitting the scene's geometry (*e.g.* default targeting strategy), it will
     pick up ambient emitter radiance samples (or zero values if no ambient
     emitter is defined). Therefore, it is almost always preferable to use a
     nondefault targeting strategy.