| .. _model_guide: |
|
|
| 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 :class:`.Mesh`. The :class:`.Mesh` is |
| basically a wrapper of any number of :class:`.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 |
| :attr:`.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 :class:`.Mesh` class. |
|
|
| Creating Triangular Meshes |
| -------------------------- |
|
|
| Simple Construction |
| ~~~~~~~~~~~~~~~~~~~ |
| Pyrender allows you to create a :class:`.Mesh` containing a |
| triangular mesh model directly from a :class:`~trimesh.base.Trimesh` object |
| using the :meth:`.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 :class:`.Mesh` from a list of |
| :class:`~trimesh.base.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 :meth:`.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 :meth:`.Mesh.from_trimesh`. |
| The main material supported by Pyrender is the |
| :class:`.MetallicRoughnessMaterial`. |
| The metallic-roughness model supports rendering highly-realistic objects across |
| a wide gamut of materials. |
|
|
| For more information, see the documentation of the |
| :class:`.MetallicRoughnessMaterial` constructor or look at the Khronos_ |
| documentation for more information. |
|
|
| .. _Khronos: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#materials |
|
|
| Creating Point Clouds |
| --------------------- |
|
|
| Point Sprites |
| ~~~~~~~~~~~~~ |
| Pyrender also allows you to create a :class:`.Mesh` containing a |
| point cloud directly from :class:`numpy.ndarray` instances |
| using the :meth:`.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. |
|
|
| .. image:: /_static/points.png |
|
|
| 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(sm, poses=tfs) |
|
|
| .. image:: /_static/points2.png |
|
|