Lights#
The pyvista.Light
class adds additional functionality and a pythonic API
to the vtk.vtkLight
class. pyvista.Plotter
objects come with a default
set of lights that work well in most cases, but in many situations a more hands-on
access to lighting is necessary.
Brief Example#
Create a red spotlight that shines on the origin, then create a scene without lighting and add our light to it manually.
import pyvista as pv
from pyvista import examples
light = pv.Light(position=(-1, 1, 1), color='red')
light.positional = True
import pyvista as pv
from pyvista import examples
plotter = pv.Plotter(lighting='none')
plotter.background_color = 'white'
mesh = examples.download_bunny()
mesh.rotate_x(90, inplace=True)
mesh.rotate_z(180, inplace=True)
plotter.add_mesh(mesh, specular=1.0, diffuse=0.7, smooth_shading=True)
plotter.add_light(light)
plotter.show()
For detailed examples please see Lighting.
Light API#
pyvista.Light
instances come in three types: headlights, camera lights, and
scene lights. Headlights always shine along the camera’s axis, camera lights
have a fixed position with respect to the camera, and scene lights are positioned
with respect to the scene, such that moving around the camera doesn’t affect the
lighting of the scene.
Lights have a position
and a
focal_point
that define the axis of the
light. The meaning of these depends on the type of the light. The color of the
light can be set according to ambient, diffuse, and specular components. The
brightness can be set with the intensity
property, and the writable on
property specifies
whether the light is switched on.
Lights can be either directional (meaning an infinitely distant point source)
or positional
. Positional lights have
additional properties that describe the geometry and the spatial distribution
of the light. The cone_angle
and
exponent
properties define the shape of the
light beam and the angular distribution of the light’s intensity within that
beam. The fading of the light with distance can be customized with the
attenuation_values
property.
Positional lights can also make use of an actor that represents the shape and
color of the light using a wire-frame, see show_actor
.
Positional lights with a cone_angle
of
less than 90 degrees are known as spotlights. Spotlights are unidirectional and
they make full use of beam shaping properties, namely exponent
and attenuation. Non-spotlight positional lights,
however, act like point sources located in the real-world position of the
light, shining in all directions of space. They display attenuation with
distance from the source, but their beam is isotropic in space. In contrast,
directional lights act as infinitely distant point sources, so they are
unidirectional but they do not attenuate.
Shadows#
With directed lights, it is possible to create complex lighting scenarios. For example, you can position a light directly above an actor (in this case, a sphere), to create a shadow directly below it.
The following example uses a positional light to create an eclipse-like shadow below a sphere by controlling the cone angle and exponent values of the light.
import pyvista as pv
plotter = pv.Plotter(lighting=None, window_size=(800, 800))
# create a top down light
light = pv.Light(position=(0, 0, 3), show_actor=True, positional=True,
cone_angle=30, exponent=20, intensity=1.5)
plotter.add_light(light)
# add a sphere to the plotter
sphere = pv.Sphere(radius=0.3, center=(0, 0, 1))
plotter.add_mesh(sphere, ambient=0.2, diffuse=0.5, specular=0.8,
specular_power=30, smooth_shading=True,
color='dodgerblue')
# add the grid
grid = pv.Plane(i_size=4, j_size=4)
plotter.add_mesh(grid, ambient=0, diffuse=0.5, specular=0.8, color='white')
# set up and show the plotter
plotter.enable_shadows()
plotter.set_background('darkgrey')
plotter.show()
Note
VTK has known issues when rendering shadows on certain window
sizes. Be prepared to experiment with the window_size
parameter.
API Reference#
|
Light class. |