目录
原文
原文 是用 GLSL 写的
PPT_transtions_with_shader(原文glsl)
效果
一、 淡入淡出 Fade
直接调用GLSL的mix函数即可
二、推入 Push
现象:一张图片从右往左把另一张图片推出屏幕
要点:
1、判断texCoord与u_ratio的大小,选择在左右两边显示哪张图
2、同时对两张图的texCoord做一定偏移三、擦除 Wipe
现象:从右往左将上面一张图片擦除
思路:
主要还是依赖于mix函数进行混合,只不过在边缘处实现渐变,渐变的实现可简单用线性插值实现,从右往左的擦除就好比将一条斜线从右往左移动,随后clamp就成为了透明度alpha四、分割 Split
现象:从中间往两边“擦除”
思路:类似于“把擦除等效为从右往左移动”,分割的实现可抽象为下图:五、显示 Reveal
现象:先是从右往左,图片微微放大的同时屏幕变白,随后从左往右,另一张图片浮现,且微微缩小
要点:
1、 图片淡出淡入的效果与前面的擦除类似,只不过混合对象变成了白图
2、 图片缩放的实现,实现缩放时,要选择缩放中心,变换顺序为:先移动到缩放中心,执行缩放后,再从缩放中心移动回去六、切入 Cut
现象:瞬间切换,很简单的效果
七、随机线条 RandomBars
现象:前一张图片消失于很多随机线条中,后一张图片浮现,就好比在多个随机位置处执行“分割”
思路:使用for循环对多个随机位置的“分割”透明度进行叠加,取多个函数的最小值:八、形状 Shape
现象:由一个形状往四周扩散,下一张图片浮现
思路:仍然从“形状移动”的思路出发,考虑不同形状的透明度函数,只不过此时的函数变成二元函数了:九、覆盖 Cover与 揭开 Uncover
现象:一张图片从一个方向滑走,或者另一张图片滑入
要点:效果与“Push推入”很类似,只不过其中一张图片不进行顶点偏移而已十、闪光 Flash
现象:类似于闪光灯闪的一下,就切换为另一张图片
要点:先将第一张图片的RGB迅速升高,成为全白图,然后全白状态下切换为第二张图,降低RGB值,使之正常十一、溶解 Dissolve
现象:一张图溶解为许多小碎片,然后另一张图浮现
要点:
1、 将屏幕划分为多个小块,比如要划分为7*5个小块,就将xy乘以vec2(7,5),然后取floor后除以vec2(7,5)既可
2、 然后每个小块设置不同的随机值,之前介绍了一维的伪随机数生成,这里可以使用二维的伪随机数生成,每个小块设置不同的随机值后,将其与u_ratio比较,决定其溶解与否十二、翻转 Flip
现象:图片原地翻转,背面为另一张图片
要点;
1、 实现绕y轴的3D旋转和透视投影,用剪切(shear)替代投影实现
2、 一个小细节,在翻转的时候,图片往z方向有偏移量十三、棋盘 CheckBoard
现象:生成许多小方块,各自翻页,背面为下一张图片
要点:
1、 将屏幕划分为多个小块,第十一中已介绍,且每个小块的翻页时间不一样,可加二维随机数
2、 每个小块的翻转操作,同十二中的翻转Flip操作十四、百叶窗 Blinds
现象:类似广告百叶窗的切换,从三棱柱的一面旋转到另一面
要点:
1、 模拟三棱柱的旋转,将第一张图初始角度设置为0,第二张图初始角度设置为60度,同时绕虚拟三棱柱的轴,旋转120度
2、由于对于纹理坐标的变换和对顶点的坐标变换有所出入,所以实现的结果仍然有一些artifact,除了对三棱柱进行实实在在建模导入顶点坐标变换之外,没有想到好的办法十五、时钟 Clock
现象:类似时钟的指针扫过一圈,同时便随着图片的消隐于浮现
要点:
1、 通过纹理坐标的xy值,计算角度
2、 对扫过的边缘添加渐变,前面在Wipe擦除中提到实现的渐变是用一个移动一个线性函数实现的,在这里,把角度当作自变量,同样用线性插值来实现渐变十六、涟漪 Ripple
现象:类似水波纹像四周扩散,同时第二张图浮现出来
要点:
1、 水波纹最外层渐变的实现,类似于Shape形状里面的圆形
2、 水波纹对于图片的折射,可用sin函数来模拟水波
3、 水波纹波峰波谷的亮度变化,同样借助sin函数十七、蜂巢 HoneyComb
现象:第一张图逐渐旋转变大,同时以蜂窝状逐个消失,同时第二张图以蜂窝状出现
要点:
1、 实现图片的旋转与缩放,比较简单
2、 在开始和结束时,用两个擦除的效果,比较简单,加到透明度上即可
3、 写出蜂窝状的形状,并对每个形状添加不同的随机值,这块比较复杂,详细讲解:要实现的蜂窝状如图所示,我们知道,如果这些小块都是一个个矩形,那么就可以按照之前的思路容易生成,但是这些蜂窝状都是六边形,并且不像矩形那样排布很规则,我在此处介绍“最小拼接块”的思想:是否可以找到最小矩形拼接块,只要生成了这个拼接块的图案,然后复制即可?
可以看到,右边这个最小矩形拼接块,可以由两个六边形和一个长条矩形通过布尔运算获得,所以难点在于如何生成六边形?
我们知道长条矩形的生成很容易,那么怎样生成一个六边形呢?
用三个旋转角度不同的长条矩形求交集就可以!有了六边形和矩形,就可以对三个图形进行布尔运算,为此,专门为float类型写了and、or和not函数十八、闪耀 Glitter
现象:许多小的正六边形随机翻转,背面显现出另一张图片
要点:
1、 正六边形的实现,并对每个六边形区域,设置不同的旋转中心和旋转角度十九、切换 Switch
现象:两张图片左右前后切换,实现比较简单,此示例代码弄丢了
二十、帘式 Curtain
现象:一张图片类似于窗帘往两边展开,随后切换到另一张图片
要点:
1、 模拟窗帘的布料,窗帘的形状主要用sin函数进行模拟,加上一些perlin噪声进行扰动,使之更自然
2、 用关键帧的思想,实现“布料”的动画,在关键时间戳,定义好布料(纹理坐标)的变换,然后tent函数进行叠加,即进行线性插值二十一、悬挂 Drape
现象:一张图片类似一块布从上往下掉落,完成切换
要点:
1、 布往下坠落的过程,需要显示布的背面
2、 布坠落到底部后,由于惯性,会有轻微的往里偏移,随后恢复二十二、上拉帷幕 Prestige
现象:一张图片像一张布一样被上拉,从而切换到另一张图
要点:
1、 选择合适的函数,模拟布料的扭曲,同时施加噪声,模拟布料的飘动二十三、剥离 PeelOff
现象:一张图片像一张纸一张被揭开,显示出另一张图
要点:
1、 此实现类似于(十九-悬挂),假想有一根斜直线,如 y = x – 1,图片背面通过镜像得到,直线右边显示底图,左边显示上面的图二十四、库 Gallery
现象:第一张图先向内旋转,同时另一张图推着进来,最后旋转回来
要点:
1、 近似实现图片的三维变换
2、 实现镜像的效果二十五、立方体 Cube
想象:类似立方体的两面进行旋转切换
要点:
1、 近似实现图片的三维变换二十六、门 Door
现象:第一张图像门一样打开,第二张图从小到大显示出来
要点:
1、 近似实现第一张图的旋转,第二张图的缩放,同时进行混合二十七、框 Box
现象:两张图片类似一个方形的框架进行旋转,切换到另一张图
要点:
1、 近似实现图片的三维旋转,思路大致和(二十四-立方体)相同二十八、梳理 Comb
现象:图像一条一条向左向右飞出,显示出另一张图片
要点:比较简单的实现,纵向分条即可二十九、缩放 Zoom
现象:两张图片缩放,一张淡出,一张淡入,实现切换
要点:
1、 实现图片缩放,比较简单的实现三十、碎片 Shred
现象:第一张图被分割成多块碎片,分别往前往后迅速移动,在最远点瞬间切换为另一张图,随后恢复
要点:
1、 随机碎片的生成,使用简单的随机数进行生成,详见generateFrag函数
2、 近似实现碎片的三维变换三十一、跌落 Fall
现象:一张图片向里跌落,切换到另一张图片
要点:
1、 对纹理坐标进行扭曲,用多项式函数来近似边缘的扭曲
2、 对图片施加旋转的同时,进行边缘扭曲三十二、翻页 PageTurn
现象:像书本翻页一样,进行图片切换
要点:实现图片右半部分的顺时针旋转
Unity代码
00基础工具 Tools.cginc
// 图片混合方法;线性插值
fixed4 mix(fixed4 a, fixed4 b, float alpha)
{
fixed4 res = 0;
res = a * (1 - alpha) + b * alpha;
return res;
}
//判断UV是否在0-1范围内:0不在范围内;1在范围内
fixed UVRange0_1(fixed2 bud2)
{
if (bud2.x < - 0.001)
return 0.0;
if(bud2.x > 1.001)
return 0.0;
if(bud2.y < - 0.001)
return 0.0;
if(bud2.y > 1.001)
return 0.0;
return 1;
}
01Fade 淡入淡出
Shader "Jack Shaders/01Fade 淡入淡出"
{
Properties
{
_MainTex ("Texture", 2D) = "black" { }
_SecondTex ("SecondTex", 2D) = "black" { }
u_ratio ("Ratio", Range(0, 1)) = 0
}
SubShader
{
Tags { "RenderType" = "Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Assets\Shaders\Tools\Tools.cginc"
struct appdata
{
float4 vertex: POSITION;
float2 uv: TEXCOORD0;
};
struct v2f
{
float2 uv: TEXCOORD0;
float4 vertex: SV_POSITION;
};
sampler2D _MainTex;
sampler2D _SecondTex;
fixed u_ratio;
float4 _MainTex_ST;
v2f vert(appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
return o;
}
fixed4 frag(v2f i): SV_Target
{
// sample the texture
fixed4 t1 = tex2D(_MainTex, i.uv);
fixed4 t2 = tex2D(_SecondTex, i.uv);
return mix(t1, t2, u_ratio) ;
}
ENDCG
}
}
}
02Push 推入
Shader "Jack Shaders/02Push 推入"
{
Properties
{
_MainTex ("Texture", 2D) = "black" { }
_SecondTex ("SecondTex", 2D) = "black" { }
_Ratio ("Ratio", Range(0, 1)) = 0
}
SubShader
{
Tags { "RenderType" = "Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex: POSITION;
float2 uv: TEXCOORD0;
};
struct v2f
{
float2 uv: TEXCOORD0;
float4 vertex: SV_POSITION;
};
sampler2D _MainTex;
sampler2D _SecondTex;
fixed _Ratio;
float4 _MainTex_ST;
v2f vert(appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
return o;
}
fixed4 frag(v2f i): SV_Target
{
fixed4 res = 0 ;
//向左
fixed R = 1 - _Ratio;
if (i.uv.x > R)
res = tex2D(_SecondTex, fixed2(i.uv.x - R + 1, i.uv.y));
else
res = tex2D(_MainTex, fixed2(i.uv.x - R, i.uv.y));
// //向右
// fixed R = _Ratio;
// if (i.uv.x > R)
// res = tex2D(_MainTex, fixed2(i.uv.x - R, i.uv.y));
// else
// res = tex2D(_SecondTex, fixed2(i.uv.x - R + 1, i.uv.y));
return res ;
}
ENDCG
}
}
}
03Fade 擦除
Shader "Jack Shaders/03Fade 擦除"
{
Properties
{
_MainTex ("Texture", 2D) = "black" { }
_SecondTex ("SecondTex", 2D) = "black" { }
_Ratio ("Ratio", Range(0, 1)) = 0
}
SubShader
{
Tags { "RenderType" = "Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Assets\Shaders\Tools\Tools.cginc"
struct appdata
{
float4 vertex: POSITION;
float2 uv: TEXCOORD0;
};
struct v2f
{
float2 uv: TEXCOORD0;
float4 vertex: SV_POSITION;
};
sampler2D _MainTex;
sampler2D _SecondTex;
fixed _Ratio;
float4 _MainTex_ST;
v2f vert(appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
return o;
}
fixed4 frag(v2f i): SV_Target
{
fixed4 t1 = tex2D(_MainTex, i.uv);
fixed4 t2 = tex2D(_SecondTex, i.uv);
float w = 0.5 ;
float alpha = -1.0 / w * i.uv.x + (1.0 + w) / w + _Ratio * ( - (1.0 + w) / w);
alpha = clamp(alpha, 0.0, 1.0);
return mix(t1, t2, alpha) ;
}
ENDCG
}
}
}
04Split 分割
Shader "Jack Shaders/04Split 分割"
{
Properties
{
_MainTex ("Texture", 2D) = "black" { }
_SecondTex ("SecondTex", 2D) = "black" { }
_Ratio ("Ratio", Range(0, 1)) = 0
}
SubShader
{
Tags { "RenderType" = "Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex: POSITION;
float2 uv: TEXCOORD0;
};
struct v2f
{
float2 uv: TEXCOORD0;
float4 vertex: SV_POSITION;
};
sampler2D _MainTex;
sampler2D _SecondTex;
fixed _Ratio;
float4 _MainTex_ST;
v2f vert(appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
return o;
}
fixed4 frag(v2f i): SV_Target
{
// sample the texture
fixed4 t1 = tex2D(_MainTex, i.uv);
fixed4 t2 = tex2D(_SecondTex, i.uv);
float w = 0.2 ;
float alpha = clamp(abs(i.uv.x - 0.5) / w + 1.0 + _Ratio * (-0.5 / w - 1.0), 0.0, 1.0);
fixed3 mixed = t1.rgb * (1 - alpha) + t2.rgb * alpha ;
return fixed4(mixed, 1) ;
}
ENDCG
}
}
}
Unity工程
项目连接:https://download.csdn.net/download/yhx956058885/19759075