3
$\begingroup$

I'm making render similar to PS1 games from the 90s. An important part of that look is the low render resolution. Right now, I render a PNG near the PS1's maximum native output of 640x270 then scale it to 2560x1080 in GIMP by clicking Image -> Scale Image and changing the image size from 640x270 to 2560x1080 and the interpolation to None. I am working in Eevee, but I would appreciate a solution for Cycles, too.

There must be a way to do this automatically using compositor nodes to scale the image output after the actual render, but I can't for the life of me figure it out.

For reference, here is the default cube rendered at default settings, 2560x1080:

default cube rendered at 2560x1080

Here is the same cube rendered at 640x270, with dither at 0 and filter size at .01 px:

default cube rendered at 640x270

Here's that last render scaled up to 2560x1080 in GIMP, which I'd like to do automatically in Blender:

default cube rendered at 640x270 then scaled to 2560x1080

This image is rendered at 640x270, and the image size is also 640x270, but I would like to scale the image to 2560x1080, without interpolation, using compositor nodes.

$\endgroup$
3

3 Answers 3

0
$\begingroup$

//EDIT: As mentioned in the comments, my version isn't flawless: it leaves a transparent gap in the top row and right column of the result. Of course you can always scale a little larger than the exact factor, but this might result in losing image information. Scroll to the end to find a solution for this.

Simple solution (with gaps): Because the link to the manual already explains what you have to do, so this will be my first option of explanation:

  • You can place a Pixelate node between two Scale nodes. If you set them to Relative, you can use the first one to scale the image down by a factor x, for example 0.1, then pixelate the image and scale it back up by 1/x i.e. in this example 10. If you want to automate this a bit you can put a Value node in there to hold the factor x and a Divide node to get the upscaling factor.

pixelate relative

Now the reason I give an answer instead of just leaving it at that link to the manual is the following: if you want to scale the image down to absolute pixel values instead of scaling relative, you can set the Scale node to absolute and enter perhaps 192 x 108 pixels.

The problem is, if you want to scale it back to normal Scene Size or Render Size, these options will not work. It seems as if scaling down the image means Blender scaled the render/scene size down as well.

So the only way would be to use Absolute for upscaling and set it manually to the render size, let's say that's 1920 x 1080. But that doesn't work either. To get back the original image size, the absolute pixels have to be scaled by the reciprocal of the downscaling factor as well. So if you scaled it down to original/10 = 192 x 108, you have to set the upscaling to original*10 = 19200 x 10800.

  • If you don't want to do all manually, you could use Value nodes for the X and Y size you want to scale down to absolutely, then place Divide nodes afterwards where you divide the original dimensions by the new small dimensions and plug the results in the upscaling node, set to Relative.

pixelate absolute

You can try different combinations of relative and absolute scaling to get the desired result, just know that using Scene Size or Render Size in the Scale node doesn't seem to work to get back to the original size. For the Absolute workflow it's a bit annoying that there are no nodes to read the render dimensions from the settings and put them in the nodetree somehow, but maybe I'm just missing something and someone else could help.

Updated solution (without gaps): The gaps are not a result of the image not being scaled up large enough, but rather a misplacement of the image's origin point. If you for example scale down to 1/4 of the original size and afterwards scale up by 4 to bring back the original size, there is a gap of 2 pixels at the top and 2 pixels to the right. If you use 1/10 down and 10 up, the gap is 5 pixels top and right.

So the upscaled image seems shifted to the left and down by 1/2 of the upscaling factor. To compensate for this, you can simply divide the upscaling factor by 2 and plug this value into the X and Y inputs of a Transform node, placed after the upscaling node.

This is a simplified version if you want to scale uniformly with a relative factor on X and Y:

uniform relative with shift

But it also doesn't matter if you want to scale X and Y different from each other, in this case you have to shift individually on X and Y in the Transform node as well:

shift X+Y individually

Of course this all works with downscaling the image to absolute pixel values as well (although this method still has the disadvantage that the render size isn't set automatically). Like in the simple solution before, by dividing the original render dimensions with the new values, you get the upscaling factors. And from those you again need the half for the Transform node:

absolute scaling with shift

$\endgroup$
8
  • $\begingroup$ This is pretty close to what I'm looking for but it leaves the topmost row and rightmost column as transparent for some reason. I am scaling from 2560x1080 -> 640x270, so a relative value of .25 should work. $\endgroup$ Aug 8, 2022 at 14:59
  • $\begingroup$ Hmmm... you're right, I have the same issue. I guess that's some interpolation problem. Maybe you could use an Alpha Over node to put the pixelated above the original to fill the gap. Of course in my example that wouldn't be a problem, in other renders it might be if there is one row and column not pixelated. I cannot try it anyway at the moment, suddenly my Blender always crashes when I try to save the result and I have to go offline now. $\endgroup$ Aug 8, 2022 at 15:10
  • $\begingroup$ I found a video explaining it, so I submitted a new answer. You were definitely on the right track! Turns out "1000 pixels" is actually 1024 pixels. Who knew? $\endgroup$ Aug 8, 2022 at 23:10
  • $\begingroup$ @HotDogWaterChugger Well, that's only half the truth. The method described there gets rid of the empty row and column, but you could achieve this with any kind of upscaling larger than the reciprocal value. Fact is, if I render something and there would be for example a thin border around the image, this gets lost if you downscale with 1/4 and upscale with 4.096 instead of 4. Of course a border of 1 pixel vanishes more or less anyway when scaled to 0.25, but even a 4 pixel border (which scales down to 1 pixel) is gone after upscaling again with 4.096 although it should be there. $\endgroup$ Aug 9, 2022 at 6:32
  • 1
    $\begingroup$ I had no time to check your answer closer (will take a time later) ... just a note how scaling behave imgur.com/mErLctx ... for the gap I saw used InPaint node (sure it doesn't solve the interpolation appearance) :) $\endgroup$
    – vklidu
    Aug 9, 2022 at 8:44
2
$\begingroup$

Compositor can output whatever image size it needs to so if you wanted to save a higher resolution image than what is rendered you just need a higher resolution image in the compositor. So for example, if you had an image node that loads a higher resolution image from disk, compositor can output that image in it's resolution no matter your renders resolution. If you mix something on top of that higher resolution image, the resolution of it remains the same. But we don't need an image, one can also use an empty Mask node that has it's own resolution and mix something on top of it to get a higher resolution image:

enter image description here

This will render 100x75px image, but output a 2000x1500px size image. enter image description here

$\endgroup$
6
  • $\begingroup$ +1 Haha, this is so much simpler than my solution :D $\endgroup$ Aug 9, 2022 at 8:13
  • $\begingroup$ I remember how much torture it was to find out this works. I render interior visualisation and often need to output different orientation and size stills that I set up as animation, but you cannot render frames with different sizes... :D $\endgroup$ Aug 9, 2022 at 8:15
  • $\begingroup$ The only downside is, if you maybe want to simulate old computer graphics and there exist some that didn't have quadratic pixels, your solution doesn't work well for individual scaling factors on X and Y. Sure, you can use a Scale node instead of a Transform node and set different factors for X and Y, but the Scale node doesn't have the "Nearest" option so it will be blurred through upscaling. $\endgroup$ Aug 9, 2022 at 8:20
  • 1
    $\begingroup$ Okay, now I got the perfect solution ;) If you also want the option to scale individually, you simply take a Pixelate node, then plug a Scale node afterwards and there you can now set individual factors for X and Y and they will not be interpolated anymore. $\endgroup$ Aug 9, 2022 at 8:28
  • $\begingroup$ Yep. Or just scale it up with Transform node and then if you scale it down with Scale node in different aspect ratio it doesn't matter, because it interpolates scaling down. $\endgroup$ Aug 9, 2022 at 8:30
0
$\begingroup$

Do you mean scaling in the Compositor?

Scale

If so, the node in question is under Add > Distort > Scale.

EDIT -Try this - you might have to figure out the math to get the right resolution, but this seems to work for the example at least - maybe its something to start with/explore:

Scale2

$\endgroup$
5
  • $\begingroup$ I think you're on the right track, but the Scale node only scales the output without scaling the actual image size (as if the camera were zoomed in) and uses some form of interpolation. I was able to get around the interpolation using the Transform node set to Nearest, but not sure how to scale the image output size. What I ultimately want is to essentially recreate what happens if you zoom into the render result using the mouse wheel, if that makes sense. $\endgroup$ Aug 8, 2022 at 4:07
  • $\begingroup$ Ok. So, let me try to rephrase just to make sure I'm clear - lets say you have your image output settings set to 1920x1080 - when you render, you want the output image to be scaled down to 256x256 (for example) and you want the image to be scaled to fit as well (distorting/stretching as necessary)., or would you like it cropped to fit instead? $\endgroup$ Aug 8, 2022 at 4:45
  • $\begingroup$ I've edited the OP to clarify. I don't want to change the render, I want to change the dimensions of the image output. $\endgroup$ Aug 8, 2022 at 5:13
  • $\begingroup$ Ok, I think I get it - A 128x128 image is tiny (in size) compared a 2048x2048 image (for example) - you want to render the image "tiny" (low-rez) and then scale it back up to 2048x2048 (output size) while keeping the same low-rez appearance? $\endgroup$ Aug 8, 2022 at 5:31
  • $\begingroup$ I edited my answer - try this out $\endgroup$ Aug 8, 2022 at 5:47

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .