Unity Shader 凹凸映射

本文介绍了Unity Shader中的凹凸映射技术,包括预备知识,如何使用高度纹理和法线纹理实现凹凸映射,以及高度图转化为法线贴图的数学方法。重点讨论了法线纹理在切线空间的重要性,以及其在UV动画和复用法线纹理方面的优势。
摘要由CSDN通过智能技术生成

预备知识

什么是凹凸映射?

在普通纹理作用下,我们实现了给模型“穿衣服”的效果,实现了真实感渲染的第一步。但是,普通的单张纹理的能力很有限。比如,当我们模拟一个砖墙的材质时,单张纹理在远处看来,效果还算可以;但是,当我们靠近这个材质时,我们发现,原本应该粗糙的砖墙表面,竟然比“磨皮”之后的效果还要平滑,就像是贴了一个壁纸。这是为什么呢?
单张纹理的墙壁

单张纹理只是调制了材质的漫反射颜色,让它看起来是那么回事。但是我们知道,实际上几乎所有材质的表面都是凹凸不平的。那么,这些凹凸不平的效果又是怎么实现的呢?
当然,为了实现凹凸不平的效果,最简单的思路是在建模的时候将模型建成凹凸不平的表面,抛开精度不谈,这种建模方法势必会导致三角形面片数量成几何增长(类似于迭代细分);那么换个角度,我们所看到的材质效果,实际上大部分是由着色模型决定的,对于凹凸表面而言,最终效果就是由于表面细小的凹凸片元的法向量不一致导致的。因此,我们只要在光照计算的时候更改模型表面法线,就可以达到凹凸不平的效果。
拥有凹凸映射的砖墙

如何实现凹凸映射?
  • 高度纹理(Height Map)
    高度纹理存储了每个位置的相对高度,很直观,但不实用。我们可以通过高度图看到模型表面的凹凸情况,但是对于shader而言,需要额外计算每个位置的法线,效率极低。

高度图

  • 法线纹理(Noraml Map)
    法线纹理是实现凹凸映射的关键,法线纹理是一张“特殊”的纹理,存储了每个位置切线空间的法向量。每个顶点都有自己的切线空间,这个空间的z轴是顶点法线方向,x轴是顶点切线方向,y轴是z轴与x轴的叉乘结果,称为副切线(Bitangent)或副法线(Binormal)。对于法向量而言,每个分量的范围是[-1,1];而对于颜色值而言,每个分量为[0,1]。所以需要一个合适的映射:
    p i x e l = n o r m a l + 1 2 pixel=\frac{normal+1}{2} pixel=2normal+1
    同样地,当我们从法线纹理采样时,我们需要进行如下逆映射:
    n o r m a l = p i x e l × 2 − 1 normal=pixel\times2-1 normal=pixel×21
    那么,我们为什么要把***切线空间***的法向量存入法线纹理中呢?模型空间不行吗?世界空间不行吗?
    切线空间
    对于着色计算而言,一般都是在世界空间进行的。考虑到直观性,模型空间却更好。但是对于凹凸映射而言,选择切线空间有如下好处:
    • 自由度高。对于模型空间或其他空间而言,法线信息是绝对的,而切线空间是相对的,取决于该顶点的法线和切线方向。这就意味着,绝对法线仅仅适用于创建它的初始模型,对于其他模型网格,就会有失真的情况。但是对于切线空间的法线纹理信息而言,其值其实是一个“扰动值”,也就是说并不是该点真实的法向量,而是用于着色计算时使用的法线值,是对该顶点法线的计算层面的扰动。这就意味着,当我们将这张贴图用于其他模型上时,也可以保证一定的效果。
    • 保证UV动画正常进行。当我们移动UV坐标实现UV动画时,相当于给新模型贴图,如上所述,绝对的法线信息就无法达到正确效果。
    • 可以复用法线纹理,通过扰动达到不通效果。
    • 可以压缩,由于切线空间法线永远是外法线,z分量永远为正,可由xy推导出来。所以我们可以将法线贴图中某个通道空出,达到压缩的目的,当然,也可以存储其他模型信息。
      对于法线纹理而言,由于大部分位置的法线与模型原法线一致,为(0,0,1),经过映射之后,变为了(0.5,0.5,1)是浅蓝色,所以法线纹理的视觉特征就是大片大片的蓝色
      法线贴图
高度图转化为法线贴图的数学方法

基本方法:利用高度图每个相邻像素平直表面的高度差,计算 s s s t t t方向上的切向量,用 H ( i , j ) H(i,j) H(i,j)表示尺寸为 w × h w\times h

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值