A different use for a Cube-Map
We all know Cube-Maps. A cube-map is a particular kind of texture that samples the surface of a cube. A Cube-Map is normally used to do environment mapping: each texel represents the color for the corresponding surface orientation. The direction of reflected rays are used as indices to access the Cube-Map.
However, you could think of using a Cube-Map as a way to texture-map, say, an apple. It would be enough to assign, to each vertex of the apple model, a proper 3D texture coordinates that specifies a position on the cube. Any object with a shape that is similar to a cube could use this method (an apple, a basket-ball, a severed head...).
Independence from Geometry.
For a start, the same cube-map texture can be used to texture any other model of an apple,
including any different resolution level of the same apple, models of different types
(quad meshes, triangle meshes, point clouds...) or connectivity:
|(images stolen from the web. sue us)
Filtering and Mipmapping. If our cube-mapped texture, mipmapping just works as usual. Also bilinear interpolation is made to work in good GPUs. If you try that with an texture atlas, texels from different charts will mix horribly and artifacts will appear in your renderings. Either you turn off mipmapping and bilinear interpolation, or you waste a lot of texels at the border of the charts by expanding the border (and that will never be enough for mipmapping.
Space efficiency In our cube-mapped texture for the apple there are no gaps, no unassigned texels. The texture memory is fully used. In a multichart, the space between charts is unused.
Data structure flexibilityThere are no seam in the apple model! (a seam is a pair of vertices sharing the same position, but having different attributes). No vertices needs to be replicated, and each vertex has an unique (3D) texture coordinates. This is very flexible as a data structure. Instead, if the apple was textured with an atlas, the vertices at the border of the chart would need to be assigned to different texture coordinates. In a chart, either some vertex is doubled, or texture coordinate are assigned per-wedge (a wedge is a corner of a triangle) rather than per-vertex.
Generalizing the concept
So, if you want to texture an apple model, Cube-Maps are an ideal type of u-v mapping (or rather, u-v-t mapping, as it should be called in this case, since the text coords are in 3D). Not many people need to texture just apples, though. This is why Cube-Maps is always used (and intended) for environment mapping, and the use described above is rather original.
PolyCubeMaps are a way to apply the above concept to model with more general shapes (but still, they cannot be applied to models with any shape). The key is to substitute the cube used in Cube-Maps with a PolyCube.
|What is a polycube? A polycube (or cubical complex) is simply a 3D shape composed of many unit-sized cubes attached face-to-face, like the example here [see definition from MathWord].
The good thing about using polycubes is that we can adapt to the shape of the model!
When we want to texture-map a given model, we will use a polycube that captures its general shape.
For example, for
this model (a laser-scanned bust by the Italian renaissance sculptor F.Laurana), we would use that polycube. You can look here for other examples.
|What image(s) is loaded
in 2D texture memory
|What is meant
(the 3D texture domain)
6 squared images
a 2D image
with a special format
|a polycube !
(in this example above, the Cube-Map for the apple is a color texture that stores rgb colors, while the PolyCube-Map for the bust stores normal values instead, and is normal-map. But this not the point)
A polycube-map texture, once is defined for a model, has all the advantages we listed
above for the a-cube-map-for-an-apple case: Independence from Geometry (see here for an example),
Filtering and Mipmapping, Space efficiency and Data structure flexibility.
Plus, being the polycube similar in shape (and identical in topology) to the object that is to be textured, distortions are kept low (areas and angles are well preserved by the texture parameterization).
It's all about Fragment Shaders!
A cube is a cube is a cube. Instead, there are many different polycubes. When we use a PolyCubeMap, unlike when we use a Cube-Map, we need to specify which polycube we use (that is, the number and the layout of cubes). We do that by encoding it in an image and loading that image in texture memory. Look in the paper to see how that encoding is done (in the paper we refer to that image as "")
|Actually, in the "specially formatted image" above, the very top-left part, that very small, seemingly black part, is actually the encoding of the of the polycube (but you cannot see this at this resolution). The polycube layout can also be stored in a separate texture just as well, if necessary. The rest of the image is subdivided in zones, which are squared, axis aligned, positioned and sized with multiples of a power of 2. This is what makes mipmapping safe.
The important thing, in Cube-Maps as well as PolyCubeMaps, is that all the redirecting (from the originally three-dimensional texture coordinates to the final texture position in 2D) is done per-fragment. This is the key that unlocks all the above advantages (and that standard atlas approaches lack). And this is ultimately what makes it possible to handle correctly the case of triangle that spans across multiple zone.
The basic mechanism behind Cube-Map consists in understanding, given a point in the 3D texture domain, on which of the six faces it projects and where inside that face. This is wired in your graphic card and is performed per fragment. PolyCubeMaps rely on a similar per fragment mechanism, which is performed by a corresponding Fragment Shader. The shader, as you imagined already, needs to access the texture encoding the layout of the polycube (this is why that structure is kept in texture space).
Sounds complicated? It is not! Refer to the paper for all the details.
From the point of view of the final rendering application, using PolyCubeMaps consists simply is loading the appropriate texture and the fragment program in the GPU. Then you have what, under all points of view, can be considered a seamless texture mapping (just as standard Cube-Maps are a seamless way to encode normal directions).
[back to PolyCubeMap page]