Search Unity

Old style dithered effect

Discussion in 'Shaders' started by kurai, Oct 22, 2012.

  1. kurai

    kurai

    Joined:
    Jan 9, 2012
    Posts:
    118
    I'm a complete newbie with shaders, so probably what I'm asking is not the better problem to start with.
    Anyway, I was looking for a shader which dithers the darker zones of an object. To better explain, what I'm looking for is something like Midwinter, an old Amiga game:



    Is this difficult to obtain?
     
  2. imaginaryhuman

    imaginaryhuman

    Joined:
    Mar 21, 2010
    Posts:
    5,834
    It's basically a way of representing specific ranges of color values as a pattern. In the image above there are apparently:

    White
    White with small blue dots
    50/50 White and blue dots
    Mostly blue dots
    Blue
    ... similar for blue levels

    In a shader one way is to have a pattern texture with one `grid` cell of pattern for each brightness level, and you can put all of the levels on one texture. Then you just need to take the fragment coordinate (relative to screen coords, not the world coordinate, otherwise the pattern will flicker and shift), use the `modulo` of those numbers to keep within 1 grid cell, then look up a pixel from the the grid cell. ... you select which cell to reference also based on the tone of the color being drawn, falling into a specific bracket. It's doable.
     
    bzor likes this.
  3. aubergine

    aubergine

    Joined:
    Sep 12, 2009
    Posts:
    2,880
  4. RC-1290

    RC-1290

    Joined:
    Jul 2, 2012
    Posts:
    639
    You'd probably want to create an image effect for that, which creates the illusion of a lower resolution and lower number of available colors. So you'd need to use Unity Pro.

    For the dithering itself you can use an existing dithering technique like Floyd-Steinberg, and convert it to work on a GPU. (For example, the pseudo code you can find on Wikipedia assumes you can write to other pixels, which is not how you work in shaders)

    I'm not sure if it is something you'd want to do as your first shader, because it is a combination of several different disciplines, but it is certainly doable.
     
  5. Martin-Kraus

    Martin-Kraus

    Joined:
    Feb 18, 2011
    Posts:
    617
    I'm unable to access screenPos in the finalcolor function of a surface shader:
    Code (csharp):
    1.  
    2. Shader "dithering" {
    3.     Properties {
    4.       _MainTex ("Texture", 2D) = "white" {}
    5.       _ColorTint ("Tint", Color) = (1.0, 0.6, 0.6, 1.0)
    6.     }
    7.     SubShader {
    8.       Tags { "RenderType" = "Opaque" }
    9.       CGPROGRAM
    10.       #pragma glsl
    11.       #pragma surface surf Lambert finalcolor:mycolor
    12.       struct Input {
    13.           float2 uv_MainTex;
    14.           float4 screenPos; // x and y between 0 and 1
    15.       };
    16.       sampler2D _MainTex;
    17.       void surf (Input IN, inout SurfaceOutput o) {
    18.           o.Albedo = half3(1.0, 0.0, 0.0);
    19.       }
    20.  
    21.       void mycolor (Input IN, SurfaceOutput o, inout fixed4 color)
    22.       {
    23.           color = fixed4(IN.screenPos.x, IN.screenPos.y, 0.0, 1.0);
    24.       }
    25.       ENDCG
    26.     }
    27.     Fallback "Diffuse"
    28.   }
    29.  
    gives:

    Shader error in 'dithering': D3D shader assembly failed with: (6): error X5204: Read of uninitialized components(*) in r0: *r/x/0 *g/y/1 b/z/2 a/w/3

    Shader Assembly: ps_2_0
    ; 3 ALU
    def c0, 0.00000000, 1.00000000, 0, 0
    mov r0.w, c0.y
    mov r0.z, c0.x
    mov_pp oC0, r0


    Any ideas?