Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Pixel Art - render half res, upscale full res

Discussion in 'iOS and tvOS' started by dead_pixel_society, Dec 14, 2014.

  1. dead_pixel_society

    dead_pixel_society

    Joined:
    Oct 1, 2013
    Posts:
    8
    Hi guys

    I am making a 'pixel perfect' 2d game targeting iOS

    This is all working great (sprites are lovely and sharp, all set to point, camera orthographic and correct size etc etc)

    However, considering that this is very low res pixel art, there seems no need to actually render at full device res, but rather half or even quarter the device res would presumably provide optimised performance to no evident visual difference to the game.

    To test this, I have set screen resolution to half the res on start (e.g. 568x320 for 1136x640 device)

    This appears all correct and as expected...however once built to the device, when unity/ios upscales to the native format, it is too blurry, i would like to maintain the sharp pixel art that is evident on setting the resolution to the full original native 1136x640.

    Is there a way to make sure that any upscaling when rendering at lower res is filtering with point/nearest neighbour?

    any advice much appreciated, let me know if you need more info
     
    Last edited: Dec 14, 2014
  2. Alexey

    Alexey

    Unity Technologies

    Joined:
    May 10, 2010
    Posts:
    1,600
    it wont work for metal (in future), and we might come up with better solution, but for now the easiest would be:
    go to Classes/Unity/GlesHelper.h in your build folder
    search for
    #define GLES_UPSCALE_FILTER GL_LINEAR
    //#define GLES_UPSCALE_FILTER GL_NEAREST
    and change it to be the other way around, like this:
    //#define GLES_UPSCALE_FILTER GL_LINEAR
    #define GLES_UPSCALE_FILTER GL_NEAREST

    this should do the trick
     
  3. tonemcbride

    tonemcbride

    Joined:
    Sep 7, 2010
    Posts:
    1,077
    If you're using Unity Pro you can do this: (I use this method and it works well)

    1) Render game to a render texture at the smaller resolution

    2) Draw a full screen sprite using that render texture but make sure the render texture is set to use the 'point' filter mode
     
  4. dead_pixel_society

    dead_pixel_society

    Joined:
    Oct 1, 2013
    Posts:
    8
    Thanks so much Alexey this is exactly what I am after, very much appreciated.

    Obviously with Unity embracing 2d, the ability to do this through the player settings would be ideal, or even a flag for scenes that may need to be rendered nearest, and those that dont (Menu screens for example)...im sure you guys are thinking about it

    thanks again
     
  5. dead_pixel_society

    dead_pixel_society

    Joined:
    Oct 1, 2013
    Posts:
    8
    Thanks tonemcbride, I had read about this method but not yet tried it.

    I am curious about two things, the extra performance overhead of rendering everything to texture first, but also how this works with the ugui? Presumably the gui bypasses this?

    This process seems to me to be unintuitive when setting the render to nearest does the trick

    I would be interested in any thoughts/feedback about the benefits of this process over the previous

    thanks all
     
  6. tonemcbride

    tonemcbride

    Joined:
    Sep 7, 2010
    Posts:
    1,077
    There is slightly more overhead rendering to a texture but the actual rendering process would usually end up being much faster because the GPU is doing less work per pixel if they're using shaders etc..

    For instance, using Alexey's method renders the game to full screen (e.g. 1024x768) - if each pixel had a fragment shader of 10 instructions that would be around 8 million fragment instructions.

    If your game was rendered to a texture of a quarter size (256x192) that would only need 0.5 million fragment instructions. Obviously you then need to render this render texture as a full screen sprite but the shader required for this is much simpler so the overall number of GPU instructions is much less. There's also better caching because the whole screen is being rendered using a single smallish texture and a single texture state.

    What kind of GUI are you using? Any camera can be set to render to a texture so you can also render any GUI to that too. If you don't want the GUI scaled up you can render it on top of the large full screen sprite instead.
     
  7. tonemcbride

    tonemcbride

    Joined:
    Sep 7, 2010
    Posts:
    1,077
    p.s. One drawback of the above technique is that when you scroll the game area it will move in a whole pixel increment. For instance, in Alexey's method each game pixel could be 4 screen pixels wide and you could scroll 1 pixel at a time. In the render texture method you'd scroll by 4 pixels at a time
     
  8. Alexey

    Alexey

    Unity Technologies

    Joined:
    May 10, 2010
    Posts:
    1,600
    just to make sure you are both on same page: ios do NOT support non-native resolution, so when you set it manually we create RT under the hood and just blit it to screen at frame end, so what tonemcbride proposes is just the same though done manually.
     
  9. tonemcbride

    tonemcbride

    Joined:
    Sep 7, 2010
    Posts:
    1,077
    If you're rendering to an RT under the hood then surely that RT is pretty large? I was just making the point that rendering to a smaller RT first would be faster if you were using a lot of pixel shaders because you wouldn't be processing as many pixels. That would also be true of using multiple transparency layers etc...