Advertisement
noradninja

EPX

Feb 11th, 2025
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 5.35 KB | None | 0 0
  1. Shader "Vita/EPXUpscaleNonPixelArt"
  2. {
  3.     Properties
  4.     {
  5.         _MainTex ("LowRes Texture", 2D) = "white" {}
  6.         _InputRes ("Input Resolution", Vector) = (400,230,0,0)
  7.         _OutputRes ("Output Resolution", Vector) = (640,368,0,0)
  8.         // Threshold for treating two colors as equal (tweak as needed)
  9.         _Threshold ("Color Threshold", Float) = 0.1
  10.     }
  11.     SubShader
  12.     {
  13.         Pass
  14.         {
  15.             CGPROGRAM
  16.             // Vertex and fragment entry points:
  17.             #pragma vertex vert
  18.             #pragma fragment frag
  19.             #include "UnityCG.cginc"
  20.            
  21.             sampler2D _MainTex;
  22.             float2 _InputRes;   // e.g. (400,230)
  23.             float2 _OutputRes;  // e.g. (640,368)
  24.             float _Threshold;   // Threshold for approximate equality
  25.            
  26.             struct appdata
  27.             {
  28.                 float4 vertex : POSITION;
  29.                 float2 uv     : TEXCOORD0;
  30.             };
  31.            
  32.             struct v2f
  33.             {
  34.                 float2 uv     : TEXCOORD0;
  35.                 float4 vertex : SV_POSITION;
  36.             };
  37.            
  38.             v2f vert (appdata v)
  39.             {
  40.                 v2f o;
  41.                 o.vertex = UnityObjectToClipPos(v.vertex);
  42.                 o.uv     = v.uv;
  43.                 return o;
  44.             }
  45.            
  46.             // Sample _MainTex using pixel coordinates, adding 0.5 to sample at pixel centers.
  47.             float4 SampleTex(float2 pixelPos)
  48.             {
  49.                 float2 uv = (pixelPos + 0.125) / _InputRes;
  50.                 return tex2D(_MainTex, uv);
  51.             }
  52.            
  53.             // Clamp pixel positions so that we don't sample outside the texture.
  54.             float4 SampleTexClamp(float2 pixelPos)
  55.             {
  56.                 pixelPos = clamp(pixelPos, float2(0.0, 0.0), _InputRes - 1.0);
  57.                 return SampleTex(pixelPos);
  58.             }
  59.            
  60.             // Helper functions for approximate color comparisons.
  61.             // We compare only the RGB components and use a squared threshold (to avoid sqrt).
  62.             bool approxEqual(float4 a, float4 b)
  63.             {
  64.                 float3 diff = a.rgb - b.rgb;
  65.                 return dot(diff, diff) < (_Threshold * _Threshold);
  66.             }
  67.            
  68.             bool approxNotEqual(float4 a, float4 b)
  69.             {
  70.                 float3 diff = a.rgb - b.rgb;
  71.                 return dot(diff, diff) > (_Threshold * _Threshold);
  72.             }
  73.            
  74.             // EPX fragment shader with coordinate remapping.
  75.             float4 frag (v2f i) : SV_Target
  76.             {
  77.                 // Compute output pixel coordinate (in target resolution, e.g. 640x368).
  78.                 float2 outCoord = i.uv * _OutputRes;
  79.                
  80.                 // Compute the “ideal” 2x upscaled resolution (doubling 400x230 yields 800x460).
  81.                 float2 upscaledRes = _InputRes * 2.0;
  82.                
  83.                 // Handle non 2x scales
  84.                 float2 scaleMapping = upscaledRes / _OutputRes;
  85.                 float2 upCoord = outCoord * scaleMapping;
  86.                
  87.                 // Undo the doubling:
  88.                 // - The integer part (ipos) selects a pixel in the low‑res image.
  89.                 // - The fractional part (fpos) tells you which quadrant of the 2x block.
  90.                 float2 srcCoord = upCoord / 2.0;
  91.                 float2 ipos = floor(srcCoord);
  92.                 float2 fpos = frac(srcCoord);
  93.                
  94.          // Sample the center pixel (E) and its four neighbors.
  95.                 float4 P = SampleTexClamp(ipos);
  96.                 float4 A = SampleTexClamp(ipos + float2(-1.0,  0.0)); // Left neighbor
  97.                 float4 B = SampleTexClamp(ipos + float2( 0.0,  1.0)); // Top neighbor
  98.                 float4 C = SampleTexClamp(ipos + float2( 1.0,  0.0)); // Right neighbor
  99.                 float4 D = SampleTexClamp(ipos + float2( 0.0, -1.0)); // Bottom neighbor
  100.                
  101.                 // Compute EPX candidates using approximate comparisons.
  102.                 float4 P1 = ((approxEqual(A,B)) && (approxNotEqual(B, D))) ? B : P; // Top-left candidate
  103.                 float4 P2 = ((approxEqual(B,C)) && (approxNotEqual(B, D))) ? C : P; // Top-right candidate
  104.                 float4 P3 = ((approxEqual(A, D)) && (approxNotEqual(A, C))) ? A : P; // Bottom-left candidate
  105.                 float4 P4 = ((approxEqual(C, D)) && (approxNotEqual(C, B))) ? C : P; // Bottom-right candidate
  106.                
  107.                 // Use explicit if/else statements for each possible quadrant.
  108.                 float4 result;
  109.                 if (fpos.x < 0.5 && fpos.y > 0.5)
  110.                 {
  111.                     result = P1;//2
  112.                 }
  113.                 else if (fpos.x > 0.5 && fpos.y > 0.5)
  114.                 {
  115.                     result = P2;
  116.                 }
  117.                 else if (fpos.x < 0.5 && fpos.y < 0.5)
  118.                 {
  119.                     result = P3;
  120.                 }
  121.                 else if (fpos.x >= 0.5 && fpos.y < 0.5)
  122.                 {
  123.                     result = P4;//p4
  124.                 }
  125.                 else
  126.                 {
  127.                     result = P; // Fallback; this case should not be reached.
  128.                 }
  129.                
  130.                 return result;
  131.             }
  132.             ENDCG
  133.         }
  134.     }
  135. }
  136.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement