Removing texture repetition is a common issue when working with tiling textures in Unreal Engine. If you've ever noticed the same pattern appearing over and over, making your surfaces look unrealistic, you're not alone! Thankfully, there's a technique called cell bombing that helps break up the repetition and add more variety to your materials.
In this guide, we'll walk through removing texture repetition using the cell bombing technique, explaining how it works, and giving you complete control over random scale, offset, and rotation.
Watch the full tutorial on YouTube
Understanding Texture Repetition
Texture repetition happens for a few reasons: tiling textures cover large surfaces without massive texture maps but often create obvious patterns; uniform UV mapping means identical portions of a texture appear at regular intervals; and a lack of variation makes a repeated texture easily recognizable, breaking immersion.
Texture repetition
Setting Up the Base Material
Create a new material (e.g. M_Default), drag in a texture (a forest ground texture works well), add a UV manipulation function or a Texture Coordinate node, promote the size input to a parameter named “Size – Main Texture” set to 1, connect the texture to Base Color, save, and create a material instance. Assign the instance to a plane and set its size to 0.1 so the repetition is obvious; that's where cell bombing comes in.
A tiling texture showing clear repetition issues
What Is Texture Cell Bombing?
Cell bombing uses a Voronoi texture to introduce randomized UV offsets to your main texture. Each cell in the Voronoi texture has a different value, which offsets the UV coordinates of the main texture, turning a repetitive pattern into unique variation across the surface while keeping performance in check.
Voronoi texture
Applying Cell Bombing
Duplicate the plane and material, naming the copy “Cell Bombing.” Create a new material instance from it and assign it to the plane, keep the size at 0.1, then open the material and drag in a Voronoi texture. Duplicate the UV function and size parameter as “Cell Texture Size,” connect that parameter to the Voronoi texture's UVs, pick one of the Voronoi channels (G works well), and add it to the main texture's UVs to offset them.
Material setup using a Voronoi texture for UV offsetting
Cell bombing has removed the texture repetition
Fixing Cell Bombing Artifacts
The repetition is gone, but zoom in and you'll likely see sharp borders between cells: the Voronoi texture itself has hard edges. Fix it by blending two texture versions with the Voronoi texture's alpha channel: add a Lerp node, run the Voronoi alpha through a Saturate node into the Lerp's Alpha input, duplicate the main texture into the Lerp's A input using the regular UV function, and connect the cell-bombed texture to B.
Material setup for removing the hard edges in a cell bombing material
With this in place, black alpha areas use the normal texture and white areas use the cell-bombed texture, smoothing out the cell transitions.
Before using Lerp blending to smooth Voronoi cell borders
After using Lerp blending to smooth Voronoi cell borders
Random Scale
Add a Lerp node, drag in the cell texture's Red channel as its alpha, create two scalar parameters named Min Scale and Max Scale (a range of 0.9 to 1.1 works well), add a Divide node connecting your UVs to A and the Lerp output to B, then link the Divide node into the Add node handling the UVs.
Random scale applied to a texture
Random Offset
Insert a Multiply node before the Add node, create a scalar parameter called Random Offset Strength (default 1), and connect the Multiply node into the Add node. With the offset at 0 the effect disappears and repetition returns; increasing it shifts textures randomly and breaks up uniformity.
Random offset applied to textures
Random Offset Direction
Right now all cells move in the same direction. Add an Append Vector node, connect the Red channel to U and Green channel to V, then multiply by 2 and subtract 1 to shift values into a -1 to 1 range, giving true random movement in every direction.
Demonstrating true random texture movement
Random Rotation
Add a Rotate About World Axis node, set its pivot to a Constant 3 Vector at world center, convert your UVs to a 3-vector with an Append Vector node, create a scalar parameter called Rotation (default 0), multiply it by a Blue channel from the cell texture, and divide by 360 to match rotation degrees.
Rotate About World Axis node in use
Fixing Rotation UV Issues
If setting rotation randomness to 0 makes the UVs disappear, it's because the output is 0. Add an Add node between the masked R and G channels and the UVs to guarantee a valid, non-zero UV input at all times, then save and test.
Fixing UV issues caused by rotation randomness
Fixing the Normal Rotation
When rotating textures to break repetition, normal maps don't always rotate along with them; they can become misaligned or flipped, ruining the shading and lighting. To fix it: add a Rotate About World Axis node with a Constant 3 Vector pivot, then correct the rotation amount by multiplying it by -1 (using a Multiply node with A set to -1, B connected to your existing Divide node) and feeding that into the Rotation Amount input.
For the World Position input, use the texture's position and add the Z-axis output to it, so the normal map follows the correct world coordinates.
Fixing the normal rotation issue
To keep the effect optional, add a Static Switch node with a Static Bool Parameter named “Is Normal Texture,” connect the Add node to the True input and the texture directly to the False input, then connect the Switch into the Lerp node's B input.
Static Switch used for normal texture handling
After saving, the normal maps should rotate properly and the lighting/shading should hold up. If normals still look off, double-check the Multiply and Switch connections.
Balancing Quality and Performance
Compared to Texture Bombing with Parallax Occlusion Mapping (the most performance-costly option), Cell Bombing is slightly more demanding than a plain texture but far more optimized than traditional Texture Bombing, a solid middle ground for interactive environments like games and simulations. You can check the cost yourself via Optimization View Modes → Shader Complexity.
Shader complexity comparison between Texture Bombing, Cell Bombing, and standard texture mapping
Handling Stretching and Sampling Issues
Cell Bombing can introduce minor texture stretching in some areas, usually only noticeable up close. If you're using it in landscape materials, set the Sampler Source of your texture samples to Shared: Wrap. Skipping this can silently fail to compile the material with no error message.
Shared: Wrap option for texture samples
Choosing the Right Textures
If you see unusual artifacts, double-check that your Texture Size and Cell Texture Size are set correctly; a good rule of thumb is a Cell Size at least 10x bigger than the original texture, though the exact ratio varies. This technique works exceptionally well with organic textures like dirt, grass, and moss, but isn't ideal for structured patterns like brick walls or tiled wood floors, where the randomness can disrupt uniform patterns. It's compatible with displacement and tessellation, so you can still get depth and parallax without compromising the material.
Final Thoughts
By combining cell bombing with random scale, offset, and rotation, you can effectively remove texture repetition in Unreal Engine. It's great for landscapes, walls, floors, and organic surfaces, giving you a much more realistic look.