前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >抖音“传送带”特效性能问题终极解决方案

抖音“传送带”特效性能问题终极解决方案

作者头像
字节流动
发布2023-12-14 18:51:06
1500
发布2023-12-14 18:51:06
举报
文章被收录于专栏:字节流动字节流动

抖音传送带特效原理

传送带特效

通过仔细观察抖音的传送带特效,你可以发现左侧是不停地更新预览画面,右侧看起来就是一小格一小格的竖条状图像区域不断地向右移动,一直移动到右侧边界位置。

抖音传送带特效原理

预览的时候每次拷贝一小块预览区域的图像送到传送带,这就形成了源源不断地向右传送的效果。

这种实现方式会有什么问题呢?

从上面的文章可以看出,它使用的是 CPU 内存来作为缓存,然后每次绘制之前都需要进行一系列的拷贝,最后再上传数据到纹理。

由于每帧都需要进行拷贝和上传数据的操作,在遇到分辨率比较高的图像时,造成性能和功耗上的开销很大。

优化的思路就是要减少数据拷贝和传输,使用纹理作为缓存,需要使用2个纹理作为缓存,一个纹理作为输入缓存,另一个作为输出缓存,每次绘制时2个纹理进行交换,这个需要配合帧缓冲区来使用,需要做离屏渲染。

如果你对帧缓冲区使用不太了解,可以参考文章:

OpenGL ES 3.0 FBO 离屏渲染(校正版)

如果对上面的思路还是不太明白的话,我画了一张图给你。

如图所示,input 表示输入纹理,buffer1表示保存上一次渲染结果的纹理,在 shader 中做一下偏移采样,然后和 input 拼成一张图,渲染结果保存到 buffer2 纹理,然后 buffer2 纹理作为下一次渲染的 buffer1,最后重复这个过程。

偏移采样和拼图的 shader:

代码语言:javascript
复制
precision highp float;
varying highp vec2 vTextureCoord;
uniform lowp sampler2D sTexture;//输入纹理
uniform lowp sampler2D sTexture2;//buffer 纹理
uniform highp vec2 inputSize;

void main() {
    vec2 uv = vTextureCoord;
    vec4 color = texture2D(sTexture, uv);//输入采样

    float offset = 10.0;
    uv.x -= offset * 1.0 / inputSize.x;//每次向右移动10个像素

    vec4 bufferCol = texture2D(sTexture2, uv);//buffer texture 采样
    float mask_val = step(uv.x, 0.5);
    gl_FragColor = mix(bufferCol, color, mask_val);//左右两边图像拼接在一起
}

实测 4K 视频毫无压力:

-- END --

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2023-12-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 字节流动 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 抖音传送带特效原理
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档