Unity3D教程宝典之Shader篇:第二十一讲视差贴图

视差贴图的展示
图一:注意轮胎印中的自阴影,实际上路面只是一个平地
 
图二:孤岛危机的成功,视差贴图功不可没
 
图三:视差贴图同样可用于人物,装备及道具
 
本讲分四个部分
一:优点特性
二:基本原理
三:使用方法
四:视差计算
 
第一部分 视差贴图的优点及特性
上一讲讲了法线贴图。法线贴图,无论是RGB法线贴图还是DXT5nm,都有一个缺点就是。越接近面的水平视角,则画面越不真实。因为使用法线贴图后,凸起的部分只是看起来凸起而已,网格模型却并没有凸起依然是平的。正常来说凸起的部分会遮挡后面的部分,法线贴图却没有这个效果。于是我们有了法线贴图的改进版 - 视差贴图
视差贴图的好处:
(1)在相对视角会发生变化时,很有立体感
(2)在入视角接近水平时,依然有不错的质量
下面两图对比可以看出,在入视角接近水平时,视差贴图要比法线贴图清晰不少。
注意:在入视角等于或接近垂直时,视差贴图与法线贴图的效果是几乎一样的。
 


 
 
 
第二部分 视差贴图的原理
视差贴图,由Tomomichi Kaneko在2001年发明,但是限于计算机的性能,真正的商业运用是从2007年开始的。视差贴图通过uv偏移实现。uv的偏移值由高度及由点指向摄像机的向量计算得出。所以视差贴图依然不改变真正的模型表面构造。
注意:如果使用的是Unity自带的Parallax 类shader,则高度必须位于A通道中(对应color.w),如果高度图是灰度图的话,则需转换至A通道,下面的使用部分有详细方法。有关高度的知识,参阅17讲的前半部分。
 
左图:凹凸不平的鹅卵石         右图:实际只是一个平面



 
第三部分 视差贴图的使用
(1)准备好贴图,法线贴图,高度图。
(2)如果高度图的高度储存在透明通道,略过此步。如果是灰度图则需:选中图,勾选Alpha from Grayscale,然后Apply即可


(3)创建plane及材质,Shader选Parallax Diffuse或者Parallax Diffuse
(4)把三个图拖到材质对应的栏里
(5)调整Height高度。
如果是初次使用视差贴图的话,把Height调到最高,然后旋转plane查看,这样能快速理解视差贴图的好处。
如果是真正运用的话,Height稍微低些,否则会失真。
 
 
第四部分 视差贴图的计算
打开Build-in shader里的 Normal-Parallax.Shader,即Parallax Diffuse。有如下代码:
  1. half h = tex2D (_ParallaxMap, IN.uv_BumpMap).w;
  2. float2 offset = ParallaxOffset (h, _Parallax, IN.viewDir);
  3. IN.uv_MainTex += offset;
  4. IN.uv_BumpMap += offset;
(1)纹理映射 取得 高度值h
  (2) 由高度值h及指向摄像机的向量计算偏移offset
  (3) 对纹理贴图以及法线贴图进行uv偏移offset
 
其中第二步是重点。打开UnityCG.cginc , 看到如下代码。
  1. // Calculates UV offset for parallax bump mapping
  2. inline float2 ParallaxOffset( half h, half height, half3 viewDir )
  3. {
  4. h = h * height - height/2.0;
  5. float3 v = normalize(viewDir);
  6. //单位指向相机向量.z +0.42
  7. v.z += 0.42;
  8. // 偏移.x = 高度*(单位指向相机向量的x / 单位指向相机向量的z)
  9. // 偏移.y = 高度*(单位指向相机向量的y / 单位指向相机向量的z)
  10. return h * (v.xy / v.z);
  11. }
计算方法出来了。具体算法的理论依据感兴趣的同学可以自己去研究。
 
部分内容出自:
posted @ 2015-03-11 12:06  zhangdongli  Views(1709)  Comments(0Edit  收藏  举报