游戏开发中,不同屏幕下的分辨率不同,模型/物品被拉伸之后贴图也会随之拉伸。
如果需要在不同屏幕下面实现贴图真实大小不变(以下简称为自适应),需要对UV进行缩放处理之后再取得对应贴图的颜色。
本文提供一种能够实现不同设备下面贴图的大小不变的方法,主要是借助于DDX/DDY接口实现。
具体效果如下:
效果
材质预览放大
材质预览缩小
可以发现枪的显示变小了,但是里面的感叹号图片标志大小没变
前置知识
DDX()和DDY()
对于指定的寄存器,求其值在临近像素上的变化率,可以传入不同类型的数据, 就可以得到对应的数据在指定的屏幕坐标下的变化率。
讲更简单一点
比如ddx(uv)就是屏幕x方向上,一像素跨度内uv变化了多少
ddx(rgb)就是屏幕x方向上,一像素跨度内rgb变化了多少(无需指定xy,类似这样)
如何自适应
那么根据ddx和ddy的含义。我们可以传入uv坐标,取得在不同设备下面两个像素uv差了多少(称之为deltUV),然后让uv去除以这个deltUV之后再取颜色即可。
举个例子
比如一个设备A是1080 * 640 ,另一个B是 108 * 64,那么同样大小的图片在A设备上占了10个像素,在B设备上面就会占1个像素,
那么A的deltUV就是0.1,B是1。
当我们传入UV取颜色的时候
- A的 UV(0,0)- (1,1)就会取到 uv(0,0)到 uv(10,10)
- 而b 的 UV(0,0)- (1,1)会取到像 uv(0,0)到 uv(1,1)
也就是上面枪里面的感叹号纹理被取了更多次,表现就是感叹号大小没有任何变化
需要理解,对于任意比例的屏幕来说,uv的u和v都只要缩放一样的系数,设备比例不同但是图片的比例自适应之后uv轴的比例并不会不同,所以对应的u都v只会缩放一样的比例,所以只需要对UV进行如下处理即可实现。Param越大感叹号在里面的尺寸就越小。
这里有几个注意的地方,一个是Divide节点,第二个参数是可以传数组的,这样就会和第一个关系逐个相除
所以下面和上面的实现方式是一样的,因为DDX和DDY大小是一样的。不信可以验证试试