cvr-props/Assets/test/HilbertWorms.shader

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
}
}
}