Search Unity

  1. We are migrating the Unity Forums to Unity Discussions. On July 12, the Unity Forums will become read-only. On July 15, Unity Discussions will become read-only until July 18, when the new design and the migrated forum contents will go live. Read our full announcement for more information and let us know if you have any questions.

Free retro inspired dithering post process

Discussion in 'Assets and Asset Store' started by Oose, Mar 28, 2021.

  1. Oose

    Oose

    Joined:
    Nov 13, 2013
    Posts:
    6
    Available free, source included at https://github.com/Ooseykins/QuickDither

    This is a post processing v2 effect that applies a limited palette dithering effect. If your project requires HDRP, you can use the URP implementation as an example of the required shader graph and camera settings. Palette generation is on a very simple editor script and can easily generate at runtime if needed.

    Video example of this effect:


     
    Last edited: Dec 14, 2022
  2. dreamyRobot

    dreamyRobot

    Joined:
    May 5, 2016
    Posts:
    8
    It looks great! Still working with Unity 2021.1 and URP? I can't add the post processing effect to the global volume.
     
  3. Oose

    Oose

    Joined:
    Nov 13, 2013
    Posts:
    6
    I've been at it for a few hours and I can't figure out how to get the effect working in URP. I think the problem I am having is likely due to linear colour vs gamma colour, giving a washed out effect. I'm also struggling to figure out how to implement post process/fullscreen effects (I don't think it's possible to make custom overrides?), as well as using the shader graph (I used both Unity and Amplify) in URP. If you're interested in using this in your project, I recommend using the builtin renderer with Post Processing v2, and gamma colour space. The downsides of using the "old", "bad" renderer are kind of lost when you consider the effect you get in the end, like this:


    If you're adamant on using URP and want this kind of effect you should make your own shader/effects (and if you do I would really love to see them!) then I can give you some tips on using the rest of the assets in the project. To start, you can deleted Dithered.cs from your project because it's just used for post processing and gives errors in urp/hdrp. The asset files generated by the editor scripts are 3D textures, essentially lookup textures that use the RGB channels of the input texture as coordinates. The alpha channel of the 3D textures represent the "dominance" of that colour that sum to 1 at the same point. You can compare the alpha channel of the primary 3D texture to a dither texture sample, and if it's greater use the primary, otherwise use the secondary. This is the unlit shader (called Dithered.shader) as it looks in Amplify Shader Editor. The dither node here seems to only ever output 1 or 0, which is why I use lerp instead of some comparison. dithered_amplify_simple.PNG
     
    Last edited: Jul 12, 2021
  4. Nick-Carver

    Nick-Carver

    Joined:
    Feb 20, 2016
    Posts:
    13
    Hey, I've been playing around with these effects and they're really impressive - congrats! I'm having trouble getting them to work in a standalone build though. Have you had any problem with this yourself?
     
  5. Oose

    Oose

    Joined:
    Nov 13, 2013
    Posts:
    6
    I have not had any problems with standalone, could you be specific with the problem? Two errors that I could see being an issue would be the shader not included in the build for some reason (Project Settings -> Graphics -> Always Included Shaders) or not being able to generate textures on runtime due to missing compute shader support (like mobile devices). If the problem is with missing compute shader support, you can pre-generate the palettes and used them as saved assets.
     
    Nick-Carver likes this.
  6. Nick-Carver

    Nick-Carver

    Joined:
    Feb 20, 2016
    Posts:
    13
    Thanks so much for replying immediately! Your first suggestion fixed it. I added both the shaders to Always Included and it's working. Thanks again!
     
    Oose likes this.
  7. sergiulupse

    sergiulupse

    Joined:
    Mar 29, 2015
    Posts:
    1
    Hi, I've seen a couple of tutorials for Shader Graph that might have Dither as an "effect" but not a "post-processing" one and nothing like what your asset does. I really loved it! I used it sparingly with the Built-In Renderer and now that I've switched to URP I miss it and I feel my game is missing that special retro look I was going for. Any chance there is a solve for URP?

    Thank you!
     
    Last edited: Nov 28, 2022
  8. lucasgrpsdecmpiles

    lucasgrpsdecmpiles

    Joined:
    Dec 31, 2021
    Posts:
    1
    How do i use it?
     
  9. Oose

    Oose

    Joined:
    Nov 13, 2013
    Posts:
    6
    Hi, I've added URP support now. It's a bit clunky, but the end effect is the same, usage instructions in the github readme. Still at https://github.com/Ooseykins/QuickDither and has a .unitypackage available in releases on the sidebar.
     
  10. scarramanga

    scarramanga

    Joined:
    Jun 8, 2013
    Posts:
    1
    Hi, thanks for this. I was having trouble getting an existing canvas with render mode "Screen Space - Camera" to render to the render texture and have it's ray-casting work as well. (I couldn't click any UI buttons). I found and built a solution, I thought I'd share in case anyone else stumbled on this thread. The problem was that the raycasting position wasn't being downscaled to the size of the render texture. To fix:

    1) Create a new script "CustomRaycaster.cs":

    Code (CSharp):
    1. using System.Collections.Generic;
    2. using UnityEngine;
    3. using UnityEngine.UI;
    4. using UnityEngine.EventSystems;
    5.  
    6. public class CustomRaycaster : GraphicRaycaster
    7. {
    8.     public Canvas canvas;
    9.  
    10.     public override void Raycast(PointerEventData eventData, List<RaycastResult> resultAppendList)
    11.     {
    12.         if (canvas.worldCamera != null && canvas.worldCamera.targetTexture != null)
    13.         {
    14.             //Debug.Log($"p: ({eventData.position.x}, {eventData.position.y})  s({Screen.width}, {Screen.height}) => s({remap.x}, {remap.y})");
    15.  
    16.             eventData.position = Remap(
    17.                 new Vector2(Screen.width, Screen.height),
    18.                 new Vector2(canvas.worldCamera.targetTexture.width, canvas.worldCamera.targetTexture.height),
    19.                 eventData.position);
    20.         }
    21.  
    22.         base.Raycast(eventData, resultAppendList);
    23.     }
    24.  
    25.     Vector2 Remap(Vector2 from, Vector2 to, Vector2 input)
    26.     {
    27.         return new Vector2(
    28.             Mathf.Lerp(0, to.x, Mathf.InverseLerp(0, from.x, input.x)),
    29.             Mathf.Lerp(0, to.y, Mathf.InverseLerp(0, from.y, input.y))
    30.             );
    31.     }
    32. }
    2) Attach the script to the canvas being used for menus and such. This script replaces Graphic Raycaster on the canvas, so remove the old one.
    3) Set the canvas field (should just be itself)
    4) Done! That should be the only steps.

    Thanks again, it was very helpful to see this approach. I learned a lot. =)