Can a rendered frame be made seamless, by some compositor tricks? What I'm looking for is something similar to the GIMP filter Make seamless.

Here's an example
Original (downloaded from Pixabay):
enter image description here

After Make seamless applied:
enter image description here

I could, of course, do this in GIMP, but I'd like to avoid post processing in external applications, and get a ready made image directly out of Blender. My goal is to have a repeating background and composite non-repeating text on top of it, and I'd like to be able to do it with two render layers or, if necessary, two scenes in the same .blend.

When searching Blender.SE, I found several questions about seamless images, but they all seemed to want to know how to use pre-existing seamless images, or how to get a texture to repeat seamlessly on an object. The ones I actually opened, did not answer my question, since I'm aiming to create a seamless image from a render.

  • 1
    $\begingroup$ I don't think it's possible, long time ago there was a thread (probably at blenderartist) to create 'seamles node' but I think it's dead by now. There is nothing wrong with using external apps to post process your work. I'm myself such a purist as you, and I wanted to make whole lightsaber in render even without compositing (!!!) but sometimes we need to give it up and use simple, outside methods. $\endgroup$ – cgslav Aug 11 '16 at 19:49
  • $\begingroup$ @LukeD I know there's no node that does it directly, but I was hoping it could be done with some tricks with the existing nodes. I actually do post processing externally, but mostly pretty simple stuff from the command line, using ImageMagick. The problem is that GIMP still doesn't do 16 bit colour channels properly, and ImageMagick doesn't have a Make seamless filter. $\endgroup$ – Duane Dibbley Aug 11 '16 at 20:04
  • $\begingroup$ So as far as I know the only 'trick' would be making masks and do it manually but that's pointless. I'm photshop user but I see that development gimp version (2.9.x) can do 16bit. $\endgroup$ – cgslav Aug 11 '16 at 20:20

The question depends on the nature of the source image. In the Fireworks example the edge is already seamless (black). So you can use the compositor. Otherwise you would prepare the edges as the other answer suggests with a blending mask.

  1. Import image
  2. Add a Translate node, turn on "Wrap Both Axes"
  3. Alter X and Y offset
  4. You can add the original image back over the top with an "Add" mix node.

Wrap image with Translate node

  • $\begingroup$ I would mention that this method works only in the cases where the background is completely black, otherwise the "add" mix node would not be able to produce clean results. $\endgroup$ – Carlo Aug 11 '16 at 23:46
  • $\begingroup$ Yes this solution is image dependent but I did write that in the response. with the Translate Wrap function I think you could go some way to making a general purpose group node for this effect. $\endgroup$ – 3pointedit Aug 12 '16 at 1:42
  • 1
    $\begingroup$ Thanks. This is the one that lead me in the right direction, and my own answer has issues, so I decided to accept yours. $\endgroup$ – Duane Dibbley Aug 12 '16 at 16:34

First of all, you need an alpha mask. It should look a bit like this:

enter image description here

Basically, black in the middle and white at the edges. It should preferrably be the same size as the image you want to make seamless, but it also works if it isn't.

Make sure that you set the render resolution to the same resolution as the image you want to make seamless. Go to the node editor, go to the compositing tree and add two image nodes, one with the image you want to make seamless and one with the alpha mask. Connect the image node with the alpha mask to a Scale node, and set it to stretch to the Render Size.

enter image description here

Add four Translate nodes and four Mix nodes. Connect the Image output of the image node with the image you want to make seamless to the Image input of each of the four Translate nodes. Set the X value of the first Translate node to 0.5, the X value of the second to -0.5, the Y value of the third to 0.5 and the Y value of the fourth to -0.5. Mix each of the Translate node's Image outputs with the original image using the Mix nodes, while using the alpha mask as the Fac input for the Mix nodes.

enter image description here

If you render it, the result will be a (somewhat) seamless image.

enter image description here

Note that there are still borders, this time caused by the borders in the alpha mask. You may want to experiment with different alpha masks in order to find one that works well for your particular image. For example, mine has a large black square in the middle, while you might be better off with one that has no square in the middle at all.

Here is the .blend file:

Even though this solution works, you are probably far better off using a different program than blender.

  • $\begingroup$ Thank you. I just had a quick look, and like you said yourself, I'll probably achieve better results with external post processing. But this is a good starting point. I will play with it, and see if I can improve it. I upvoted, but I'll wait a few days or so before accepting, to see if something ever better shows up. $\endgroup$ – Duane Dibbley Aug 11 '16 at 21:47
  • $\begingroup$ Doesn't look seamless to me. Seamless at the edges, but now there are seams in the middle of the image. (actually at the edge of the black part of the alpha mask) $\endgroup$ – immibis Aug 12 '16 at 3:26
  • $\begingroup$ Indeed, my method is far from perfect, but using a different alpha map might help. In the end, the best way to make it seamless depends heavilly on the image. For example, it is possible to make the black background of the image in the question transparent, making it much easier to make the image seamless. $\endgroup$ – Ezra Aug 12 '16 at 6:39

Combining the two previous answers, I came up with this.

Here is the original image, which I'm going to try to make seamless.
enter image description here

Add an Ellipse Mask node and connect its output to the Image input socket of a Blur node. Connect the output to the Fac of a ColorRamp node. Connect the rendered image to the Image input socket of a Set Alpha node and the Image output socket of the ColorRamp node to the Alpha socket of the Set Alpha node.

The Blur node blurs the edges of the Ellipse Mask, and combined with the ColorRamp the shape of the mask can be set quite precisely. The output from the Set Alpha will look something like this.
enter image description here

Connect the output of the Set Alpha node to a Translate node and enable Wrap: Both Axes.

After translating, the alpha channel will be something like this.
enter image description here

And the translated image, with the alpha channel above will look like this.
enter image description here

Connect the output of the Translate node to the lower Image input socket of an Alpha Over node, and the unmodified rendered image to the upper Image input socket of that Alpha Over node. Enable Convert Premul on the Alpha Over.

And this step combines the original image and the masked, translated one into this.
enter image description here

That's about it. Now just tweak the size of the Ellipse Mask, the settings for the Blur node and the positions of the handles in the ColorRamp node, and possibly the position of the Ellipse Mask and the values for the Translate node.

The image I used here isn't the same as in my question. I used this one to make sure I had one where the colours of opposite edges aren't identical.

Screenshot of the node setup. enter image description here

  • $\begingroup$ After some further playing with this, I must confess that this has some issues with the masking. It can probably be solved by some tweaking, and I'll be looking into it as soon as I can get the peace and quiet. $\endgroup$ – Duane Dibbley Aug 12 '16 at 16:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.