当前位置: 首页 > news >正文

干货分享 | Shader 实现 PPT 转场效果(附源码)

知乎上看到一位大佬用 Shader 实现了 PPT 里面的转场效果,转载大佬的文章,一起围观膜拜一下。

原文分为上下两篇,详细阐述了每个效果的实现。

上篇:https://zhuanlan.zhihu.com/p/378967288

下篇:https://zhuanlan.zhihu.com/p/380968758

两篇文章实现了 PPT 里面大部分切换效果,如下图所示:

并且还提供了源码,除了两张转场图片之外,没有用到其他纹理,所有形状都是 shader 生成,并且没有开 FBO,保证单次 drawcall 完成。

源码地址如下:

https://github.com/ydc258ttbaby/PPT_transtions_with_shader

摘录了几个效果供大家参考:

擦除效果

现象:从右往左将上面一张图片擦除。

思路:主要还是依赖于 mix 函数进行混合,只不过在边缘处实现渐变,渐变的实现可简单用线性插值实现,如下图所示:

从右往左的擦除就好比将一条斜线从右往左移动,随后 clamp 就成为了透明度 alpha 。

代码:

void main()
{
 vec4 texColor1 = texture(u_ourTexture1, texCoord);
 vec4 texColor2 = texture(u_ourTexture2, texCoord);
 float w = 0.5;
 float alpha = clamp(-1.0 / w * texCoord.x + (1.0 + w) / w + u_ratio * (-(1.0 + w) / w), 0.0, 1.0);
 FragColor = mix(texColor1, texColor2, alpha);
};

剥离效果

现象:一张图片像一张纸一样被揭开,显示出另一张图 。

要点:此实现类似于(十九-悬挂),假想有一根斜直线,如 y = x – 1,图片背面通过镜像得到,直线右边显示底图,左边显示上面的图。

代码实现:

// 斜直线对于 x 的表达式
float fx(float x)
{
 return x - u_width + u_ratio * (u_height + u_width + 100.0);
}
// 斜直线对于 y 的表达式
float gy(float y)
{
 return y + u_width - u_ratio * (u_height + u_width + 100.0);
}
void main()
{
 vec4 resColor = vec4(u_ratio, 0.0, 0.0, 1.0);
 vec4 texColor1 = texture(u_ourTexture1, texCoord);
 vec4 texColor2 = texture(u_ourTexture2, texCoord);
 
 // 转到画布真实的像素坐标系进行变换
 vec2 coordRealScale = texCoord * vec2(u_width, u_height);
 
 // 用二次函数,对揭开的边缘添加偏移
 float xNor = (coordRealScale.x - gy(0.0)) / (u_width - gy(0.0));
 float yNor = (coordRealScale.y - 0.0) / (fx(u_width) - 0.0);
 if (coordRealScale.x > gy(0.0) && coordRealScale.x < u_width)
 coordRealScale.y = coordRealScale.y + 70.0 * xNor * (1.0 - xNor);
 if (coordRealScale.y > 0.0 && coordRealScale.y < fx(u_width))
 coordRealScale.x = coordRealScale.x - 70.0 * yNor * (1.0 - yNor);
 
 // 沿 y = f(x) 翻转
 coordRealScale = vec2(gy(coordRealScale.y), fx(coordRealScale.x));
 vec2 coord = coordRealScale / vec2(u_width, u_height);
 // 添加光影变化
 float intensityOffset = (1.0 - (1.0 - coord.x) * u_width / u_height - coord.y) + 2.0 * u_ratio - 0.1;
 // 揭开的背面的部分
 resColor = texture(u_ourTexture1, coord) * intensityOffset;
 if (coord.x < 0.0 || coord.x > 1.0 || coord.y < 0.0 || coord.y > 1.0)
 resColor = texColor1;
 if (coordRealScale.y > fx(coordRealScale.x))
 resColor = texColor2;
 FragColor = resColor;
};

这种剥离效果在其他地方也是可以用到的,很有参考意义。

关于其他更多的效果,欢迎到原作者的文章上去看,有着详细代码讲解和技术总结,受益匪浅~~


技术交流,欢迎加我微信:ezglumes ,拉你入技术交流群。

推荐阅读:

音视频面试基础题

OpenGL ES 学习资源分享

开通专辑 | 细数那些年写过的技术文章专辑

NDK 学习进阶免费视频来了

推荐几个堪称教科书级别的 Android 音视频入门项目

觉得不错,点个在看呗~

相关文章:

  • Filament 实时渲染引擎介绍~~
  • 码率直降70%,拍乐云发布国内首个 AV1 编码引擎 Venus,引领实时视频互动革新...
  • RecyclerView性能优化的最后一公里
  • 腾讯视频会议真实内部实现分享
  • Systrace 流畅性实战 1 :了解卡顿原理
  • 短视频中解决音视频混音出现杂音的问题
  • mmap可以让程序员解锁哪些骚操作?
  • 如何实现H.264的实时传输?
  • WebRTC 系列1--创建相机预览
  • 如何用研发效能搞垮一个团队
  • 揭秘版权保护下的视频隐形水印算法(下篇)
  • 浅谈音视频自动化测试
  • 拒绝卡顿,揭秘盒马鲜生 APP Android 短视频秒播优化方案
  • WebRTC 系列2--双摄像头同时预览
  • 如何实现 Android 短视频跨页面的流畅续播?
  • 「译」Node.js Streams 基础
  • 0x05 Python数据分析,Anaconda八斩刀
  • Android 架构优化~MVP 架构改造
  • CSS3 变换
  • Git 使用集
  • IE报vuex requires a Promise polyfill in this browser问题解决
  • Java编程基础24——递归练习
  • JS进阶 - JS 、JS-Web-API与DOM、BOM
  • Mithril.js 入门介绍
  • python docx文档转html页面
  • Selenium实战教程系列(二)---元素定位
  • win10下安装mysql5.7
  • 当SetTimeout遇到了字符串
  • 反思总结然后整装待发
  • ------- 计算机网络基础
  • 用mpvue开发微信小程序
  • 06-01 点餐小程序前台界面搭建
  • 【运维趟坑回忆录 开篇】初入初创, 一脸懵
  • ​软考-高级-系统架构设计师教程(清华第2版)【第1章-绪论-思维导图】​
  • ​一些不规范的GTID使用场景
  • ​云纳万物 · 数皆有言|2021 七牛云战略发布会启幕,邀您赴约
  • "无招胜有招"nbsp;史上最全的互…
  • ## 临床数据 两两比较 加显著性boxplot加显著性
  • #多叉树深度遍历_结合深度学习的视频编码方法--帧内预测
  • $().each和$.each的区别
  • (2)MFC+openGL单文档框架glFrame
  • (42)STM32——LCD显示屏实验笔记
  • (M)unity2D敌人的创建、人物属性设置,遇敌掉血
  • (ros//EnvironmentVariables)ros环境变量
  • (草履虫都可以看懂的)PyQt子窗口向主窗口传递参数,主窗口接收子窗口信号、参数。
  • (第一天)包装对象、作用域、创建对象
  • (二)什么是Vite——Vite 和 Webpack 区别(冷启动)
  • (规划)24届春招和25届暑假实习路线准备规划
  • (论文阅读30/100)Convolutional Pose Machines
  • (三)centos7案例实战—vmware虚拟机硬盘挂载与卸载
  • (十一)JAVA springboot ssm b2b2c多用户商城系统源码:服务网关Zuul高级篇
  • (四)c52学习之旅-流水LED灯
  • (译) 函数式 JS #1:简介
  • (转)GCC在C语言中内嵌汇编 asm __volatile__
  • (转)IOS中获取各种文件的目录路径的方法