当前位置:   article > 正文

Unity&Shader案例篇—旋转、平移和缩放_unity 平移shader

unity 平移shader

一、前言

     在Unity中通过控制物体的Transform可以很容易的对物体进行旋转、平移和缩放,得到一些简单的动画效果。但是有个不好的地方是,一旦这个物体上有碰撞体的话,会跟环境发生碰撞。我就就想能不能在不麻烦特效动画那边的情况下,自己用Shader去处理一些基于模型顶点或贴图的dong动画效果。如图所示是我完全使用Shader处理处理的顶点的xuan旋转、平移和缩放,另外还有两个是贴图的旋转和平移。Unity的版本为2017.3.1

飒飒顶点的移动

 

顶点的旋转

 

顶点的缩放

 

贴图的移动

 

贴图的旋转

 上面五个类型的操作,其中旋转是比较难的,其他的顶点操作都比较简单。

二、实现

1、顶点的移动:在Shader代码里设置三个方向的变量_SpeedX、_SpeedY和_SpeedZ,然后再顶点变换的时候fen分别加上这个变量就可以来对顶点进行位移操作,如果乘以shi'时间就可以得到自动位移的效果了,所以顶点Shader代码为:

  1. v2f vert (appdata v)
  2. {
  3. v2f o;
  4. o.vertex = UnityObjectToClipPos(v.vertex);
  5. o.vertex += float4(_SpeedX, _SpeedY, 0, _SpeedZ)*_Time.y;
  6. o.uv = TRANSFORM_TEX(v.uv, _MainTex);
  7. return o;
  8. }

2、贴图的移动:关键是对UV进行操作,关键的片段Shader部分的代码为

  1. fixed4 frag (v2f i) : SV_Target
  2. {
  3. // sample the texture
  4. fixed2 UV = i.uv;
  5. fixed xV = _XSpeed * _Time.x;
  6. fixed yV = _YSpeed * _Time.y;
  7. UV += fixed2(xV, yV);
  8. fixed4 col = tex2D(_MainTex, UV);
  9. return col;
  10. }

 3、顶点的缩放:上面的位移是对顶点ji进行加操作,而缩放是对顶点的值进行乘操作就可以了,关键的顶点Shader部分代码为

  1. v2f vert (appdata v)
  2. {
  3. v2f o;
  4. v.vertex.xz *= clamp((_SinTime.w + 3.0)*0.5, 1.0, 2.0);
  5. o.vertex = UnityObjectToClipPos(v.vertex);
  6. o.uv.xy = TRANSFORM_TEX(v.uv, _MainTex);
  7. return o;
  8. }

4、顶点的旋转:旋转相比上面的操作会比较难,思路是先计算要旋转的角度,然后得到旋转矩阵,最后直接讲顶点的 位置向量和旋转矩阵相乘得到新的顶点值,关键的计算函数为:

  1. float4 CalculateRotation(float4 pos)
  2. {
  3. float rotation=_RotationSpeed*_Time.y;
  4. float s,c;
  5. sincos(radians(rotation), s, c);
  6. float2x2 rotMatrix=float2x2(c,-s,s,c);
  7. pos.xy=mul(pos.xy,rotMatrix);
  8. return pos;
  9. }

新的顶点的计算并不是每个方向都计算,我这里只处理了x和z方向的,将新得到的顶点位置赋值给输出顶点的时候要注意原来的z就是新顶点的y顶点Shader的代码为:

  1. v2f vert (appdata v)
  2. {
  3. v2f o;
  4. float4 k=float4(v.vertex.x,v.vertex.z,1.0,1.0);
  5. k=CalculateRotation(k);
  6. o.vertex = UnityObjectToClipPos(float4(k.x,v.vertex.y,k.y,v.vertex.w));
  7. o.uv = TRANSFORM_TEX(v.uv, _MainTex);
  8. return o;
  9. }

5、贴图的旋转:这里要用到一个变量“_MainTex_ST”(如果贴图的名称为“_MainTex”),其实只要涉及到对模型贴图的UV进行位移和偏移操作都要用到这个变量,还必须先声明一下,如下所示:它是一个四维向量,其中xy是贴图的Scale,zw是贴图的offset

  1. sampler2D _MainTex;
  2. uniform float _RotationSpeed;
  3. float4 _MainTex_ST;

先计算当前贴图的缩放比例和偏移相对原点的值div,然后对当前贴图的顶点进行旋转,最后加上div得到正在旋转之后的贴图的值,关键代码如下:

  1. float4 CalculateRotation(float4 pos)
  2. {
  3. //先计算距离位置点距离原点的值
  4. float2 div= (_MainTex_ST.xy / 2.0) + _MainTex_ST.zw;
  5. float rot = _RotationSpeed * _Time.y;
  6. pos.xy -= div;
  7. float s, c;
  8. sincos(radians(rot), s, c);
  9. float2x2 rotMatrix = float2x2(c, -s, s, c);
  10. pos.xy = mul(pos.xy, rotMatrix);
  11. pos.xy += div;
  12. return pos;
  13. }
  14. v2f vert (appdata v)
  15. {
  16. v2f o;
  17. o.vertex = UnityObjectToClipPos(v.vertex);
  18. o.uv.xy = CalculateRotation(v.uv);
  19. return o;
  20. }

三、总结

1、由物体的transform的旋转、平移和缩放尝试着实现了Shader对模型顶点或贴图的旋转、平移和缩放

2、其实还差一个贴图的缩放,有兴趣的朋友可以自己去实现一下,跟旋转操作的变量是一致的

3、工程下载地址或者可以去我的蛮牛博客Unity&Shader案例篇—旋转、平移和缩放

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/107881
推荐阅读
相关标签
  

闽ICP备14008679号