Spaces:
Build error
Build error
File size: 4,902 Bytes
8554568 |
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 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
.. _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
|