Lighting setups#

Each Scene has associated lights. The lights control how the objects in a scene is lit.

[1]:
import fresnel
import math
import matplotlib, matplotlib.cm
from matplotlib import pyplot
%matplotlib inline
import numpy

device = fresnel.Device()
scene = fresnel.Scene(device)
position = []
for k in range(5):
    for i in range(5):
        for j in range(5):
            position.append([2*i, 2*j, 2*k])
geometry = fresnel.geometry.Sphere(scene, position = position, radius=1.0)
geometry.material = fresnel.material.Material(primitive_color_mix=1.0, color=(1,1,1))
mapper = matplotlib.cm.ScalarMappable(norm = matplotlib.colors.Normalize(vmin=0, vmax=1, clip=True),
                                      cmap = matplotlib.cm.get_cmap(name='viridis'))

v = numpy.linspace(0,1,len(position))
geometry.color[:] = fresnel.color.linear(mapper.to_rgba(v))
scene.camera = fresnel.camera.Orthographic.fit(scene, view='isometric')
tracer = fresnel.tracer.Path(device, w=450, h=450)

Lighting presets#

Fresnel defines many lighting presets that use classic photography techniques to light the scene. Create a setup and assign it to the Scene’s lights.

The images in these examples are noisy because of the small number of samples. Increase the number of samples to obtain less noisy images.

Light box#

A light box lights the scene equally from all sides. This type of lighting is commonly used product photography.

[2]:
scene.lights = fresnel.light.lightbox()
tracer.sample(scene, samples=64, light_samples=10)
[2]:
../../_images/examples_00-Basic-tutorials_05-Lighting-setups_4_0.png

Cloudy#

Cloudy lighting mimics a cloudy day. Strong light comes from all directions above, while weak light comes from below.

[3]:
scene.lights = fresnel.light.cloudy()
tracer.sample(scene, samples=64, light_samples=10)
[3]:
../../_images/examples_00-Basic-tutorials_05-Lighting-setups_6_0.png

Rembrandt#

Rembrandt lighting places the key light 45 degrees to one side and slightly up.

[4]:
scene.lights = fresnel.light.rembrandt()
tracer.sample(scene, samples=64, light_samples=10)
[4]:
../../_images/examples_00-Basic-tutorials_05-Lighting-setups_8_0.png

Use the side argument specify which side to place the key light on.

[5]:
scene.lights = fresnel.light.rembrandt(side='left')
tracer.sample(scene, samples=64, light_samples=10)
[5]:
../../_images/examples_00-Basic-tutorials_05-Lighting-setups_10_0.png

Loop lighting#

Loop lighting places the key light slightly to one side and slightly up.

[6]:
scene.lights = fresnel.light.loop()
tracer.sample(scene, samples=64, light_samples=10)
[6]:
../../_images/examples_00-Basic-tutorials_05-Lighting-setups_12_0.png

Butterfly lighting#

Butterfly lighting places the key light high above the camera.

[7]:
scene.lights = fresnel.light.butterfly()
tracer.sample(scene, samples=64, light_samples=10)
[7]:
../../_images/examples_00-Basic-tutorials_05-Lighting-setups_14_0.png

Ring lighting#

The ring lighting setup provides a strong front area light. This type of lighting is common in fashion photography.

[8]:
scene.lights = fresnel.light.ring()
tracer.sample(scene, samples=64, light_samples=10)
[8]:
../../_images/examples_00-Basic-tutorials_05-Lighting-setups_16_0.png

Custom lights#

You can define your own custom lights. Provide a direction vector pointing to the light in the coordinate system of the camera (+x points to the right, +y points up, and +z points out of the screen). The light color defines both the color (RGB) and the intensity of the light in a linear sRGB color space.

[9]:
my_lights = [fresnel.light.Light(direction=(1,-1,1), color=(1,1,1))]
scene.lights = my_lights
[10]:
tracer.sample(scene, samples=64, light_samples=10)
[10]:
../../_images/examples_00-Basic-tutorials_05-Lighting-setups_19_0.png

The shadows are very dark. Add another light to fill them in. You can access the scene’s lights directly. The value theta defines the half angle width of the light source. Large lights provide soft shadows.

[11]:
scene.lights.append(fresnel.light.Light(direction=(0,0,1), color=(1,1,1), theta=3.14))
tracer.sample(scene, samples=64, light_samples=10)
[11]:
../../_images/examples_00-Basic-tutorials_05-Lighting-setups_21_0.png

This image is overexposed.

Highlight warnings show overexposed areas of the image as a special color (default: magenta).

[12]:
tracer.enable_highlight_warning()
tracer.render(scene)
[12]:
../../_images/examples_00-Basic-tutorials_05-Lighting-setups_23_0.png

If the histogram is blocking up at 1.0, there are overexposed highlights.

[13]:
L, bins = tracer.histogram()
pyplot.fill_between(bins, L[:,3], color='blue');
pyplot.fill_between(bins, L[:,2], color='green');
pyplot.fill_between(bins, L[:,1], color='red');
pyplot.fill_between(bins, L[:,0], color='gray');
../../_images/examples_00-Basic-tutorials_05-Lighting-setups_25_0.png

Reduce the intensity of the light to correctly expose the image.

[14]:
scene.lights[1].color=(0.45,0.45,0.45)
tracer.sample(scene, samples=64, light_samples=10)
[14]:
../../_images/examples_00-Basic-tutorials_05-Lighting-setups_27_0.png

Now there are no clipping warnings and the histogram shows a perfectly exposed image.

[15]:
L, bins = tracer.histogram()
pyplot.fill_between(bins, L[:,3], color='blue');
pyplot.fill_between(bins, L[:,2], color='green');
pyplot.fill_between(bins, L[:,1], color='red');
pyplot.fill_between(bins, L[:,0], color='gray');
../../_images/examples_00-Basic-tutorials_05-Lighting-setups_29_0.png

scene.lights has typical sequence like behavior. You can assign a sequence of Light objects to it, append lights to it, and loop over the lights in it. For example, reverse the direction of every light:

[16]:
for l in scene.lights:
    d = l.direction;
    l.direction = (-d[0], -d[1], -d[2])
[17]:
scene.lights[1].color=(0.05,0.05,0.05)
tracer.disable_highlight_warning()
tracer.sample(scene, samples=64, light_samples=10)
[17]:
../../_images/examples_00-Basic-tutorials_05-Lighting-setups_32_0.png

This page was generated from a jupyter notebook. You can download and run the notebook locally from the fresnel-examples repository.