Created
December 1, 2025 16:12
-
-
Save dasannikov/9d6040833d1b44d603ac01b09788b1cc to your computer and use it in GitHub Desktop.
Unity3D Shader for UI Image with Rotated Grid Super-Sampling
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Shader "UiImage-RGSS" | |
| { | |
| Properties | |
| { | |
| _MainTex ("Sprite Texture", 2D) = "white" {} | |
| _Color ("Tint", Color) = (1,1,1,1) | |
| _StencilComp ("Stencil Comparison", Float) = 8 | |
| _Stencil ("Stencil ID", Float) = 0 | |
| _StencilOp ("Stencil Operation", Float) = 0 | |
| _StencilWriteMask ("Stencil Write Mask", Float) = 255 | |
| _StencilReadMask ("Stencil Read Mask", Float) = 255 | |
| _ColorMask ("Color Mask", Float) = 15 | |
| [Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0 | |
| } | |
| SubShader | |
| { | |
| Tags | |
| { | |
| "Queue"="Transparent" | |
| "IgnoreProjector"="True" | |
| "RenderType"="Transparent" | |
| "PreviewType"="Plane" | |
| "CanUseSpriteAtlas"="True" | |
| } | |
| Stencil | |
| { | |
| Ref [_Stencil] | |
| Comp [_StencilComp] | |
| Pass [_StencilOp] | |
| ReadMask [_StencilReadMask] | |
| WriteMask [_StencilWriteMask] | |
| } | |
| Cull Off | |
| Lighting Off | |
| ZWrite Off | |
| ZTest [unity_GUIZTestMode] | |
| Blend SrcAlpha OneMinusSrcAlpha | |
| ColorMask [_ColorMask] | |
| Pass | |
| { | |
| CGPROGRAM | |
| #pragma vertex vert | |
| #pragma fragment frag | |
| #pragma target 3.0 | |
| #include "UnityCG.cginc" | |
| #include "UnityUI.cginc" | |
| #pragma multi_compile_local _ UNITY_UI_CLIP_RECT | |
| #pragma multi_compile_local _ UNITY_UI_ALPHACLIP | |
| struct appdata | |
| { | |
| float4 vertex : POSITION; | |
| float4 color : COLOR; | |
| float2 texcoord : TEXCOORD0; | |
| UNITY_VERTEX_INPUT_INSTANCE_ID | |
| }; | |
| struct v2f | |
| { | |
| float4 vertex : SV_POSITION; | |
| fixed4 color : COLOR; | |
| float2 texcoord : TEXCOORD0; | |
| float4 worldPosition : TEXCOORD1; | |
| UNITY_VERTEX_OUTPUT_STEREO | |
| }; | |
| sampler2D _MainTex; | |
| fixed4 _Color; | |
| fixed4 _TextureSampleAdd; | |
| float4 _ClipRect; | |
| float4 _MainTex_ST; | |
| // Rotated Grid Super-Sampling (RGSS) | |
| // RGSS offsets for 2x2 rotated grid supersampling | |
| static const float2 rgss_uv_offsets = float2(0.125, 0.375); | |
| // RGSS texture sampling function | |
| fixed4 rgss_tex2D(sampler2D texture_sampler, float2 uv) | |
| { | |
| // Per pixel partial derivatives | |
| float2 dx = ddx(uv); | |
| float2 dy = ddy(uv); | |
| // Supersampled using 2x2 rotated grid | |
| fixed4 col = tex2D(texture_sampler, uv + rgss_uv_offsets.x * dx + rgss_uv_offsets.y * dy); | |
| col += tex2D(texture_sampler, uv - rgss_uv_offsets.x * dx - rgss_uv_offsets.y * dy); | |
| col += tex2D(texture_sampler, uv + rgss_uv_offsets.y * dx - rgss_uv_offsets.x * dy); | |
| col += tex2D(texture_sampler, uv - rgss_uv_offsets.y * dx + rgss_uv_offsets.x * dy); | |
| col *= 0.25; | |
| return col; | |
| } | |
| v2f vert(appdata v) | |
| { | |
| v2f o; | |
| UNITY_SETUP_INSTANCE_ID(v); | |
| UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); | |
| o.worldPosition = v.vertex; | |
| o.vertex = UnityObjectToClipPos(o.worldPosition); | |
| o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex); | |
| o.color = v.color * _Color; | |
| return o; | |
| } | |
| fixed4 frag(v2f i) : SV_Target | |
| { | |
| // Use RGSS sampling | |
| fixed4 color = rgss_tex2D(_MainTex, i.texcoord) + _TextureSampleAdd; | |
| color *= i.color; | |
| #ifdef UNITY_UI_CLIP_RECT | |
| color.a *= UnityGet2DClipping(i.worldPosition.xy, _ClipRect); | |
| #endif | |
| #ifdef UNITY_UI_ALPHACLIP | |
| clip(color.a - 0.001); | |
| #endif | |
| return color; | |
| } | |
| ENDCG | |
| } | |
| } | |
| } |
Author
Author
Here is live web Demo but for Defeold Engine implementation:
https://indiesoftby.github.io/defold-sharp-sprite/
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Here is the details: https://medium.com/@dasannikov/unity-tricks-solving-noisy-ui-icons-485c79f746a4
Assign the shader as a Material to your UI Image, and make sure to enable mipmaps with trilinear filtering for the image's texture.
It’s worth mentioning that better results are achieved only when the mipmap bias is set to –1. In Unity3D, you can only change this via script - google it.