﻿// license: may not be redistributed, except for in your own avatars or worlds
// made by: luka[#]8375, zoey "luka" moon, luka.moe lukasong.booth.pm lukasong.gumroad.com github.com/lukasong lukazoeysong[@]gmail.com
Shader "luka/safespace/SS_Write"
{
    Properties
    {
        _Distance ("Distance", Float) = 1.0
        _StencilRef ("Stencil Ref", Int) = 34
    }
    SubShader
    {

        // a few pieces of info
        Tags 
        { 
            "IsEmissive"="true" // just in case
            "Queue"="Overlay+28767" // render before anything else is able to
            "RenderType"="Overlay" // it is an overlay, after all
            "IgnoreProjector"="True" // don't render on projectors
            "PreviewType"="Sphere" // don't render in the preview window
            "ForceNoShadowCasting"="True" // don't cast shadows
            "DisableBatching"="True" // don't batch
            "VRCFallback" = "Hidden" // don't render in fallback mode
        }

        // no culling or depth
        Cull Off ZWrite Off ZTest Always

        // catch the rewrite before it hits the skybox
        Stencil { Ref [_StencilRef] Comp Always Pass Replace Fail Keep ZFail Keep }
        
        Pass
        {
            CGPROGRAM
            #pragma target 5.0
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

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

            struct v2f
            {
                float4 vertex : SV_POSITION;
                float4 uv : TEXCOORD1;
                float dist : TEXCOORD2;
                UNITY_VERTEX_OUTPUT_STEREO
            };

            float3 getCamera() {
	            #if UNITY_SINGLE_PASS_STEREO
                    return (unity_StereoWorldSpaceCameraPos[0] + unity_StereoWorldSpaceCameraPos[1]) * 0.5;
                #else
                    return _WorldSpaceCameraPos;
                #endif
            }
            
           float getDistance(float3 pos) {
                // getting a basic distance away from the center of the object 
                return float(distance(getCamera(), pos));
            }

            float _Distance;

            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 = ComputeGrabScreenPos(o.vertex);
                o.dist = getDistance(v.uv.xyz);
                if (o.dist > _Distance) {
                    o.vertex = float4(0, 0, 0, 0);
                }
                return o;
            }

            UNITY_DECLARE_SCREENSPACE_TEXTURE(_SafespaceScreen);

            fixed4 frag (v2f i) : SV_Target
            {
                UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
                fixed4 col = tex2D(_SafespaceScreen, i.uv.xy / i.uv.w);
                return col;
            }
            ENDCG
        }
    }
}
