Unity Shader 菲涅尔环境反射

2020-03-19 15:45:01 浏览数 (2)

菲涅尔反射描述了一种光学现象,当光照到物体表面时,一部分发生反射,另一部分则进入物体内部,发生折射或散射;相比直接的反射和折射计算,菲涅尔反射更接近真实情况。

可用下面的等式近似计算这种反射效果:

F=F0 (1-F0)*pow((1-dot(v,n)),p);

其中,F0为反射系数,v为视野方向,n为法线方向,p为控制指数,一般p=5。

代码如下:

代码语言:javascript复制
 1 Shader "MyUnlit/FresnelReflection"
 2 {
 3     Properties
 4     {
 5         _Color("Color Tint", Color) = (1,1,1,1)
 6         _ReflectColor("Reflection Color",Color) = (1,1,1,1)
 7         _FresnelScale("Fresnel Scale",range(0,1)) = 0.5
 8         _CubeMap("Reflection CubeMap",cube) = "_skybox"{}
 9     }
10         SubShader
11     {
12         Tags{ "RenderType" = "Opaque" }
13 
14         Pass
15     {
16         Tags{ "lightmode" = "forwardbase" }
17 
18         CGPROGRAM
19         #pragma multi_compile_fwdbase
20         #pragma vertex vert
21         #pragma fragment frag
22 
23         #include "UnityCG.cginc"
24         #include "autolight.cginc"
25         #include "lighting.cginc"
26 
27         fixed4 _Color;
28         fixed4 _ReflectColor;
29         fixed _FresnelScale;
30         samplerCUBE _CubeMap;
31 
32     struct appdata
33     {
34         float4 vertex : POSITION;
35         float3 normal:NORMAL;
36     };
37 
38     struct v2f
39     {
40         float3 worldPos : TEXCOORD0;
41         float4 pos : SV_POSITION;
42         float3 worldNormal:TEXCOORD1;
43         float3 worldViewDir:TEXCOORD2;
44         float3 worldRef:TEXCOORD3;
45         SHADOW_COORDS(4)
46     };
47 
48     v2f vert(appdata v)
49     {
50         v2f o;
51         o.pos = UnityObjectToClipPos(v.vertex);
52         o.worldNormal = UnityObjectToWorldNormal(v.normal);
53         o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
54         o.worldViewDir = UnityWorldSpaceViewDir(o.worldPos);
55         o.worldRef = reflect(-o.worldViewDir, o.worldNormal);
56 
57         TRANSFER_SHADOW(o);
58         return o;
59     }
60 
61     fixed4 frag(v2f i) : SV_Target
62     {
63         fixed3 worldNormal = normalize(i.worldNormal);
64         fixed3 worldViewDir = normalize(i.worldViewDir);
65         fixed3 worldLightDir = normalize(UnityWorldSpaceLightDir(i.worldPos));
66 
67         fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
68         fixed3 col = texCUBE(_CubeMap, i.worldRef).rgb;
69         fixed3 reflection = col * _ReflectColor.rgb;
70 
71         fixed3 diffuse = _LightColor0.rgb*_Color.rgb*saturate(dot(worldNormal, worldLightDir));
72         fixed fresnel = _FresnelScale   (1 - _FresnelScale)*pow(1 - dot(worldViewDir, worldNormal), 5);
73 
74         UNITY_LIGHT_ATTENUATION(atten, i, i.worldPos);
75         fixed3 color = ambient   lerp(diffuse, reflection, saturate(fresnel))*atten;
76         return fixed4(color,1.0);
77     }
78         ENDCG
79     }
80     }
81         fallback "Reflective/VertexLit"
82 }

0 人点赞