关于三向贴图
对于一些地形网格来说,有时候会因为地形的起伏导致网格分布不均匀,这就会导致贴图被拉伸。三向贴图技术就是为了解决这个问题。
三向贴图不再采用传统的uv作为采样坐标,而是用世界坐标作为新的采样坐标。这个方法需要的额外操作是:对于朝向不同的面需要用不同的平面坐标系作为uv。例如:当面朝向x轴时,用yz坐标系作为uv。这一点用法线朝向即可解决。
但是当遇到斜坡,即法线的各个分量都有值时,就需要进行一定的加权运算来得到最终的混合结果。这个加权混合就是重点。因为有三个分量,所以不能用传统的线性插值,而是要使用三角形插值。这里最好使用法线xyz的平方的值较好。其运算为:
(x * col1 + y * col2 + z * col3)/(x + y + z);
其中col1是对yz平面采样的结果,col2、col3以此类推。
如果想要控制混合带的宽度,则需要引入另一个参数_SmoothScale,而以上算法也要改进。
当前x,y,z分量的范围是[0,1],目的是使当xyz取到的值为 [0.5 - _SmoothScale, 0.5 + _SmoothScale] 时,才对其进行混合,而剩下的范围内不混合,只取当前最高分量。为了达到这一目的,需要对xyz进行一个范围变换的操作:
saturate(x -0.5 + _SmoothScale);
这就是新的x。
所以新的混合式是:
col = (saturate(x - 0.5 + _SmoothScale) * col1 + saturate(y - 0.5 + _SmoothScale) * col2 + saturate(z - 0.5 + _SmoothScale) * col3)/
(saturate(x -0.5 + _SmoothScale) + saturate(y - 0.5 + _SmoothScale) + saturate(z - 0.5 + _SmoothScale));
使用xyz的平方比较准确,但这样会出现一个问题,即会出现新xyz都为0的情况。解决的办法是不要把SmoothScale设置到0.5以下。
法线的三向混合
实际上早期的思路是想办法修改WhiteOut/UDN或者PDBlend,使其变为加权的三向混合来混合三向的法线图。但实际实施了之后,混合这一步还是有问题。因为法线的混合一定要在同一个切线空间内,如果要实现三向混合就要把三向法线转换到顶点切线空间内,这一步比较复杂。
第二个思路是直接旋转坐标轴,然后仍然采用再切平面采样的方式。当时我认为这样甚至可以不用混合,但后来发现,对于一个突起的块面,总会出现两个面之间的纹理不连续的情况。也就是说旋转并非完全严格,所以这种方法被抛弃。
第三种方法应该是通用的方法,用每个三向面的法线和顶点法线进行WhiteOut/UDN混合,再将三个混合后的法线加权相加。其中这个权重是VertexNormal.xyz/x + y + z。
第三种方法将混合拆分成了两部,把法线混合用在了和顶点法线的混合上,三向的混合仅仅是个简单的三向插值。而单独和顶点法线混合就非常简单,只需要把三向法线转换到世界坐标轴下,这只需要交换坐标轴即可。