當光到達材質的交界面時,一部分光被反射,而另一部分將發生折射,這個現象稱為Fresnel Effect。Fresnel Effect混合了反射和折射,使得物體更真實。
理論物理中的Fresnel公式是很復雜的,因而在實時圖形學中只要在最終效果上滿足人們的視覺感受就可以了。筆者采用了以下簡化公式:
factor = bias + scale * (1.0f + I·N)power)
color = factor * 反射光顏色 + (1 - factor) * 折射光顏色
其中,bias為偏移系數,scale為縮放系數,power為Fresnel指數,I為入射光方向向量,N為發向量。
由于不能顏色的光的波長不同,所以要真實模擬自然光通過不同介質的效果,還需要考慮光的散射。為此,需要給RGB分配不同的折射率來獲取三色光折射后的方向向量。下面是Fresnel Effect部分的fx代碼(既可放在vs也可以放在ps中):
#if ENV_MAP == 1

/**//// 菲涅耳效果
float3 etaRatio = float3(0.7f , 0.8f , 0.6f);
float3 I = worldpos - g_vEyeModel;
float3 R = reflect(I ,normal);
float3 Tred = refract(I , -normal , etaRatio.x);
float3 Tgreen = refract(I , -normal , etaRatio.y);
float3 Tblue = refract(I , -normal , etaRatio.z);
float refFactor = 0.1f + 0.1f * pow(1.0f + dot(I , normal) , 1.0f);
float4 reflectedColor = texCUBE(EnvSampler ,R);
float4 refractedColor;
refractedColor.r = texCUBE(EnvSampler , Tred).r;
refractedColor.g = texCUBE(EnvSampler , Tgreen).g;
refractedColor.b = texCUBE(EnvSampler , Tblue).b;
refractedColor.a = 1;
float4 combColor = lerp(refractedColor , reflectedColor , refFactor);
color = lerp(color , combColor , 0.8f);
#endif
效果圖如下:

bais = 0.1, scale = 0.1, power = 1.0