I’m trying to make a fragment shader in HLSL that makes a dithering pattern when adjusting the transparency of the shader. This shader is added to a camera with a C# script. I copied a shader from the internet that kind of did what I wanted, and modified it to my needs.
There are 3 problems I am facing, but I can’t wrap my head around what is happening:
- The shader follows the movement of the camera. I would like the dithering pattern to stay in place.
- The scaling of the dithering pattern changes when I set Unity to Maximize On Play
- Changing the Transparency value in Play Mode causes some kind of weird ghosting effect. In Edit Mode it works as expected.
I’m new to shaders, and I find some things pretty confusing. If I’m doing something very stupid in this code, please be kind ![]()
Shader "TestShader"
{
Properties
{
_MainTex("Texture", 2D) = "white" {}
_Transparency("Transparency", Range(0,1)) = 1.0
_PixelSize("Pixel size", Range(0,1)) = 0.25
_ColorToDither("Color to dither", Color) = (1,0,0,0)
}
SubShader
{
Cull Off ZWrite Off ZTest Always
Tags
{
"RenderType" = "Opaque"
}
Pass
{
CGPROGRAM
#include "UnityCG.cginc"
#pragma vertex vert
#pragma fragment frag
sampler2D _MainTex;
float _Transparency;
float _PixelSize;
float4 _ColorToDither;
struct appdata
{
float4 position : POSITION;
float4 uv : TEXCOORD0;
};
struct v2f
{
float4 position : POSITION;
float4 uv : TEXCOORD1;
float4 screenPosition : TEXCOORD2;
};
v2f vert(appdata v, float2 screenPosition : TEXCOORD2)
{
v2f OUT;
OUT.position = UnityObjectToClipPos(v.position);
OUT.uv = v.uv;
OUT.screenPosition = ComputeScreenPos(OUT.position);
return OUT;
}
float4 frag(v2f i) : COLOR
{
float4 currentColor = tex2D(_MainTex, i.uv);
if (currentColor.r == _ColorToDither.r && currentColor.g == _ColorToDither.g && currentColor.b == _ColorToDither.b) //Checks if the current pixel is red, to only apply dithering to red pixels
{
float DITHER_THRESHOLDS[16] =
{
1.0 / 17.0, 9.0 / 17.0, 3.0 / 17.0, 11.0 / 17.0,
13.0 / 17.0, 5.0 / 17.0, 15.0 / 17.0, 7.0 / 17.0,
4.0 / 17.0, 12.0 / 17.0, 2.0 / 17.0, 10.0 / 17.0,
16.0 / 17.0, 8.0 / 17.0, 14.0 / 17.0, 6.0 / 17.0
};
uint index = (uint(i.position.x * _PixelSize) % 4) * 4 + uint(i.position.y * _PixelSize) % 4;
clip(_Transparency - DITHER_THRESHOLDS[index]);
}
return currentColor;
}
ENDCG
}
}
This is the C# script to add the shader to the camera:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[ExecuteInEditMode]
public class ShaderHandler : MonoBehaviour
{
public Material material;
private void OnRenderImage(RenderTexture source, RenderTexture destination)
{
Graphics.Blit(source, destination, material);
}
}

