Unity ShaderLab特效教程:2D 贴图动态波浪 Shader 教程(带代码详解)

本文介绍如何在Unity3D中使用自定义Shader创建波浪动画效果,详细解析Shader代码,包括波浪高度、密度及流动速度的参数设置,适用于Sprite和UGUI元素。

如果代码中有什么不清楚请查看以下基础知识

Shader基础知识
unity3d 中 七种坐标知识详解

2D 贴图动态波浪 Shader 教程(带代码详解)

一、效果预览

该 Shader 实现贴图动态波浪效果,通过 UV 坐标的纵向正弦偏移,让贴图呈现横向流动的波浪形态;可调节波浪高度、密度与流动速度,适配 2D 图片、UI、Sprite 等,适合水流、旗帜飘动、动态背景等场景。
在这里插入图片描述

二、代码结构与核心部分说明

1. 属性面板(Properties)

Properties
{
   _MainTex ("图片", 2D) = "black" {}  // 待添加波浪的主贴图(默认黑色)
   _Height ("波浪高度", Range(0, 2)) = 1  // 波浪起伏的高度(值越大,波浪越突出)
   _Width ("波浪密度", Range(0, 100)) = 50  // 单位长度内的波浪数量(值越大,波浪越密集)
   _Speed ("流动速度", Range(0, 100)) = 50  // 波浪流动的快慢(值越大,流动越快;0为静止)
}
  • 核心作用:暴露可调节参数,在 Unity 编辑器实时控制波浪的形态与动态效果。

2. SubShader 与 Pass 配置

SubShader
{
   Tags { "LightMode" = "ForwardBase" }  // 光照模式:正向基础光照(适配基础光照系统)
   Pass
   {
       CGPROGRAM
           #include "UnityCG.cginc"  // 引入坐标转换、UV处理工具库
           #include "Lighting.cginc"  // 引入光照工具库(本Shader暂未使用,预留扩展)
           #pragma vertex vert  // 声明顶点着色器函数
           #pragma fragment frag  // 声明片元着色器函数
           // 声明属性变量与贴图参数
           sampler2D _MainTex;
           float4 _MainTex_ST;  // 贴图的缩放(tiling)与偏移(offset)参数(TRANSFORM_TEX需用到)
           float _Height;    
           float _Width;    
           float _Speed;  

3. 数据结构定义

struct v2f
{
   float4 pos : SV_POSITION;  // 裁剪空间顶点坐标(用于屏幕渲染)
   float2 uv : TEXCOORD0;     // 传递处理后的UV坐标给片元着色器

};
  • 关键作用:简化数据传递,仅保留顶点坐标与 UV,满足波浪计算需求。

4. 顶点着色器(vert 函数)

v2f vert(appdata_base  v)
{
   v2f o;
   // 模型空间→裁剪空间(屏幕渲染必备,2D物体直接映射平面坐标)
   o.pos = UnityObjectToClipPos(v.vertex);
   // 处理UV:将顶点UV与贴图的tiling/offset结合(支持在材质面板调节贴图缩放偏移)
   o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
   return o;
}
  • 核心功能:处理坐标转换与 UV 预处理,为片元着色器的波浪计算提供基础 UV。

5. 片元着色器(frag 函数)—— 波浪核心逻辑

fixed4 frag(v2f i) : COLOR
{
   // 核心:UV纵向偏移(通过正弦函数实现波浪,关联时间实现动态流动)
   // _Width*i.uv.x:控制横向波浪密度(x每增加1,正弦周期数=Width)
   // _Time.y*_Speed:关联时间,让波浪随时间移动(实现流动)
   // sin(...):生成-1~1的周期性波动,乘_Height控制波浪高度
   // 最终让UV的y坐标随x和时间偏移,形成波浪
   i.uv.y += sin(_Width * i.uv.x + _Time.y*_Speed) *_Height;
   // 采样偏移后的UV颜色,输出波浪效果
   return tex2D(_MainTex, i.uv);
}
  • 核心原理:利用正弦函数的周期性,让 UV 的 y 坐标随 x(横向位置)和时间(_Time.y)动态偏移,采样偏移后的 UV 时,贴图呈现波浪形态,且随时间流动。

三、使用步骤(3 步完成)

  1. 创建 Shader 与材质:Unity 中右键→Create→Shader→Unlit Shader,替换为上述代码并命名 “Custom/wave”;再右键→Create→Material,将材质的 Shader 设为 “Custom/wave”。
  2. 调节参数出效果:拖入需要添加波浪的图片到_MainTex;调_Height(如 0.1→0.5,波浪高度增加);调_Width(如 20→50,波浪更密集);调_Speed(如 10→30,波浪流动更快)。
  3. 应用到物体:将材质赋给 2D Quad、UI Image 或 Sprite,运行即可看到贴图动态波浪效果。

完整代码

Shader "Custom/wave"
{
	Properties 
	{
		_MainTex ("图片", 2D) = "black" {}
		_Height ("波浪高度", Range(0, 2)) = 1     
        _Width ("波浪密度", Range(0, 100)) = 50     
        _Speed ("流动速度", Range(0, 100)) = 50  
	}
    
	SubShader 
	{
		Tags { "LightMode" = "ForwardBase" }
		Pass 
		{
			CGPROGRAM
                #include "UnityCG.cginc"
                #include "Lighting.cginc"
                #pragma vertex vert
                #pragma fragment frag
                sampler2D _MainTex;
                float4 _MainTex_ST;

                float _Height;     
                float _Width;     
                float _Speed;   

                struct v2f
                {
                    float4 pos : SV_POSITION;
                    float2 uv : TEXCOORD0; 
                };
                //顶点着色器
                v2f vert(appdata_base  v)
                {
                    v2f o;
                    //模型空间转裁剪空间 因为2d空间就是平面的,所以直接编辑裁剪空间即可
                    o.pos = UnityObjectToClipPos(v.vertex);
                    //TRANSFORM_TEX的作用是用顶点的uv去和贴图的tiling和offset作运算
                    //_MainTex_ST.xy中是tiling  _MainTex_ST.zw中是offset
                    o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
                    return o;
                }
                // 片元着色器
                fixed4 frag(v2f i) : COLOR
                {
                    //uv坐标的y = 浪高 * sin(浪宽 * 像素uv的x + 速度 * 时间增量)
                    i.uv.y += sin(_Width * i.uv.x + _Time.y*_Speed) *_Height;
                    //计算贴图颜色和uv
                    return tex2D(_MainTex, i.uv);
                }
			ENDCG
		}
	}
    //备用
	FallBack "Diffuse"
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

千年奇葩

从来没受过打赏,这玩意好吃吗?

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值