1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
"""
.. _light_shadows_example:
Shadows
~~~~~~~
Demonstrate the usage of lights and shadows in PyVista.
"""
from __future__ import annotations
import numpy as np
# sphinx_gallery_thumbnail_number = 2
import pyvista
from pyvista import examples
mesh = examples.download_dragon()
mesh.rotate_x(90, inplace=True)
mesh.rotate_z(120, inplace=True)
# %%
# Using two lights, plot the Stanford Dragon with shadows.
#
# .. Note::
# VTK has known issues when rendering shadows on certain window
# sizes. Be prepared to experiment with the ``window_size``
# parameter. An initial window size of ``(1000, 1000)`` seems to
# work well, which can be manually resized without issue.
light1 = pyvista.Light(
position=(0, 0.2, 1.0),
focal_point=(0, 0, 0),
color=[1.0, 1.0, 0.9843, 1.0], # Color temp. 5400 K
intensity=0.3,
)
light2 = pyvista.Light(
position=(0, 1.0, 1.0),
focal_point=(0, 0, 0),
color=[1.0, 0.83921, 0.6666, 1.0], # Color temp. 2850 K
intensity=1,
)
# Add a thin box below the mesh
bounds = mesh.bounds
rnge = (bounds[1] - bounds[0], bounds[3] - bounds[2], bounds[5] - bounds[4])
expand = 1.0
height = rnge[2] * 0.05
center = np.array(mesh.center)
center -= [0, 0, mesh.center[2] - bounds[4] + height / 2]
width = rnge[0] * (1 + expand)
length = rnge[1] * (1 + expand)
base_mesh = pyvista.Cube(center, width, length, height)
# rotate base and mesh to get a better view
base_mesh.rotate_z(30, inplace=True)
mesh.rotate_z(30, inplace=True)
# create the plotter with custom lighting
pl = pyvista.Plotter(lighting=None, window_size=(800, 800))
pl.add_light(light1)
pl.add_light(light2)
pl.add_mesh(
mesh,
ambient=0.2,
diffuse=0.5,
specular=0.5,
specular_power=90,
smooth_shading=True,
color='orange',
)
pl.add_mesh(base_mesh)
pl.enable_shadows()
pl.camera.zoom(1.5)
pl.show()
# %%
# Show light penetrating several planes. Adjust the light intensity
# and the ``shadow_attenuation`` to change how many planes the
# light can go through.
plotter = pyvista.Plotter(lighting=None, window_size=(800, 800))
# add several planes
for plane_y in [2, 5, 10]:
screen = pyvista.Plane(center=(0, plane_y, 0), direction=(0, 1, 0), i_size=5, j_size=5)
plotter.add_mesh(screen, color='white')
light = pyvista.Light(
position=(0, 0, 0),
focal_point=(0, 1, 0),
color='cyan',
intensity=15,
positional=True,
cone_angle=15,
attenuation_values=(2, 0, 0),
)
light.show_actor()
plotter.add_light(light)
plotter.view_vector((1, -2, 2))
plotter.enable_shadows()
plotter.show()
# %%
# Here, we use a lower shadow_attenuation value to demonstrate how the
# light can travel through more planes.
plotter = pyvista.Plotter(lighting=None, window_size=(800, 800))
# add several planes
for plane_y in [2, 5, 10]:
screen = pyvista.Plane(center=(0, plane_y, 0), direction=(0, 1, 0), i_size=5, j_size=5)
plotter.add_mesh(screen, color='white')
light = pyvista.Light(
position=(0, 0, 0),
focal_point=(0, 1, 0),
color='cyan',
intensity=15,
cone_angle=15,
shadow_attenuation=0.95,
positional=True,
attenuation_values=(2, 0, 0),
)
light.show_actor()
plotter.add_light(light)
plotter.view_vector((1, -2, 2))
plotter.enable_shadows()
plotter.show()
|