cvr-props/Assets/automata/WireWorld/wireworld.shader

143 lines
2.8 KiB
Text

Shader "CrispyPin/WireWorld"
{
Properties
{
_LastFrame ("Texture", 2D) = "white" {}
[Toggle]
_Running ("Running", Int) = 0
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
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
};
sampler2D _LastFrame;
int _Running;
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;
}
int close(float4 a, float4 b) {
return dot(normalize(a), normalize(b)) > 0.95;
}
#define EMPTY 0
#define WIRE 1
#define SIGNAL 2
#define TAIL 3
#define UNKNOWN 4
#define C_EMPTY float4(0, 0, 0, 1)
#define C_WIRE float4(1, 0.5, 0, 1)
#define C_SIGNAL float4(0.5, 0.5, 1, 1)
#define C_TAIL float4(0.5, 1, 0.5, 1)
int value(float2 center, float x, float y) {
fixed4 col = tex2D(_LastFrame, center + float2(x, y));
col = sqrt(col);
// col = col*col;
col.a = 1;
if (close(col, C_SIGNAL)) {
return SIGNAL;
}
if (close(col, C_TAIL)) {
return TAIL;
}
if (close(col, C_WIRE)) {
return WIRE;
}
return EMPTY;
}
fixed4 frag (v2f i) : SV_Target
{
const float resolution = 32.0;
const float d = 1.0/resolution;
float t = tex2D(_LastFrame, 0).r;
if (i.uv.x < d && i.uv.y < d) {
if (t > 0.9) {
return float4(0, 0, 0, 1);
}
t += unity_DeltaTime.x * 4;
return float4(t, t, t, 1);
}
int old_state = value(i.uv, 0, 0) ;
if (old_state == EMPTY) {
return C_EMPTY * C_EMPTY;
}
if (t > 0 || _Running == 0) {
if (old_state == SIGNAL) {
return C_SIGNAL * C_SIGNAL;
}
if (old_state == TAIL) {
return C_TAIL * C_TAIL;
}
return C_WIRE * C_WIRE;
}
if (old_state == SIGNAL) {
// return C_SIGNAL * C_SIGNAL;
return C_TAIL * C_TAIL;
}
if (old_state == TAIL) {
// return C_TAIL * C_TAIL;
return C_WIRE * C_WIRE;
}
int count =
(int)(value(i.uv, -d, -d) == SIGNAL) +
(int)(value(i.uv, 0, -d) == SIGNAL) +
(int)(value(i.uv, d, -d) == SIGNAL) +
(int)(value(i.uv, -d, 0) == SIGNAL) +
(int)(value(i.uv, d, 0) == SIGNAL) +
(int)(value(i.uv, -d, d) == SIGNAL) +
(int)(value(i.uv, 0, d) == SIGNAL) +
(int)(value(i.uv, d, d) == SIGNAL) ;
if (count == 1 || count == 2){
return C_SIGNAL * C_SIGNAL;
}
return C_WIRE * C_WIRE;
}
ENDCG
}
}
}