107 lines
2.3 KiB
GLSL
107 lines
2.3 KiB
GLSL
Shader "CrispyPin/HilbertWorms" {
|
|
Properties {
|
|
_Speed ("Speed (px/s)", Integer) = 100
|
|
[IntRange]_Worms ("Worms", Range(1,10)) = 1
|
|
[IntRange]_Level ("Level", Range(2,9)) = 3
|
|
[IntRange]_SmallLen ("Small length", Range(1,32)) = 8
|
|
_WormColor ("worm color", Color) = (1, 0.5, 1, 1)
|
|
}
|
|
SubShader {
|
|
Tags { "RenderType"="Opaque" }
|
|
LOD 100
|
|
Pass {
|
|
CGPROGRAM
|
|
#pragma vertex vert
|
|
#pragma fragment frag
|
|
|
|
#include "UnityCG.cginc"
|
|
|
|
#define SPEED _Speed
|
|
#define WORM_COUNT _Worms
|
|
#define LEVELS _Level
|
|
#define PIXEL_COUNT (1 << (2 * LEVELS + 2 - WORM_COUNT))
|
|
#define SMALL_LEN _SmallLen
|
|
|
|
float _Speed;
|
|
uint _Worms;
|
|
uint _Level;
|
|
uint _SmallLen;
|
|
float3 _WormColor;
|
|
|
|
struct appdata {
|
|
float4 vertex : POSITION;
|
|
float2 uv : TEXCOORD0;
|
|
UNITY_VERTEX_INPUT_INSTANCE_ID
|
|
};
|
|
|
|
struct v2f {
|
|
float2 uv : TEXCOORD0;
|
|
float4 vertex : SV_POSITION;
|
|
UNITY_VERTEX_OUTPUT_STEREO
|
|
};
|
|
|
|
v2f vert (appdata v) {
|
|
v2f o;
|
|
UNITY_SETUP_INSTANCE_ID(v);
|
|
UNITY_INITIALIZE_OUTPUT(v2f, o);
|
|
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
|
|
o.vertex = UnityObjectToClipPos(v.vertex);
|
|
o.uv = v.uv;
|
|
return o;
|
|
}
|
|
|
|
float4 frag (v2f i) : SV_Target {
|
|
uint pos = 0;
|
|
uint mask = 1 << (2 * LEVELS);
|
|
float2 p = i.uv * 2 - 1;
|
|
for (uint level = 0; level < LEVELS; level += 1) {
|
|
bool lower_half = false;
|
|
bool lower_quarter = false;
|
|
if (p.x < 0) {
|
|
lower_half = true;
|
|
p.x = (p.x * 2) + 1.0;
|
|
p.y *= -1;
|
|
} else {
|
|
pos |= mask;
|
|
p.x = (p.x - 0.5) * 2;
|
|
}
|
|
if (p.y < 0) {
|
|
p.y = (p.y * 2) + 1.0;
|
|
pos |= mask/2;
|
|
} else {
|
|
lower_quarter = true;
|
|
p.y = (p.y - 0.5) * 2;
|
|
}
|
|
if (lower_half && lower_quarter) {
|
|
p = float2(-p.y, p.x);
|
|
} else if (lower_half && !lower_quarter) {
|
|
p.y *= -1;
|
|
} else if (!lower_half && !lower_quarter) {
|
|
p = -p.yx;
|
|
}
|
|
mask >>= 2;
|
|
}
|
|
|
|
uint time = ((uint)(_Time.y * SPEED)) % PIXEL_COUNT;
|
|
uint distance = (time - pos) % PIXEL_COUNT;
|
|
if (distance < SMALL_LEN) {
|
|
float worm = 1 - ((float)distance / SMALL_LEN);
|
|
return float4(_WormColor * worm, 1);
|
|
} else {
|
|
// distance = (time/32 - pos/32) % (PIXEL_COUNT/32);
|
|
// const int tail_length = 4;
|
|
// if (distance < tail_length) {
|
|
// float tail = ((float)distance / tail_length);
|
|
// tail = 1-abs(1-tail*2);
|
|
// return float4(tail, tail/8, 0, 1);
|
|
// }
|
|
}
|
|
// if ((time - pos) % PIXEL_COUNT <= n){
|
|
// return 1 - ((float)((time - pos) % PIXEL_COUNT) / n);
|
|
// }
|
|
return 0;
|
|
}
|
|
ENDCG
|
|
}
|
|
}
|
|
}
|