Shader "Ien/Refraction/Refraction-Ring ViewSpaceNormals NoSurface" { Properties { _IndxOfRefract ("Index of Refraction", Range(-1.0,1.0)) = 0.1 _Expansion ("Expansion", Range(0.0, 1.0)) = 1 _Width ("Width", Range(-1.0, 1.0)) = -0.075 } SubShader { Tags { "RenderType"="Transparent" "Queue"="Transparent" "ForceNoShadowCasting" = "True"} LOD 100 GrabPass{} Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" // builtin variable to get Grabbed Texture if GrabPass has no name sampler2D _GrabTexture; half _IndxOfRefract; half _Expansion; half _Width; struct v2f { float4 vertex : SV_POSITION; float4 screenUV : TEXCOORD0; float3 viewNormal : TEXCOORD1; float4 worldPos : TEXCOORD2; }; v2f vert(appdata_base v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.screenUV = ComputeGrabScreenPos(o.vertex); // transform normal vectors from model space to world space float3 worldNorm = normalize( unity_WorldToObject[0].xyz * v.normal.x + unity_WorldToObject[1].xyz * v.normal.y + unity_WorldToObject[2].xyz * v.normal.z ); o.worldPos = mul(unity_ObjectToWorld, v.vertex); o.viewNormal = mul((float3x3)UNITY_MATRIX_V, worldNorm); return o; } float4 frag(v2f i) : SV_TARGET { float3 viewDirection = normalize(_WorldSpaceCameraPos.xyz - i.worldPos.xyz); float3 NormalBlendDetail = i.viewNormal.rgb * float3(-1, -1, 1); float3 NormalBlendBase = (mul(UNITY_MATRIX_V, float4(viewDirection, 0)).rgb*float3(-1, -1, 1)) + float3(0, 0, 1); float3 noSknewViewNormal = NormalBlendBase * dot(NormalBlendBase, NormalBlendDetail) / NormalBlendBase.b - NormalBlendDetail; float distortStrength = clamp((length(noSknewViewNormal.xy) - _Expansion) * (1/_Width), 0, 1); distortStrength = sin(distortStrength*3.14159265)*_IndxOfRefract; return tex2Dproj(_GrabTexture, i.screenUV + float4(distortStrength*noSknewViewNormal.x, distortStrength*noSknewViewNormal.y, 0, 0)); } ENDCG } } }