概述

在Shader中,波形可以作为一种模拟动态的手段,例如颜色的波动,形状的波动,可以基于此创作出各种效果。
下文介绍几种基本波形以及变种的Shader实现代码,并配以函数图像和简单动画效果图。在效果图中,Shader代码计算出y值,在顶点着色器中赋给顶点的y坐标或在片段着色器中插值后乘以颜色。效果图中利用了一个细长条网格,它的uv.x的两端为0和一个与它长度等比例的一个较大的值。

波形公式中参数的说明:

base:基点。波形的起始点。振幅从此点开始计算。
amplitude:振幅。振幅越大,波形峰值越大或谷值越小。
phase:相位。决定波形的起始值。波形随着phase整体平移。
freq:频率。单位时间内波形重复的次数。

每个参数的具体作用分析可见上一篇文章。

正弦家族 Sin Family:

完美正弦 Perfect Sin:

公式描述:y=sin(x*freq+phase)*amplitude+base
Shader代码:y=sin(fmod(v.uv.x,1.0f)2.0f3.1415926f+_Time.y);

山形 Hill:

公式描述:y=abs(sin(x*freq+phase))*amplitude+base
Shader代码:y=abs(sin(fmod(v.uv.x,1.0f)*3.1415926f+_Time.y));

倒转山行 Inverse Hill:

公式描述:y=(1-abs(sin(x*freq+phase)))*amplitude+base
Shader代码:y=1.0f-abs(sin(fmod(v.uv.x,1.0f)*3.1415926f+_Time.y));

锯齿家族 Sawtooth Family:

锯齿 SawTooth:

公式描述:y=max(min(((x+phase) mod freq),1),0)*amplitude+base
Shader代码:y=saturate(fmod(v.uv.x+_Time.y,1.0f));

倒转锯齿 Inverse SawTooth:

公式描述:y=(max(min(((x+phase) mod freq),1),0))*amplitude+base
Shader代码:y=1-saturate(fmod(v.uv.x+_Time.y,1.0f));

指数锯齿 Exponential SawTooth:

公式描述:y=max(min(((x+phase) mod freq)^exp,1),0)*amplitude+base
Shader代码:y=saturate(pow(frac(v.uv.x+_Time.y),10.0f));

倒转指数锯齿 Inverse Exponential SawTooth:

公式描述:y=(1-max(min(((x+phase) mod freq)^exp,1),0))*amplitude+base
Shader代码:y=1-saturate(pow(fmod(v.uv.x+_Time.y,1.0f),10.0f));

饱和指数锯齿 Saturate Exponential SawTooth:

公式描述:y=min(max(min(((x+phase) mod freq)^10,1),0)*100,1)*amplitude+base
类似于指数锯齿,但单位时间内波形达到峰值时间更长
Shader代码:y=saturate(saturate(pow(fmod(x+_Time.y,1.0f),10.0f))*100.0f);

三角形家族

三角形 Triangle

公式描述:y=abs(((x*freq+phase) mod 1)*2-1)*amplitude+base
Shader代码:y=abs(fmod(x+_Time.y,1.0f)*2.0f-1.0f);

梯形 Trapezium

公式描述:y=min(abs(((x*freq+phase)mod1)*2-1)*2,1)*amplitude+base
Shader代码:y=saturate(abs(fmod(x+_Time.y,1.0f)*2.0f-1.0f)*2.0f);

倒转梯形/不连续三角形 Inverse Trapezium/Discrete Triangles

公式描述:y=(1-min(abs(((x*freq+phase)mod 1)*2-1)*2,1))*amplitude+base
Shader代码:y=1-saturate(abs(fmod(x+_Time.y,1.0f)*2.0f-1.0f)*2.0f);

直角家族

直角

公式描述:y=round(sin(x*freq+phase))*amplitude+base
Shader代码:y=round(sin(x+_Time.y));

效果图中使用的Shader

顶点波动动画:

Shader "Unlit/WaveformTest"
{Properties{_MainTex ("Texture", 2D) = "white" {}}SubShader{Tags { "RenderType"="Opaque" }LOD 100Pass{CGPROGRAM#pragma vertex vert#pragma fragment frag// make fog work#pragma multi_compile_fog#include "UnityCG.cginc"struct appdata{float4 vertex : POSITION;float2 uv : TEXCOORD0;};struct v2f{float2 uv : TEXCOORD0;UNITY_FOG_COORDS(1)float4 vertex : SV_POSITION;};sampler2D _MainTex;float4 _MainTex_ST;v2f vert (appdata v){v2f o;float phase=_Time.y;float y;float x=v.uv.x;//perfect sin//y=sin(fmod(v.uv.x,1.0f)*2.0f*3.1415926f+phase);//hill//y=abs(sin(fmod(v.uv.x,1.0f)*3.1415926f+phase));//inverse hill//y=1.0f-abs(sin(fmod(v.uv.x,1.0f)*3.1415926f+phase));//SawTooth//y=saturate(fmod(v.uv.x+phase,1.0f));//Inverse SawTooth//y=1-saturate(fmod(v.uv.x+phase,1.0f));//Exponential SawTooth//y=saturate(pow(frac(v.uv.x+phase),10.0f));//Inverse Exponential SawTooth//y=1-saturate(pow(fmod(v.uv.x+phase,1.0f),10.0f));//Saturate Exponential SawTooth//y=saturate(saturate(pow(fmod(x+phase,1.0f),10.0f))*100.0f);//Triangle//y=abs(fmod(x+phase,1.0f)*2.0f-1.0f);//Tapezoid//y=saturate(abs(fmod(x+phase,1.0f)*2.0f-1.0f)*2.0f);//Discontinuous Triangles/Inverse Trapezoid//y=1-saturate(abs(fmod(x+phase,1.0f)*2.0f-1.0f)*2.0f);//Squarey=round(sin(x+phase));v.vertex.y=y;o.vertex = UnityObjectToClipPos(v.vertex);o.uv = TRANSFORM_TEX(v.uv, _MainTex);UNITY_TRANSFER_FOG(o,o.vertex);return o;}fixed4 frag (v2f i) : SV_Target{// sample the texturefixed4 col = tex2D(_MainTex, i.uv);// apply fogUNITY_APPLY_FOG(i.fogCoord, col);return col;}ENDCG}}
}

颜色波动动画:

Shader "Unlit/WaveformTestFrag"
{Properties{_MainTex ("Texture", 2D) = "white" {}_Color("Color",color)=(1,1,1,1)}SubShader{Tags { "RenderType"="Opaque" }LOD 100Pass{CGPROGRAM#pragma vertex vert#pragma fragment frag// make fog work#pragma multi_compile_fog#include "UnityCG.cginc"struct appdata{float4 vertex : POSITION;float2 uv : TEXCOORD0;};struct v2f{float2 uv : TEXCOORD0;float y:FLOAT;UNITY_FOG_COORDS(1)float4 vertex : SV_POSITION;};sampler2D _MainTex;float4 _MainTex_ST;fixed4 _Color;v2f vert (appdata v){v2f o;float phase=_Time.y;float y;float x=v.uv.x;//perfect sin//y=sin(fmod(v.uv.x,1.0f)*2.0f*3.1415926f+phase);//hill//y=abs(sin(fmod(v.uv.x,1.0f)*3.1415926f+phase));//inverse hill//y=1.0f-abs(sin(fmod(v.uv.x,1.0f)*3.1415926f+phase));//SawTooth//y=saturate(fmod(v.uv.x+phase,1.0f));//Inverse SawTooth//y=1-saturate(fmod(v.uv.x+phase,1.0f));//Exponential SawTooth//y=saturate(pow(frac(v.uv.x+phase),10.0f));//Inverse Exponential SawTooth//y=1-saturate(pow(fmod(v.uv.x+phase,1.0f),10.0f));//Saturate Exponential SawTooth//y=saturate(saturate(pow(fmod(x+phase,1.0f),10.0f))*100.0f);//Triangle//y=abs(fmod(x+phase,1.0f)*2.0f-1.0f);//Tapezoid//y=saturate(abs(fmod(x+phase,1.0f)*2.0f-1.0f)*2.0f);//Discontinuous Triangles/Inverse Trapezoid//y=1-saturate(abs(fmod(x+phase,1.0f)*2.0f-1.0f)*2.0f);//Squarey=round(sin(x+phase));o.y=y;o.vertex = UnityObjectToClipPos(v.vertex);o.uv = TRANSFORM_TEX(v.uv, _MainTex);UNITY_TRANSFER_FOG(o,o.vertex);return o;}fixed4 frag (v2f i) : SV_Target{// sample the texturefixed4 col = tex2D(_MainTex, i.uv);// apply fogUNITY_APPLY_FOG(i.fogCoord, col);return _Color*i.y;}ENDCG}}
}

参考:
Algorithmic drawing,Patricio Gonzalez Vivo https://thebookofshaders.com/05/
Quake3 Arena Shader Manual Revision#12, Paul Jaquays and Brian Hook
Tilt Brush, Google
维护日志:
2020-8-15:review

Unity Shader:Waveform波形(2)-基本波形:正弦,三角,锯齿,直角以及其变种的实现方式相关推荐

  1. Unity Shader入门精要笔记(五):其他数学相关介绍

    本系列文章由Aimar_Johnny编写,欢迎转载,转载请标明出处,谢谢. http://blog.csdn.net/lzhq1982/article/details/73747162 前两篇介绍了U ...

  2. Unity Shader:Waveform波形(3)-复合波

    2D复合波 (图1:在xy平面有三个波,y1=sinx,y2=sin2x,y3=sin3x) 根据叠加原理(superposition principle),可以将这三个波组合成一个复合波形,这个复合 ...

  3. Unity Shader 序列帧动画

    shader中的序列帧动画属于纹理动画中的一种,主要原理是将给定的纹理进行等分,再根据时间的变化循环播放等分中的一部分. Unity Shader 内置时间变量 名称 类型 描述 _Time floa ...

  4. 【Unity Shader】 CubeMap(立方体贴图)

    Unity Shader 立方体贴图 一.介绍CubeMap Shader中对CubeMap采样 Unity中如何制作CubeMap 二.Reflect CubeMap(反射立方体纹理用于环境映射) ...

  5. 《Unity Shader 入门精要》读书笔记

    <Unity Shader 入门精要>读书笔记 --记录一下自己看书时遇到的一下困惑的地方和自己的一些想法,愿明天的我更加强大 1.要正确获得阴影和光照衰减效果,需要#pragma mul ...

  6. 《Unity Shader入门精要》笔记01 前言

    <Unity Shader入门精要>笔记01 前言 --本系列是基于人民邮电出版社<Unity Shader入门精要>(冯乐乐著 )的自学Unity Shader笔记,如果您发 ...

  7. Unity Shader - 翻书效果

    今天实现一个简单的翻书的效果,话不多说,先上一张效果图: 这里就随便用的一张纹理了,我们还是称为"翻木板"吧,哈哈. 实现过程: 其实这个效果实现起来还是挺简单的,大概思路其实就是 ...

  8. Unity Shader入门精要--第4 章 学习Shader 所需的数学基础:点和矢量

    Unity系列文章目录 文章目录 Unity系列文章目录 前言 点和矢量 4.3.1 点和矢量的区别 参考 前言 点(point)是n 维空间(游戏中主要使用二维和三维空间)中的一个位置,它没有大小. ...

  9. Unity Shader动画-做捕鱼达人效果

    本篇将介绍向Unity Shader中引入时间变量,以实现一个顶点动画和一个UV动画的效果. 捕鱼达人效果 内置时间变量 1: float4是内置向量 (x, y, z, w); float4 a; ...

最新文章

  1. RabbitMQ是什么
  2. android里的editText怎么用,Android自定义控件EditText使用详解
  3. 织梦DEDE后台定时分时段自动更新发布文章插件
  4. 《linux内核完全剖析:基于0.12内核》读书笔记一
  5. 淘宝拼多多之争,从宏观的角度看拼多多是如何实现商业逆袭的?
  6. WinForm 数据库无限填充树目录 treeView
  7. http post,get,put,delete区别(收集整理)
  8. socket通信数据类型
  9. 《Access 2007开发指南(修订版)》一一1.11 额外的提示和技巧
  10. postfixadmin 导入数据库出错 ERROR 1062 (23000) at line 29
  11. 几个查询优化小技巧,可以大大提高效率并解决一些问题
  12. [译]如何成为一个优秀的前端工程师
  13. 创建物理卷报错Can‘t open /dev/sdb1 exclusively. Mounted filesystem?以及对应的解决方法
  14. Google网络硬盘GDrive在几个月内即将成真?!
  15. 直播推流拉流概念介绍
  16. java 加密word_Java 加密和解密PDF文档
  17. 2020 icpc 沈阳
  18. 苹果手机怎样添加无线网服务器,如何让苹果手机网速提升三倍?
  19. p5.js实现细胞免疫动画
  20. 浅谈LZSS与游戏图片破解

热门文章

  1. Ubuntu下Chrome浏览器不能以根用户身份运行的解决方法
  2. python有趣的函数_Python中有趣在__call__函数
  3. html盒子中盒子排列,css3中弹性盒排布使用方法
  4. gitlab 只能owner 上传_代码管理-gitlab使用方法建议
  5. 二叉搜索树的删除操作可以交换吗_一文看懂数据结构中的树
  6. java日期格式化代码的写法_Java中的`DateTimeFormatter`格式化代码中的`uuuu`与`yyyy`?...
  7. mysql删除emp表的语句_MySQL删除数据表(DORP TABLE语句)
  8. mysql olap 函数_Mysql中的窗口函数
  9. 商业方向的大数据专业_好程序员大数据培训分享大数据就业方向有哪些
  10. python 获取当前是星期几_基金定投选星期几更划算?[python统计分析]