Skip to content

Instantly share code, notes, and snippets.

@luispedrofonseca
Created September 4, 2019 16:51
Show Gist options
  • Save luispedrofonseca/d353a121c8cf8343f4f968acf553e817 to your computer and use it in GitHub Desktop.
Save luispedrofonseca/d353a121c8cf8343f4f968acf553e817 to your computer and use it in GitHub Desktop.
Modern pixel art solution
// https://colececil.io/blog/2017/scaling-pixel-art-without-destroying-it/
Shader "Custom/PixelArtShader"
{
Properties
{
_MainTex("Texture", 2D) = "" {}
}
SubShader
{
Tags
{
"Queue" = "Transparent"
"IgnoreProjector" = "True"
"RenderType" = "Transparent"
}
ZWrite Off
Cull Off
Blend SrcAlpha OneMinusSrcAlpha
Pass
{
CGPROGRAM
#pragma vertex vertexShader
#pragma fragment fragmentShader
sampler2D _MainTex;
float4 _MainTex_TexelSize;
float texelsPerPixel;
struct vertexInput
{
float4 vertex : POSITION;
fixed4 color : COLOR;
float2 textureCoords : TEXCOORD0;
};
struct vertexOutput
{
float4 vertex : SV_POSITION;
fixed4 color : COLOR;
float2 textureCoords : TEXCOORD0;
};
vertexOutput vertexShader(vertexInput input)
{
vertexOutput output;
output.vertex = UnityObjectToClipPos(input.vertex);
output.textureCoords = input.textureCoords * _MainTex_TexelSize.zw;
output.color = input.color;
return output;
}
fixed4 fragmentShader(vertexOutput input) : SV_Target
{
float2 locationWithinTexel = frac(input.textureCoords);
float2 interpolationAmount = clamp(locationWithinTexel / texelsPerPixel,
0, .5) + clamp((locationWithinTexel - 1) / texelsPerPixel + .5, 0,
.5);
float2 finalTextureCoords = (floor(input.textureCoords) +
interpolationAmount) / _MainTex_TexelSize.zw;
return tex2D(_MainTex, finalTextureCoords) * input.color;
}
ENDCG
}
}
}
using System;
using UnityEngine;
[ExecuteInEditMode]
[RequireComponent(typeof(Camera))]
public class PixelShaderConfig : MonoBehaviour
{
[Range(0, 100)] public int PixelsPerUnit = 10;
private float _texelsPerPixel;
private Camera _camera;
private int _texelsPerPixelID;
private float _previousOrthoSize;
void Start()
{
_camera = GetComponent<Camera>();
_texelsPerPixelID = Shader.PropertyToID("texelsPerPixel");
_previousOrthoSize = _camera.orthographicSize;
UpdateTexelsPerPixel();
}
void OnValidate()
{
if (_camera == null)
Start();
UpdateTexelsPerPixel();
}
void Update()
{
#if UNITY_EDITOR
if (_camera == null)
Start();
#endif
if (Math.Abs(_previousOrthoSize - _camera.orthographicSize) < float.Epsilon) return;
_previousOrthoSize = _camera.orthographicSize;
UpdateTexelsPerPixel();
}
void UpdateTexelsPerPixel()
{
_texelsPerPixel = (_camera.orthographicSize * 2f * PixelsPerUnit) / Screen.height;
Shader.SetGlobalFloat(_texelsPerPixelID, _texelsPerPixel);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment