Unity3d-Shader-UV移动
2016-04-03 22:18
281 查看
本文使用UV偏移,创建车道方向动画
原始素材
最终效果(带水平向移动)
偏移:Offset(xo,yo),将原点偏移到(xo,yo)。
平铺:Tiling(xt,yt),以偏移后的坐标为新原点,平铺(xt,yt)范围
Unity3d在创建Material,默认Offset = (0, 0),Tiling(1, 1)。即原点不偏移,平铺方向各1次。也就是原图显示。
Unity3d与OpenGl的纹理坐标同持一致。U方向从左到右,V方向从下到上。而DX U从左到右,V从上到下
Offset = (0, 0.5) Tiling = (0.5, 0.5)
Offset = (0.5, 0.5) Tiling = (0.5, 0.5)
Offset = (0, 0)Tiling = (0.5, 0.5)
Offset = (0.5, 0) Tiling = (0.5, 0.5)
Offset = (0, 0.5)Tiling = (1.0, 0.5)
Offset = (0, 0)Tiling = (1.0, 0.5)
Offset = (0, 0)Tiling = (0.5, 1)
Offset = (0.5, 0)Tiling = (0.5, 1)
顶点纹理 = 时间 * 速度
即 uv.x += _Time.x * _USpeed 其中_Time是Unity3d内置变量。
参考链接http://docs.unity3d.com/Manual/SL-UnityShaderVariables.html
当前纹理(平铺)= 当前纹理 * 平铺个数
即 uv.x *= _UCount;
我们假设顶点范围[0,1],以U轴方向为例(顶点与纹理不是同一个东西)
在_UCount = 1的情况下,uv.x = uv.x * 1,顶点与纹理一一对应。
在_UCount = 2的情况下,uv.x = uv.x * 2, 原本水平方向x = 0.5顶点,这次由于uv.x * 2,抽取了uv.x = 1.0的纹理(也可以说是uv.x = 0.0的纹理)。即相比于_UCount = 1,这次在顶点从开始x = 0.5,便重新以uv.x =0提取纹理。
主要使用到了Material.GetTextureOffset、SetTextureOffset对应纹理坐标Offset
Material.GetTextureScale、SetTextureScale对应纹理坐标Tiling
原始素材
最终效果(带水平向移动)
Unity3d纹理坐标
偏移:Offset(xo,yo),将原点偏移到(xo,yo)。
平铺:Tiling(xt,yt),以偏移后的坐标为新原点,平铺(xt,yt)范围
Unity3d在创建Material,默认Offset = (0, 0),Tiling(1, 1)。即原点不偏移,平铺方向各1次。也就是原图显示。
Unity3d与OpenGl的纹理坐标同持一致。U方向从左到右,V方向从下到上。而DX U从左到右,V从上到下
Offset = (0, 0.5) Tiling = (0.5, 0.5)
Offset = (0.5, 0.5) Tiling = (0.5, 0.5)
Offset = (0, 0)Tiling = (0.5, 0.5)
Offset = (0.5, 0) Tiling = (0.5, 0.5)
Offset = (0, 0.5)Tiling = (1.0, 0.5)
Offset = (0, 0)Tiling = (1.0, 0.5)
Offset = (0, 0)Tiling = (0.5, 1)
Offset = (0.5, 0)Tiling = (0.5, 1)
GPU实现
了解纹理坐标后。接下来,我们将编写Shader实现车道方向动画。实现原理就是持续地修改贴图在U方向的偏移。(注意创建场景、GameObject、Material等基本操作不在此本文说明)。下面给出UV偏移的Shader代码。Shader "Custom/UVOffset" { Properties { _MainTex ("Base (RGB)", 2D) = "white" {} _USpeed("USpeed ", float) = 1.0 _UCount("UCount", float) = 1.0 _VSpeed("VSpeed", float) = 1.0 _VCount("VCount", float) = 1.0 } SubShader { Tags { "RenderType"="Opaque" } LOD 200 CGPROGRAM #pragma surface surf Lambert // 贴图 sampler2D _MainTex; // U轴方向滚动速度 float _USpeed; // U轴方向平铺个数 float _UCount; // V轴方向滚动速度 float _VSpeed; // V轴方向平铺个数 float _VCount; struct Input { float2 uv_MainTex; }; void surf (Input IN, inout SurfaceOutput o) { float2 uv = IN.uv_MainTex; float detalTime = _Time.x; // 计算X轴方向变化 uv.x += detalTime * _USpeed; uv.x *= _UCount; // 计算Y轴方向变化 uv.y += detalTime * _VSpeed; uv.y *= _VCount; half4 c = tex2D (_MainTex, uv); o.Albedo = c.rgb; o.Alpha = c.a; } ENDCG } FallBack "Diffuse" }
顶点纹理 = 时间 * 速度
即 uv.x += _Time.x * _USpeed 其中_Time是Unity3d内置变量。
Name | Type | Value |
---|---|---|
_Time | float4 | Time (t/20, t, t*2, t*3), use to animate things inside the shaders. |
当前纹理(平铺)= 当前纹理 * 平铺个数
即 uv.x *= _UCount;
我们假设顶点范围[0,1],以U轴方向为例(顶点与纹理不是同一个东西)
在_UCount = 1的情况下,uv.x = uv.x * 1,顶点与纹理一一对应。
在_UCount = 2的情况下,uv.x = uv.x * 2, 原本水平方向x = 0.5顶点,这次由于uv.x * 2,抽取了uv.x = 1.0的纹理(也可以说是uv.x = 0.0的纹理)。即相比于_UCount = 1,这次在顶点从开始x = 0.5,便重新以uv.x =0提取纹理。
CPU实现
为GPU计算的负担,可以将UV偏移的计算工作放到CPU中,最后将计算结果传回GPU渲染即可。下面是使用MonoBehaviour实现UV偏移代码。主要使用到了Material.GetTextureOffset、SetTextureOffset对应纹理坐标Offset
Material.GetTextureScale、SetTextureScale对应纹理坐标Tiling
using UnityEngine; public class UVOffset: MonoBehaviour { // U轴方向滚动速度 public float USpeed = 1.0f; // U轴方向平铺个数 public int UCount = 1; // V轴方向滚动速度 public float VSpeed = 1.0f; // V轴方向平铺个数 public int VCount = 1; private Material mat = null; private void Awake() { if (this.renderer != null) this.mat = this.renderer.material; } private void Update() { if (this.mat == null) return; Vector2 offset = this.mat.GetTextureOffset("_MainTex"); Vector2 tiling = this.mat.GetTextureScale("_MainTex"); offset.x += Time.deltaTime * USpeed; offset.y += Time.deltaTime * VSpeed; tiling.x = UCount; tiling.y = VCount; this.mat.SetTextureOffset("_MainTex", offset); this.mat.SetTextureScale("_MainTex", tiling); } }
相关文章推荐
- Unity发布IOS在Xcode7.3报错的问题
- Unityclient通信測试问题处理(二)
- Unity3D学习笔记(6)—— 飞碟射击游戏
- 【Unity Shaders】使用CgInclude让你的Shader模块化——创建CgInclude文件存储光照模型
- 【Unity Shader】Unity Chan的卡通材质
- 【Unity Shader】Unity Chan的卡通材质
- ARToolKit for Unity Scripting and Low-Level API
- [Unity热更新]tolua# & LuaFramework(四):读取数据
- unity3d的playmaker插件使用教程,九、playmaker和脚本
- 【Unity】协程
- Unity3D 自带摇杆 拓展, CrossPlatformInputManager
- Unity3D~2D游戏背景的循环滚动
- Unity3D研究院之两种方式播放游戏视频-转自雨松mono
- Unity 捕获IronPython脚本错误
- Unity3D中使用Profiler精确定位性能热点的优化技巧
- surface shader
- FIX SHADER
- 在editor模式下遍历unity3d builtsetting中的场景
- [Unity] Shader(着色器)之纹理贴图
- [Unity] Shader(着色器)之固定管线