shader学习之路(2)- 贴图uv移动模拟水流效果


前言

在游戏中,水流效果是十分常见的,实现的原理除开真实流体计算以外,还有一种简易的方式实现简单的水流效果,即通过移动贴图的UV坐标,在静态的物体贴图上模拟出水流效果。
神秘海域3 水流效果
上图为《神秘海域3》的水流效果,其开发花絮讲述了该作的水流基于离线渲染、动态渲染,是复杂的物理效果,移动uv贴图的效果自然无法媲美,不过在一般情况下很多游戏的中那些非细节性的水流、岩浆等,使用移动uv贴图也是足够了。再此使用shader来进行uv坐标的偏移。

准备知识

再此小讲一下UV坐标,UV坐标是指二维图像作为一个平面,水平方向是U,而垂直方向是V,根据UV坐标即可确定图中任意一个像素点,U、V坐标的范围均为(0,1)。在directx中,UV坐标方向如下图:
这里写图片描述
而OpenGL中方向一般如下图:
这里写图片描述
在不同的API下,需要考虑不同的uv方向。

准备工作

下载Unity shaders and effects cookbook的素材资源:点击下载

解压Unity assets中的5084_02_UnityAssets.rar,将其中的 River_GRP.fbxChapter02_WaterfallGraph_Diffuse.png 拷贝到你的工程中

Shader编写

接下来,来尝试下这个uv坐标偏移shader
首先,建立一个新的surface shader
这里写图片描述
打开后在Properties变量栏中删除原有属性,添加如下几个属性
这里写图片描述

这两个属性分别为uv坐标的X Y左边的偏移速度,放在该效果中能控制水流速度。接着在SubShader段中声明与Properties同名的变量Properties:
这里写图片描述

同时修改一下光照模型,再此我使用的是默认Lambert模型
这里写图片描述

接下就是surf函数了
这里写图片描述
因为已经不是默认的surf函数,所以记得将inout类型写为SurfaceOutput,scrolledUV是获取贴图的UV偏移量,这个源自于所设置的采样器结构体
这里写图片描述
_Time变量是基于Unity游戏时钟的递增性浮点数,将其与偏移速度相乘,即可获得随着时间改变的uv偏移量。通过时间计算出偏移量后,将偏移量添加到原有的uv值上,传入tex2D中作为新的纹理数据。

接下来创建一个新材质,将该shader赋予该材质
这里写图片描述

此时还缺少个贴图,将准备好的水流贴图放入其中,即完成了整个材质的创建。
这里写图片描述

将准备好的模型拖入场景中,在将本材质拖入到模型中的River_GEO中
这里写图片描述

启动编辑器后即可看到水流的效果
这里写图片描述

有些时候,可能出现水流只播放一次然后彻底变为底色的情况,如果shader没有错误,只需将贴图的wrap mode该为Repeat即可。
这里写图片描述

完整代码:

Shader "Custom/RiverShader" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
_ScrollXSpeed ("X Scrll Speed", Range(0, 10)) = 2
_ScrollYSpeed ("Y Scrll Speed", Range(0, 10)) = 2
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 200

CGPROGRAM
// Physically based Standard lighting model, and enable shadows on all light types
#pragma surface surf Lambert

// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0

fixed _ScrollXSpeed;
fixed _ScrollYSpeed;
sampler2D _MainTex;

struct Input {
float2 uv_MainTex;
};



void surf (Input IN, inout SurfaceOutput o) {
fixed2 scrolledUV = IN.uv_MainTex;

fixed xScrollValue = _ScrollXSpeed * _Time;
fixed yScrollValue = _ScrollYSpeed * _Time;

scrolledUV += fixed2(xScrollValue, yScrollValue);

half4 c = tex2D(_MainTex, scrolledUV);
o.Albedo = c.rgb;
o.Alpha = c.a;
}
ENDCG
}
FallBack "Diffuse"
}

由于一款游戏中可能有很多需要移动uv贴图的情况,所以有时候使用脚本代码来控制,但使用shader控制也是可行的。有关代码来移动贴图,可以参考程序媛冯乐乐的博客文章:
【Unity Shaders】Using Textures for Effects——通过修改UV坐标来滚动textures

uv移动其实还有许多用处,不仅仅是做水流,例如岩浆、火焰等都可以使用类似的原理进行模拟,这个是最初级的一种效果,shader学习之路还很漫长,愿诸君共同加油!

参考书目

1.Unity shaders and effects cookbook

智能推荐

注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
© 2014-2019 ITdaan.com 粤ICP备14056181号  

赞助商广告