Shader "Custom/VignetteShader" { Properties { _MainTex ("Texture", 2D) = "white" {} _OFOV ("Outer Radius", Range(0.0, 1.0)) = 0.7 _IFOV ("Inner Radius", Range(0.0, 1.0)) = 0.3 _THRES_LR ("Threshold L/R overlap", Range(0.0, 1.0)) = 0.2 //linearly decrease transparency from _IFOV to _OFOV; see Fernandes & Feiner (2016) [MaterialToggle] _Smooth ("Smooth", Float) = 0 //alternatively use hermite function } SubShader { // No culling or depth Cull Off ZWrite Off ZTest Always Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma multi_compile_instancing #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 }; v2f vert(appdata v) { v2f o; UNITY_SETUP_INSTANCE_ID(v); UNITY_INITIALIZE_OUTPUT(v2f, o); //Insert UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); //Insert o.vertex = UnityObjectToClipPos(v.vertex); o.uv = v.uv; return o; } //sampler2D _MainTex; UNITY_DECLARE_SCREENSPACE_TEXTURE(_MainTex); //Insert float _IFOV; float _OFOV; float _THRES_LR; float _Smooth; fixed4 frag(v2f i) : SV_Target { UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i); //Insert fixed4 col = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_MainTex, i.uv); //Insert float2 center = float2(0.5, 0.5); float distFromCenter = distance(i.uv.xy, center); float2 distFromCenter2 = i.uv.xy - center; float rest = 1 - _IFOV; //float distFromInnerRadius = -1 * (distFromCenter - _IFOV) / rest + 1; if (unity_StereoEyeIndex == 0) // left eye { if (distFromCenter2[0] >= 0) //right of center { if(abs(distFromCenter2[0]) < _THRES_LR) { distFromCenter = abs(distFromCenter2[1]); }else { center = center + float2(_THRES_LR,0); distFromCenter = distance(i.uv.xy, center); } //return 1 - col; } } else if (unity_StereoEyeIndex == 1) // right eye { if (distFromCenter2[0] <= 0) //left of center { if( abs(distFromCenter2[0]) < _THRES_LR) { distFromCenter = abs(distFromCenter2[1]); }else { center = center - float2(_THRES_LR,0); distFromCenter = distance(i.uv.xy, center); } //return 1 - col; } } float vignette; if (distFromCenter < _IFOV) { vignette = 1; } else if (distFromCenter > _OFOV) { vignette = 0; } else { vignette = -(distFromCenter - _IFOV) / (_OFOV - _IFOV) + 1; } col = saturate(col * vignette); return col; } ENDCG } } }