### LightHandler LightInterface Availability LightWave® 9.5 Component Layout Header lwlight.h Light handlers implement different types of light. Before LightWave® 9.5 only a fixed set of built-in light types were available. With version 9.5 the light calculations have been moved to a plugin API, enabling an unlimited range of light types to be added. Light plugins provide illumination in a scene. Light plugins are not concerned with how this illumination interacts with a surface to create shading (that is the role of shader handlers). To enforce the seperation between lighting and shading, light handlers are provided with only minimal surface and mesh information. What mesh information is provided is meant for optimization purposes. Different parts of the rendering and Layout preview system have different requirements for light evaluation. The light API therefore contains several light evaluation functions, each specialized for the various areas. Some are optional, in which case the light does not support that type of rendering, or a fallback evaluation method is used (which may slow down rendering, or produce inaccurate results). There are four light evaluation functions that a light plugin can implement: `evaluate` Determines the lighting at a point in space. Used for surface shading. `getPhotons` Generates particles of light originating at the light, shooting into the scene. This is used for caustics. `getRayIlluminations` Gets illumination samples along a ray segment. For use with volumetric lighting. `preview` Returns an array of standard lights which are used as an approximation of the light type for Layout preview rendering. Light evaluation generates illumination information in the form of one or more rays that illuminate a point in space. These rays can originate from anywhere, and need not be tied to the position of the light item. This allows a single light to create complex lighting effects. Light handlers can override several parts of the lighting and shading pipeline. Reasons for doing this include optimization, providing the user with controls beyond that provided natively, and removal of options which do not apply to the light type. Handlers can opt to do their own occlusion and volumetric shadow calculations, and apply their own light falloff instead of the native falloff calculations. As lights are evaluated during rendering, light plugins must be aware of multithreading. Light evaluations associated with rendering are supplied with a pre-allocated array to fill in, rather than having to manage per-thread illumination arrays themselves. For speed, light plugins should avoid using write locks or critical sections in the evaluation functions. The `newFrame` callback can be used to do pre-computation at the start of each render frame. Light plugins can also be evaluated from other plugins through the light evaluation global. Evaluating a plugin from mulitple clients at the same time can cause problems if each client expects the plugin to be in a different state (for example, at different frame numbers). To prevent such problems each light evaluator is given a copy of the light plugin instance. It is therefore important that the plugin implements the copy instance function. Handler Activation Function
       XCALL_( int ) MyLight( int version, GlobalFunc *global,
          LWLightHandler *local, void *serverData );
The `local` argument to a LightHandler activation function is an LWLightHandler.
       typedef struct st_LWLightHandler
       {
          LWInstanceFuncs* inst;
          LWItemFuncs* item;
          LWRenderFuncs* rend;
          unsigned int (*flags)      (LWInstance);
          LWError      (*newFrame)   (LWInstance, const LWFrameInfo* frameinfo,
                                      unsigned int* maxilluminations,
                                      const LWLightAccess* lightaccess);
          int          (*evaluate)   (LWInstance, const LWDVector spot, double fractime,
                                      LWIllumination illumination[],
                                      const LWLightAccess* lightaccess);
          unsigned int (*getPhotons) (LWInstance, unsigned int maxphotons, LWPhoton photons[],
                                      const LWLightAccess* lightaccess);
          unsigned int (*getRayIlluminations) (LWInstance, LWDVector raystart, LWDVector raydir,
                                               double farclip, unsigned int maxrayilluminations,
                                               LWRayIllumination rayilluminations[],
                                               const LWLightAccess* lightaccess);
          const LWPreviewLight* (*preview)    (LWInstance);
       } LWLightHandler;
  The first three members of this structure are the standard handler functions. The `context` argument to the `inst->create` function is the LWItemID of the associated light item. `flags = flags( instance )` Returns bit flags combined using bitwise-or. Currently defined flags are: `LWLIGHTTYPEF_NO_PHOTONS` The light does not support photon generation (for example, caustics). `LWLIGHTTYPEF_NO_RAYILLUM` The light does not support ray illumination (for example, volumetric lights). `LWLIGHTTYPEF_OCCLUSION_SHADOWED` Returned illumination already includes the effects of occlusion shadowing. `LWLIGHTTYPEF_VOLUMETRICS_SHADOWED` Returned illumination already includes the effects of volumetric shadowing. `LWLIGHTTYPEF_NO_FALLOFF` Do not show standard falloff gadgets, and do not apply falloff. `LWLIGHTTYPEF_SHOW_FALLOFF` Show the standard falloff gadgets, but do not apply falloff. The `NO_FALLOFF` and `SHOW_FALLOFF` flags can be used by light plugins to override the standard falloff calculations applied by the renderer. At most one of these two flags can be set. `result = newFrame( instance, frameinfo, maxilluminations, lightaccess )` This is called whenever a new set of evaluations is started, usually at the start of a frame render. This is a good place to do some pre-computation. The light access structure is explained below. The `frameinfo` structure is the same as that used by camera plugins. The plugin fills in `maxilluminations` with the largest number of illuminations it intends to fill in in the evaluation functions. As this is used to allocate the illumination array, the value should be a tight upper bound (if not exact). Returns a pointer to an error string of something went wrong, or NULL if all is well. `result = evaluate( instance, spot, fractime, illumination, lightaccess )` Given a position `spot` in space and a fractional time into the frame, compute the illumination by the light. The illumination is returned by filling in the supplied illumination array. The plugin must fill in no more than the maximum number of illuminations it returned in `newFrame()`. It can however fill in fewer entries, or even none. The actual number is allowed to vary with each call (for example, for some sort of adaptive illumination).
         typedef struct st_LWIllumination {
            LWDVector color;
            double intensity;
            LWDVector direction;
            double distance;
            LWDVector shadowAttenuation;
         } LWIllumination;
  `color, intensity` The color and intensity of the sample. Do not include the intensity in the color. The renderer will combine the color and intensity. The renderer will also take care of applying the standard light color and intensity and, unless set otherwise through the `NO_FALLOFF` or `SHOW_FALLOFF` flags, the falloff. For a light which just uses the standard color, intensity, and falloff settings, the color would be set to white and the intensity to 1. `direction` The direction from which the illumination is coming, in world coordinates. It must be normalized. `distance` The distance between the spot being illuminated, and the source of the illumination. The source need not be the position of the light item. This is used by the renderer to apply falloff and occlusion, if needed. A value of `DBL_MAX` indicates the source is infinitely far away. `shadowAttenuation` Degree by which shadows attenuate the illumination. Note that each color channel can have its own attenuation. The supplied time value is a fraction between 0 and 1 that ranges over the time duration of the frame (which can be retrieved from the frameinfo structure supplied to `newFrame()`). 0 means the start time of the frame, while 1 means the time at the end of the duration of the frame (which may be different than that implied by the current frames per second setting, as it includes the effects of fields and motion blur length). There is no defined ordering to the time values that will be given. It is recommended that the handler pre-compute any animation of settings in `newFrame()` and uses the `fractime` parameter to interpolate. The return value of the function is the number of entries filled in by the evaluation, and must be between zero and `maxilluminations` set by the `newFrame()` callback. `result = getPhotons( instance, maxphotons, photons, lightaccess )` Called to generate a number of photons from the light. This is used for caustics, which traces photons through the scene by shooting them from the light source. Each photon has a color, intensity, starting position and direction in world space.
         typedef struct st_LWPhoton {
            LWDVector color;
            double intensity;
            LWDVector direction;
            LWDVector worldPos;
         } LWPhoton;
  The light plugin fills in the photon information in the `photons` array. Up to `maxphotons` photons can be stored in the array. This number is not related to the `maxilluminations` value set by `newFrame()`. The functions returns the number of photons filled in, which must be a number between zero and `maxphotons`. `result = getRayIlluminations( instance, raystart, raydir, farclip, maxrayilluminations, rayilluminations, lightaccess )` Used to sample the illumination of a light along an arbitrary ray. This is intended to be used for volumetric lights. Support for this function is not yet implemented. `previewlights = preview( instance )` In order to preview a light in Layout, the plugin can provide an array of preview light descriptions. Each preview light is a standard OpenGL light type: `LWPREVIEWLIGHT_DISTANT` `LWPREVIEWLIGHT_POINT` `LWPREVIEWLIGHT_SPOT` `LWPREVIEWLIGHT_AMBIENT` The array must be terminated by a preview light type of `LWPREVIEWLIGHT_END`. The array contains `LWPreviewLight` structures. Not all the fields in the structure are used for all preview light types.
         typedef struct st_LWPreviewLight {
            int previewtype;

            LWDVector worldPos;
            LWDVector toWorld[3];

            LWDVector color;
            double intensity;

            double range;
            int falloff;

            double coneAngle;
            double coneEdge;
         } LWPreviewLight;
`previewtype` The preview light type. The array must be terminated with a `LWPREVIEWLIGHT_END` type. `worldPos` The world position of the light. Only point and spot lights have a position. Ignored for other types. `toWorld` The X, Y, and Z axes of the light in world coordinates. The distant and spot lights require only the Z axis. The ambient and point lights have no directional component, so this field is ignored completely for those. `color, intensity` The color and intensity of the light. `range, falloff` Falloff settings for point and spot lights. The falloff is one of the `LWLFALL_*` values. See the Light Info global on how range and falloff are used. `coneAngle, coneEdge` Used only for the spot preview light type, these give the radius and soft edge angles of the spot in radians. The return value can be NULL, in which case no preview lights are used. Interface Activation Function
       XCALL_( int ) MyInterface( int version, GlobalFunc *global,
          LWInterface *local, void *serverData );
This is the standard interface activation for handlers. XPanels are inserted at the bottom of the Basic tab in the Light Properties panel. Light Access The access structure information that may be useful for computing the light.
       typedef struct st_LWLightAccess {
          LWItemID lightID;

          LWDVector worldPos;

          LWDVector toWorld[3];
          LWDVector toLight[3];

          unsigned int maxIlluminations;

          LWRayCastFunc*      rayCast;
          RandomFloatData     randomData;
          LWRandomFloatFunc*  randomFloat;

          unsigned int bounces;
          unsigned int flags;

          LWDVector surfaceNormal;

       } LWLightAccess;
`lightID` The ItemID of the light that the LightHandler plugin is be applied to. `worldPos` The position of the light item in world coordinates. `toWorld[3]` Right, Up and Forward directions of the light in world coordinates. `toLight[3]` Inverse of `toWorld[3]` . `maxIlluminations` The maximum number of illumination samples the plugin set in `newFrame()`. `rayCast` Raytracing function available to light plugins for determining occlusion and distance to mesh surfaces. Note that using other raytracing functions which do light evaluations potentially create an infinite recursion situation. `randomFloat` A random number generator which produces consistent results across frames. Returns values in the interval (0, 1). `bounces` The number of times the viewing ray has branched, or bounced, before evaluating the light. `flags` A combination of zero or more of: `LWLF_SAMPLEDRAY` Set when the light is being evaluated for a sampling ray, for example for soft reflections. Such cases can generally use a lower light quality, resulting in significant time savings. `LWLF_HAVESURFACE` The light is being evaluated for a point on a mesh surface. This indicates the existence of a surface normal (see below). `LWLF_PREPROCESS` The light evaluation is part of a preprocessing step, typically radiosity preprocessing. As with the `LWLF_SAMPLEDRAY` flag the plugin can use this to evaluate quicker at a lower quality. `surfaceNormal` If the `LWLF_HAVESURFACE` flag is set (see above), then the normal of the surface is supplied in this field. Otherwise the values are undefined.