Shader "Custom/FresnelOverlay_Add1" { Properties { [HDR]_RimColor ("Fresnel Color (HDR)", Color) = (3,3,3,1) _RimPower ("Fresnel Power", Range(0.1, 8)) = 3.0 _RimStrength ("Fresnel Strength", Range(0, 10)) = 1.0 _DoubleSided ("Double-Sided (0=Back,1=Off,2=Front)", Range(0,2)) = 2 _DepthBias ("Depth Bias (to avoid misses)", Float) = 0.0 } SubShader { Tags { "Queue"="Transparent+10" "RenderType"="Transparent" } // Additive overlay on top of what’s already rendered Blend One One ZWrite Off ZTest Equal // draw only where depth already matches (on the mesh) Cull Back // default: draw front faces only ColorMask RGB Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma target 3.0 #pragma multi_compile_instancing #include "UnityCG.cginc" float4 _RimColor; float _RimPower; float _RimStrength; float _DoubleSided; // 0=Back, 1=Off (both), 2=Front float _DepthBias; struct appdata { float4 vertex : POSITION; float3 normal : NORMAL; UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float4 pos : SV_POSITION; float3 worldPos : TEXCOORD0; float3 worldNrm : TEXCOORD1; UNITY_VERTEX_INPUT_INSTANCE_ID UNITY_VERTEX_OUTPUT_STEREO }; v2f vert (appdata v) { v2f o; UNITY_SETUP_INSTANCE_ID(v); UNITY_INITIALIZE_OUTPUT(v2f, o); UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); float3 worldPos = mul(unity_ObjectToWorld, v.vertex).xyz; float3 worldNrm = UnityObjectToWorldNormal(v.normal); // Optional tiny depth bias to make ZTest Equal more forgiving float4 clip = UnityObjectToClipPos(v.vertex); clip.z += _DepthBias * clip.w; o.pos = clip; o.worldPos = worldPos; o.worldNrm = worldNrm; return o; } fixed4 frag (v2f i) : SV_Target { // Handle sidedness quickly float3 N = normalize(i.worldNrm); float3 V = normalize(_WorldSpaceCameraPos - i.worldPos); // Which faces to keep: // Front: dot(N,V) > 0 // Back: dot(N,V) < 0 // Both: no discard float ndotv = dot(N, V); if (_DoubleSided < 0.5) // Back faces only { if (ndotv > 0) discard; } else if (_DoubleSided > 1.5) // Front faces only { if (ndotv < 0) discard; } // else: both sides // Fresnel ndotv = saturate(abs(ndotv)); // abs for double-sided consistency float rim = pow(1.0 - ndotv, _RimPower); float3 color = _RimColor.rgb * (rim * _RimStrength); return float4(color, 1); } ENDCG } } Fallback Off }