SLOPLORE · SLOPCORE · EVOLVESLOP

$_CUNTSLOP

GEN 01

LIN 0051 · SEED 0051050E

Forge burns a new strain. Evolve bends this one.

WarpShaderController

Live uniforms for this plate. The .cs writes the same properties onto a SlopLore/WarpCard material.

INSPECTOR

Flat kills warp, melt, and grit so the plate can be read. F forges. E evolves. Motion stays still if the device asks for it.

DECK

WarpShaderController.cs

Quad, material SlopLore/WarpCard, this behaviour. Plate PNG is _MainTex. Set wrap to Clamp.

VIEW .CS
using UnityEngine;

namespace SlopLore
{
    /// <summary>
    /// EVOLVESLOP warp driver. Same uniform contract as the $_CUNTSLOP forge.
    /// Put this on a quad whose material is SlopLore/WarpCard.
    /// Drop a forged PLATE png on _MainTex and set the texture wrap to Clamp.
    /// </summary>
    [ExecuteAlways]
    [DisallowMultipleComponent]
    [AddComponentMenu("SlopLore/Warp Shader Controller")]
    public class WarpShaderController : MonoBehaviour
    {
        [Header("Identity")]
        public string callsign = "WET ORACLE";
        public int generation = 1;
        public int seed = 5301518;

        [Header("Warp")]
        [Range(0f, 1.4f)] public float warpAmount = 0.28f;
        [Range(0.5f, 8f)] public float warpFrequency = 3.4f;
        [Range(0f, 2f)] public float warpSpeed = 0.45f;
        [Range(0.4f, 8f)] public float noiseScale = 2.6f;
        [Range(0f, 1f)] public float melt = 0.18f;
        [Range(0f, 0.08f)] public float chroma = 0.018f;
        [Range(0f, 1f)] public float grit = 0.42f;
        [Range(0f, 1f)] public float pulse = 0.55f;

        [Header("Bile")]
        public Color bile = new Color(0.839f, 1f, 0.247f, 1f);
        public Color meat = new Color(1f, 0.239f, 0.431f, 1f);

        static readonly int WarpAmountId = Shader.PropertyToID("_WarpAmount");
        static readonly int WarpFrequencyId = Shader.PropertyToID("_WarpFrequency");
        static readonly int WarpSpeedId = Shader.PropertyToID("_WarpSpeed");
        static readonly int NoiseScaleId = Shader.PropertyToID("_NoiseScale");
        static readonly int MeltId = Shader.PropertyToID("_Melt");
        static readonly int ChromaId = Shader.PropertyToID("_Chroma");
        static readonly int GritId = Shader.PropertyToID("_Grit");
        static readonly int PulseId = Shader.PropertyToID("_Pulse");
        static readonly int GenerationId = Shader.PropertyToID("_Generation");
        static readonly int SeedId = Shader.PropertyToID("_Seed");
        static readonly int BileId = Shader.PropertyToID("_Bile");
        static readonly int MeatId = Shader.PropertyToID("_Meat");

        Renderer _renderer;
        MaterialPropertyBlock _block;

        void OnEnable()
        {
            _renderer = GetComponent<Renderer>();
            Apply();
        }

        void OnValidate()
        {
            Apply();
        }

        void Update()
        {
            if (Application.isPlaying) Apply();
        }

        public void Evolve(int nextSeed)
        {
            generation = Mathf.Max(1, generation + 1);
            seed = nextSeed;
            float drift = (((seed >> 3) & 255) / 255f) - 0.5f;
            warpAmount = Mathf.Clamp(warpAmount + drift * 0.12f, 0f, 1.4f);
            melt = Mathf.Clamp(melt + 0.03f, 0f, 1f);
            warpFrequency = Mathf.Clamp(warpFrequency + drift * 0.4f, 0.5f, 8f);
            Apply();
        }

        public void Apply()
        {
            if (_renderer == null) _renderer = GetComponent<Renderer>();
            if (_renderer == null) return;

            _block ??= new MaterialPropertyBlock();
            _renderer.GetPropertyBlock(_block);
            _block.SetFloat(WarpAmountId, warpAmount);
            _block.SetFloat(WarpFrequencyId, warpFrequency);
            _block.SetFloat(WarpSpeedId, warpSpeed);
            _block.SetFloat(NoiseScaleId, noiseScale);
            _block.SetFloat(MeltId, melt);
            _block.SetFloat(ChromaId, chroma);
            _block.SetFloat(GritId, grit);
            _block.SetFloat(PulseId, pulse);
            _block.SetFloat(GenerationId, generation);
            _block.SetFloat(SeedId, seed & 0xffff);
            _block.SetColor(BileId, bile);
            _block.SetColor(MeatId, meat);
            _renderer.SetPropertyBlock(_block);
        }
    }
}
VIEW .SHADER
Shader "SlopLore/WarpCard"
{
    Properties
    {
        _MainTex ("Plate", 2D) = "white" {}
        _WarpAmount ("Warp Amount", Range(0, 1.4)) = 0.28
        _WarpFrequency ("Warp Frequency", Range(0.5, 8)) = 3.4
        _WarpSpeed ("Warp Speed", Range(0, 2)) = 0.45
        _NoiseScale ("Noise Scale", Range(0.4, 8)) = 2.6
        _Melt ("Melt", Range(0, 1)) = 0.18
        _Chroma ("Chroma", Range(0, 0.08)) = 0.018
        _Grit ("Grit", Range(0, 1)) = 0.42
        _Pulse ("Pulse", Range(0, 1)) = 0.55
        _Generation ("Generation", Float) = 1
        _Seed ("Seed", Float) = 1
        _Bile ("Bile", Color) = (0.839, 1, 0.247, 1)
        _Meat ("Meat", Color) = (1, 0.239, 0.431, 1)
    }
    SubShader
    {
        Tags { "RenderType" = "Opaque" }
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma target 3.0
            #include "UnityCG.cginc"

            sampler2D _MainTex;
            float _WarpAmount;
            float _WarpFrequency;
            float _WarpSpeed;
            float _NoiseScale;
            float _Melt;
            float _Chroma;
            float _Grit;
            float _Pulse;
            float _Generation;
            float _Seed;
            float4 _Bile;
            float4 _Meat;

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float4 pos : SV_POSITION;
                float2 uv : TEXCOORD0;
            };

            float hash21(float2 p)
            {
                return frac(sin(dot(p, float2(127.1, 311.7))) * 43758.5453);
            }

            float noise(float2 p)
            {
                float2 i = floor(p);
                float2 f = frac(p);
                float a = hash21(i);
                float b = hash21(i + float2(1.0, 0.0));
                float c = hash21(i + float2(0.0, 1.0));
                float d = hash21(i + float2(1.0, 1.0));
                float2 u = f * f * (3.0 - 2.0 * f);
                return lerp(lerp(a, b, u.x), lerp(c, d, u.x), u.y);
            }

            float fbm(float2 p)
            {
                float v = 0.0;
                float a = 0.5;
                [unroll]
                for (int i = 0; i < 5; i++)
                {
                    v += a * noise(p);
                    p = p * 2.02 + float2(1.7, 9.2);
                    a *= 0.5;
                }
                return v;
            }

            v2f vert(appdata v)
            {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
                o.uv = v.uv;
                return o;
            }

            fixed4 frag(v2f i) : SV_Target
            {
                float2 uv = i.uv;
                float t = _Time.y * _WarpSpeed + _Generation * 0.17;
                float seedShift = frac(_Seed * 0.00017);
                float2 q = float2(
                    fbm(uv * _NoiseScale + float2(t, seedShift)),
                    fbm(uv * _NoiseScale + float2(5.2, 1.3) - t)
                );
                float2 r = float2(
                    fbm(uv * _NoiseScale + q * _WarpFrequency + float2(1.7, 9.2)),
                    fbm(uv * _NoiseScale + q * _WarpFrequency + float2(8.3, 2.8))
                );
                float breathe = 0.82 + 0.18 * sin(_Pulse * 6.28318 + t);
                float2 warp = (r - 0.5) * _WarpAmount * breathe;
                float towardBottom = smoothstep(0.82, 0.05, uv.y);
                warp.y -= towardBottom * _Melt * (0.35 + fbm(float2(uv.x * 6.0, t * 0.35)));

                float edge = smoothstep(0.22, 0.0, min(min(uv.x, 1.0 - uv.x), min(uv.y, 1.0 - uv.y)));
                float2 puv = saturate(uv + warp * lerp(0.14, 0.85, edge));
                float ca = _Chroma * (0.65 + 0.35 * sin(t * 2.0 + _Pulse * 6.28));
                float pr = tex2D(_MainTex, saturate(puv + float2(ca, 0.0))).r;
                float pg = tex2D(_MainTex, puv).g;
                float pb = tex2D(_MainTex, saturate(puv - float2(ca, ca * 0.35))).b;
                float a = tex2D(_MainTex, puv).a;

                float fieldN = fbm(uv * _NoiseScale * 1.6 + r * 1.8 + float2(t * 0.2, seedShift));
                float3 sludge = lerp(float3(0.035, 0.043, 0.027), lerp(_Bile.rgb, _Meat.rgb, fieldN), 0.42 + 0.5 * fieldN);
                sludge *= 0.45 + 0.7 * fieldN;
                float3 ink = float3(pr, pg, pb);
                ink *= lerp(float3(1.0, 1.0, 1.0), lerp(_Bile.rgb, float3(1.0, 1.0, 1.0), 0.72), 0.28);
                float3 col = lerp(sludge, ink, a);
                col += (hash21(uv * float2(900.0, 1400.0) + frac(t) * 13.0) - 0.5) * _Grit * 0.16;
                col *= 0.94 + 0.06 * sin(uv.y * 780.0);
                float vig = smoothstep(1.2, 0.28, length((uv - 0.5) * float2(1.05, 1.25)));
                col *= lerp(0.72, 1.0, vig);
                return float4(saturate(col), 1.0);
            }
            ENDCG
        }
    }
}