cvr-props/Assets/automata/wireworld.shader
2023-06-19 23:17:23 +02:00

139 lines
2.6 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;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
sampler2D _LastFrame;
int _Running;
v2f vert (appdata v)
{
v2f 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 < 0.01 && i.uv.y < 0.01) {
if (t > 0.9){
return float4(0, 0, 0, 1);
}
t = t + 0.02;
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
}
}
}