ianmackenzie / elm-3d-scene / Scene3d.Light


type alias Light coordinates castsShadows =
Scene3d.Types.Light coordinates castsShadows

A Light represents a single source of light in the scene, such as the sun or a light bulb. Lights are not rendered themselves; they can only be seen by how they interact with objects in the scene.


type CastsShadows a

The CastsShadows type is used to indicate either whether a given light casts shadows. Lights can usually be constructed using Light.castsShadows True or Light.castsShadows False, but if you want to use more than four lights in a scene then the extra lights must be constructed with the special Light.neverCastsShadows value. This system allows the first four lights to have shadows dynamically enabled/disabled at runtime, while using the type system to guarantee that no more than four lights ever cast shadows.

castsShadows : Basics.Bool -> CastsShadows Basics.Bool

Construct a CastsShadows Bool value used to indicate whether a given light casts shadows.

neverCastsShadows : CastsShadows Basics.Never

Construct a special CastsShadows Never value used to indicate that a given light never casts shadows.

directional : CastsShadows castsShadows -> { chromaticity : Chromaticity, intensity : Illuminance, direction : Direction3d coordinates } -> Light coordinates castsShadows

Create a directional light given its chromaticity, intensity, direction, and whether or not it casts shadows:

sunlightAtNoon =
    Light.directional (Light.castsShadows True)
        { chromaticity = Light.sunlight
        , intensity = Illuminance.lux 80000
        , direction = Direction3d.negativeZ
        }

Note that the direction is the direction the light is traveling (the direction of the light, not the direction to the light source from the scene).

Directional lights cast uniform light across the entire scene and result in relatively simple shadows:

Scene illuminated by a directional light

(Note that this scene also includes some soft lighting in addition to the directional light.)

point : CastsShadows castsShadows -> { chromaticity : Chromaticity, intensity : LuminousFlux, position : Point3d Length.Meters coordinates } -> Light coordinates castsShadows

Create a point light given its chromaticity, intensity, position, and whether or not it casts shadows:

tableLamp =
    Light.point (Light.castsShadows True)
        { chromaticity = Light.incandescent
        , intensity = LuminousFlux.lumens 500
        , position = Point3d.centimeters 40 50 30
        }

Compared to a directional light, the illumination from a point light varies more over the scene (brighter close to the light, less bright further away) and results in more interesting shadows:

Scene illuminated by a point light

(Note that this scene also includes some soft lighting in addition to the point light.)

soft : { upDirection : Direction3d coordinates, chromaticity : Chromaticity, intensityAbove : Illuminance, intensityBelow : Illuminance } -> Light coordinates Basics.Never

Add some 'soft' indirect/environmental lighting to a scene: this is a rough approximation for light coming from all different directions, such as light coming from the sky (as opposed to direct sunlight) or indirect lighting reflected from surrounding surfaces. The intensity of the light will vary smoothly from a given intensity 'above' to 'below', based on given 'up' direction and with a given chromaticity.

For example, a decent approximation to indoors office lighting might be:

Light.soft
    { upDirection = Direction3d.positiveZ
    , chromaticity = Light.fluorescent
    , intensityAbove = Illuminance.lux 400
    , intensityBelow = Illuminance.lux 100
    }

Note that soft lighting does not cast shadows. Soft lighting is a great way to make sure the entire scene has some reasonable illumination; the point and directional light examples both include a small amount of soft lighting to 'fill in' otherwise unlit areas. For example, here's the point light example without any additional lighting:

Scene illuminated by a point light only

Conversely, soft lighting by itself can be a bit boring, so in many cases you'll want to add one or more point and/or directional lights to add interest:

Scene illuminated by soft lighting only

overhead : { upDirection : Direction3d coordinates, chromaticity : Chromaticity, intensity : Illuminance } -> Light coordinates Basics.Never

A slightly simplified version of Light.soft with the given intensity above and zero intensity below. This can be useful if you want color (chromaticity) to also vary from above to below; for example, for and outdoors scene you might use two 'overhead' lights with different chromaticities and opposite 'up' directions to represent light from the blue sky plus some more neutral-colored light reflected from the surrounding environment:

sky =
    Light.overhead
        { upDirection = Direction3d.positiveZ
        , chromaticity = Light.skylight
        , intensity = Illuminance.lux 20000
        }

environment =
    Light.overhead
        { upDirection = Direction3d.negativeZ
        , chromaticity = Light.daylight
        , intensity = Illuminance.lux 15000
        }

Note that the environment light has the 'up' direction set to negative Z since that light mostly comes from below (reflected from the ground) than above.

ambient : { chromaticity : Chromaticity, intensity : Illuminance } -> Light coordinates Basics.Never

A simple version of Light.soft with constant intensity light in every direction. Provided for completeness, but you generally won't want to use this as it tends to result in very flat, unrealistic-looking scenes:

Scene illuminated by ambient lighting

disabled : Light coordinates castsShadows

A 'light' that does not actually do anything. Can be useful if you have some conditional logic that decides whether a particular light is on or off:

lamp =
    if model.lampIsOn then
        Light.point (Light.castsShadows True)
            { position = model.lampPosition
            , chromaticity = Light.incandescent
            , intensity = LuminousFlux.lumens 400
            }

    else
        Light.disabled

Chromaticity


type alias Chromaticity =
Scene3d.Types.Chromaticity

Chromaticity is a precise way of describing color independent of brightness. You can think of it as roughly hue and saturation without value or lightness.

Chromaticity is used for specifying the color of individual lights as well as the white balance to use for the overall scene.

color : Color -> Chromaticity

Extract the chromaticity of a given color. Note that this is a lossy conversion since it throws away any lightness/brightness information. For example, any greyscale color value will have chromaticity equal to Light.daylight (since that is the standard 'white' chromaticity for the sRGB color space).

daylight : Chromaticity

The approximate chromaticity of noon daylight; this is a combination of direct sunlight and blue sky, so is slightly cooler than pure sunlight. As a result, this is a good default choice for white balance and indirect lighting, but for direct lighting you'll likely want to use sunlight, skylight, incandescent or fluorescent instead.

This is standardized as Illuminant D65, "Noon Daylight", and is the 'white' color of a properly-calibrated sRGB monitor.

sunlight : Chromaticity

An approximate chromaticity value for direct daytime sunlight. This doesn't seem to have an offically standardized value, but 'sunlight' film is apparently calibrated to a color temperature of 5600 K so that is what is used here. (This falls at low end of 'vertical daylight' and above 'horizon daylight', so should be a decent representative value.)

skylight : Chromaticity

An approximate chromaticity value for clear blue sky. There seems to be even less agreement on a representative value to use here, but a color temperature of 12000 K seems fairly reasonable (see e.g. here).

incandescent : Chromaticity

The chromaticity of typical incandescent/tungsten lighting. This is standardized as Illuminant A, "Incandescent/Tungsten".

fluorescent : Chromaticity

The chromaticity of typical fluorescent lighting. This is standardized as Illuminant F2, "Cool White Fluorescent".

colorTemperature : Temperature -> Chromaticity

Specify chromaticity by providing a color temperature. For example, Light.daylight is equivalent to

Light.colorTemperature (Temperature.kelvins 5600)

See here for the color temperatures of many common sources of light.

chromaticity : { x : Basics.Float, y : Basics.Float } -> Chromaticity

Specify chromaticity by its xy coordinates in the CIE xyY color space.