Frac artifacts on a tiled flipbook texture: how to remove them?


In order to improve a water shader, I’m using a flipbook to have the water surface animated.
And I get this:

From other posts about this problem, it is usually called “frac artifacts” as it is due to the use of a frac node in the material.
With this frac node the texture displays correctly but the downside is these visible seams.
A few tricks seems available to remove them:
and I tried to use them, without success, due to the fact I’m using the flipbook node
and I don’t know how to implement them in my setup or even if it can be done.
Here is my setup:

(Tiling parameters are set to 1 by default but are increased in a material instance).

So: any help appreciated.


The flipbook node is a material function. So you can go inside and adjust the texture sampling yourself. (Make sure to make a copy of the node first though)

Here you go:

The custom node is from that guy’s blog you mention but he had a small typo… make sure DDX and DDY are with capitals!

return Tex.SampleGrad(TexSampler,UV,DDX(UV1),DDY(UV1));

Default flipbook result:

With custom node:

Few months ago I’ve spent 5 hours at least, trying to fight with SampleGrad error. And felt like a fool when found that solution was so simple.

Thanks for your answers, guys!

@TK_Master: I reproduced your setup with the default flipbook and it works, connected to Base Color.
But with mine, connected to normals, it doesn’t. Seems are a bit reduced but are not completely removed.
Also, when rotating the cube in the material editor viewport, it doesn’t display in all angles. Some faces remind black.
And when I use this material in a level, the water surface is black.

On this one, if I go on rotating the cube, normals will disappear as they already did on the left part of the face.


On this one, you can see normals aren’t displayed on 2 faces.


So it seems to work for diffuse but not for normals.

Yeah you are right, SampleGrad doesn’t seem to work with normals (it returns wrong color values or something).

You can try this instead of the custom node:

You will still be able to see some minor artifacts depending on the pixel distance but once you put diffuse on top and if your normal is detailed enough then you won’t be able to see them.

Yes, this one works well and seems are very softened.
However, they are still visible, even with a diffuse, as my normals are not as strong as yours.
I wanted to make something like a calm lake surface, not something as “frosted” as the one in your screenshot.
I suppose I have to come back to panning normal maps.
Anyway, thanks for your help. At least I learned some tips! Could be useful in other cases.

Is it that visible with your normal? Well I will let you know if I find a cleaner method :p, I have a few things left to try.

Could you send me your normal by any chance? (in pm if you have to).

I got the normal here:

A the bottom of the list, you have 2 .png: water_nor & watermap.
It’s one of those 2, don’t remember which one, I renamed it.

Just looked at the link, that normal map has seams all over the place. I see 9 seams which looks like somebody tiled a non tiling pattern 10x10.

Lol yup… that normal is not seamless at all :stuck_out_tongue:
So your first step should be to make a better normal flipbook, it seems too low res anyway.

Edit: actually the normal is probably fine… it’s supposed to be animated right? so the frames shouldn’t really need to be seamless between them but only with themselves (if that makes sense lol).

But I have also found a way to further eliminate the frac artifacts to the point where I can literally not see them at all.


Now it also calculates correct mip map level so it looks smoother at distance.

There is probably a better and more optimized way of doing it but at least this pretty much works perfectly for me.

Edit: you might wanna change the Divide by 2 node (after GetDimensions V2) to the number of rows of your texture or so (play around with that value I guess).

looks like you grabbed that math from ComputeMipLevel instead of just showing the ComputeMipLevel material function being used. Any particular reason, was there a problem with the function by default?

fwiw, computemip gives you only bilinear filtering which will never look quite as good as either trilinear or anisotropic. So you will see feint seams between the mip levels. For water which is usually viewed right along the surface this may pose a quality issue.

It’s a slightly edited ComputeMipLevel function which blends a different mipmap based on camera/vertex dot product but now that I’m re-testing it cant find the difference tbh, it could be placebo effect :stuck_out_tongue:

Anyways it’s still not perfect, I can still see seams at some angles (with a perfectly seamless normal flipbook) :\ any further ideas?

Btw I analyzed that normal map a little bit and there are many problems with it… first of all it’s a 1024 texture with 10x10 tiles but 1024 / 10 = 102.4 so the tiles are not the same pixel size (therefore more seams).

Yes, it’s fine as it’s a flipbook. With tex coord (1,1), it loops correctly. That said, a little bit low res, I agree but fine for testing purposes.

I’ll try your new setup and give you feedback.

For 10x10 tiles, which perfect size(s) should be this flipbook?

ok here is what I meant:

So the seams you are seeing are because the mips are mipping to the neighbor frame which does not tile with the current frame. Mips that smoothly blend the side of one frame to another simply do not exist. With ddx/ddy you have simply removed the problem where its trying to blend to a different mip level across borders since the GPU saw a huge jump from 0 to 1 happening in 1 pixel so assumes it must be super far away. Now that is fixed but you still are seeing mips that blend to incorrect data.

To get completely smoothed tiling flipbooks I believe you need to sub-tile each frame within itself so that it has at least 1-2 border pixels of the other side, and then shrink the UVs of each frame by that amount.

The last time I had to do something like that was back in 1999 for monster truck madness 2 when all tiling textures needed that done. It was a huge pain when making giant turn textures since they would be grids of like 12x12 textures. Back then somebody made a script to automate it but I don’t know of anything that works like that anymore. Perhaps a photoshop action sequence can automate it if you do it for one frame and then record your actions?