Shader "Custom/PBR_FresnelRim" { Properties { _Color ("Base Color", Color) = (1,1,1,1) _MainTex ("Albedo (RGB) Alpha (A)", 2D) = "white" {} _Metallic ("Metallic", Range(0,1)) = 0.0 _Glossiness ("Smoothness", Range(0,1)) = 0.5 [NoScaleOffset]_BumpMap ("Normal Map", 2D) = "bump" {} _BumpScale ("Normal Scale", Range(0,2)) = 1.0 [HDR]_RimColor ("Fresnel Edge Color (HDR)", Color) = (4,4,4,1) _RimPower ("Fresnel Power (falloff)", Range(0.1, 8)) = 3.0 _RimStrength ("Fresnel Strength (intensity)", Range(0, 10)) = 1.0 } SubShader { Tags { "RenderType"="Opaque" "Queue"="Geometry" } LOD 300 CGPROGRAM #pragma surface surf Standard fullforwardshadows #pragma target 3.0 #pragma multi_compile_instancing sampler2D _MainTex; fixed4 _Color; half _Metallic; half _Glossiness; sampler2D _BumpMap; half _BumpScale; fixed4 _RimColor; half _RimPower; half _RimStrength; struct Input { float2 uv_MainTex; float2 uv_BumpMap; float3 worldPos; float3 viewDir; // Unity provides world-space view direction }; UNITY_INSTANCING_BUFFER_START(Props) UNITY_INSTANCING_BUFFER_END(Props) inline float3 UnpackNormalScaled(sampler2D nmap, float2 uv, float scale) { float3 n = UnpackNormal(tex2D(nmap, uv)); n.xy *= scale; n = normalize(n); return n; } void surf (Input IN, inout SurfaceOutputStandard o) { fixed4 albedo = tex2D(_MainTex, IN.uv_MainTex) * _Color; o.Albedo = albedo.rgb; o.Metallic = _Metallic; o.Smoothness = _Glossiness; o.Alpha = albedo.a; // Normal mapping (optional) float3 N = float3(0,0,1); if (_BumpScale > 0.0001) N = UnpackNormalScaled(_BumpMap, IN.uv_BumpMap, _BumpScale); else N = normalize(o.Normal); // Fresnel rim: pow(1 - N·V, power) float3 V = normalize(IN.viewDir); float ndotv = saturate(dot(N, V)); float rim = pow(1.0 - ndotv, _RimPower); // Emission drives the glow; HDR color recommended o.Emission = _RimColor.rgb * rim * _RimStrength; } ENDCG } FallBack "Diffuse" }