Search Unity

Low resolution rendering 3d pixel art with integer upscaling

Discussion in 'Universal Render Pipeline' started by jRocket, Jul 14, 2021.

  1. jRocket

    jRocket

    Joined:
    Jul 12, 2012
    Posts:
    700
    I am trying to convert my game to from the built-in pipeline to URP. I am currently using the old Pixel Perfect Camera to change the rendering resolution to 960x540 to give it a nice pixel art feel that also integrates well with my 2d sprites. Something like this:
    victorydance.gif

    Unfortunately, the maintainer of that project did not accurately translate the behavior of that plugin over when it was updated for LWRP/URP, so it no longer works for my purposes and so I have to figure out how to do this on my own.

    The first thing I tried was the resolution slider, which does render a lower resolution, but it upscales it with bilinear filtering. I need point filtering to get the crisp pixel look. This is also why I don't just set the resolution lower directly- it will look blurry when upscaling to full-screen because it does not have integer scaling.

    I figured there should be a way to set a low res render target with point filtering set, have my camera render to that, and then blit that rendertexture to the screen. I haven't been able to find a way to do that yet.

    So far, I have attempted to make a ScriptableRenderPass to do so.

    Code (CSharp):
    1. public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
    2.         {
    3.             CommandBuffer cmd = CommandBufferPool.Get();
    4.             cmd.SetRenderTarget(BuiltinRenderTextureType.None);
    5.             cmd.Blit(LowResRT, BuiltinRenderTextureType.None);
    6.             context.ExecuteCommandBuffer(cmd);
    7.             CommandBufferPool.Release(cmd);
    8.         }
    I tried a few variations of that with different BuiltinRenderTextureType's, but still doesn't work. The camera will happily render to my small RT, no problem- I just can't find out how to blit it to the screen. Any ideas?
     
    insomnisan likes this.
  2. jRocket

    jRocket

    Joined:
    Jul 12, 2012
    Posts:
    700
    Any ideas?
     
  3. UnityLighting

    UnityLighting

    Joined:
    Mar 31, 2015
    Posts:
    3,874
    Use a sharpen image effect
     
  4. jRocket

    jRocket

    Joined:
    Jul 12, 2012
    Posts:
    700
    I don't think sharpening is the look I'm going for.

    I mean, I could always show the camera rendertexture in the UI, since that is done on top of everything, but I would rather just blit it to the screen.
     
  5. UnityLighting

    UnityLighting

    Joined:
    Mar 31, 2015
    Posts:
    3,874
    My idea was that reduce screen resolution to very low amount
    then use sharpen image effect to make borders aliased
     
  6. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    You'd possibly want to render everything at native size to a texture, then just a shader to blit this texture to the full res display using a "retro AA" style shader which will account for a mix of resolutions.
     
  7. UnityLighting

    UnityLighting

    Joined:
    Mar 31, 2015
    Posts:
    3,874
  8. Radivarig

    Radivarig

    Joined:
    May 15, 2013
    Posts:
    121
    You can check out my asset UPixelator, it renders a smaller resolution into a RenderTexture (which is set to Point filtering so the pixels are sharp) then upscales it so you save up on performance as opposed to rendering the full resolution with downscaling. It supports built-in and URP so far, and also has subpixel camera offset to get rid of pixel creep.