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
|
"""
.. _pbr_example:
Physically Based Rendering
~~~~~~~~~~~~~~~~~~~~~~~~~~
VTK 9 introduced Physically Based Rendering (PBR) and we have exposed
that functionality in PyVista. Read the `blog about PBR
<https://blog.kitware.com/vtk-pbr/>`_ for more details.
PBR is only supported for :class:`pyvista.PolyData` and can be
triggered via the ``pbr`` keyword argument of ``add_mesh``. Also use
the ``metallic`` and ``roughness`` arguments for further control.
Let's show off this functionality by rendering a high quality mesh of
a statue as though it were metallic.
"""
# sphinx_gallery_start_ignore
# physically based rendering does not seem to work in vtk-js
from __future__ import annotations
PYVISTA_GALLERY_FORCE_STATIC_IN_DOCUMENT = True
# sphinx_gallery_end_ignore
from itertools import product
import pyvista as pv
from pyvista import examples
# Load the statue mesh
mesh = examples.download_nefertiti()
mesh.rotate_x(-90.0, inplace=True) # rotate to orient with the skybox
# Download skybox
cubemap = examples.download_sky_box_cube_map()
# %%
# Let's render the mesh with a base color of "linen" to give it a metal looking
# finish.
p = pv.Plotter()
p.add_actor(cubemap.to_skybox())
p.set_environment_texture(cubemap) # For reflecting the environment off the mesh
p.add_mesh(mesh, color='linen', pbr=True, metallic=0.8, roughness=0.1, diffuse=1)
# Define a nice camera perspective
cpos = [(-313.40, 66.09, 1000.61), (0.0, 0.0, 0.0), (0.018, 0.99, -0.06)]
p.show(cpos=cpos)
# %%
# Show the variation of the metallic and roughness parameters.
#
# Plot with metallic increasing from left to right and roughness
# increasing from bottom to top.
colors = ['red', 'teal', 'black', 'orange', 'silver']
p = pv.Plotter()
p.set_environment_texture(cubemap)
for i, j in product(range(5), range(6)):
sphere = pv.Sphere(radius=0.5, center=(0.0, 4 - i, j))
p.add_mesh(sphere, color=colors[i], pbr=True, metallic=i / 4, roughness=j / 5)
p.view_vector((-1, 0, 0), (0, 1, 0))
p.show()
# %%
# Combine custom lighting and physically based rendering.
# download louis model
mesh = examples.download_louis_louvre()
mesh.rotate_z(140, inplace=True)
plotter = pv.Plotter(lighting=None)
plotter.set_background('black')
plotter.add_mesh(mesh, color='linen', pbr=True, metallic=0.5, roughness=0.5, diffuse=1)
# set up lighting
light = pv.Light((-2, 2, 0), (0, 0, 0), 'white')
plotter.add_light(light)
light = pv.Light((2, 0, 0), (0, 0, 0), (0.7, 0.0862, 0.0549))
plotter.add_light(light)
light = pv.Light((0, 0, 10), (0, 0, 0), 'white')
plotter.add_light(light)
# plot with a good camera position
plotter.camera_position = [(9.51, 13.92, 15.81), (-2.836, -0.93, 10.2), (-0.22, -0.18, 0.959)]
cpos = plotter.show()
|