Mikkelsen 2022 Hex
Mikkelsen 2022 Hex
org
Morten S. Mikkelsen
Unity Technologies, USA
Figure 1. Illustration of hex-tiling, by the algorithm of Heitz and Neyret, which alleviates
repetition and is achieved by each hexagonal region sampling at a random offset. Results are
illustrated at different scales in each row. The two bottom images of the second column show
conventional tiling, and repetition is evident at a distance. In the fourth column we see the
original histogram-preserving method compared to the very similar results in column three
using our more simple approach to compositing hex tiles.
Abstract
To provide a convenient, easy-to-adopt approach to randomly tiled textures in the context
of real-time graphics, we propose an adaptation of the by-example noise algorithm of Heitz
and Neyret. The original method preserves contrast using a histogram-preserving method
that requires a precomputation step to convert the source texture into a transform and inverse
transform texture, which must both be sampled in the shader rather than the original source
texture. Thus deep integration into the application is required for this to appear opaque to
the author of the shader and material. In our adaptation we omit histogram preservation and
replace it with a novel blending method that allows us to sample the original source texture.
This omission is particularly sensible for a normal map as it represents the partial derivatives
of a height map. In order to diffuse the transition between hex tiles, we introduce a simple
metric to adjust the blending weights. For a texture of color, we reduce loss of contrast by
applying a contrast function directly to the blending weights. Though our method works for
color, we emphasize the use case of normal maps in our work because non-repetitive noise is
ideal for mimicking surface detail by perturbing normals.
77 ISSN 2331-7418
Journal of Computer Graphics Techniques Vol. 11, No. 2, 2022
Practical Real-Time Hex-Tiling http://jcgt.org
Figure 2. Left: Barycentric coordinate used to establish the hexagonal weight. Middle: Expo-
nentiation applied to the hexagonal weight that separates the hex tiles. Right: All distributed
hex tiles of the lattice.
1. Introduction
A key challenge in modern computer graphics is the time it takes to create a suffi-
cient quantity of artwork to make up a full scene. Using modern workflows such as
photogrammetry and sculpting alone, to create complex and expansive surface detail,
is impractical both in terms of development time as well as constraints in resolu-
tion to a single mesh or texture. A common simple approach to address this is by
tiling textures; however, repetition is noticeable. A possible solution to repetition is
to use procedural textures, as analytical functions, such as proposed by Perlin [1985],
Worley [1996], and Tricard [2019]. The problem with such methods is that they are
expensive and they lack artistic control to choose a pattern.
A by-example noise algorithm was introduced by Heitz and Neyret [2018] that
allows the user to choose a stochastic texture as a sample. Their method then syn-
thesizes an infinite non-repetitive output with the same appearance. This is achieved
by structuring the synthesized texture space on an equilateral-triangle lattice also fa-
mously used in simplex noise by Perlin [2002]. Each vertex in the grid represents the
center of a hexagonal shape, which we refer to as a hex tile and is illustrated on the
left in Figure 2. Each such tile is assigned a random offset when the source texture is
sampled. During synthesis the sampling location represents a barycentric coordinate
within a triangle of the lattice. This coordinate is then used to blend between the three
corresponding hex tiles.
Heitz and Neyret [2018] pointed out that simply blending these three sampled col-
ors will result in loss of contrast and introduce transitional colors that are distinctly
not present in the source texture provided by the user. It is argued that the problem
with linear blending is that the statistical properties of the input are not preserved, i.e.,
its histogram. In order to blend in a way that preserves the histogram, a precomputa-
tion step is performed that performs a histogram transformation on the channel data
and stores it in a new texture T . A second texture T −1 is generated that is used to
78
Journal of Computer Graphics Techniques Vol. 11, No. 2, 2022
Practical Real-Time Hex-Tiling http://jcgt.org
perform the inverse transformation. In the fragment shader the texture T is queried
three times (once for each hex tile), followed by an approximate variance-preserving
blend function. The second texture T −1 is then used to transform the result back into
a color.
The histogram-preserved blending technique applied to hex-tiling achieves im-
pressive results. However, to replace the original texture with the textures T and
T −1 in the background—i.e., so these are not explicit within the shader or on the
material—requires a considerable amount of foundational effort in order to adopt this
technique. In this paper we explore a simple adaptation of the method that is straight-
forward to use inside any shader. For normal maps our approach offers very similar
results with the additional benefit of being able to randomize rotation of the hex tiles.
For textures of color there is a trade-off in quality when observed side by side, though
in our experience the compromise is acceptable.
2. Our Method
In our work we require a solution that will allow us to adopt hex-tiling instantly in
any shader. To achieve this, we constrain ourselves to sampling the source texture
directly. As mentioned in Section 1, the barycentric coordinate (ω1 , ω2 , ω3 ) ∈ R3
within a triangle of the lattice is used to blend the samples x1 , x2 , x3 ∈ M , i.e., one
per hex tile, where the dimension of M corresponds to the number of channels and
ω1 + ω2 + ω3 = 1.
It was pointed out by Burley [2019] that even with histogram preservation en-
abled, though diminished, ghosting remains a problem. To further alleviate the issue,
the author exponentiates the weights ωiγ and divides by the sum of the exponenti-
ated weights. This is illustrated in the middle picture of Figure 2 and more closely
resembles a blend mask. The same approach is applicable when blending the sam-
ples xi without histogram preservation, and we adopt this in our solution, too. To
improve on this, we diffuse the transition between adjacent tiles by modulating each
exponentiated weight ωiγ by a metric δ : M → R+ applied to each corresponding
sample xi :
δ (xi ) · ωiγ
ωi′ = P3 γ. (1)
j=1 δ (xj ) · ωj
Thus we leverage characteristics retained in the image data to diffuse the transition
between adjacent hex tiles, as illustrated in the upper-left image of Figure 1.
For tangent-space normal maps, specifically, the image data represents directional
data rather than color. Though a histogram-preserving approach will work, it has less
relevance in this context because normal maps tend to form a single wide cluster and
then occupy the range semi-evenly.
79
Journal of Computer Graphics Techniques Vol. 11, No. 2, 2022
Practical Real-Time Hex-Tiling http://jcgt.org
The derivative is a linear operator, which means that by blending the partial
derivatives, the obtained result is equivalent to blending directly from the height map.
In the context of normal mapping, our samples xi represent the partial derivatives to
be blended.
In choosing our δ, we attribute significance to samples based on the steepness of
their slope. We empirically choose to use sine to the angle θ between the normal and
the ⃗z-axis as our measure. Given Equation (2), it follows that cos2 θ = 1/(1 + ∥xi ∥2 ),
and from this we obtain sin θ from the following equation when β equals 1:
s
∥xi ∥2
δN (xi ) = (1 − β) + β · . (3)
1 + ∥xi ∥2
2.2. Color
In the context of color xi , the choice for δ is more arbitrary. In our case we use
luminance to drive the diffusion between hex tiles:
0.299
δC (xi ) = (1 − β) + β · xTi · 0.587 . (4)
0.114
Unlike normals, it is more common for colors to form individual separated clusters—
particularly when these are tileable patterns. This makes the omission of histogram
preservation a more significant problem in this case compared to normal mapping.
To address this problem, we apply a ramp to ωi′ , shaped like an S-curve, just be-
fore blending the samples. To perform the described operation, we use the following
curve: (
1 k
2 (2x) if x < 0.5,
g(x) = k
(5)
1
1 − 2 (2 − 2x) if x ≥ 0.5,
80
Journal of Computer Graphics Techniques Vol. 11, No. 2, 2022
Practical Real-Time Hex-Tiling http://jcgt.org
Figure 3. On the lower right we see Perlin’s S-curve for three different input values r. The
lower-left image shows the mask we produce when the blending weights are modulated by
this curve using r = 0.5. The corresponding composited image is shown above the mask.
Columns two and three show similar results for r = 0.75 and r = 0.95, respectively, and
appear less blurry. As ground truth the histogram-preserving result is shown in the upper-
right image.
which was introduced by Perlin and Hoffert [1989] and is shown in Figure 3. The
authors introduced a second curve, k = log 1 (1 − r), that allows the user to choose
2
the exponent k indirectly on a range that is normalized, r ∈ ]0, 1[. Note that for
r = 0.5 the curve will have no impact. For r ∈ 12 , 1 we get an increase in sharpness
at the border between adjacent hex tiles. We divide by the sum of the weights to
renormalize prior to blending.
3. Implementation
Our implementation is based on the one given by Deliot and Heitz [2019] and is
provided here in the appendix. The main functions are given in Listing 3 and in
Listing 4 for normal maps and color, respectively. For the parameters γ and β in
Equations (1), (3), and (4), we are using γ = 7 and β = 0.6. Though these could
be exposed as values to the user, we have found them to be good choices in general.
For the curve given by Equation (5), we expose the input parameter r to the user,
which allows them to preserve contrast. Our implementation is given in Listing 8. An
alternative option to using Perlin’s version is to use the approximate form given by
Schlick [1994].
As mentioned in Section 2, for normal mapping, we are blending partial deriva-
tives. We obtain the derivative using the shader function given by Mikkelsen [2020,
81
Journal of Computer Graphics Techniques Vol. 11, No. 2, 2022
Practical Real-Time Hex-Tiling http://jcgt.org
Listing 2], but for completion we provide it here as well in Listing 9. When hex-tiling
we must use SampleGrad() due to the randomized offset applied to the sampling coor-
dinate with respect to each hex tile. We do this in Listing 10, and the returned deriva-
tive can be converted to a tangent space normal using normalize(float3(-deriv.xy,
1.0)). When using gFlipVertDeriv set to true, in Listing 9, the second component
must also be negated when converting back to a normal. (Refer to [Mikkelsen 2020]
for further details.)
To allow for further flexibility, we have added support for randomized rotation of
hex tiles. As a note, this feature is only possible with normal maps when histogram
preservation is disabled. The reason for this is that normals/derivatives represent di-
rectional data. Thus, when rotating the hex tiles individually, we must rotate each
sample with respect to its hex tile prior to blending. When histogram preservation is
used, the directionality is unknown until blending has already taken place.
4. Results
In Figure 4 test results are presented using a selection of different normal-map sample
textures as the source. In each case the test result is the corresponding synthesized
image with twice the width of the source image. A comparison is shown between
our method and the original histogram-preserving approach, and in our opinion the
results are strikingly similar. In practice it is very difficult to tell which is which unless
a toggle is done between the two methods.
A similar example is given in Figure 5, where the sample textures are different
color patterns. Though our approach, as described in Section 2, is not as ideal for
color as it is for normal maps, the approach appears to be surprisingly resilient in
this case, too. As predicted, there is a more significant distinction between the two
methods compared to normal maps, but in our experience it remains difficult to tell
which is which until you toggle between them or scrutinize a location that is known
to be at the border between two hex tiles, such as shown in Figure 3.
When choosing the parameter r, this is a compromise between preserving contrast
and not making the hexagonal boundaries noticeable. The latter is specific to the
chosen source image, however in our experience a conservative choice is in the range
r ∈ [0.65, 0.75].
In Figure 6 an example is given of randomized rotation applied to the sampling
coordinate during hex-tiling. This is a particularly useful feature when there are rec-
ognizable elements in the sample texture with a distinct orientation. In the middle
image where randomized rotation is disabled, we see the same pebble appearing at
different locations but always with the same alignment. In the top image randomized
rotation is applied, which alleviates the issue.
A collection of lit materials composited from texture maps for albedo, roughness,
and normal are shown in Figure 7. On the left side we see a single instance of the
82
Journal of Computer Graphics Techniques Vol. 11, No. 2, 2022
Practical Real-Time Hex-Tiling http://jcgt.org
5. Conclusion
We have introduced an adaptation of the hex-tiling method, by Heitz and Neyret,
that allows a shader artist or engineer to adopt the technique within minutes into any
shader. The original method, although impressive, requires a substantial amount of
engineering work to achieve an integration that is practical to users.
Furthermore, we have shown that our approach achieves similar results to the
histogram-preserving method though with subjectively minor trade-off in terms of
quality when applied to color.
Given how useful hex-tiling is, we hope that our work will help pave the way for
a wider adoption of this technique.
83
Journal of Computer Graphics Techniques Vol. 11, No. 2, 2022
Practical Real-Time Hex-Tiling http://jcgt.org
Figure 4. Different example patterns as normal maps. In each case hex-tiling is used to
produce a similar image of twice the width of the original source image. We compare our
proposed adaptation to the original histogram-preserving method.
84
Journal of Computer Graphics Techniques Vol. 11, No. 2, 2022
Practical Real-Time Hex-Tiling http://jcgt.org
Figure 5. Different example patterns in color. In each case hex-tiling is used to produce a
similar image of twice the width of the original source image. We compare our proposed
adaptation to the original histogram-preserving method.
85
Journal of Computer Graphics Techniques Vol. 11, No. 2, 2022
Practical Real-Time Hex-Tiling http://jcgt.org
Figure 6. Conventional texture tiling is shown in the bottom image and the sense of repetition
is evident. In the middle image hex-tiling is used, which improves the result. However, some
sense of repetition is still visible because a few distinct pebbles are consistently pointing in
the same direction. We are able to solve this using randomized rotation, as shown in the top
image.
86
Journal of Computer Graphics Techniques Vol. 11, No. 2, 2022
Practical Real-Time Hex-Tiling http://jcgt.org
Figure 7. Different materials of terrain using texture maps for albedo, roughness, and normal.
In each case hex-tiling is used to produce a similar image (right) that is three times the width
of the original source image (left).
87
Journal of Computer Graphics Techniques Vol. 11, No. 2, 2022
Practical Real-Time Hex-Tiling http://jcgt.org
// Output: weights associated with each hex tile and integer centers
void TriangleGrid(out float w1, out float w2, out float w3,
out int2 vertex1, out int2 vertex2, out int2 vertex3,
float2 st)
{
// Scaling of the input
st *= 2 * sqrt(3);
w1 = -temp.z*s2;
w2 = s - temp.y*s2;
w3 = s - temp.x*s2;
88
Journal of Computer Graphics Techniques Vol. 11, No. 2, 2022
Practical Real-Time Hex-Tiling http://jcgt.org
// Fetch input.
float2 d1 = sampleDeriv(nmap, samp, st1,
mul(dSTdx, rot1), mul(dSTdy, rot1));
float2 d2 = sampleDeriv(nmap, samp, st2,
mul(dSTdx, rot2), mul(dSTdy, rot2));
float2 d3 = sampleDeriv(nmap, samp, st3,
mul(dSTdx, rot3), mul(dSTdy, rot3));
d1 = mul(rot1, d1); d2 = mul(rot2, d2); d3 = mul(rot3, d3);
89
Journal of Computer Graphics Techniques Vol. 11, No. 2, 2022
Practical Real-Time Hex-Tiling http://jcgt.org
// Fetch input.
float4 c1 = tex.SampleGrad(samp, st1,
mul(dSTdx, rot1), mul(dSTdy, rot1));
float4 c2 = tex.SampleGrad(samp, st2,
mul(dSTdx, rot2), mul(dSTdy, rot2));
float4 c3 = tex.SampleGrad(samp, st3,
mul(dSTdx, rot3), mul(dSTdy, rot3));
90
Journal of Computer Graphics Techniques Vol. 11, No. 2, 2022
Practical Real-Time Hex-Tiling http://jcgt.org
// Remap to +/-pi.
angle = fmod(angle, 2*M_PI);
if(angle<0) angle += 2*M_PI;
if(angle>M_PI) angle -= 2*M_PI;
angle *= rotStrength;
float3 ProduceHexWeights(float3 W,
int2 vertex1, int2 vertex2, int2 vertex3)
{
float3 res = 0.0;
int v1 = (vertex1.x-vertex1.y)%3;
if(v1<0) v1+=3;
return res;
}
Listing 7. Swizzle the weights to produce a consistent hex color for visualization purposes.
91
Journal of Computer Graphics Techniques Vol. 11, No. 2, 2022
Practical Real-Time Hex-Tiling http://jcgt.org
Listing 8. Apply an S-curve–shaped ramp to the signal and normalize the weights.
⃗ to a derivative d⃗.
Listing 9. Conversion of tangent-space normal m
Listing 10. Sample a normal map with gradients and return a derivative dHduv.
92
Journal of Computer Graphics Techniques Vol. 11, No. 2, 2022
Practical Real-Time Hex-Tiling http://jcgt.org
References
B URLEY, B. 2019. On histogram-preserving blending for randomized texture tiling. Journal
of Computer Graphics Techniques 8, 4 (November), 31–53. URL: http://jcgt.org/published/
0008/04/02/. 79
D ELIOT, T., AND H EITZ , E. 2019. Procedural stochastic textures by tiling and blend-
ing. In GPU Zen 2: Advanced Rendering Techniques, W. Engel, Ed. Black Cat Pub-
lishing Inc., Encinitas, CA, ch. 2, 177–200. URL: https://gpuzen.blogspot.com/2019/04/
gpu-zen-2-procedural-stochastic.html. 81
H EITZ , E., AND N EYRET, F. 2018. High-performance by-example noise using a histogram-
preserving blending operator. Proceedings of the ACM on Computer Graphics and Inter-
active Techniques 1, 2 (aug), 31:1–31:25. URL: https://doi.org/10.1145/3233304. 78
M IKKELSEN , M. S. 2020. Surface gradient–based bump mapping framework. Journal
of Computer Graphics Techniques 9, 3 (October), 60–90. URL: http://jcgt.org/published/
0009/03/04/. 80, 82
P ERLIN , K., AND H OFFERT, E. M. 1989. Hypertexture. In Proceedings of the 16th Annual
Conference on Computer Graphics and Interactive Techniques, Association for Computing
Machinery, New York, 253–262. URL: https://doi.org/10.1145/74333.74359. 81
P ERLIN , K. 1985. An image synthesizer. ACM SIGGRAPH Computer Graphics 19, 3,
287–296. URL: https://doi.org/10.1145/325165.325247. 78
P ERLIN , K. 2002. Noise hardware. In Real-Time Shading Languages, Association for
Computing Machinery, New York, ACM SIGGRAPH 2002 Course Notes. URL: https:
//www.csee.umbc.edu/∼olano/s2002c36/ch02.pdf. 78
S CHLICK , C. 1994. Fast alternatives to Perlin’s bias and gain functions. In Graphics Gems
IV, P. S. Heckbert, Ed. Academic Press Professional, Boston, 401–403. URL: https://dl.
acm.org/doi/10.5555/180895.180931. 81
T RICARD , T., E FREMOV, S., Z ANNI , C., N EYRET, F., M ART ÍNEZ , J., AND L EFEBVRE , S.
2019. Procedural phasor noise. ACM Transactions on Graphics 38, 4 (jul), 57:1–57:13.
URL: https://doi.org/10.1145/3306346.3322990. 78
W ORLEY, S. 1996. A cellular texture basis function. In Proceedings of the 23rd Annual
Conference on Computer Graphics and Interactive Techniques, Association for Computing
Machinery, New York, SIGGRAPH ’96, 291–294. URL: https://doi.org/10.1145/237170.
237267. 78
93
Journal of Computer Graphics Techniques Vol. 11, No. 2, 2022
Practical Real-Time Hex-Tiling http://jcgt.org
Received: 2022-02-11
Recommended: 2022-05-03 Corresponding Editor: Angelo Pesce
Published: 2022-08-25 Editor-in-Chief: Marc Olano
94