Loading and Configuring Models¶
The first step to any rendering application is loading your models. Pyrender implements the GLTF 2.0 specification, which means that all models are composed of a hierarchy of objects.
At the top level, we have a Mesh. The Mesh is
basically a wrapper of any number of Primitive types,
which actually represent geometry that can be drawn to the screen.
Primitives are composed of a variety of parameters, including
vertex positions, vertex normals, color and texture information,
and triangle indices if smooth rendering is desired.
They can implement point clouds, triangular meshes, or lines
depending on how you configure their data and set their
Primitive.mode parameter.
Although you can create primitives yourself if you want to,
it’s probably easier to just use the utility functions provided
in the Mesh class.
Creating Triangular Meshes¶
Simple Construction¶
Pyrender allows you to create a Mesh containing a
triangular mesh model directly from a Trimesh object
using the Mesh.from_trimesh() static method.
>>> import trimesh
>>> import pyrender
>>> import numpy as np
>>> tm = trimesh.load('examples/models/fuze.obj')
>>> m = pyrender.Mesh.from_trimesh(tm)
>>> m.primitives
[<pyrender.primitive.Primitive at 0x7fbb0af60e50>]
You can also create a single Mesh from a list of
Trimesh objects:
>>> tms = [trimesh.creation.icosahedron(), trimesh.creation.cylinder()]
>>> m = pyrender.Mesh.from_trimesh(tms)
[<pyrender.primitive.Primitive at 0x7fbb0c2b74d0>,
<pyrender.primitive.Primitive at 0x7fbb0c2b7550>]
Vertex Smoothing¶
The Mesh.from_trimesh() method has a few additional optional parameters.
If you want to render the mesh without interpolating face normals, which can
be useful for meshes that are supposed to be angular (e.g. a cube), you
can specify smooth=False.
>>> m = pyrender.Mesh.from_trimesh(tm, smooth=False)
Per-Face or Per-Vertex Coloration¶
If you have an untextured trimesh, you can color it in with per-face or per-vertex colors:
>>> tm.visual.vertex_colors = np.random.uniform(size=tm.vertices.shape)
>>> tm.visual.face_colors = np.random.uniform(size=tm.faces.shape)
>>> m = pyrender.Mesh.from_trimesh(tm)
Instancing¶
If you want to render many copies of the same mesh at different poses,
you can statically create a vast array of them in an efficient manner.
Simply specify the poses parameter to be a list of N 4x4 homogenous
transformation matrics that position the meshes relative to their common
base frame:
>>> tfs = np.tile(np.eye(4), (3,1,1))
>>> tfs[1,:3,3] = [0.1, 0.0, 0.0]
>>> tfs[2,:3,3] = [0.2, 0.0, 0.0]
>>> tfs
array([[[1. , 0. , 0. , 0. ],
[0. , 1. , 0. , 0. ],
[0. , 0. , 1. , 0. ],
[0. , 0. , 0. , 1. ]],
[[1. , 0. , 0. , 0.1],
[0. , 1. , 0. , 0. ],
[0. , 0. , 1. , 0. ],
[0. , 0. , 0. , 1. ]],
[[1. , 0. , 0. , 0.2],
[0. , 1. , 0. , 0. ],
[0. , 0. , 1. , 0. ],
[0. , 0. , 0. , 1. ]]])
>>> m = pyrender.Mesh.from_trimesh(tm, poses=tfs)
Custom Materials¶
You can also specify a custom material for any triangular mesh you create
in the material parameter of Mesh.from_trimesh().
The main material supported by Pyrender is the
MetallicRoughnessMaterial.
The metallic-roughness model supports rendering highly-realistic objects across
a wide gamut of materials.
For more information, see the documentation of the
MetallicRoughnessMaterial constructor or look at the Khronos
documentation for more information.
Creating Point Clouds¶
Point Sprites¶
Pyrender also allows you to create a Mesh containing a
point cloud directly from numpy.ndarray instances
using the Mesh.from_points() static method.
Simply provide a list of points and optional per-point colors and normals.
>>> pts = tm.vertices.copy()
>>> colors = np.random.uniform(size=pts.shape)
>>> m = pyrender.Mesh.from_points(pts, colors=colors)
Point clouds created in this way will be rendered as square point sprites.
Point Spheres¶
If you have a monochromatic point cloud and would like to render it with spheres, you can render it by instancing a spherical trimesh:
>>> sm = trimesh.creation.uv_sphere(radius=0.1)
>>> sm.visual.vertex_colors = [1.0, 0.0, 0.0]
>>> tfs = np.tile(np.eye(4), (len(pts), 1, 1))
>>> tfs[:,:3,3] = pts
>>> m = pyrender.Mesh.from_trimesh(m, poses=poses)