-
Notifications
You must be signed in to change notification settings - Fork 129
Texturing
Geogram has several mesh parameterization algorithms, and a texture atlas generator. It makes it possible to decompose a mesh into multiple charts, unfold each chart individually and assemble them in texture space.
The main interface to the texture atlas generator is the
mesh_make_atlas()
function declared in
geogram/mesh/parameterization/mesh_atlas_maker.h:
mesh_make_atlas(
Mesh& mesh,
double hard_angles_threshold = 45.0,
ChartParameterizer param=PARAM_ABF,
ChartPacker pack=PACK_TETRIS,
bool verbose = false
)
Three parameterization algorithms (ChartParameterizer
) are implemented:
-
PARAM_LSCM
: LSCM [1] -
PARAM_SPECTRAL_LSCM
: Spectral conformal parameterization [2] -
PARAM_ABF
: ABF++ [3]
LSCM is the historic one. It is simple and fast, but does not always give the best result. Spectral LSCM is a modification proposed in [2]. The original LSCM gets rids of two degrees of freedom by locking two extremal vertices, but the solution is dependent on the chosen two vertices and can have distortion around these vertices. The solution proposed in [2] gets rid of the degrees of freedom by computing eigenvectors of the LSCM matrix. This results in better balanced distortions (at the expense of requiring an eigensolve). Finally, ABF++ is a non-linear algorithm, that better balances deformations, by solving for the angles subject to constraints that ensure the validity of the triangulation. The figure above gives an idea of the difference between LSCM (that has some distorted squares) and ABF++ (squares are more regular).
To assemble the charts in texture space, two packers (ChartPacker
) are implemented:
-
PACK_TETRIS
: the packing algorithm in [2] -
PACK_XATLAS
: uses the xatlas library
The function also has a hard_angles_threshold
parameter, that specifies the angle from which edges will be
considered as creases. Such edges are disconnected, in order to avoid creating a chart that crosses a crease.
The parameterization function creates a vector attribute of dimension 2 attached to the facet corners of the mesh. Once the surface is parameterized, one can access texture coordinates as follows:
Attribute<double> tex_coord;
tex_coord.bind_if_is_defined(mesh.facet_corners.attributes(),"tex_coord");
if(!tex_coord.is_bound() || tex_coord.dimension() != 2) {
Logger::err("tex") << "\'tex_coord\' attribute undefined or of wrong dimension"
<< std::endl;
return;
}
for(index_t f: mesh.facets) {
for(index_t lv = 0; lv < mesh.facets.nb_corners(f); ++lv) {
index_t c = mesh.facets.corner(f,lv);
double u = tex_coord[2*c];
double v = tex_coord[2*c+1];
... // do something with u,v
}
}
Under the hood, the individual mesh parameterization algorithms can be called on an individual chart:
Note: one can call spectral LSCM by setting the bool spectral=true
parameter of mesh_compute_LSCM()
One of the applications of mesh parameterization is to replace a highly detailed mesh with a coarser remeshed version, and keep the same visual richness by transferring the details of the fine mesh to textures applied to the coarse one (one talks about "texture baking"). Consider the high resolution full body scan in the image above, from XYZRGB. It is a dense PLY file, with (nearly) 14M vertices and 28M faces, with colors attached to each vertex.
To obtain a lighter object, the first step consists in remeshing it (left-right image), then computing a texture atlas with the (coarse) remeshed version (bottom-left image). Then we generate two images: a normal map (bottom-center) and a texture map (bottom-right), by copying normals and colors from the high-resolution initial mesh. The functions to do so are implemented in geogram/mesh/mesh_baking.h.
Here is how the bundled utility geobox
implements the functionality remesh and bake normals
.
The first step creates the low-resolution mesh (see remeshing tutorial):
Mesh lowres_mesh;
compute_normals(highres_mesh);
simple_Laplacian_smooth(highres_mesh, 3, true);
set_anisotropy(highres_mesh, double(anisotropy) * 0.02);
remesh_smooth(
highres_mesh, lowres_mesh, nb_vertices,
0, // dimension (0 = default)
5, // nb Lloyd iter.
10 // nb Newton iter.
);
// anisotropic meshing embeds the mesh in 6 dimensions,
// get back to 3d
highres_mesh.vertices.set_dimension(3);
The second step creates the texture atlas:
mesh_make_atlas(
lowres_mesh,
45.0 * M_PI / 180.0,
PARAM_LSCM,
PACK_XATLAS,
false // verbose
);
The third step creates the normal map, using the mesh baking functions. We first
create what is called a "geometry image" [6], that is, a texture (indexed
by the texture coordinates), where the R,G,B
components encode the X,Y,Z
coordinates of all the points:
Image_var geometry_image = new Image(
Image::RGB, Image::FLOAT64, size, size
);
bake_mesh_geometry(&M,geometry_image);
Then we can create a normal map and transfer the normals of the high-resolution mesh to the normal map by using the geometry image:
Image_var normal_map_ = new Image(Image::RGBA, Image::BYTE, size, size);
bake_mesh_facet_normals_indirect(
geometry_image, normal_map, &highres_mesh
);
Under the hood, Geogram uses a AABB (see this tutorial) to quicky find for each texel the point on the high resultion mesh that is nearest to the point on the low resolution mesh.
Normal maps can encode fine geometric details at a low cost. The following example is a full body scan from Polyga. The texture of the pullover is replaced by a normal map, as shown in the image below:
[1] Least Squares Conformal Maps for automatic texture atlas generation, Bruno Lévy, Sylvain Petitjean, Nicolas Ray and Jérôme Maillot, ACM Transactions on Graphics, 2002, HAL, PDF
[2] ABF++: fast and robust angle based flattening, Alla Sheffer, Bruno Lévy, Maxim Mogilnitsky and Alexander Bogomyakov, ACM Transactions on Graphics, 2005, HAL
[3] Spectral conformal parameterization, Patrick Mullen, Yiying Tong, Pierre Alliez and Mathieu Desbrun, [https://dl.acm.org/doi/10.5555/1731309.1731335](Symposium on Geometry Processing), 2008, HAL
[4] Constrained texture mapping for polygonal meshes, Bruno Lévy, ACM SIGGRAPH, 2001, PDF
[5] Non-distorted Texture Mapping for Sheared Triangulated Meshes, Bruno Lévy and Jean-Laurent Mallet, ACM SIGGRAPH, 1998, HAL, PDF
[6] Geometry Images, Xianfeng Gu, Steven Gortler and Hugues Hoppe, ACM SIGGRAPH, 2002, Project page