How can I tell if a texture tiles without seams?
Repeat it several times and check that the last column of pixels flows into the first and the last row into the top one. If the edges jump, every copy draws a line on the wall, floor or terrain it covers.
The checker gives you two ways to see it:
- The 5 × 5 repeat. Good for problems that only show at a distance: one corner brighter than the rest, a stain or a crack that repeats in a visible rhythm, or a gradient that turns into stripes.
- The edge check. A number for each join, on a 0 to 255 scale, set next to how much neighbouring pixels change just inside the edge. A clean join changes about as much as the texture around it does.
What edge mismatches look like in numbers
These are measurements from test textures we generated for this page, checked as a grid repeat. “Beside” is the normal change between neighbouring pixels near that edge.
| Test texture | Left/right join | Top/bottom join | Verdict |
|---|---|---|---|
| Normal map made to wrap exactly, 256 × 256 PNG | 1.7 (beside: 1.7) | 1.2 (beside: 1.1) | Joins cleanly |
| The same normal map saved as lossy WebP | 3.9 (beside: 1.6) | 3.2 (beside: 1.1) | Seam may show |
| Colour texture lit unevenly, up to 30% darker on the left, 512 px PNG | 40 (beside: 0.6) | 0.3 (beside: 0.4) | Left/right seam likely visible |
| Random plasma texture, not made to tile, 1000 × 700 WebP | 82 (beside: 1.7) | 79 (beside: 1.9) | Both seams likely visible |
The WebP row is worth noting: the normal map was seamless as a PNG, and lossy compression alone more than doubled the difference across both joins. Keep source textures in a lossless format and compress at export.
The uneven lighting row is the most common real case: a photo of a surface taken with light from one side. Each edge looks fine on its own, but the dark side meets the bright side at every join.
Why does power-of-two size matter?
Some targets can only repeat a texture if both sides are a power of two, such as 256, 512, 1024 or 2048 px. MDN’s WebGL guide puts it plainly for WebGL 1: a non-power-of-two texture must use clamp-to-edge wrapping and can’t have mipmaps, while a power-of-two texture can use REPEAT (MDN: Using textures in WebGL).
The bar above the viewer shows the texture size and adds “power of two” when both sides qualify. If yours doesn’t, resize it in your editor before you fix seams, because resizing resamples the edges too.
| Size | Power of two |
|---|---|
| 512 × 512, 1024 × 1024, 2048 × 2048 | Yes |
| 1024 × 512 | Yes, both sides are powers of two |
| 1000 × 1000, 1920 × 1080 | No |
How do I fix the seams in a texture?
Offset it by half so the edges meet in the middle, retouch that cross, and check again. Select Offset by half to preview it, turn on seam lines to see exactly where the old edges run, and download the offset texture as PNG or as a layered PSD with the original and a seam guide layer kept hidden underneath.
Clone or heal across the cross without touching the outer border, since the border already joins correctly after the offset. Then drop the fixed texture back here; the numbers for both joins should drop close to the “beside” values.
What the texture checker can’t see
- Seams caused by UV layout, texture filtering or mipmaps in your engine. It only checks the image file.
- Values beyond 8 bits per channel, formats other than PNG, JPG and WebP, and textures over 8192 x 8192 pixels.
- Data packed into the alpha channel. The browser rounds the colour under transparent pixels when it reads the file.
- Whether a normal map is in the right convention for your engine. It checks the stored values, not what they mean.
- It doesn’t repair anything. Retouching stays in your editor.