CG之菲涅尔效果简单实现

  菲涅尔效果,指当光到达两种材质的接触面时,一些光在接触面的表面被反射出去,而另一部分光将发生折射穿过接触面。

  现在要用shader来实现这种效果,如果要精确地描述这种底层的物理,其计算公式是非常复杂的,性能消耗也比较大。我们的目的是使创建的图像看上去真实,因此我们不使用菲涅尔公式本身,而是使用以下经验公式,它能够用非常少的计算获得很好的效果。

 

reflectionCoefficient = max(0, min(1, bias + scale * pow(1 + dot(I,N), power)))

finalColor = reflectionCoefficient * reflectedColor + (1 - reflectionCoefficient ) * refractedColor

 

在unity3d中的渲染效果如下:

 

shader如下:

 1 Shader "Custom/Test"
 2 {
 3     Properties
 4     {
 5         _Cube("Cube", Cube) = "white" {}
 6         _EtaRatio("Eta ratio", float) = 0.8
 7         _FresnelPower("Fresnel power", float) = 2
 8         _FresnelScale("Fresnel scale", float) = 1
 9         _FresnelBias("Fresnel bias", float) = 0
10     }
11 
12     SubShader
13     {
14         Tags
15         {
16             "RenderType" = "Opaque"
17         }
18 
19         Pass
20         {
21             CGPROGRAM
22             #pragma vertex Vert
23             #pragma fragment Frag
24 
25             #include "UnityCG.cginc"
26 
27             uniform samplerCUBE _Cube;
28             uniform float _EtaRatio;
29             uniform float _FresnelPower;
30             uniform float _FresnelScale;
31             uniform float _FresnelBias;
32 
33             struct AppData
34             {
35                 float4 pos : POSITION;
36                 float3 nor : NORMAL;
37             };
38 
39             struct V2F
40             {
41                 float4 pos : SV_POSITION;
42                 float reflectionFactor : Color;
43                 float3 r : TEXCOORD0;
44                 float3 t : TEXCOORD1;
45             };
46 
47             V2F Vert(AppData vi)
48             {
49                 V2F fi;
50                 fi.pos = mul(UNITY_MATRIX_MVP, vi.pos);
51 
52                 float3 n = normalize(mul(vi.nor, (float3x3)_World2Object));
53                 float3 viewDir = WorldSpaceViewDir(vi.pos);
54                 float3 i = normalize(-viewDir);
55 
56                 fi.r = reflect(i, n);                                                                        // 反射向量
57                 fi.t = refract(i, n, _EtaRatio);                                                            // 折射向量
58                 fi.reflectionFactor = _FresnelBias + _FresnelScale * pow(1 + dot(i, n), _FresnelPower);        // 反射颜色所占比例
59 
60                 return fi;
61             }
62 
63             float4 Frag(V2F fi) : Color
64             {
65                 float4 reflectC = texCUBE(_Cube, fi.r);
66                 float4 refractC = texCUBE(_Cube, fi.t);
67                 return lerp(refractC, reflectC, fi.reflectionFactor);
68             }
69 
70             ENDCG
71         }
72     }
73 }
shader

 

转载请注明出处: http://www.cnblogs.com/jietian331/p/5564901.html

posted @ 2016-06-06 19:44  孤独の巡礼  阅读(5508)  评论(0编辑  收藏  举报