To store unique information per triangle, e.g. lightmaps, you may need to create a texture atlas. This is my first attempt to create one by myself. There are more sophisticated solutions out there, but its good to have something to compare.
- transformation 3D-2D: each triangle is transformed to 2D. The longest edge is aligned on the x-axis, the height is aligned at the y-axis. This assures that the bounding rectangle is of mimimum size (exactly two times the area of the triangle).
- sorting: all transformed triangles are then sorted by their height.
- packing: the sorted triangles are layed out horizontally, as long as they fit into the estimated bounds (in my case a square layout ). If one row is full, another row is started. During this fitting process, the triangles may be flipped horizontally or vertically, depending on the left neighbor. The layouts’ bounds are always kept square, and are dynamically extended.
- rasterizing (OpenGL): the triangles are then rasterized with the new coordinates (normalized) , and use the original tex-coords, to lookup the color of the original texture(s). The normalized coordinates are the new UV-coords for the atlas.
- dilation (GLSL): to take care of the borders (see images below)
while this is very fast (half the time is spent on sorting the triangles), and relatively simple to implement, it has quite some flaws:
- due to rasterization and a limited texture size, small/skinny triangles may are not rasterized at all, or in a very bad quality.
- special care needs to be taken for the borders, since former adjacent triangles are separated in the texture-atlas.
- quite a lot of pixels are wasted, because of the padding between the triangles to avoid “pixel-bleeding”. This is especially noticable when there number of triangles is huge compared to the texture resolution. In that case, the number of pixels used for padding really bashes the packing-efficiency (covered pixels).
- … and so on
no padding, no dilation
padding, no dilation
very problematic case: sponza scene (crytek) ~ 300k triangles.