File: attenuation.py

package info (click to toggle)
python-pyvista 0.44.1-11
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 159,804 kB
  • sloc: python: 72,164; sh: 118; makefile: 68
file content (102 lines) | stat: -rw-r--r-- 4,050 bytes parent folder | download
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
"""
.. _attenuation_example:

Attenuation
~~~~~~~~~~~

Attenuation is the phenomenon of light's intensity being gradually dampened as
it propagates through a medium. In PyVista positional lights can show attenuation.
The quadratic attenuation model uses three parameters to describe attenuation:
a constant, a linear and a quadratic parameter. These parameters
describe the decrease of the beam intensity as a function of the distance, `I(r)`.
In a broad sense the constant, linear and quadratic components correspond to
`I(r) = 1`, `I(r) = 1/r` and `I(r) = 1/r^2` decay of the intensity with distance
from the point source. In all cases a larger attenuation value (of a given kind)
means stronger dampening (weaker light at a given distance).

So the constant attenuation parameter corresponds roughly to a constant intensity
component. The linear and the quadratic attenuation parameters correspond to intensity
components that decay with distance from the source. For the same parameter value the
quadratic attenuation produces a beam that is shorter in range than that produced
by linear attenuation.

Three spotlights with three different attenuation profiles each:
"""

# sphinx_gallery_thumbnail_number = 3
from __future__ import annotations

import pyvista as pv

plotter = pv.Plotter(lighting='none')
billboard = pv.Plane(direction=(1, 0, 0), i_size=6, j_size=6)
plotter.add_mesh(billboard, color='white')

all_attenuation_values = [(1, 0, 0), (0, 2, 0), (0, 0, 2)]
offsets = [-2, 0, 2]
for attenuation_values, offset in zip(all_attenuation_values, offsets):
    light = pv.Light(position=(0.1, offset, 2), focal_point=(0.1, offset, 1), color='cyan')
    light.positional = True
    light.cone_angle = 20
    light.intensity = 15
    light.attenuation_values = attenuation_values
    plotter.add_light(light)

plotter.view_yz()
plotter.show()


# %%
# It's not too obvious but it's visible that the rightmost light with quadratic
# attenuation has a shorter range than the middle one with linear attenuation.
# Although it seems that even the leftmost light with constant attenuation loses
# its brightness gradually, this partly has to do with the fact that we sliced
# the light beams very close to their respective axes, meaning that light hits
# the surface in a very small angle. Altering the scene such that the lights
# are further away from the plane changes this:

plotter = pv.Plotter(lighting='none')
billboard = pv.Plane(direction=(1, 0, 0), i_size=6, j_size=6)
plotter.add_mesh(billboard, color='white')

all_attenuation_values = [(1, 0, 0), (0, 2, 0), (0, 0, 2)]
offsets = [-2, 0, 2]
for attenuation_values, offset in zip(all_attenuation_values, offsets):
    light = pv.Light(position=(0.5, offset, 3), focal_point=(0.5, offset, 1), color='cyan')
    light.positional = True
    light.cone_angle = 20
    light.intensity = 15
    light.attenuation_values = attenuation_values
    plotter.add_light(light)

plotter.view_yz()
plotter.show()

# %%
# Now the relationship of the three kinds of attenuation seems clearer.
#
# For a more practical comparison, let's look at planes that are perpendicular
# to the axis of each light (making use of the fact that shadowing between
# objects is not handled by default):

plotter = pv.Plotter(lighting='none')

# loop over three lights with three kinds of attenuation
all_attenuation_values = [(2, 0, 0), (0, 2, 0), (0, 0, 2)]
light_offsets = [-6, 0, 6]
for attenuation_values, light_x in zip(all_attenuation_values, light_offsets):
    # loop over three perpendicular planes for each light
    for plane_y in [2, 5, 10]:
        screen = pv.Plane(center=(light_x, plane_y, 0), direction=(0, 1, 0), i_size=5, j_size=5)
        plotter.add_mesh(screen, color='white')

    light = pv.Light(position=(light_x, 0, 0), focal_point=(light_x, 1, 0), color='cyan')
    light.positional = True
    light.cone_angle = 15
    light.intensity = 5
    light.attenuation_values = attenuation_values
    light.show_actor()
    plotter.add_light(light)

plotter.view_vector((1, -2, 2))
plotter.show()