【猫猫的Unity Shader之旅】之UV动画

来源:互联网 发布:国考面试报网络培训班 编辑:程序博客网 时间:2024/06/09 23:29

  UV动画是一种常用的渲染技巧,经常用来描述水的流动、霓虹灯的闪烁等。实现的原理就是动态修改贴图的UV坐标,使物体表面产生变化。

贴图坐标

  说到UV动画就不得不多说一点贴图了。我们知道,贴图是覆盖在模型表面用来描述模型表面细节的2D图片,那么贴图是怎么覆盖到模型上的呢?我们知道模型是由很多顶点组成的,这些顶点,三个一个组组成了若干三角形,正是这些三角形构成了模型的表面(三个点确定一个面嘛),这样的三个点每一个都有一组贴图坐标,表示贴图上的某个点,这样三组贴图坐标就可以贴图上的一个区域,这个区域就是将来贴在这个三角形的部分。

  这里的贴图坐标也叫UV坐标,是一组[0,1]之间的二维向量,以贴图左上角为(0,0)点,水平方向向右,水平方向向下增长。例如模型的一个三角面的UV坐标可能是这样的:

  这里写图片描述

UV动画实现简易水流效果

  明白了贴图坐标是怎么一回事,下一步就是怎么用Shader控制UV坐标变化来实现动画效果。为了使贴图坐标每次都在不同位置,我们需要一个不断增长的变量,_Time就是Unity为我们提供的这样一个内置的变量。_Time是一个float4类型的向量,4个分量表示不同增速的累积时间,分别为t/20,t,t*2,t*3,利用_Time,我们就可以计算出一个不断增长的UV坐标。等等…,不断增长,之前我们说过UV坐标是在[0,1]之间的,如果超过范围会怎样呢,没有关系,Unity会帮我们转换成[0,1]之间的坐标。

  剩下的事情就变得简单了,只需要获取到UV坐标后先修改再使用就可以了,我们可以再定义两个变量XScrollSpeed和YScrollSpeed来控制贴图滚动的速度。为了更好地表现水的效果,我们用两幅贴图来表现水的颜色,每幅图各占一半。以下是完整代码:

Shader "Custom/UVAnim" {    Properties {        _MainTex ("Water Texture1", 2D) = "white" {}        _MainTex2("Water Texture2", 2D) = "white" {}        _XScrollSpeed1("X ScrollSpeed 1", float) = 0        _YScrollSpeed1("Y ScrollSpeed 1", float) = 0        _XScrollSpeed2("X ScrollSpeed 2", float) = 0        _YScrollSpeed2("Y ScrollSpeed 2", float) = 0    }    SubShader {        Tags { "RenderType"="Opaque" }        LOD 200        CGPROGRAM        #pragma surface surf Lambert        sampler2D _MainTex;        sampler2D _MainTex2;        float _XScrollSpeed1;        float _YScrollSpeed1;        float _XScrollSpeed2;        float _YScrollSpeed2;        struct Input {            float2 uv_MainTex;        };        void surf (Input IN, inout SurfaceOutput o) {            float2 uvScrolled1 = IN.uv_MainTex;            float2 uvScrolled2 = IN.uv_MainTex;            uvScrolled1 += float2(_XScrollSpeed1 * _Time.y, _YScrollSpeed1 * _Time.y);            uvScrolled2 += float2(_XScrollSpeed2 * _Time.y, _YScrollSpeed2 * _Time.y);            half4 water1 = tex2D (_MainTex, uvScrolled1);            half4 water2 = tex2D (_MainTex2, uvScrolled2);            o.Albedo = water1.rgb * 0.5 + water2.rgb * 0.5;            o.Alpha = 1.0;        }        ENDCG    }     FallBack "Diffuse"}

  明白了UV动画的原理,代码就非常好理解了。有一点需要注意,因为_Time是要程序运行之后才开始计时,所以需要运行才可以看到效果哟~

  这里写图片描述

  这次终于不再是立方体啦~大家可以点击这里获取工程,自由调节两幅贴图不同方向的速度来看下效果,速度值可以是负数哦~

结束语

  我们这次用非常简单的方法做了个水效果,虽然效果不怎么样,但是在移动设备上还是比较实用的。要做出真正华丽的水效果是很难的,需要强大的图形学知识做支撑,当然实现出来的效果也是令人惊叹的。不积跬步,无以至千里,大家加油吧~

0 0