Lightning

By default ipyvolume uses a fake lighting model that works ok for depth perception. To get more realistic lighting effects ipyvolume supports a few light models from pythreejs/threejs.

[1]:
import ipyvolume as ipv
import numpy as np
[2]:
def scene():
    f = ipv.figure()
    ipv.xyzlim(-1, 1)
    x = np.array([0.1, 0.5], dtype=np.float32)
    ipv.material_phong()
    s = ipv.scatter(x, x, x, marker="sphere", size=10);
    k = ipv.examples.klein_bottle(show=False)
    ipv.xyzlim(2)
    m = ipv.plot_plane('bottom')
    ipv.show()
    return f

Ambient light

For global illumination, which will not cast shadows

[3]:
scene()
light = ipv.light_ambient(intensity=0.4);

Hemisphere light

A light source positioned directly above the scene, with color fading from the sky color to the ground color. This light cannot be used to cast shadows.

[4]:
scene()
ipv.light_hemisphere(intensity=1);

Directional light

A Directional Light source illuminates all objects equally from a given direction. This light can be used to cast shadows. The light is recommended together with hemisphere.

[5]:
f = scene()
ipv.light_ambient(intensity=0.4)
ipv.light_directional(position=[3, 10, 3]);

Spot light

A Spot Light produces a directed cone of light. The light becomes more intense closer to the spotlight source and to the center of the light cone. This light can be used to cast shadows.

[6]:
scene()
ipv.light_hemisphere(intensity=0.2)
l = ipv.light_spot(position=[0, 3, 2]);

Point light

A Point Light originates from a single point and spreads outward in all directions. This light can be used to cast shadows.

[7]:
scene()
ipv.light_hemisphere(intensity=0.2)
l = ipv.light_point(position=[0., 1.6, 1.0]);

Animation example

[8]:
import ipyvolume as ipv
import ipyvolume.datasets
stream = ipyvolume.datasets.animated_stream.fetch()
print("shape of steam data", stream.data.shape) # first dimension contains x, y, z, vx, vy, vz, then time, then particle
shape of steam data (6, 200, 1250)
[9]:
fig = ipv.figure()
# instead of doing x=stream.data[0], y=stream.data[1], ... vz=stream.data[5], use *stream.data
# limit to 50 timesteps to avoid having a huge notebook
ipv.material_physical()
# q = ipv.quiver(*stream.data[:,0:200:10,:2000:10], color="red", size=7)
q = ipv.quiver(*stream.data, color="red", size=7)
ipv.style.use("dark") # looks better
m = ipv.plot_plane('bottom')
m = ipv.plot_plane('back')
m = ipv.plot_plane('left')
ipv
l = ipv.light_directional(position=[20, 50, 20], shadow_camera_orthographic_size=1, far=140, near=0.1);
ipv.animation_control(q, interval=200)
ipv.show()

[10]:
ipv.light_ambient(intensity=0.4);

Volume rendering and lighting

For volumetric rendering we only support the Phong lighting model. No material needs to be set, only lights need to be setup.

Note that volumetric regions do not cast, not receive shadows.

[11]:
import ipyvolume as ipv
[12]:
# no material and lighting
ipv.figure()
volume = ipv.examples.example_ylm(shape=64, show=False)
s = ipv.scatter(x=32, y=32, z=50, size=30, marker='sphere', color="green");

volume.tf.level1 = 0.24
volume.tf.opacity1 = 0.1
volume.brightness = 2
ipv.show()
[13]:
import ipyvolume as ipv
f = ipv.figure(debug=True)
# we only add two lights
ipv.light_hemisphere(intensity=0.8)
ipv.light_directional()

volume = ipv.examples.example_ylm(shape=64, show=False)
ipv.material_phong(specular='white')
s = ipv.scatter(x=32, y=32, z=50, size=30, marker='sphere', color="green");

volume.tf.level1 = 0.24
volume.tf.opacity1 = 0.1
volume.material.specular = 'white'
volume.brightness = 2
ipv.show()
/home/docs/checkouts/readthedocs.org/user_builds/ipyvolume/envs/latest/lib/python3.7/site-packages/ipykernel_launcher.py:2: DeprecationWarning: debug=True no longer needed

screenshot

[ ]: