Last active
August 21, 2024 14:48
-
-
Save antonkudin/9ff45ec9a2c6755b3e7f4221faef81a1 to your computer and use it in GitHub Desktop.
This file contains 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 starts here, c# companion script below | |
// | |
// PS. Make sure to use square texture (sides must be equal) | |
// | |
Shader "Unlit/spritePixelated" | |
{ | |
Properties | |
{ | |
_MainTex ("Texture", 2D) = "white" {} | |
[Header(Scaling)] | |
_Res ("Resolution", Float) = 1024 | |
_PixelSize ("Pixel Size", Float) = .0625 | |
[Header(Sprite MetaData)] | |
_SpriteUV ("Sprite Rect", Vector) = (1,1,0,0) | |
_SpritePivot ("Sprite Pivot", Vector) = (1,1,0,0) | |
_UVCenter ("_UVCenter", Vector) = (0,0,0,0) | |
} | |
SubShader | |
{ | |
Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" | |
"DisableBatching"="True" | |
} | |
LOD 100 | |
Blend SrcAlpha OneMinusSrcAlpha | |
Pass | |
{ | |
CGPROGRAM | |
#pragma vertex vert | |
#pragma fragment frag | |
#include "UnityCG.cginc" | |
uniform half _Res, _PixelSize; | |
uniform half4 _SpriteUV, _SpritePivot, _UVCenter; | |
struct appdata | |
{ | |
float4 vertex : POSITION; | |
float2 uv : TEXCOORD0; | |
}; | |
struct v2f | |
{ | |
float2 uv : TEXCOORD0; | |
float4 vertex : SV_POSITION; | |
}; | |
sampler2D _MainTex; | |
float4 _MainTex_ST; | |
float2 quant(float2 q, float2 v){ | |
return floor(q/v)*v; | |
} | |
v2f vert (appdata v) | |
{ | |
v2f o; | |
o.vertex = UnityObjectToClipPos(v.vertex); | |
o.uv = TRANSFORM_TEX(v.uv, _MainTex); | |
return o; | |
} | |
float2 quantToWorld(float2 value, float q){ | |
float2 wp = mul(unity_ObjectToWorld, float4(value,0,0) ); | |
wp = quant(wp, q) ; | |
return mul(unity_WorldToObject, float4(wp,0,0)); | |
} | |
fixed4 frag (v2f i) : SV_Target | |
{ | |
float2 uv = i.uv; | |
// next line is the pixelation | |
uv = quantToWorld(uv-_UVCenter.xy, 1/_Res)+_UVCenter.xy; | |
fixed4 col = tex2D(_MainTex, uv); | |
clip(col.a-.001); | |
return col; | |
} | |
ENDCG | |
} | |
} | |
} |
This file contains 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
// c# companion script | |
// SpriteUVToShader.cs -------------------------------------------------------------------------------------------------------------------------------- // | |
// Save you your project, add to your SpriteRenderer gameObject | |
using UnityEngine; | |
using System.Collections; | |
using System.Collections.Generic; | |
[ExecuteInEditMode] | |
[RequireComponent(typeof(SpriteRenderer))] | |
public class SpriteUVToShader : MonoBehaviour { | |
public string UV_property="_SpriteUV"; | |
public string Pivot_property="_SpritePivot"; | |
public string uvCenter_property="_UVCenter"; | |
public string textureSize_property="_Res"; | |
public string pixelSize_property="_PixelSize"; | |
SpriteRenderer sr; | |
Sprite sprite; | |
MaterialPropertyBlock mpb; | |
void OnValidate() | |
{ | |
update(); | |
} | |
void OnWillRenderObject(){ | |
update(); | |
} | |
void Start(){ | |
update(); | |
} | |
void update(){ | |
if(sr==null) | |
sr = GetComponent<SpriteRenderer>(); | |
if(sprite != sr.sprite){ | |
sprite = sr.sprite; | |
applySpriteUV(sr, sprite, ref mpb, UV_property, Pivot_property, uvCenter_property); | |
applySpriteTX(sr, sprite, ref mpb, textureSize_property, pixelSize_property); | |
} | |
} | |
public static void applySpriteUV(Renderer renderer, Sprite toSprite, ref MaterialPropertyBlock mpb, | |
string uvProp=null, string pivotProp=null, string uvCenterProp=null){ | |
if(toSprite==null) return; | |
var scale = new Vector2( | |
toSprite.textureRect.width/ toSprite.texture.width, | |
toSprite.textureRect.height/toSprite.texture.height); | |
var offset = new Vector2( | |
toSprite.rect.x/toSprite.texture.width, | |
toSprite.rect.y/toSprite.texture.height); | |
Vector4 uvVector = new Vector4(scale.x,scale.y,offset.x,offset.y); | |
Vector4 pivotVector = new Vector4(toSprite.pivot.x/toSprite.rect.width,toSprite.pivot.y/toSprite.rect.height); | |
if(string.IsNullOrEmpty(uvProp)) | |
uvProp = "_MainTex_ST"; | |
if(mpb==null) | |
mpb = new MaterialPropertyBlock(); | |
renderer.GetPropertyBlock(mpb); | |
mpb.SetVector(uvProp, uvVector); | |
if(!string.IsNullOrEmpty(pivotProp)) | |
mpb.SetVector(pivotProp, pivotVector); | |
if(!string.IsNullOrEmpty(uvCenterProp)) | |
mpb.SetVector(uvCenterProp, new Vector2( | |
Mathf.Lerp(uvVector.z, uvVector.z+uvVector.x, pivotVector.x), | |
Mathf.Lerp(uvVector.w, uvVector.w+uvVector.y, pivotVector.y) | |
)); | |
renderer.SetPropertyBlock(mpb); | |
} | |
public static void applySpriteTX(Renderer renderer, Sprite toSprite, ref MaterialPropertyBlock mpb, | |
string texSizeProp=null, string pixSizeProp=null){ | |
if(toSprite==null || string.IsNullOrEmpty(texSizeProp)) return; | |
if(mpb==null) | |
mpb = new MaterialPropertyBlock(); | |
renderer.GetPropertyBlock(mpb); | |
mpb.SetFloat(texSizeProp, toSprite.texture.width); | |
if(!string.IsNullOrEmpty(pixSizeProp)) | |
mpb.SetFloat(pixSizeProp, 1f/toSprite.pixelsPerUnit); | |
renderer.SetPropertyBlock(mpb); | |
} | |
} |
facinating, I don't understand anything but it works .. now I wonder how we do to modify the pixel/unit :-p (to have bigger pixels than screen
resolution...)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The texture used needs to be a square, otherwise it will look like this ;)