博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Shader 动画
阅读量:7235 次
发布时间:2019-06-29

本文共 1867 字,大约阅读时间需要 6 分钟。

Shader 动画和 Canvas 动画原理是一样的,通过定时器循环渲染,并改变画布中图形的属性来实现动画。

一些 Shader 编辑器都已经实现好了定时器的功能,同时会传递一些跟时间相关的值给到着色器代码中,如 ShaderToy 中与时间相关的属性是 iTime/iTimeDelta,gl-transition 中与时间相关的属性是 progress。通过将着色器代码中的变量与时间相结合,就可以让动画产生。

一、位移动画

在之前的中讲到了坐标的运算,其中加减就是位移:

那常规的位移动画就不说,下面讲些复杂的运动:

1. 圆周运动

st += vec(cos(u_time), sin(u_time)) 就是圆周运动了:

二、旋转

旋转可以通过矩阵来轻松完成:

但你会发现,当我们把矩阵和坐标相乘,得到的确实上面的圆周运动,这是因为旋转坐标在左下角,如果想旋转矩形,则必须把中心点挪到矩形中心,或者换个说法,把矩形中心挪到左下角。

封装好的代码:

mat2 rotate2d(float _angle){    return mat2(cos(_angle),-sin(_angle),                sin(_angle),cos(_angle));}复制代码

当我们在非正方形的画布中对材质进行旋转的时候,会遇到一个难以避开的问题,就是拉伸问题。举个例子,当画布是矩形时,暴露了旋转时拉伸的问题:

// 部分代码void main() {    vec2 st = textureCoordinate;    float ratio = inputImageTextureSize.x / inputImageTextureSize.y;    float animationTime = getAnimationTime();    float easingTime = animationTime;    float bigRotation = 30./180.*3.14159;    st = rotateUv(st, bigRotation*easingTime, vec2(.5, .5), 1.);    gl_FragColor = texture2D(inputImageTexture, st);}复制代码

这篇也提到了这个问题,之所以会出现这个问题,是因为由于宽高的比例不是 1:1,说明虽然 x 和 y 的坐标都是 0~1,但是它们表示的长度是不一样的,正因为这个长度不一样,导致在旋转的时候,像素点的运动并不符合画布的比例:

而解决方案也比较简单,我们在旋转的时候,对 y 轴进行画布比例的拉伸即可:

void main() {    vec2 st = textureCoordinate;    float ratio = inputImageTextureSize.x / inputImageTextureSize.y;    float animationTime = getAnimationTime();    float easingTime = animationTime;    float bigRotation = 30./180.*3.14159;    st.y *= 1./ratio;    st = rotateUv(st, bigRotation*easingTime, vec2(.5, .5), 1.);    st.y *= ratio;    gl_FragColor = texture2D(inputImageTexture, st);}复制代码

三、缩放

缩放就是坐标的乘除运算,同样也可以通过矩形来实现:

同理,如果不对坐标系进行转换,缩放的中心还是在左下角:

两个动画组合一起:

封装好的代码:

mat2 scale(vec2 _scale){    return mat2(_scale.x,0.0,                0.0,_scale.y);}复制代码

四、正弦运动

正弦余弦是非常优美的动画曲线,我们在讲也展示过下面这张图(图片来源于bookofshader):

所以通过这张图你应该知道正弦余弦函数可以做出什么样的效果了,我们来试试:

这是笛卡尔坐标系的运动,假设我们把坐标系变成,大家能脑补大概的效果了吗?

假如我想做一个外向扩散的动画,类似雷达那样的效果呢?去掉 sin() 函数即可:

相关链接:

转载地址:http://ptlfm.baihongyu.com/

你可能感兴趣的文章
【AngularJS】—— 4 表达式
查看>>
[LeetCode] Surrounded Regions
查看>>
【Android布局】在程序中设置android:gravity 和 android:layout_Gravity属性
查看>>
U盘启动笔记本无法安装Win7问题和解决
查看>>
基于SignalR的站点有连接数限制问题及解决方案
查看>>
程序猿当下需要准备涉及的技术方向
查看>>
一起学微软Power BI系列-使用技巧(1)连接Oracle与Mysql数据库
查看>>
2017"百度之星"程序设计大赛 - 复赛1005&&HDU 6148 Valley Numer【数位dp】
查看>>
Linux setjmp longjmp
查看>>
Java自定义注解开发
查看>>
EMF介绍系列(四、枚举类型、自定义类型和Map)
查看>>
淘宝API开发系列--商家的绑定
查看>>
js函数定义参数个数和实际传入参数的对比
查看>>
从数据库中获取Insert语句
查看>>
DataInputStream和DataOutputStream
查看>>
Database2Sharp重要更新之数据库文档的生成(国庆专辑,祝福我们的祖国)
查看>>
线程的通俗讲解
查看>>
十年之后再看“面向对象”
查看>>
HDFS简介【全面讲解】
查看>>
UVA 11292 Dragon of Loowater(简单贪心)
查看>>