OSL shaders: part 4

Light-emitting shaders

Although the OSL specification says that one possible shader type is a light shader, it immediately goes on to say that a separate shader type is not necessary, since surface shaders can also emit light. So how do we write such a shader?

1. Shader type

The first thing to note is that to emit light, this shader should be a closure. The OSL function required is emission(), and a simple shader would look like this:

// simple light emission closure

surface LightEmitter (
    color Color = color(1, 0.5, 0),
    float Strength = 1.0,
    output closure color Light = emission()
)
{
    Light = emission() * Color * Strength;
}

As you can see, the output is a closure color and all we need to do is link the output port 'Light' to the 'Surface' input of the Output node. There's no need to use a material node in between, in fact if you do so, it won't work at all.

This is the result:

There are a couple of things to note. First, the light is really there, it isn't a fake - the light illuminates the cylinder and casts a shadow. Secondly, there is no shading on the emitting object - it's just a light source.

2. Using an inbuilt closure

Although the above code is really simple, OSL makes it even easier. See this code:

// even simpler light emission closure

surface LightEmitter (
    color Color = color(1, 0.5, 0),
    float Strength = 1.0,
)
{
    Ci = emission() * Color * Strength;
}

Here, no output variable is declared. The closure is calculated in the same way, but is then assigned to a variable named 'Ci'. This is a built-in global variable, which is also a closure. All we do is assign the colour to be output to Ci, then it will automatically appear as an output port in the node interface. Connect the 'Ci' output to the 'Surface' input of the Output node, and it works exactly as before.

3. Input variables

With this shader, we aren't restricted to single colours. For example, we can use a Ramp node to control the colour like so:

Which gives this result when rendered:

So light-emitting shaders are possible with OSL and work very well without the need for a separate shader type.

<-- Part 3: Converting a Renderman shader for use in Redshift

Part 5: Converting a Blender shader to Redshift -->

Page last updated July 31st 2025