简单的玻璃视差效果实现

该效果比较简单,模拟橱窗内还有一层内部墙面的效果,当然也可以配合深度贴图做不同的深度偏移。

思路就是做一张模拟室内墙面的贴图,然后再采样这张贴图的时候按照深度值进行偏移,模拟一个视差效果,直接上关键代码吧:

float2 offsetUV = IN.viewDirTS.xy/IN.viewDirTS.z * _ParallaxDepth;
float4 parallaxColor = SAMPLE_TEXTURE2D_LOD(_ParallaxMap,sampler_ParallaxMap,(IN.uv + offsetUV) * _ParallaxMap_ST.xy + _ParallaxMap_ST.zw, lerp(6,0,_Smoothness));

上面的代码中假如把_ParallaxDepth替换成深度图采样值,则可以制作更有层次感的空间深度。

使用SAMPLE_TEXTURE2D_LOD采样是为了通过降Mip模拟粗糙度效果,跟移动端模拟反射粗糙度一样。

 

效果演示:

 

但是这样做出的效果还有一点问题,就是在边角处的视差延伸表现很不合理。如下图:

再次参考奥德赛的做法,发现他们对视差深度做了NV夹角判断,视角偏差越大,视差深度越弱。

所以我们对代码进行一下修改,增加NV权重:

float dotNV = 1 - dot(float3(0,0,1),IN.viewDirTS);
float2 offsetUV = IN.viewDirTS.xy/IN.viewDirTS.z * (_ParallaxDepth * saturate( 1 - dotNV * dotNV));
float4 parallaxColor = SAMPLE_TEXTURE2D_LOD(_ParallaxMap,sampler_ParallaxMap,(IN.uv + offsetUV) * _ParallaxMap_ST.xy + _ParallaxMap_ST.zw, lerp(6,0,o.Smoothness));

虽然不能完全解决穿帮的问题,但是对于美术来说已经完全可以接受了~

接下来就是增加环境反射等等等等工作丰富玻璃墙面的细节了~本篇只讲到视差的制作部分~