你好,uv变换(新手入门向聊天教程)

温馨提示:本文只是一篇入门聊天,不涉及代码教程,看不懂代码就跳过,没关系!

一、什么是uv

1、uv其实就是一个二维坐标系啊,就俩轴,就跟xy轴一样。
那为什么不叫xy,反而叫uv呢?
不知道,应该是为了跟空间坐标系xyz区别开来,以免在工作流程中产生误解吧吧吧。

2、uv坐标用于采样贴图,然后把它映射到模型表面。
图是网上找的,如果侵权了我立马删对不起对不起对不起

图是网上找的,如果侵权了我立马删对不起对不起对不起

3、类比xOy直角坐标系,在unity shader中,uv坐标原点也是在左下角(0,0)的位置的。
注意,不同的shader体系,它们设定的原点坐标是不一样的,比如dirctX的原点就在左上角。
8×8格纹uv贴图

用这个uv贴图比较方便观察。记得再ps里转化成.tga格式再使用)

4、uv坐标的原始范围都是[0,1]。

二、uv变换

1、为什么是uv变换?

啊?为什么是uv变换,而不是贴图变换呢?
因为,贴图是不会变换的!
uv采样本质上就是用一个横向范围[0,1]和纵向范围[0,1]的直角坐标系去采样一张图,然后映射到模型表面上。Shader着色器通过各种花里胡哨的运算改变uv坐标,从而改变采样范围(内容),从而使我们看到贴图变形。
嗯……就好像我们拿望远镜观察星空,星星(贴图)当晚不会变,只有我们移动望远镜(uv坐标),我们看到的星星才会不同。
甚至,我们还可以在望远镜上装哈哈镜(shader),这样看到的星星也会不同。
或者,你可以想象你坐在火车上,窗外的风景就是贴图,窗就是uv坐标。风景不会跑,只有咱们的窗户在跟着车平移。

2、加减(平移)

举例,uv + (0.1, 0.1)

i.uv += float2(0.1, 0.1);

看起来贴图向左下角偏移了

看起来贴图向左下角偏移了。
(会不会有同学没反应过来,为什么不是偏移一整格呢?因为这图是8×8格的所以要+0.125才能偏移一整格哈哈哈)

为什么呢?
一开始,原点(0,0)采样的是H1左下角明黄色的点
在这里插入图片描述
Uv坐标经过加减变换之后,原点(0,0)变成了(0.1, 0.1),坐标轴整体向右上角移动了,此时采样的点是H1接近右上角的明黄色的点.
在这里插入图片描述
以此类推别的坐标点(可以参考上面的坐标轴偏移示意图)
得到的采样结果就是这样啦。
在这里插入图片描述
所以,其实不是贴图向左下角偏移了,而是坐标向右上角偏移了。
嗯呃呃呃有一点相对论地拗口。
注意,贴图是循环平铺的。也就是说,原本边缘处(1, 1)的坐标点,经过加减变换之后变成了(1.1, 1.1),超出了贴图大于0小于1的坐标范围,但是,由于贴图是循环的,所以(1, 1)–加0.1→(1.1, 1.1)处采样的点与(0.1, 0.1)处采样的点是一致的!
在这里插入图片描述
但如果我把wrap mode网络循环模式从默认的Repeat循环改为Clamp钳制(超出范围的颜色,则与边缘颜色保持一致,将范围钳制在[0, 1]之间),那么,(1, 1)–加0.1→(1.1, 1.1)处采样的颜色就与(1, 1)处的颜色是一致的。而且(0.9, 0.9)–加0.1→(1, 1),同样也采了(1, 1)处的颜色。
在这里插入图片描述
同理,如果uv - (0.1, 0.1),就是将整个坐标轴向左下角移动,那么采样的范围就会向左下角偏移,采样的结果看起来就是贴图向右上角移动了。
嘿嘿。
在这里插入图片描述

2、乘除(缩放)

坐标轴乘以2。

i.uv *= float2(2, 2);

贴图以坐标原点(0,0)为中心缩小了2倍
啊…看得我自己都快眼花了……

啊…看得我自己都快眼花了……

然后,还是用刚才相对的思想去分析。
贴图是永远不会变的!只有坐标轴变大了两倍。uv坐标的范围变成了[0,2],贴图的范围是[0,1],由于贴图是循环平铺的,在[0,2]里就能出现两次[0,1],在22的坐标系里,就可以出现4个11,也就是4张贴图。
就这样,看起来,贴图缩小了!
同理,坐标轴除以2,贴图放大2倍

Unity内置了变换函数TRANSFORM_TEX,用于计算uv变换。在参数面板调整_MainTex_ST的tilling数值,结果也是如此

o.uv = TRANSFORM_TEX(v.uv, _MainTex); 

在这里插入图片描述

tilling值越大,就缩小;值越小,就变大。

3、 加减和乘除

o.uv = TRANSFORM_TEX(v.uv, _MainTex); 

Unity内置的变换函数TRANSFORM_TEX等价于

fixed2 uv = i.uv * fixed2(_ScaleX, _ScaleY) - fixed2(_OffsetX, _OffsetY); // **先缩放,后移动**
half4 var_MainTex = tex2D(_MainTex, uv); 

为什么是先缩放后移动?

因为顶底变换的底层数学逻辑 总是 以最原始的原点(0, 0)为操作锚点的。如果先移动,再缩放,就会变成这样…

o.uv = v.uv + float2(0.5, 0.5);
o.uv *= sin(_Time.y) * 0.5 + 1;

在这里插入图片描述
在这里插入图片描述
用更玄学的话讲,就是,矩阵相乘不满足交换律


Q:如果想让贴图以(0.8, 0.7)为中心放大3倍,公式怎么写?

我们用一个新的10*10棋盘格贴图,红点就是目标中心。

在这里插入图片描述

A:o.uv = v.uv / 3 + float2(0.8, 0.7) * (3-1)/3 ;
在这里插入图片描述

三、搞点事情吧——uv动画

1、基础动画

最基础的,就是用全局变量_Time时间单改变其中一个数值,让贴图动起来。
我们举例,改变offset偏移量。

i.uv += float2(_Time.x, 0);

动起来啦!就像坐在火车上看风景的比喻一样。
在这里插入图片描述

题外话,为什么是_Time.x捏?其实_Time有xyzw的,x是每秒+0.05,y是每秒+1,z是每秒+2,w是每秒+3。在这就不一一给大家截gif啦,亲自去试试吧很好玩的。
另外,为了防止因时间过长导致数据溢出,我们一般会给_Time取余。

i.uv += float2(frac(_Time.x), 0);

用函数frac()和运算符%都可以。

i.uv += float2(_Time.x % 1, 0);

如果我改变的是纵向的v轴呢,再换一张贴图呢?
在这里插入图片描述

看!是瀑布?是河流?

2、帧动画

帧动画的制作思路就是把uv坐标缩小,再移动到贴图中的第一帧,然后用floor向上取整,实现逐帧“跳动”。
那岂不是一个材质只能播放一个动画了?
No,你也可以再次把uv坐标放大,这时候就可以播放多个动画了,只是,每个动画的播放进度都不一样。

四、高级变换

1、极坐标变换

就是把直角坐标系变成极坐标系,就是把正方形变成圆形。庄懂老师说,这个一般用于实现角色脚下的法阵特效,比美术画出来的好使多了。
在这里插入图片描述

在这里附上庄懂老师的代码:

// 直角坐标转极坐标方法
float2 RectToPolar(float2 uv, float2 centerUV) {
     uv = uv - centerUV;                 // 将原点偏移到中心位置
     float theta = atan2(uv.y, uv.x);    // atan()的值域为[-π/2, π/2],只能画半圆,一般不用; atan2()的值域为[-π, π],刚好画出一个完整的圆
     float r = length(uv);
     return float2(theta, r);
}

// 输出结构>>>像素
half4 frag(VertexOutput i) : COLOR {
     // 直角坐标转极坐标
     float2 thetaR = RectToPolar(i.uv, float2(0.5, 0.5));
     // 极坐标转纹理采样UV
     float2 polarUV = float2(
         thetaR.x / 3.141593 * 0.5 + 0.5,    // θ从[-π, π]映射到[0, 1]
         thetaR.y + frac(_Time.x * 3.0)      // r随时间流动
     );
      // 采样MainTex
      half4 var_MainTex = tex2D(_MainTex, polarUV);
      // 处理最终输出
      half3 finalRGB = (1 - var_MainTex.rgb) * _Color;
      half opacity = (1 - var_MainTex.r) * _Opacity * i.color.r;
      // 返回值
      return half4(finalRGB * opacity, opacity);
}

因为特效一般是bulingbuling的并且涉及透明度,所以这里有用到AD透明度叠加shader

原视频:庄懂的技术美术入门课(美术向)-直播录屏-第18课_哔哩哔哩_bilibili
(帧动画 + 极坐标变换)

GitHub源码:AP01:A向技术美术入门课程

  • 17
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值