Search Unity

(SOLVED) Converting an image-shader/post processing effect (dithering) into a material?

Discussion in 'Shaders' started by forteller, Jun 16, 2019.

  1. forteller

    forteller

    Joined:
    Jun 15, 2019
    Posts:
    55
    I created a post processing image shader using an ordered dithering algorithm to create a sort of mechanical stippling effect which works great.

    I want to be able to apply the effect to individual game-objects in my scene, because of this I made an unlit version of this shader but now that the shader is working on 3D meshes (instead of the orthogonal quad the image shader was working on) the quantized dithering patterns now curve in perspective along the shape of the mesh (like I dithered the texture and then wrapped it back around the mesh) instead of flat look I want.


    I noodled around with different projections in the vertex shader and using multiple passes a bit but I couldn't get anything to work (I am a total beginner when it comes to writing custom shaders). Is there any way to obtain this effect by using materials or do i have to apply dithering as a post processing/image shader-- in that case should I look into stencils?

    Here's my fragment shader on my attempt to make a unlit version of this shader (all other code is just boilerplate stuff that a default unlit shader has)
    Code (CSharp):
    1.  fixed4 frag (v2f inn) : SV_Target
    2.             {
    3.    
    4.                 uint matSize = 4;
    5.                 float4x4 mat = { //ordered dithering matrix
    6.                 1, 8, 2,10,
    7.                 12,4,14, 6,
    8.                 3, 11, 1,9,
    9.                 15, 7 ,13,5
    10.                 };
    11.  
    12.                 mat = mat / (matSize * matSize);
    13.  
    14.                 int pxIndex = inn.uv.x * _ScreenParams.x; //x index of texel
    15.                 int pyIndex = inn.uv.y * _ScreenParams.y; //y index of texel
    16.  
    17.                 float4 c = tex2D(_MainTex, inn.uv); //base image un-dithered
    18.  
    19.                 int mati = pxIndex % matSize; //get which index of dithering matrix texel corresponds to
    20.                 int matj = pyIndex % matSize;
    21.  
    22.                 //quantization
    23.                 if (c.r > mat[mati][matj]) { c.r = 1; }
    24.                 else { c.r = 0; }
    25.                 if (c.g > mat[mati][matj]) { c.g = 1; }
    26.                 else { c.g = 0; }
    27.                 if (c.b > mat[mati][matj]) { c.b = 1; }
    28.                 else { c.b = 0; }
    29.  
    30.                 UNITY_APPLY_FOG(inn.fogCoord, col);
    31.                 return c;
    32.                
    33.             }
    Thanks!
     

    Attached Files:

  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    The v2f value using SV_Position is the screen pixel position in the fragment shader. For example, if you use o.pos = UnityObjectToClipPos(v.vertex);
    Code (CSharp):
    1. int pxIndex = inn.pos.x; //x index of texel
    2. int pyIndex = inn.pos.y; //y index of texel
     
    forteller likes this.
  3. forteller

    forteller

    Joined:
    Jun 15, 2019
    Posts:
    55
    Thanks for the quick reply!
    Guess I should have known the transformed vertex positions were the screen pixel positions -- very useful!