/////////////////////////////////////////////////////////////////////////////
// skylight.osl
//
// Description:
//   A light that illuminates surfaces with a hemisphere of uniform
//   brightness (i.e., a sky dome), taking local occlusion into
//   account.
//
// Parameters:
//   lightcolor - color of the light
//   intensity - intensity scale for the light
//   up - vector giving the center of the hemisphere
//   occlusionname - name of the geometry set to trace against.
//   sdbname - overrides the name of the occlusion spatial database.
//      If "" (the default), the database name will be as set by 
//      Attribute("occlusion:spatialdb"), which defaults to "occlusion.sdb".
//   sdbmode - overrides or amends the file reading/writing mode for the
//      occlusion spatial database, as set by appropriate attribs.
//   samples - the number of samples to use to estimate occlusion.
//   adaptive - if zero, always use full samples.  If nonzero, use adaptive
//      sampling.  Default is 1, higher is more aggressively adaptive,
//      lower tends to use full sampling more frequently.
//   maxerror - allowable error for interpolation (versus more expensive
//      resampling of the hemisphere).  If <0, uses the value of
//      Attribute("occlusion:maxerror").
//   maxpixeldist - max allowable distance of influence for interpolation.
//      If <0, uses the value of Attribute("occlusion:maxpixeldist").
//   maxhitdist - causes ray hits farther than this distance to be ignored
//      by the occlusion test.
//   bias - ignores ray hits closer than this amount, handy for preventing
//      incorrect self-intersections due to numeric tolerance problems.
//      If bias < 0, it'll use the value set by Attribute "shadow:bias".
//   falloff - if 0, all ray hits are equally occluding.  If nonzero, the
//      influence of occluders falls off with distance according to
//      falloffmode.
//   falloffmode - if 0, occlusion is exp(-falloff/dist);  if 1, occlusion
//      is pow (1-dist/maxhitdist, falloff).
//
/////////////////////////////////////////////////////////////////////////////
// Copyright 2004 NVIDIA Corporation.  All Rights Reserved.
// 
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// 
// * Redistributions of source code must retain the above copyright
//   notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
//   notice, this list of conditions and the following disclaimer in the
//   documentation and/or other materials provided with the distribution.
// * Neither the name of NVIDIA nor the names of its contributors
//   may be used to endorse or promote products derived from this software
//   without specific prior written permission.
// 
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// (This is the Modified BSD License)
/////////////////////////////////////////////////////////////////////////////


light
skylight
    [[ string description = "Sky light, hemispherical light with occlusion" ]]
(
    vector up = vector("world", 0, 0, 1)
        [[ string description = "Up vector, points to top of sky" ]],
    float intensity = 1
        [[ string description = "Overall light intensity",
           float UIsoftmin=0 ]],
    color lightcolor = 1
        [[ string description = "Overall light color" ]],
    string occlusionname = ""
        [[ string description = "Geometry set for occlusion" ]],
    string sdbname = ""
        [[ string description = "Spatial database name for occlusion cache" ]],
    string sdbmode = ""
        [[ string description = "File mode for occlusion cache spatial database",
           string UItype = "enum:,r,w,rw,wo" ]],
    float samples = 64
        [[ string description = "Number of hemispherical samples" ]],
    float adaptive = 1
        [[ string description = "Use adaptive sampling of hemisphere",
           string UItype = "bool" ]],
    float maxerror = -1
        [[ string description = "Error metric (-1 for global default)",
           float UImax = 1 ]],
    float maxpixeldist = -1
        [[ string description = "Max pixel distance between occlusion samples (-1 for global default)" ]],
    float bias = -1
        [[ string description = "Bias - minimum distance for ray hits" ]],
    float maxhitdist = 1.0e6
        [[ string description = "Max distance for ray hits",
           float UImin = 0 ]],
    float falloff = 0
        [[ string description = "Falloff exponent of occlusion effect (0 = none)" ]],
    float falloffmode = 0
        [[ string description = "Alternate falloff mode",
           string UItype="bool" ]]
  )
{
    normal Nunocc;
    float a;

    // Compute the local occlusion
    a = 1 - occlusion (Ps, normalize(up), 
					   "traceset", occlusionname, "coneangle", M_PI_2,
					   "environmentdir", Nunocc,
                       "samples", (int)samples, "maxerror", maxerror,
                       "maxpixeldist", maxpixeldist,
                       "maxdist", maxhitdist, "bias", bias,
                       "falloff", falloff, "falloffmode", (int)falloffmode/*,
                       "adaptive", adaptive, 
                       "filename", sdbname, "filemode", sdbmode*/);

    emit (-Nunocc, 0) {
        Cl = lightcolor;
        Cl *= intensity * a;
    }
}
