Search Unity

Pixelation post prossesing effect

Discussion in 'Shaders' started by raycosantana, Dec 5, 2014.

  1. raycosantana

    raycosantana

    Joined:
    Dec 23, 2012
    Posts:
    319
    Hi I want to make a shader that makes as if the game was really low resolution and pixelated like old school games but all in 3D, so I have been searchin around about shaders that makes the screen pixelated and I think It could be made by dividing the screen resolution (for example 1/2 or 1/4 its original resolution) and then resizing the resulting image back into the original size.

    Basically I want to input an int (lets say for example 4), divide the screen resolution by that int and then resize it back to the original size while keeping all the alliasing and pixelation of the low resolution


    The problem is I dont have any idea about programming shaders, could any one help me or guide me into this?

    Yes, I have Unity pro I can use post processing image effects.

    I got the idea from a mission on Saints row 4 where you play a old school side scroller:




    Thanks a lot!

    By the way while searching about this I found some awesome post processing shaders, maybe someone could port them to unity, they are in GLSL.

    here:

    http://www.geeks3d.com/geexlab/shader_library.php
     
  2. imaginaryhuman

    imaginaryhuman

    Joined:
    Mar 21, 2010
    Posts:
    5,834
    You didnt say where in the 10 minute video to look so I did not bother trying to see what you meant. But it sounds like you mean a `de-res` or `de-resolution` effect... you just need the shader to clamp the texture coordinates to a certain amount of resolution. But either way you'd have to draw the stuff to the screen first (or to a render texture) and grab it into a texture.
     
  3. raycosantana

    raycosantana

    Joined:
    Dec 23, 2012
    Posts:
    319
    Hi thanks for the response I will look into how to do what you said, the shader is in the whole video, its the whole mission like that, the models are in 3D but they look pixel art because of this effect (an others I assume, "posterization" maybe?) which is basically what I want to achieve but yes I want make the game to look really low resolution.
     
  4. 0tacun

    0tacun

    Joined:
    Jun 23, 2013
    Posts:
    245
  5. raycosantana

    raycosantana

    Joined:
    Dec 23, 2012
    Posts:
    319
    Your Shader its not working for me, it keeps throwing the following error:
    Assets/scripts/shader/Pixelation.js(7,20): BCE0018: The name 'IndieEffects' does not denote a valid type ('not found').
    I changed "Custom/Tiles Effect" in the shader to "Indie Effects/Tiles Effect" still doesnt work.
     
  6. BBeck

    BBeck

    Joined:
    Jan 12, 2014
    Posts:
    57
    It would seem to me that a shader here would only create problems. Why can't you just paint the sprites to be pixelated? I mean generally, you just want to reduce the resolution of the sprites. When you display a 64 by 64 sprite on the screen it's gonna be pixelated. I mean, that's how they got the "effect" in the first place because back then the computer monitor couldn't display any resolution sharper than that and had an extremely limited color pallet. So use very low resolution textures in your sprite and reduce the number of colors in the pallet to something like 256 and viola! Right?

    If you take high resolution sprites with 64 bit color and write a shader to make them look bad... I mean make them look like they're from the 90's ;) ... you've wasted a lot of space and bandwidth on the graphics card. Unless, maybe you need both a modern version and a low res version at the same time for the same game. (Perhaps the game is about the world being turned into a 90's video game and the whole world randomly changes from "real" to "video game" and back during the game.)

    If you really wanted to do it, you should be able to sample a group of pixels and convert them to a single color which would pixelate them. The blur post process effect basically samples neighboring pixels and so you might start there and look at that code. But you need to do it in the local space of the sprite. If this is 2D, the local space and screen space may be practically the same, but if it were in 3D that could be a real problem. In 3D, I would especially go back to just using pixelated textures or very low res textures. In a game where they were switching back and forth, I'd probably use a high res texture and a super low res texture both.

    I did sort of a Minecraft thing once where I was purposefully using low res textures. As I recall, there was one of the settings...anti-aliasing I think it was... that had to be set just right because the graphics card wanted to "correct" my low res textures and make them look more modern by blending adjacent pixels.
     
  7. raycosantana

    raycosantana

    Joined:
    Dec 23, 2012
    Posts:
    319
    Thanks for your response, well the point is Im not gonna use sprites at all, everything its gonna be 3D but in super low resolution (while still having HD GUI and all that), here is a perfect example, this is exactly what I wanna do: http://chrismckenzie.com/
     
    BBeck likes this.
  8. aubergine

    aubergine

    Joined:
    Sep 12, 2009
    Posts:
    2,878
  9. raycosantana

    raycosantana

    Joined:
    Dec 23, 2012
    Posts:
    319
    Nope, its 3D, well the characters are, the backgrounds I think they are not.
     
  10. vetasoft

    vetasoft

    Joined:
    Nov 15, 2013
    Posts:
    432
  11. Flailer

    Flailer

    Joined:
    Apr 1, 2014
    Posts:
    66
    I mean in all fairness, I wrote this in python like ages ago, but its very easily transferable to a script in C# when you've got like a performant, low resish render texture overlay and just apply this to read the pixels and then write out the new values to a tex2D and apply to the overlay

    Code (CSharp):
    1.    
    2. def square(bw):
    3.         '''
    4.        replaces the pixels with squares
    5.        '''
    6.         for y in range(0,height,pixellation):
    7.             for x in range(0,width,pixellation):
    8.                 RGB = Intensity(x,y)
    9.                 if bw:
    10.                     grey = luma(RGB)
    11.                     draw.rectangle((x,y,x+pixellation,y+pixellation),
    12.                                     fill=(grey,grey,grey))
    13.                 else:
    14.                     draw.rectangle((x,y,x+pixellation,y+pixellation),
    15.                                     fill=(RGB[0],RGB[1],RGB[2]))
    Or even thinking about it.. if you just do a super low res rendertexture with point sampling you'd get a very 8bit look, but i suppose this gives you a bit more control over it. It's pretty damn fast if you do a 960x540 RT and then run every 2-4 pixels.
    Probs faster than post image effect too.