Idea for globally unique texturing without UV sets
25/Aug 2010
Quick idea I’ve had for a while, but likely won’t have time to try out, for getting rid of UV sets once and for all by just looking up textures with a 3D position.
Start with a coarse grained 3D hash grid (i.e a hash map of your grid cell coordinates), then each of these cells would represent, say, a 2563 volume texture indexed by your vertex position. For compression (this volume data would be extremely sparse, usually little more than a flat 2D slice through it), it would use 3D Random Access trees (read this if you haven’t heard about primal vs dual subdivision – eye opener for me!), but probably with a higher branching factor to reduce the number of levels required. Probably 43 child pointers per node, or maybe 33. The grid cells are best looked as “short cuts” into the RA-tree, rather than viewing each cell as its own tree.
This means we get a properly quadrilinear-filtered 3D lookup into a sparse tree at the cost of 8 fetches per level in the tree (if you’re going “huh, how does he get 8?” here, then read the aforementioned paper regarding the magic of primal subdivision as it pertains to filtering), so in the higher branching case it would be 3*8=24 fetches total. But we can cache a lot of this because of locality. You’d start traversing the tree in the geometry shader for the whole triangle (possibly tessellating it so it fits entirely within one hash grid cell, and obviously making sure that the nodes referred to by each such cell covers the neighbourhood, and not just what’s strictly internal to that cell, since a triangle may stick out a bit). Most triangles are small so hopefully you could do 1-2 levels of traversal on the triangle level, and then only do the final 1-2 levels in the pixel shader (you may also store the leaf nodes as plain old 3D volume textures, or rather a part of a single giant one).
If you want to get clever you could do some sort of tetrahedral tessellation of the volume (so rather than keeping a “cube” that you progressively make smaller to zero in on the desired sample, you keep a tetrahedron). This means you need fewer samples per level, but also makes my head hurt a bit so you’d need to think that through carefully (in particular how to sort out a primal-esque subdivision). This obviously would make the filtering look “different” in some sense, but it would still be smooth.
Clearly, you’d stop early in this hierarchy based on LOD.
For streaming, you’d store the active nodes of the trees in a big pool and just request the unavailable ones on the fly a la standard 2D virtual texturing.
Maybe you’d build a simple 3D volume texture “brick” to substitute for the most detailed node currently loaded to cut down on “manual” filtering.
Maybe you’d store multiple hash grids. For very small triangles (the majority of them, these days) you may be able to “short cut” much deeper into the tree than for big triangles. These grids would be extremely sparse so storage should be okay if you have some very coarse streaming on top of this. For very distant triangles you may need to start at the real root of the RA-tree instead of using the grids as a short cut.