Blog Post: Tiling within SubUV or volume textures

I have written a new blog post about a method for making subUV textures tile seamlessly:


Seam with a tiling subUV by default:

Seam removed by over sampling edges:


Reading using subUV node:

Hey @RyanB ,

Trying to utilize your method for some tiling caustics in a water material from a flipbook/subUV texture. It’s pretty big around 8K but it looks like the one you used in your blogpost.

I’m probably being dim but I’m still getting the seams, there’s a picture attached.

Something I think I’m doing wrong is where you mention “encoding the single caustic texture into a SubUV animation”.

Is this related to the scatter/gather (not sure which) method that you talked about for rendering caustics to render targets? As in, does the SubUV texture you use finally need to be baked with this kind of altered UVs?

I bake the textures in Houdini so I might be able to replicate this before baking, just wanted to confirm. I’m thinking the answer is yes because it doesn’t really make sense I guess for the method to work otherwise.


Yes each frame of the subuv needs to have a few border texels encoded. you can use a ue4 material to re-encode it, although there may be a slight resolution loss from resizing the frames. All you need is the 2d correction part of the encoding from the article. I wont have time today but tomorrow or monday I can show an example.

Hey @RyanB ,

Ahhh that makes sense!

I would really appreciate the example if you have the time for it, I’m still a little green on how to use the render target baking stuff (though the BP API for it is pretty straightforward from what I’ve seen).

It would also prove useful to people coming back to this forum post so might be worth it for future posterity as well?

In any case, I’ll keep noodling around on my water material, thanks a bunch!

So, I took a look at the BPSubUVMaker blueprint in your GDC Plugin pack and it pretty much had exactly what was needed to get the job done.

There was a hurdle in the Render Material with getting the new subUV to render correctly with its looping preserved as Material ‘Time’ (which I read on a post you made elsewhere is the game ‘Real Time’) is not correctly synced with the progression of DeltaTime which causes issues of desyncing the flipbook when you use the ‘Time’ node to drive the animation/blending.

Solved it by using the ‘Flipbook’ material node instead of the ‘SubUV_Function’ node and driving the animation phase with a scalar parameter ‘Frame’ I set in the BPSubUVMaker blueprint.

This bypasses any issues with relying on game time being correct and all of that headache.

I think this might only matter with a looping material, for any other type of bake you could probably just check if the number of rendered frames has reached the max.

Incidentally I couldn’t understand what was going on with the time accumulator stuff in there, would be interested to know what your intended purpose was with it.

Anyway Ryan, thanks a ton, now have some really sweet tileable animated caustics I can use for pretty much any water material :slight_smile:

Link to gif:


The subUV maker BP is specific the fluid sim BP so far. The time accumulation thing was an attempt to make it capture with frame rate independence assuming the source was independent. But my fluid was never actually frame independent and probably won’t be so I will likely remove that. If you are just using it to re-encode some existing flipbook frames then you shouldn’t need it. Actually you don’t need the blueprint logic at all and could do this entire re-encode with a single shader if you wanted (well you need 1 BP draw event for that but not the flipbook logic).

The main difference between the SubUV and Flipbook functions (other than the fact that one takes 0-1 and the other 0-framenumber) is that SubUV interpolates between frames whereas Flipbook just displays the current frame. If you were using this to re-encode (vs just render the final result), then yes you would want flipbook so as to not blend frames in time. But you’d want to use SubUV to display the final result because frame blending will make it smoother.

I also worked on a shader to generate motion vectors and save them out using a caustics texture as an example. My results were only ‘ok’ though and I didn’t really have much time to finish it. Maybe next year.