Last week I found a blog post from the Hauke Thießen in which he describes cheap hex-tiling in Unreal Engine. I'm not much of a real-time person, but his article was interesting to read. At one point in the text he mentions couple of different implementations of hex tiling which got me interested in recreating something similar. Here, I am using Maya, LookdevX and MaterialX as a tools of choice, but this can be recreated in pretty much any node editor with math nodes. Some nodes don't have same names, but logic behind entire process is the same.
I started with Ben Cloward's YT channel which is literally a gold mine for anyone interested in computer graphics and shading. In his video series he describes how to create hex-tiling grid. It is a simple, yet effective way to breakup texture tiling. I watched his videos and recreated hex-grid, some additional compounds and learned a lot about manipulating UVs. Again, really great resource for artists.
One drawback of this method is that it uses blurred hex tiles and linear blending, which creates ghosting in the texture on the hex edges.
Although, not that apparent at the first glance it is not creating satisfying result. We can play with different blur levels of the masks, but it always has some level of ghosting.
Next step was to figure out how to do proper blending of the hex-tiles. There are two papers that do different approach fixing this:
- Procedural Stochastic Textures by Tiling and Blending (2019) by Thomas Deliot and Eric Heitz
- Practical Real-Time Hex-Tiling (2022) by Morten S. Mikkelsen
First paper covers how to do histogram-preserving blending to preserve contrast and do proper blending. Second paper builds on the first one, but does texture luminance blending and doesn't require additional precomputation steps. As, second paper looked a bit simpler to implement I decided to give it a try.
As a base, I used hex grid from the Ben's videos and implemented math from the second paper. First part was to get luminance values from the sampled texture, do some math and get proper edges on the hex-tiles:
There are two constants here that play a role of influencing blur width (γ) and detail strength (β). Both should be exposed in the compound in order to get more granular control over the blending edge. Paper suggest following values: γ = 7 and β=0.6, but values will depend on the texture that is being used.
Second part of the paper is to apply S-curve to the result in order to increase contrast of the edge blending.
In paper constant r is used to control strength of the curve. Paper shows use of three values for r constant: r = 50, r = 75 and r = 95. With bigger r values we get stronger contrast on the edge. This is also important constant to expose in the final compound in order to have more control with blending.
As a result, we get really nice texture blending between each hex-tile. Best thing about it is that is controllable with couple of parameters. This gives us flexibility when using different textures in order to achieve best possible blending.
And for comparison, here is the .gif of a two versions of hex-tile blending.
As you can see, we have much better blending. There is little to no ghosting and contrast is in line with the rest of the texture. This way we have much better visual quality over the the basic blending.
Here it is in action - normal UV tiling vs luminance based hex - tiling. All in all, it was an interesting weekend exercise - I am satisfied with the result. I learned a lot from Ben's videos and two papers I've mentioned. Next step would probably be to make it work with normal maps, but that would require different math. We will see if I have time next weekend to do normal map implementation and luminance blending.