======
Lights
======

Visualize treats lights as geometry. A light illuminates all geometry in the same scene, irrespective of its location in the segment tree. The only exception is with subwindows - lights do not affect geometry in a subwindow. Multiple lights can be added to a scene, each with different attributes. Light color defaults to white, though color can be controlled using the ``HPS::MaterialMappingControl``. Visualize also offers a few different :doc:`lighting interpolation algorithms <0805_lighting_interpolation>`.

.. tabs::

	.. group-tab:: C++
	
		.. literalinclude:: ../../../internals/tests/docs/source/cpp/00700_lights.cpp
		   :start-after: //! [0213_a]
		   :end-before: //! [0213_a]
		   
	.. group-tab:: C#

		.. literalinclude:: ../../../internals/tests/docs/source/cs/00700_lights.cs
		   :start-after: //! [0213_a]
		   :end-before: //! [0213_a]

Visualize supports two types of lights: spotlights and distant lights. If a scene contains any lights, then Visualize performs lighting calculations for all the objects in the scene. The color of each object will then depend not only on that object's color, but also on the amount and color of the light falling on it. Thus, inserting the first light into a scene can sometimes make the scene look darker, because the sides of objects facing away from the light source will be darker than before. In Visualize, light intensity does not attenuate over distance. Additionally, there is no shadowing by default - the lighting for each triangle is independent of other triangles.

.. image:: images/lights-1.png

*The top image has no lights, the bottom image is lit*


.. _distant_lights:

Distant Lights
==============

If all you want to do is provide diffuse light to a scene, so that Visualize draws objects brighter on one side than on the other to convey a sense of depth, then you probably want a distant light. Distant lights are recommended as a general purpose light source because they are fully supported by 3D graphics hardware. To insert a distant light, simply use:

.. tabs::

	.. group-tab:: C++
	
		.. literalinclude:: ../../../internals/tests/docs/source/cpp/00700_lights.cpp
		   :start-after: //! [021302_a]
		   :end-before: //! [021302_a]
		   
	.. group-tab:: C#

		.. literalinclude:: ../../../internals/tests/docs/source/cs/00700_lights.cs
		   :start-after: //! [021302_a]
		   :end-before: //! [021302_a]

In the case of a distant light, the arguments x, y, and z are not a location in space - they are a direction vector from the origin toward the light source. The light source acts as though it were infinitely far away: the light rays are all parallel to one another, and the light intensity does not drop off with distance.

.. image:: images/building_lighting.jpg

*The model on the left is lit with a distant light, the right is lit by a light positioned near the model*

If you notice that lights cause your scene to appear in a way that you did not expect, check to see that your normals are set up correctly. Visualize can generate normals automatically, although it depends on the polygon handedness setting to do so. Polygon handedness is described in the :ref:`culling optimizations <prog_guide/0703_performance_considerations:Culling optimizations>` section.


Spotlights
==========

Spotlights are a directional light source emitted from a single point in space. The light position and target points define a primary direction in which a spotlight shines. Expanding in this direction from the light position is an infinite cone of illumination inside which surfaces are illuminated.

.. image:: images/pergola.png

*A scene lit by a spotlight positioned above the table*

.. tabs::

	.. group-tab:: C++
	
		.. literalinclude:: ../../../internals/tests/docs/source/cpp/00700_lights.cpp
		   :start-after: //! [021301_a]
		   :end-before: //! [021301_a]
		   
	.. group-tab:: C#

		.. literalinclude:: ../../../internals/tests/docs/source/cs/00700_lights.cs
		   :start-after: //! [021301_a]
		   :end-before: //! [021301_a]

In the image below, you can see the effect of the spotlight cone. The dark grey area is unlit by the light. The fuzzy blended area is lit by the spotlight's outer cone. The white area is lit by the inner cone. The diagram below demonstrates this:

.. image:: images/2.4.1.b.png

*Spotlight diagram*


.. _camera_relative:

Camera-Relative Lights
======================

When the camera changes, lights behave like any other piece of geometry. Their insertion point and direction are based on object-space coordinates, and those coordinates do not change when the camera changes. This means that if a light happens to be shining down the direction of the camera target vector, a highlight will be present on the 'front' of all visible geometry, and the highlight will appear to move with the geometry as the camera moves. Therefore, if the camera moves to the other side of the object, the object will be dark, since the camera is now viewing the dark side of the object.

It is frequently desirable to have the highlights remain visible on objects relative to the camera position so that when orbiting the camera, the object does not become shadowed. Of course, this can be controlled directly by the developer by moving the lights as the camera changes. However, this requires having special code that gets executed every time the camera is adjusted. Instead, you can use a feature called 'camera-relative lights'. This is an option applied to lights which locks their relative position to the camera. The end result is the position of the light will automatically get updated as the current camera changes. This setting is available for spotlights as well as distant lights. You can make a light into a camera-relative light by calling:

.. tabs::

	.. group-tab:: C++
	
		.. literalinclude:: ../../../internals/tests/docs/source/cpp/00700_lights.cpp
		   :start-after: //! [camera_relative_lights]
		   :end-before: //! [camera_relative_lights]
		   
	.. group-tab:: C#

		.. literalinclude:: ../../../internals/tests/docs/source/cs/00700_lights.cs
		   :start-after: //! [camera_relative_lights]
		   :end-before: //! [camera_relative_lights]
		   